Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/components/revolut.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ interface RevolutProps {
onPaid: () => void;
onCancel?: () => void;
mode?: Mode;
/** Save the card for merchant-initiated (off-session) automatic renewals */
saveCard?: boolean;
}

export function RevolutPayWidget({
Expand All @@ -24,6 +26,7 @@ export function RevolutPayWidget({
onPaid,
onCancel,
mode,
saveCard,
}: RevolutProps) {
const login = useLogin();
const { formatMessage } = useIntl();
Expand Down Expand Up @@ -163,6 +166,10 @@ export function RevolutPayWidget({
streetLine1: streetLine1 || undefined,
streetLine2: streetLine2 || undefined,
},
// Save the payment method for merchant-initiated (off-session) automatic
// renewals. The backend then captures the saved customer/payment-method
// ids on webhook completion.
...(saveCard ? { savePaymentMethodFor: "merchant" as const } : {}),
});
}

Expand Down
12 changes: 12 additions & 0 deletions src/components/subscription-payment-flow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export default function SubscriptionPaymentFlow({
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string>();
const [account, setAccount] = useState<AccountDetail>();
const [autoRenewalEnabled, setAutoRenewalEnabled] = useState(false);

useEffect(() => {
if (!login?.api) return;
Expand All @@ -61,6 +62,16 @@ export default function SubscriptionPaymentFlow({
.catch((e) => console.error("Failed to load account info:", e));
}, [login?.api]);

// Load the subscription so we know whether to save the card for off-session
// automatic renewals during a Revolut checkout.
useEffect(() => {
if (!login?.api) return;
login.api
.getSubscription(subscriptionId)
.then((s) => setAutoRenewalEnabled(s.auto_renewal_enabled))
.catch((e) => console.error("Failed to load subscription:", e));
}, [login?.api, subscriptionId]);

const handlePaymentComplete = useCallback(() => {
setPayment(undefined);
onPaymentComplete();
Expand Down Expand Up @@ -225,6 +236,7 @@ export default function SubscriptionPaymentFlow({
payment={toVmPayment(payment)}
account={account}
onPaid={handlePaymentComplete}
saveCard={autoRenewalEnabled}
/>
) : (
<div className="bg-cyber-panel-light p-4 rounded-sm space-y-2 text-center">
Expand Down
Loading