import {CheckoutLayout} from '../checkout-layout'; import {useParams, useSearchParams} from 'react-router-dom'; import {loadStripe, PaymentIntent} from '@stripe/stripe-js'; import {useEffect, useRef, useState} from 'react'; import {message} from '../../../i18n/message'; import {CheckoutProductSummary} from '../checkout-product-summary'; import { BillingRedirectMessage, BillingRedirectMessageConfig, } from '../../billing-redirect-message'; import {useNavigate} from '../../../utils/hooks/use-navigate'; import {apiClient} from '../../../http/query-client'; import {useSettings} from '../../../core/settings/use-settings'; import {useBootstrapData} from '../../../core/bootstrap-data/bootstrap-data-context'; export function CheckoutStripeDone() { const {invalidateBootstrapData} = useBootstrapData(); const {productId, priceId} = useParams(); const navigate = useNavigate(); const { billing: {stripe_public_key}, } = useSettings(); const [params] = useSearchParams(); const clientSecret = params.get('payment_intent_client_secret'); const [messageConfig, setMessageConfig] = useState(); const stripeInitiated = useRef(); useEffect(() => { if (stripeInitiated.current) return; loadStripe(stripe_public_key!).then(async stripe => { if (!stripe || !clientSecret) { setMessageConfig(getRedirectMessageConfig()); return; } stripe .retrievePaymentIntent(clientSecret) .then(async ({paymentIntent}) => { if (paymentIntent?.status === 'succeeded') { await storeSubscriptionDetailsLocally(paymentIntent.id); setMessageConfig( getRedirectMessageConfig('succeeded', productId, priceId), ); window.location.href = '/billing'; } else { setMessageConfig( getRedirectMessageConfig( paymentIntent?.status, productId, priceId, ), ); } }); }); stripeInitiated.current = true; }, [ stripe_public_key, clientSecret, priceId, productId, invalidateBootstrapData, ]); if (!clientSecret) { navigate('/'); return null; } return ( ); } function getRedirectMessageConfig( status?: PaymentIntent.Status, productId?: string, priceId?: string, ): BillingRedirectMessageConfig { switch (status) { case 'succeeded': return { message: message('Subscription successful!'), status: 'success', buttonLabel: message('Return to site'), link: '/billing', }; case 'processing': return { message: message( "Payment processing. We'll update you when payment is received.", ), status: 'success', buttonLabel: message('Return to site'), link: '/billing', }; case 'requires_payment_method': return { message: message('Payment failed. Please try another payment method.'), status: 'error', buttonLabel: message('Go back'), link: errorLink(productId, priceId), }; default: return { message: message('Something went wrong'), status: 'error', buttonLabel: message('Go back'), link: errorLink(productId, priceId), }; } } function errorLink(productId?: string, priceId?: string): string { return productId && priceId ? `/checkout/${productId}/${priceId}` : '/'; } function storeSubscriptionDetailsLocally(paymentIntentId: string) { return apiClient.post('billing/stripe/store-subscription-details-locally', { payment_intent_id: paymentIntentId, }); }