65 lines
1.4 KiB
TypeScript
65 lines
1.4 KiB
TypeScript
import React from 'react';
|
|
import { StripeError } from '@stripe/stripe-js';
|
|
import {
|
|
PaymentElement,
|
|
useElements,
|
|
useStripe,
|
|
} from '@stripe/react-stripe-js';
|
|
|
|
import './stripe-form.css';
|
|
|
|
import Button from '../button/button';
|
|
|
|
type Props = {
|
|
subscriptionReceiptId: string;
|
|
isProcessing: boolean;
|
|
paymentResultUrl: string;
|
|
onSubmit: () => void;
|
|
onSuccess: () => void;
|
|
onError: (error: StripeError) => void;
|
|
};
|
|
|
|
export default function StripeForm(props: Props) {
|
|
const stripe = useStripe();
|
|
const elements = useElements();
|
|
|
|
const [formReady, setFormReady] = React.useState(false);
|
|
|
|
const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
|
event.preventDefault();
|
|
|
|
if (!stripe || !elements) return;
|
|
|
|
props.onSubmit();
|
|
|
|
try {
|
|
const { error } = await stripe.confirmPayment({
|
|
elements,
|
|
confirmParams: {
|
|
return_url: props.paymentResultUrl,
|
|
},
|
|
});
|
|
|
|
if (error) {
|
|
props.onError(error);
|
|
} else {
|
|
props.onSuccess();
|
|
}
|
|
} catch (error) {
|
|
props.onError(error as StripeError);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<form className="stripe-form" onSubmit={onSubmit}>
|
|
<PaymentElement onReady={() => setFormReady(true)}/>
|
|
|
|
<div className="stripe-form__button">
|
|
<Button type="submit" disabled={props.isProcessing || !formReady} active>
|
|
Pay
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
);
|
|
}
|