Agent Wranglers

PAY-3Recommended

Save cards with consent and charge renewals off-session

To charge a card later, save it at the first payment with SCA and the customer's consent. Mark each later charge as merchant-initiated.

How to do it

Charges you start without the customer present, such as renewals, are merchant-initiated transactions. They fall outside SCA when the first payment set up the agreement with SCA. Tell the provider at setup that the card is for future use, such as setup_future_usage: "off_session" at Stripe. Show the terms beside the pay button, such as "Example Bakery charges 129.50 SEK every month until you cancel". Mark each later charge as off-session. If the bank still asks for authentication, email the customer a link to finish it. Record the consent as Show the terms and record consent before the first charge says.

Examples

JavaScript example

await stripe.paymentIntents.create({
  amount: 12950,
  currency: 'sek',
  customer: customerId,
  payment_method: savedPaymentMethodId,
  off_session: true,
  confirm: true,
}, { idempotencyKey: `renewal-${subscriptionId}-${periodStart}` })

Python example

stripe.PaymentIntent.create(
    amount=12950,
    currency="sek",
    customer=customer_id,
    payment_method=saved_payment_method_id,
    off_session=True,
    confirm=True,
    idempotency_key=f"renewal-{subscription_id}-{period_start}",
)

How to check

On staging, start a subscription with a card that needs authentication unless it was set up, such as Stripe's 4000 0025 0000 3155. The first payment shows a challenge. The renewal a month later, run with the provider's test clock, succeeds without one.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/payments/card-security-and-sca/off-session-payments">Agent Wranglers payments and billing playbook</a>. In code you write, add a comment next to it with the same link.