first commit
Some checks failed
Build / run (push) Has been cancelled

This commit is contained in:
maher
2025-10-29 11:42:25 +01:00
commit 703f50a09d
4595 changed files with 385164 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
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<BillingRedirectMessageConfig>();
const stripeInitiated = useRef<boolean>();
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 (
<CheckoutLayout>
<BillingRedirectMessage config={messageConfig} />
<CheckoutProductSummary showBillingLine={false} />
</CheckoutLayout>
);
}
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,
});
}