diff --git a/client/src/App/App.js b/client/src/App/App.js index eac4b499d..1ce5d674c 100644 --- a/client/src/App/App.js +++ b/client/src/App/App.js @@ -24,6 +24,9 @@ const Unauthorized = lazy(() => import("../pages/unauthorized/unauthorized.component") ); const CsiPage = lazy(() => import("../pages/csi/csi.container.page")); +const MobilePaymentContainer = lazy(() => + import("../pages/mobile-payment/mobile-payment.container") +); const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -50,20 +53,25 @@ export function App({ checkUserSession, currentUser }) {
- }> - - - - - + }> + + + + + + diff --git a/client/src/components/_test/test.component.jsx b/client/src/components/_test/test.component.jsx index 6a547176a..b02768f4c 100644 --- a/client/src/components/_test/test.component.jsx +++ b/client/src/components/_test/test.component.jsx @@ -1,11 +1,17 @@ import axios from "axios"; -import React from "react"; +import React, { useState, useEffect } from "react"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { auth, logImEXEvent } from "../../firebase/firebase.utils"; import { selectBodyshop } from "../../redux/user/user.selectors"; import { setEmailOptions } from "../../redux/email/email.actions"; import { TemplateList } from "../../utils/TemplateConstants"; +import { + PaymentRequestButtonElement, + useStripe, + Elements, + useElements, +} from "@stripe/react-stripe-js"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -15,86 +21,53 @@ const mapDispatchToProps = (dispatch) => ({ setEmailOptions: (e) => dispatch(setEmailOptions(e)), }); -export default connect( - mapStateToProps, - mapDispatchToProps -)(function Test({ bodyshop, setEmailOptions }) { - const handle = async () => { - const response = await axios.post( - "/accounting/iif/receivables", - { jobId: "661dd1d5-bf06-426f-8bd2-bd9e41de8eb1" }, - { - headers: { - Authorization: `Bearer ${await auth.currentUser.getIdToken(true)}`, +function Test({ bodyshop, setEmailOptions }) { + const stripe = useStripe(); + + const [paymentRequest, setPaymentRequest] = useState(null); + useEffect(() => { + if (stripe) { + console.log("in useeff"); + const pr = stripe.paymentRequest({ + country: "CA", + displayItems: [{ label: "Deductible", amount: 1099 }], + currency: "cad", + total: { + label: "Demo total", + amount: 1099, }, - } - ); - console.log("handle -> result", response); - const url = window.URL.createObjectURL(new Blob([response.data])); - const link = document.createElement("a"); - link.href = url; - link.setAttribute( - "download", - response.headers.filename || "receivables.iif" - ); //or any other extension - document.body.appendChild(link); - link.click(); - }; + requestPayerName: true, + requestPayerEmail: true, + }); - const handleLocal = async () => { - try { - const response = await axios.post( - "http://localhost:1337/qb/receivables", - { jobId: "661dd1d5-bf06-426f-8bd2-bd9e41de8eb1" }, - { - headers: { - Authorization: `Bearer ${await auth.currentUser.getIdToken(true)}`, - }, + console.log("pr", pr); + // Check the availability of the Payment Request API. + pr.canMakePayment().then((result) => { + console.log("result", result); + if (result) { + setPaymentRequest(pr); + } else { + var details = { + total: { label: "", amount: { currency: "CAD", value: "0.00" } }, + }; + // new PaymentRequest( + // [{ supportedMethods: ["basic-card"] }], + // {} + // // details + // ).show(); } - ); - console.log("handle -> result", response); - } catch (error) { - console.log("error", JSON.stringify(error)); + }); } - }; + }, [stripe]); - const handleQbxml = async () => { - const response = await axios.post( - "/accounting/qbxml/receivables", - { jobId: "661dd1d5-bf06-426f-8bd2-bd9e41de8eb1" }, - { - headers: { - Authorization: `Bearer ${await auth.currentUser.getIdToken(true)}`, - }, - } + if (paymentRequest) { + console.log("****************render"); + return ( +
+ +
); - console.log("handle -> XML", response); - - try { - const response2 = await axios.post( - "http://localhost:1337/qb/receivables", - response.data, - { - headers: { - Authorization: `Bearer ${await auth.currentUser.getIdToken(true)}`, - }, - } - ); - console.log("handle -> result", response2); - } catch (error) { - console.log("error", error, JSON.stringify(error)); - } - - // const url = window.URL.createObjectURL(new Blob([response.data])); - // const link = document.createElement("a"); - // link.href = url; - // link.setAttribute( - // "download", - // response.headers.filename || "receivables.iif" - // ); //or any other extension - // document.body.appendChild(link); - // link.click(); - }; + } return (
@@ -116,9 +89,6 @@ export default connect( > send email - - -
); -}); +} + +export default connect(mapStateToProps, mapDispatchToProps)(Test); diff --git a/client/src/firebase/firebase.utils.js b/client/src/firebase/firebase.utils.js index 694d1d1bb..0be887823 100644 --- a/client/src/firebase/firebase.utils.js +++ b/client/src/firebase/firebase.utils.js @@ -61,54 +61,56 @@ export const logImEXEvent = (eventName, additionalParams, stateProp = null) => { analytics.logEvent(eventName, eventParams); }; -messaging.onMessage(async (payload) => { - console.log("**********UTILS Message received. ", payload); - navigator.serviceWorker.getRegistration().then((registration) => { - return registration.showNotification( - "[UTIL]" + payload.notification.title, - payload.notification - ); +if (messaging) { + messaging.onMessage(async (payload) => { + console.log("**********UTILS Message received. ", payload); + navigator.serviceWorker.getRegistration().then((registration) => { + return registration.showNotification( + "[UTIL]" + payload.notification.title, + payload.notification + ); + }); + + // if (!payload.clientId) return; + + // // Get the client. + // const client = await clients.get(payload.clientId); + // // Exit early if we don't get the client. + // // Eg, if it closed. + // if (!client) return; + + // // Send a message to the client. + // console.log("Posting to client."); + // client.postMessage({ + // msg: "Hey I just got a fetch from you!", + // url: payload.request.url, + // }); + + // [START_EXCLUDE] + // Update the UI to include the received message. + //appendMessage(payload); + + // [END_EXCLUDE] }); - // if (!payload.clientId) return; - - // // Get the client. - // const client = await clients.get(payload.clientId); - // // Exit early if we don't get the client. - // // Eg, if it closed. - // if (!client) return; - - // // Send a message to the client. - // console.log("Posting to client."); - // client.postMessage({ - // msg: "Hey I just got a fetch from you!", - // url: payload.request.url, - // }); - - // [START_EXCLUDE] - // Update the UI to include the received message. - //appendMessage(payload); - - // [END_EXCLUDE] -}); - -messaging.onTokenRefresh(() => { - messaging - .getToken() - .then((refreshedToken) => { - console.log("**********Token refreshed."); - // Indicate that the new Instance ID token has not yet been sent to the - // app server. - // setTokenSentToServer(false); - // // Send Instance ID token to app server. - // sendTokenToServer(refreshedToken); - // // [START_EXCLUDE] - // // Display new Instance ID token and clear UI of all previous messages. - // resetUI(); - // [END_EXCLUDE] - }) - .catch((err) => { - console.log("**********Unable to retrieve refreshed token ", err); - // showToken("Unable to retrieve refreshed token ", err); - }); -}); + messaging.onTokenRefresh(() => { + messaging + .getToken() + .then((refreshedToken) => { + console.log("**********Token refreshed."); + // Indicate that the new Instance ID token has not yet been sent to the + // app server. + // setTokenSentToServer(false); + // // Send Instance ID token to app server. + // sendTokenToServer(refreshedToken); + // // [START_EXCLUDE] + // // Display new Instance ID token and clear UI of all previous messages. + // resetUI(); + // [END_EXCLUDE] + }) + .catch((err) => { + console.log("**********Unable to retrieve refreshed token ", err); + // showToken("Unable to retrieve refreshed token ", err); + }); + }); +} diff --git a/client/src/pages/manage/manage.page.component.jsx b/client/src/pages/manage/manage.page.component.jsx index 041984369..291667c61 100644 --- a/client/src/pages/manage/manage.page.component.jsx +++ b/client/src/pages/manage/manage.page.component.jsx @@ -165,15 +165,20 @@ export function Manage({ match, conflict }) { } > + + + - - - + - { + if (stripe) { + console.log("in useeff"); + const pr = stripe.paymentRequest({ + country: "CA", + displayItems: [{ label: "Deductible", amount: 1 }], + currency: "cad", + total: { + label: "Demo total", + amount: 1, + }, + requestPayerName: true, + requestPayerEmail: true, + }); + + console.log("pr", pr); + // Check the availability of the Payment Request API. + pr.canMakePayment().then((result) => { + console.log("result", result); + if (result) { + setPaymentRequest(pr); + } else { + var details = { + total: { label: "", amount: { currency: "CAD", value: "0.00" } }, + }; + // new PaymentRequest( + // [{ supportedMethods: ["basic-card"] }], + // {} + // // details + // ).show(); + } + }); + } + }, [stripe]); + + if (paymentRequest) { + // paymentRequest.on("paymentmethod", async (ev) => { + // //Call server side to get the client secret + // // Confirm the PaymentIntent without handling potential next actions (yet). + // const { error: confirmError } = await stripe.confirmCardPayment( + // clientSecret, + // { payment_method: ev.paymentMethod.id }, + // { handleActions: false } + // ); + + // if (confirmError) { + // // Report to the browser that the payment failed, prompting it to + // // re-show the payment interface, or show an error message and close + // // the payment interface. + // ev.complete("fail"); + // } else { + // // Report to the browser that the confirmation was successful, prompting + // // it to close the browser payment method collection interface. + // ev.complete("success"); + // // Let Stripe.js handle the rest of the payment flow. + // const { error, paymentIntent } = await stripe.confirmCardPayment( + // clientSecret + // ); + // if (error) { + // // The payment failed -- ask your customer for a new payment method. + // } else { + // // The payment has succeeded. + // } + // } + // }); + return ( +
+ +
+ ); + } + + return
; +} diff --git a/client/src/pages/mobile-payment/mobile-payment.container.jsx b/client/src/pages/mobile-payment/mobile-payment.container.jsx new file mode 100644 index 000000000..18c36a1cb --- /dev/null +++ b/client/src/pages/mobile-payment/mobile-payment.container.jsx @@ -0,0 +1,23 @@ +import React from "react"; +import MobilePaymentComponent from "./mobile-payment.component"; +import { Elements } from "@stripe/react-stripe-js"; +import { loadStripe } from "@stripe/stripe-js"; + +const stripePromise = new Promise((resolve, reject) => { + resolve( + loadStripe(process.env.REACT_APP_STRIPE_PUBLIC_KEY, { + stripeAccount: "acct_1Fa7lFIEahEZW8b4", + }) + ); +}); + +export default function MobilePaymentContainer() { + return ( +
+ The mobile payment container. + + + +
+ ); +} diff --git a/server.js b/server.js index 0a6d04237..48394ed5a 100644 --- a/server.js +++ b/server.js @@ -83,6 +83,7 @@ app.post("/notifications/send", fb.sendNotification); //Stripe Processing var stripe = require("./server/stripe/payment"); app.post("/stripe/payment", stripe.payment); +app.post("/stripe/mobilepayment", stripe.mobile_payment); //Tech Console var tech = require("./server/tech/tech"); diff --git a/server/stripe/payment.js b/server/stripe/payment.js index 3e315d410..b03605026 100644 --- a/server/stripe/payment.js +++ b/server/stripe/payment.js @@ -44,3 +44,38 @@ exports.payment = async (req, res) => { res.status(400).send(error); } }; + +exports.mobile_payment = async (req, res) => { + const { amount, stripe_acct_id } = req.body; + console.log("exports.payment -> amount", amount); + console.log("exports.payment -> stripe_acct_id", stripe_acct_id); + try { + await stripe.paymentIntents + .create( + { + //Pull the amounts from the payment request. + payment_method_types: ["card"], + amount: amount, + currency: "cad", + application_fee_amount: 50, + }, + { + stripeAccount: stripe_acct_id, + } + ) + .then(function (paymentIntent) { + try { + return res.send({ + clientSecret: paymentIntent.client_secret, + }); + } catch (err) { + return res.status(500).send({ + error: err.message, + }); + } + }); + } catch (error) { + console.log("error", error); + res.status(400).send(error); + } +};