124 lines
3.3 KiB
TypeScript
124 lines
3.3 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import {
|
|
PaymentRequestButtonElement,
|
|
useStripe,
|
|
useElements,
|
|
} from "@stripe/react-stripe-js";
|
|
import { PaymentRequest } from "@stripe/stripe-js";
|
|
import { ISubscriptionPlan } from "@/api/resources/SubscriptionPlans";
|
|
import { useAuth } from "@/auth";
|
|
import { useApi } from "@/api";
|
|
import styles from "./styles.module.css";
|
|
|
|
interface ApplePayButtonProps {
|
|
activeSubPlan: ISubscriptionPlan | null;
|
|
}
|
|
|
|
function ApplePayButton({ activeSubPlan }: ApplePayButtonProps) {
|
|
const stripe = useStripe();
|
|
const elements = useElements();
|
|
const api = useApi();
|
|
const { token } = useAuth();
|
|
const [paymentRequest, setPaymentRequest] = useState<PaymentRequest | null>(
|
|
null
|
|
);
|
|
// const [test, setTest] = useState<string>("");
|
|
|
|
const getAmountFromSubPlan = (subPlan: ISubscriptionPlan) => {
|
|
if (subPlan.trial) {
|
|
return subPlan.trial.price_cents;
|
|
}
|
|
return subPlan.price_cents;
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!stripe || !elements || !activeSubPlan) {
|
|
return;
|
|
}
|
|
|
|
const pr = stripe.paymentRequest({
|
|
country: "US",
|
|
currency: "usd",
|
|
total: {
|
|
label: activeSubPlan.name || "Subscription",
|
|
amount: getAmountFromSubPlan(activeSubPlan),
|
|
},
|
|
requestPayerName: true,
|
|
requestPayerEmail: true,
|
|
});
|
|
console.log("paymentRequest: ", pr);
|
|
|
|
// Check the availability of the Payment Request API.
|
|
pr.canMakePayment().then((result) => {
|
|
console.log("canMakePayment: ", result);
|
|
// setTest("canMakePayment: " + JSON.stringify(result));
|
|
|
|
if (result) {
|
|
setPaymentRequest(pr);
|
|
}
|
|
});
|
|
|
|
pr.on("paymentmethod", async (e) => {
|
|
// const { error: backendError, clientSecret } = await fetch(
|
|
// "/create-payment-intent",
|
|
// {
|
|
// method: "POST",
|
|
// headers: {
|
|
// "Content-Type": "application/json",
|
|
// },
|
|
// body: JSON.stringify({
|
|
// paymentMethodType: "card",
|
|
// currency: "usd",
|
|
// }),
|
|
// }
|
|
// ).then((r) => r.json());
|
|
|
|
const { subscription_receipt } = await api.createSubscriptionReceipt({
|
|
token,
|
|
way: "stripe",
|
|
subscription_receipt: {
|
|
sub_plan_id: activeSubPlan?.id || "stripe.7",
|
|
},
|
|
});
|
|
const { client_secret } = subscription_receipt.data;
|
|
|
|
if (!subscription_receipt) {
|
|
return;
|
|
}
|
|
|
|
const { error: stripeError } = await stripe.confirmCardPayment(
|
|
client_secret,
|
|
{
|
|
payment_method: e.paymentMethod.id,
|
|
},
|
|
{ handleActions: false }
|
|
);
|
|
|
|
if (stripeError) {
|
|
// Show error to your customer (e.g., insufficient funds)
|
|
return;
|
|
}
|
|
|
|
// Show a success message to your customer
|
|
// There's a risk of the customer closing the window before callback
|
|
// execution. Set up a webhook or plugin to listen for the
|
|
// payment_intent.succeeded event that handles any business critical
|
|
// post-payment actions.
|
|
});
|
|
}, [stripe, elements, activeSubPlan, api, token]);
|
|
|
|
return (
|
|
<>
|
|
{/* {test} */}
|
|
{paymentRequest && (
|
|
<PaymentRequestButtonElement
|
|
className={styles["stripe-element"]}
|
|
options={{ paymentRequest }}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default ApplePayButton;
|