Skip to main content

Recurring and saved methods

Saved methods are available on rails that support mandates

Saving a method and charging it again needs a rail that both declares mandate support and implements it. No rail enabled today does, and the shape of that matters when you build: setup_future_usage, an explicit mandate_data block and a zero-amount setup all complete with 200 succeeded and return mandate_id: null. Nothing is stored, and the later off-session charge is refused with ERR_4088. Treat a missing mandate_id on the first payment as the signal, not the status of that payment.

Read this page to design for it, and build it once support confirms a mandate-capable rail is enabled for you. There is no API flag to check: whether a rail carries mandates is a property of the rail, so ask support.

Subscriptions are a separate question. The /subscriptions endpoints are billed by a billing processor — a connector class separate from the rails that move the money — so they are not unlocked by a mandate-capable rail, or by a card one. See Subscriptions in the API reference.

Save a payment method once, then charge it again without the customer re-entering anything. This powers two flows over the same API:

  • One-click — a returning customer pays with a method they already saved.
  • Off-session (recurring) — you charge a saved method later with no customer present, for subscriptions, top-ups, or usage billing.

Both work by saving a method against a customer_id on the first payment, then referencing the token TensorRail returns on later payments. You never handle or store card data — the token is a TensorRail reference, not the underlying credential.

Where it applies

Saving and reuse are available for methods that support it (such as cards). Methods that are inherently single-use in a market are charged fresh each time; the API shape is the same, so you can write one integration and let the platform apply what each method supports.

1. Save a method on the first payment

Set setup_future_usage and attach a customer_id. Use off_session when you intend to charge later with no customer present (subscriptions), or on_session when the customer will return and confirm themselves (one-click).

setup_future_usage saves the method used by this payment, so a confirming call still has to say how to pay. Omitting the payment method with confirm: true is refused with ERR_2002 — A payment token or payment method data or ctp service details is required.

curl -X POST https://api.tensorrail.com/payments \
-H "api-key: rail_full_test_xxx" \
-H "Content-Type: application/json" \
-d '{
"amount": 50000,
"currency": "INR",
"customer_id": "cus_8x2Kp",
"setup_future_usage": "off_session",
"confirm": true,
"payment_method": "upi",
"payment_method_type": "upi_collect",
"payment_method_data": { "upi": { "upi_collect": { "vpa_id": "success@upi" } } },
"return_url": "https://yourshop.com/checkout/complete"
}'

Once the payment succeeds, the response carries the token you store against your customer:

{
"payment_id": "pay_N5cPeGw6uS2QIMjnsjVF",
"status": "succeeded",
"customer_id": "cus_8x2Kp",
"payment_method_id": "pm_9c1f7e4a2d6b4f8b8c1e3a5d",
"mandate_id": "man_2d6a4f8b8c1e3a5d9e7b2f10"
}
FieldStore it?Use it for
payment_method_idYesCharging the saved method again (one-click and off-session)
mandate_idIf presentCharging under a mandate the customer authorised for recurring debits

Keep payment_method_id (and mandate_id, when the method uses a mandate) on your customer record. That is all you need to charge again.

2. Charge off-session (recurring)

To bill later with no customer present, create a payment that references the saved token and set off_session. Confirm in the same call.

curl -X POST https://api.tensorrail.com/payments \
-H "api-key: rail_full_test_xxx" \
-H "Idempotency-Key: sub-cus_8x2Kp-2026-08" \
-H "Content-Type: application/json" \
-d '{
"amount": 50000,
"currency": "INR",
"customer_id": "cus_8x2Kp",
"recurring_details": { "type": "payment_method_id", "data": "pm_9c1f7e4a2d6b4f8b8c1e3a5d" },
"off_session": true,
"confirm": true
}'

Give each recurring charge a stable, period-based Idempotency-Key (for example one per customer per billing month). If a retry fires for the same period, the duplicate is rejected rather than double-charging.

If the method was saved under a mandate, reference mandate_id instead of recurring_details; everything else about the call is the same.

3. One-click for returning customers

For a returning customer who is present, charge the payment_method_id you stored on their record. Present your saved-method choice in your own UI, then confirm the payment against the token — no card fields, no re-entry. The call is the same as an off-session charge, without off_session (the customer is here to complete any step-up the method requires):

{
"amount": 50000,
"currency": "INR",
"customer_id": "cus_8x2Kp",
"recurring_details": { "type": "payment_method_id", "data": "pm_9c1f7e4a2d6b4f8b8c1e3a5d" },
"confirm": true,
"return_url": "https://yourshop.com/checkout/complete"
}

If the method needs authentication (for example a 3-D Secure challenge), the response is requires_customer_action with a next_action — forward the customer to it exactly as in Accept a payment.

Lifecycle and webhooks

A saved method is backed by a mandate, which has its own lifecycle independent of any one payment:

Recurring charges emit the same events as any other payment (payment_succeeded, payment_failed, and the intermediate states). Drive your subscription state from those webhooks rather than the create response, so an off-session charge that completes asynchronously is reflected correctly. See Handle webhooks.

Subscriptions need a billing processor

Everything above is you charging a saved method on your own schedule: you hold the billing logic, and each charge is an ordinary payment. That is one of two routes, and it is the one this page describes.

The other is the /subscriptions endpoints, where TensorRail holds the schedule, the plan and the invoice run. Those are driven by a billing processor — a connector class separate from the rails that move the money — and billing_processor_id is required on every subscription.

The practical consequence is the one to take away: a mandate-capable payment rail does not switch subscriptions on, and neither does a card rail. They are independent account configuration. No billing processor is connected today, so a subscription cannot be created and the call is refused for the missing billing_processor_id. Ask your account manager if you need one; if you only need recurring charges, build them the way this page describes and you do not need a billing processor at all.

Security

  • You store TensorRail tokens (pm_…, man_…), never card numbers. The tokens are scoped to your account and are meaningless elsewhere.
  • The underlying credential is held in TensorRail's vault; your servers and your database never see the underlying credential, which is held in TensorRail's vault.
  • Revoking a saved method or mandate stops future charges against it.

Next steps