UNPKG

medusa-plugin-paypal

Version:
203 lines (176 loc) 4.43 kB
# Medusa-plugin-paypal medusa-plugin-paypal is a integration of payment provider for Paypal. **[Example](https://github.com/SummerFans/medusa-plugin-paypal/tree/dev/example)** ## ⚠️ Warn >| Requires Medusa v2.10.4 or later. ## Installaction ``` npm i medusa-plugin-paypal ``` ## Backend ```js // medusa-config.js const { loadEnv, defineConfig, Modules } = require("@medusajs/framework/utils"); // ... modules:[ [Modules.PAYMENT]: { resolve: "@medusajs/medusa/payment", options: { providers: [ { resolve: "medusa-plugin-paypal/providers/paypal-payment", id: "payment-paypal", options: { intent: "CAPTURE", clientId: process.env.PAYPAL_CLIENT_ID, clientSecret: process.env.PAYPAL_CLIENT_SECRET, sandbox: true, webhookId: process.env.PAYPAL_WEBHOOK_ID, } } ] } } ] plugins: [ { resolve: "medusa-paypal-payment", options: { intent: "CAPTURE", clientId: process.env.PAYPAL_CLIENT_ID, clientSecret: process.env.PAYPAL_CLIENT_SECRET, sandbox: true, webhookId: process.env.PAYPAL_WEBHOOK_ID, }, } ] ``` ## Store 1) Create `/src/modules/checkout/components/payment-wrapper/paypal-wrapper.tsx` ```tsx "use client" import { HttpTypes } from "@medusajs/types" import { createContext } from "react" import { PayPalScriptProvider, ReactPayPalScriptOptions, } from "@paypal/react-paypal-js" type PaypalWrapperProps = { paymentSession: HttpTypes.StorePaymentSession clientId: string children: React.ReactNode } export const PaypalContext = createContext(false) const PaypalWrapper: React.FC<PaypalWrapperProps> = ({ paymentSession, clientId, children, }) => { const initialOptions: ReactPayPalScriptOptions = { clientId, currency: paymentSession.currency_code.toLocaleUpperCase(), intent: "capture", components:"buttons", debug:false } return ( <PayPalScriptProvider deferLoading={false} options={initialOptions}> {children} </PayPalScriptProvider> ) } export default PaypalWrapper ``` 2) Update `/src/modules/checkout/components/payment-wrapper/index.tsx` ```tsx // add // !!!isPaypal() is 'pp_paypal' if (isPaypal(paymentSession?.provider_id) && paymentSession) { return ( <PaypalWrapper paymentSession={paymentSession} clientId={paypaylClientId} > {children} </PaypalWrapper> ) } ``` 3) Update `/src/modules/checkout/components/payment-button/index.tsx` ```tsx // add paypal button const PaypalPaymentButton = ({ cart, notReady, "data-testid": dataTestId, }: { cart: HttpTypes.StoreCart notReady: boolean "data-testid"?: string }) => { const [submitting, setSubmitting] = useState(false) const [errorMessage, setErrorMessage] = useState<string | null>(null) const onPaymentCompleted = async () => { await placeOrder() } const handlePayment = async ( _data: OnApproveData, actions: OnApproveActions ) => { setSubmitting(true) await actions?.order ?.capture() .then((authorization) => { if (authorization.status !== "COMPLETED") { setSubmitting(false) setErrorMessage(`An error occurred, status: ${authorization.status}`) return } onPaymentCompleted() }) .catch((error) => { setErrorMessage(`An unknown error occurred, please try again.`) setSubmitting(false) }) } const session = cart.payment_collection?.payment_sessions?.find( (s) => s.status === "pending" ) return ( <> <PayPalButtons disabled={submitting} createOrder={async (data, actions) => { return session?.data.id as string }} onApprove={handlePayment} onError={(err) => { console.error("PayPal Checkout onError", err) }} style={styles} /> <ErrorMessage error={errorMessage} data-testid="paypal-payment-error-message" /> </> ) } // Update PaymentButton const PaymentButton: React.FC<PaymentButtonProps> = ({ ... switch (true) { ... case isPaypal(paymentSession?.provider_id): return ( <PaypalPaymentButton notReady={notReady} cart={cart} data-testid={dataTestId} /> ) ... } ... }) ```