Charge a Saved Card
This guide explains how to charge a customer's saved card without them being present. This is a merchant-initiated transaction (MIT) - the customer has already consented to future charges during the initial payment, so no checkout flow or redirect is required.
Charging Stored Card Details
📘 Before you start
This guide assumes you have already completed Save a Card & Take Payment and have both a
paymentMethodId(from thecustomer.payment_method.enabledwebhook) and acustomerIdstored in your system.
Super does not manage subscription scheduling.Super will process the charge when you send the request, but it is your responsibility to determine when to trigger each payment - for example, tracking renewal dates, handling billing cycles, and retrying failed charges.
How It Works
The off-session charge is a single server-side API call. There is no SDK component to mount and no redirect for the customer. Because this is a merchant-initiated transaction, it falls outside the scope of Strong Customer Authentication - 3DS is neither required nor triggered.
Once the charge is submitted, the payment moves to a PaymentPending state while it is processed. A payment.success webhook fires when the charge completes successfully.
Prerequisites
- A
paymentMethodIdfrom thecustomer.payment_method.enabledwebhook (e.g.pm_123456) - Your
paymentInitiatorIdfrom the business portal
Integration Guide
Step 1: Trigger the charge
Call POST to our /payments endpoint from your server with offSession: true and the customer's paymentMethodId. This should be called at the point in your billing logic where you have determined a charge is due e.g. subscription renewal date.
Request
curl --request POST \
--url https://api.superpayments.com/2026-04-01/payments \
--header 'accept: application/json' \
--header 'authorization: YOUR_SECRET_KEY' \
--header 'content-type: application/json' \
--data '{
"amount": 2500,
"currency": "GBP",
"externalReference": "order-123",
"offSession": true,
"paymentInitiatorId": "YOUR_PAYMENT_INITIATOR_ID",
"paymentMethodId": "pm_123456"
}'curl --request POST \
--url https://api.test.superpayments.com/2026-04-01/payments \
--header 'accept: application/json' \
--header 'authorization: YOUR_SECRET_KEY' \
--header 'content-type: application/json' \
--data '{
"amount": 2500,
"currency": "GBP",
"externalReference": "order-123",
"offSession": true,
"paymentInitiatorId": "YOUR_PAYMENT_INITIATOR_ID",
"paymentMethodId": "pm_123456"
}'| Field | Type | Description |
|---|---|---|
amount | integer | Charge amount in minor units (e.g. 2500 = £25.00). |
currency | string | ISO 4217 currency code (e.g. GBP). |
externalReference | string | Your unique reference for this charge (e.g. order or invoice ID). |
offSession | boolean | Must be true for merchant-initiated charges. |
paymentInitiatorId | string | Your payment initiator ID from the business portal. |
paymentMethodId | string | The paymentMethodId received from the customer.payment_method.enabled webhook. |
shippingAddress | object | Optional. Shipping address for the order. |
billingAddress | object | Optional. Billing address associated with the card. |
Step 2: Handle the response
A successful request returns 200 with a PaymentPending status. This means the charge has been accepted and is being processed - it is not yet confirmed. Do not update your order status to paid at this point.
200 Response
{
"brandId": "YOUR_BRAND_ID",
"id": "123456-26f8-48b6-8f94-8c5df6162f7d",
"offSession": true,
"paymentInitiatorId": "YOUR_PAYMENT_INITIATOR_ID",
"paymentReference": "CAM7M2S396SECWJP2Z",
"status": "PaymentPending"
}Store the id and paymentReference against the charge in your system. You will need the id to correlate the incoming PaymentSuccess webhook in Step 3.
Step 3: Listen for the PaymentSuccess webhook
PaymentSuccess webhookOnce the payment has been processed, Super fires a payment.success event to your configured webhook endpoint. Update your order status and notify the customer only after receiving this event.
Never confirm a subscription renewal or dispatch goods based on thePaymentPendingresponse alone. Always wait for thepayment.successwebhook.
Webhook Event: payment.success
{
"data": {
"amount": {
"amount": 5000,
"amountMultiplier": 100,
"currency": "GBP"
},
"source": "paymentLink",
"status": "PaymentSuccess",
"brandId": "123-123-123-123",
"paymentId": "ae317082-d563-4796-9d75-00c89d4bf8d9",
"fundingSummary": {
"cashPayableToMerchant": {
"amount": 5000,
"amountMultiplier": 100,
"currency": "GBP"
},
"customerFundedAmount": {
"amount": 5000,
"amountMultiplier": 100,
"currency": "GBP"
},
"superFundedAmount": {
"amount": 0,
"amountMultiplier": 100,
"currency": "GBP"
},
"merchantFundedAmount": {
"amount": 0,
"amountMultiplier": 100,
"currency": "GBP"
}
},
"paymentReference": "CAGS5FJVNHYMEUAZRP",
"externalReference": "Test name 12113",
"paymentInitiatorId": "123-123-123-123"
},
"eventId": "evt_y8bcolwLT_GWFGx5BW4wjw",
"eventType": "payment.success",
"eventDatetime": "2040-12-12T10:51:13.000Z"
}| Field | Description |
|---|---|
data.paymentId | Matches the id returned in the Step 2 response. Use this to correlate the webhook with the pending charge in your system. |
data.paymentReference | Super's reference for the transaction. |
data.externalReference | The reference you passed in the charge request. |
data.status | Will be PaymentSuccess for a completed charge. |
data.amount.amount | Amount charged in minor units. |
data.fundingSummary.cashPayableToMerchant | The net amount that will be settled to your account. |
📘 Webhook setup
Configure your webhook endpoint in the business portal. Subscribe to the
payment.successevent type. For general webhook guidance, see the Webhook Documentation.
3DS & SCA Reference
| Transaction type | Customer present? | 3DS required? | Who handles it? |
|---|---|---|---|
| Initial payment (card setup) | Yes - CIT | Yes, automatically | Super via redirectUrl |
| Off-session charge (this guide) | No - MIT | No | N/A - MIT exemption applies |
Off-session charges are merchant-initiated transactions and are explicitly exempt from Strong Customer Authentication.
Testing
Use the following test cards in the sandbox. The paymentMethodId used in the charge request must have been saved during an initial payment with one of these cards.
For a full list of test cards and decline scenarios, see Test with Cards.
Next Steps
Updated about 15 hours ago
