Skip to content

Instantly share code, notes, and snippets.

@imprakharshukla
Created July 21, 2023 05:58
Show Gist options
  • Save imprakharshukla/4150620a3a32b5a62bffd0477a0925b2 to your computer and use it in GitHub Desktop.
Save imprakharshukla/4150620a3a32b5a62bffd0477a0925b2 to your computer and use it in GitHub Desktop.
import {useCheckout} from "@lib/context/checkout-context"
import {PaymentSession} from "@medusajs/medusa"
import Button from "@modules/common/components/button"
import Spinner from "@modules/common/icons/spinner"
import {useCart} from "medusa-react"
import React, {useCallback, useEffect, useState} from "react"
import useRazorpay, {RazorpayOptions} from "react-razorpay";
type PaymentButtonProps = {
paymentSession?: PaymentSession | null
}
const PaymentButton: React.FC<PaymentButtonProps> = ({paymentSession}) => {
const [notReady, setNotReady] = useState(true)
const {cart} = useCart()
useEffect(() => {
setNotReady(true)
if (!cart) {
return
}
if (!cart.shipping_address) {
return
}
if (!cart.billing_address) {
return
}
if (!cart.email) {
return
}
if (cart.shipping_methods.length < 1) {
return
}
setNotReady(false)
}, [cart])
switch (paymentSession?.provider_id) {
case "razorpay":
return (
<RazorpayPaymentButton session={paymentSession} notReady={notReady}/>
)
default:
return <Button disabled>Select a payment method</Button>
}
}
const RazorpayPaymentButton = ({
session,
notReady,
}: {
session: PaymentSession
notReady: boolean
}) => {
const [submitting, setSubmitting] = useState(false)
const [errorMessage, setErrorMessage] = useState<string | undefined>(
undefined
)
const [Razorpay] = useRazorpay();
const {cart} = useCart()
const {onPaymentCompleted, updatePayment} = useCheckout()
const orderData = session.data as Record<string, string>
const handlePayment = useCallback(() => {
console.log({"NAME": cart?.billing_address.first_name + " " + cart?.billing_address.last_name})
console.log({"ORDER ID": orderData.id})
const options: RazorpayOptions = {
key: process.env.NEXT_PUBLIC_RAZORPAY_KEY ?? '',
amount: session.amount.toString(),
currency: orderData.currency.toLocaleUpperCase(),
name: process.env.COMPANY_NAME ?? "Reskinn Store",
description: `Order number ${orderData.id}`,
//image: "https://example.com/your_logo",
order_id: orderData.id,
"prefill": {
"name": cart?.billing_address.first_name + " " + cart?.billing_address.last_name,
"email": cart?.email,
"contact": (cart?.shipping_address?.phone) ?? undefined
},
"notes": {
"address": cart?.billing_address,
"order_notes": session.data.notes
},
"modal": {
// @ts-ignore
"ondismiss": (() => {
console.log("dismissed payment");
setSubmitting(false)
return false
})()
},
"handler": async (response) => {
console.log(response);
if (!response) {
const error = "razorpay unsuccessful"
console.log(error)
setErrorMessage(error);
setSubmitting(false);
return;
} else {
console.log("razorpay successful", cart?.id)
const cart_updated = await updatePayment(cart?.id ?? "", "razorpay", response)
if (!cart_updated) {
setSubmitting(false)
return
}
onPaymentCompleted()
}
return;
},
};
const razorpay = new Razorpay(options);
razorpay.on('payment.submit', function (data: { method: string }) {
if (data.method === 'bank_transfer') {
console.log("initiating bank transfer")
}
});
razorpay.on('virtual_account.credited', function () {
onPaymentCompleted()
})
razorpay.open();
}, [Razorpay]);
return (
<>
<Button
disabled={submitting || notReady}
onClick={handlePayment}
>
{submitting ? <Spinner/> : "Checkout"}
</Button>
{errorMessage && (
<div className="text-red-500 text-small-regular mt-2">
{errorMessage}
</div>
)}
</>
)
}
// const StripePaymentButton = ({
// session,
// notReady,
// }: {
// session: PaymentSession
// notReady: boolean
// }) => {
// const [disabled, setDisabled] = useState(false)
// const [submitting, setSubmitting] = useState(false)
// const [errorMessage, setErrorMessage] = useState<string | undefined>(
// undefined
// )
//
// const {cart} = useCart()
// const {onPaymentCompleted} = useCheckout()
//
// const stripe = useStripe()
// const elements = useElements()
// const card = elements?.getElement("cardNumber")
//
// useEffect(() => {
// if (!stripe || !elements) {
// setDisabled(true)
// } else {
// setDisabled(false)
// }
// }, [stripe, elements])
//
// const handlePayment = async () => {
// setSubmitting(true)
//
// if (!stripe || !elements || !card || !cart) {
// setSubmitting(false)
// return
// }
//
// await stripe
// .confirmCardPayment(session.data.client_secret as string, {
// payment_method: {
// card: card,
// billing_details: {
// name:
// cart.billing_address.first_name +
// " " +
// cart.billing_address.last_name,
// address: {
// city: cart.billing_address.city ?? undefined,
// country: cart.billing_address.country_code ?? undefined,
// line1: cart.billing_address.address_1 ?? undefined,
// line2: cart.billing_address.address_2 ?? undefined,
// postal_code: cart.billing_address.postal_code ?? undefined,
// state: cart.billing_address.province ?? undefined,
// },
// email: cart.email,
// phone: cart.billing_address.phone ?? undefined,
// },
// },
// })
// .then(({error, paymentIntent}) => {
// if (error) {
// const pi = error.payment_intent
//
// if (
// (pi && pi.status === "requires_capture") ||
// (pi && pi.status === "succeeded")
// ) {
// onPaymentCompleted()
// }
//
// setErrorMessage(error.message)
// return
// }
//
// if (
// (paymentIntent && paymentIntent.status === "requires_capture") ||
// paymentIntent.status === "succeeded"
// ) {
// return onPaymentCompleted()
// }
//
// return
// })
// .finally(() => {
// setSubmitting(false)
// })
// }
//
// return (
// <>
// <Button
// disabled={submitting || disabled || notReady}
// onClick={handlePayment}
// >
// {submitting ? <Spinner/> : "Checkout"}
// </Button>
// {errorMessage && (
// <div className="text-red-500 text-small-regular mt-2">
// {errorMessage}
// </div>
// )}
// </>
// )
// }
// const PAYPAL_CLIENT_ID = process.env.NEXT_PUBLIC_PAYPAL_CLIENT_ID || ""
//
// const PayPalPaymentButton = ({
// session,
// notReady,
// }: {
// session: PaymentSession
// notReady: boolean
// }) => {
// const [submitting, setSubmitting] = useState(false)
// const [errorMessage, setErrorMessage] = useState<string | undefined>(
// undefined
// )
//
// const {cart} = useCart()
// const {onPaymentCompleted} = useCheckout()
//
// const handlePayment = async (
// _data: OnApproveData,
// actions: OnApproveActions
// ) => {
// actions?.order
// ?.authorize()
// .then((authorization) => {
// if (authorization.status !== "COMPLETED") {
// setErrorMessage(`An error occurred, status: ${authorization.status}`)
// return
// }
// onPaymentCompleted()
// })
// .catch(() => {
// setErrorMessage(`An unknown error occurred, please try again.`)
// })
// .finally(() => {
// setSubmitting(false)
// })
// }
// return (
// <PayPalScriptProvider
// options={{
// "client-id": PAYPAL_CLIENT_ID,
// currency: cart?.region.currency_code.toUpperCase(),
// intent: "authorize",
// }}
// >
// {errorMessage && (
// <span className="text-rose-500 mt-4">{errorMessage}</span>
// )}
// <PayPalButtons
// style={{layout: "horizontal"}}
// createOrder={async () => session.data.id as string}
// onApprove={handlePayment}
// disabled={notReady || submitting}
// />
// </PayPalScriptProvider>
// )
// }
// const ManualTestPaymentButton = ({notReady}: { notReady: boolean }) => {
// const [submitting, setSubmitting] = useState(false)
//
// const {onPaymentCompleted} = useCheckout()
//
// const handlePayment = () => {
// setSubmitting(true)
//
// onPaymentCompleted()
//
// setSubmitting(false)
// }
//
// return (
// <Button disabled={submitting || notReady} onClick={handlePayment}>
// {submitting ? <Spinner/> : "Checkout"}
// </Button>
// )
// }
export default PaymentButton
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment