Skip to main content

Recurring Billing Flow

Recurring billing is used to charge money without user interaction. For example, to charge subsequent amounts from a user's credit card for monthly subscriptions.

Overview

Recurring billing requires a prior completed payment with user interaction to obtain a token. The first Payment Request has to be completed with user interaction before subsequent automated charges can occur.

Token Reuse

After obtaining a token from the first payment, you can reuse the same token for all future charges until it expires.

Prerequisites

Before using recurring billing, you must:

  1. Complete the standard payment flow with token_strategy: "required"
  2. Store the issued_token received in the notification
  3. Link the token to the customer in your database

Recurring Billing Steps

Once you have a stored token, recurring charges follow these steps:

Step 1: Create Payment Request

Create a new payment request via POST to /checkout/rest/v1/payment-requests

Required parameters:

{
"business_id": "your_business_id",
"order_id": "SUB_12345_MONTH_2",
"price": {
"amount": 999,
"currency": "EUR"
},
"description": "Monthly subscription - February",
"method_key": "card",
"payer": {
"email": "customer@example.com"
},
"locale": "en",
"callback_url": "https://yoursite.com/payment/callback"
}

Response:

{
"id": "payment_request_id",
"status": "new",
"order_id": "SUB_12345_MONTH_2"
}

Step 2: Authorize with Token

Authorize the payment using the stored token via PUT to /checkout/rest/v1/payment-requests/{id}/authorize

Request:

{
"token": "vLUGdTtnDjQs7Yv0fjYQyYfG60m"
}

Response:

{
"id": "payment_request_id",
"status": "captured",
"order_id": "SUB_12345_MONTH_2",
"price_paid": {
"amount": 999,
"currency": "EUR"
},
"payer": {
"email": "customer@example.com",
"name": "John",
"surname": "Doe"
}
}
Automatic Capture

The payment is automatically captured during the authorisation process. No additional confirmation is needed.

Step 3: Handle Notification

Paysera sends a POST request to your callback_url with a notification_id parameter.

Your server must:

  1. Retrieve notification: GET /notification/rest/v1/notifications/{notification_id}
  2. Check the event field (e.g., "payment_request.captured")
  3. Verify status is "captured"
  4. Process the payment in your system
  5. Mark as read: PUT /notification/rest/v1/notifications/{notification_id}/read
Critical

You must mark notifications as read. If you don't, Paysera will retry the callback multiple times until it's marked as read.

API Endpoints

Payment Request API:

  • Host: checkout-eu-a.paysera.com
  • Create: POST /checkout/rest/v1/payment-requests
  • Authorize: PUT /checkout/rest/v1/payment-requests/{id}/authorize

Notification Event API:

  • Host: checkout-eu-a.paysera.com
  • Get notification: GET /notification/rest/v1/notifications/{id}
  • Mark as read: PUT /notification/rest/v1/notifications/{id}/read

Authentication: All requests require MAC authentication headers.

Flow Diagram

┌─────────────────────────────────────────────────────────────┐
│ Step 1: Create Payment Request │
│ POST /checkout/rest/v1/payment-requests │
│ → Receive payment_request_id │
└──────────────────────┬──────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ Step 2: Authorize with Token │
│ PUT /checkout/rest/v1/payment-requests/{id}/authorize │
│ → Payment automatically captured │
│ → Status: "captured" │
└──────────────────────┬──────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ Step 3: Handle Notification (async) │
│ POST to your callback_url with notification_id │
│ → GET /notification/rest/v1/notifications/{id} │
│ → Process payment details │
│ → PUT /notification/rest/v1/notifications/{id}/read │
└─────────────────────────────────────────────────────────────┘

Obtaining a Token Without Charging the Customer

You can also obtain a recurring billing token without actually transferring any funds from the customer. This is useful when you only need to register a payment method for future automatic charges (for example, a free trial that converts to a paid subscription later).

To do this, the initial Payment Request must include both:

  • token_strategy: "required"
  • parameters.refund_on_capture: true

When refund_on_capture is true, the captured amount is automatically refunded back to the customer and the Payment Request ends in the canceled status, but a recurring billing token is still issued.

Example request body:

{
"business_id": "your_business_id",
"order_id": "12345446",
"price": {
"amount": "10.00",
"currency": "EUR"
},
"description": "Card verification",
"method_key": "card",
"payer": {
"email": "payer@email.com"
},
"locale": "en",
"accept_url": "https://yoursite.com/accept",
"cancel_url": "https://yoursite.com/cancel",
"callback_url": "https://yoursite.com/callback",
"token_strategy": "required",
"parameters": {
"refund_on_capture": true
}
}

Notification differences:

  • The notification event is payment_request.checkout_token_issued (not payment_request.captured).
  • The Payment Request status inside data.payment_request is canceled.
  • The issued_token field is still present on the Payment Request and can be used for subsequent recurring charges exactly like a token from a normal capture.
{
"id": "ABcJDZe-rWzLgQKxZTamdfZRApsrPuyE",
"event": "payment_request.checkout_token_issued",
"status": "read",
"data": {
"payment_request": {
"id": "PRAHdH4r8NJtep-s8VRkWyKhv1GzP_oW",
"status": "canceled",
"token_strategy": "required",
"parameters": {
"refund_on_capture": true
},
"issued_token": "vLUGdTtnDjQs7Yv0fjYQyYfG60m"
}
}
}
tip

Use this flow when you want to validate a card and store a reusable token without billing the customer up front.

Token Security

Security Requirements
  • Store tokens encrypted in your database
  • Never expose tokens in client-side code
  • Use HTTPS for all API communications
  • Implement proper access controls

Important Notes

  • No user interaction: Recurring charges are processed automatically without customer approval
  • Automatic capture: Payment is captured immediately upon successful authorization
  • Token validity: Tokens remain valid until customer revokes them or the payment card expires
  • Callback handling: Always mark notifications as read to prevent repeated callbacks
  • Error handling: If authorization fails (expired token, insufficient funds), you'll receive an error response

Next Steps

Support

Need help with complex integrations?

Contact: tech_support@paysera.com