Recurring billing used to charge money without user interaction. For example to charge subsequent amount of money from user's credit card for monthly subscription.

Info Recurring billing only works with subsequent Payment Requests for specific user. First Payment Request has to be completed with user interaction described at Payment flow page

Recurring billing consists of two steps:

  1. Payment Request initialization described at Payment flow page
  2. Payment Request authorisation with token (payment is automatically captured during authorisation)
Info After obtaining token, there is no need for new token obtaining each time, unless it has expired and has to be obtained again

Payment Request authorization with token

To authorise and capture payments without user interaction, you have to make an API call to the Recurring Billing API using a token generated for recurring billing using the Payment Request hash after initialising the Payment Request. The payment will be automatically captured during the authorisation process.

Please visit Recurring Billing API specification page to get list of required parameters as well as endpoint path and examples. Or use any of our libraries, which can be found on Libraries page.

Flow example

Step 1

First, we need to create a new Payment Request, which we will automatically authorise and bill.

Info At that point token already has to be issued with first payment with user interaction

Request
POST /checkout/rest/v1/payment-requests HTTP/1.1
Host: checkout-eu-a.paysera.com
Content-Type: application/json;charset=utf-8
User-Agent: Paysera WalletApi PHP library
Authorization: MAC id="wkVd93h2uS", ts="1343811600", nonce="nQnNaSNyubfPErjRO55yaaEYo9YZfKHN", mac="ikVkAqVe4Yp5JZ/VckAgZQTVOBaDItb1H2GWWP5INSg=", ext="body_hash=A3KDuD2IfzzJeEtoJFYIZ%2B2UIZwMmEnLNpSKpZZVMLQ%3D"
{
    "business_id": "LcKB4rs-pNVLgQKxZTaGzfZRAuiQPuyE",
    "order_id": "12345446",
    "price": {
        "amount": "10.00",
        "currency": "EUR"
    },
    "description": "Payment for goods on order 12345446 on the website https://shop.com.",
    "method_key": "card",
    "payer": {
        "email": "payer@email.com"
    },
    "locale": "en",
    "accept_url": "https://shop.com/accept-url",
    "cancel_url": "https://shop.com/cancel-url",
    "callback_url": "https://shop.com/callback-url"
}
Response body
{
    "id": "PRAFY24n-UBgSkiRCL-h_CVAAvj4MEkj",
    "payer": {
        "email": "payer@email.com"
    },
    "authorization_url": "https://checkout.paysera.com/PRAFY24n-UBgSkiRCL-h_CVAAvj4MEkj",
    "price": {
        "amount": "10.00",
        "currency": "EUR"
    },
    "locale": "en",
    "business_id": "LcKB4rs-pNVLgQKxZTaGzfZRAuiQPuyE",
    "order_id": "12345447",
    "unique_identifier": null,
    "valid_until": null,
    "description": "Payment for goods on order 12345447 on the website https://shop.com.",
    "method_key": "card",
    "method_country": null,
    "accept_url": "https://shop.com/accept-url",
    "cancel_url": "https://shop.com/cancel-url",
    "callback_url": "https://shop.com/callback-url",
    "affiliate_key": null,
    "parameters": null,
    "status": "new",
    "gateway_key": null,
    "token_strategy": null
}

Step 2

Now you have to authorise the Payment Request with issued_token for that user. The payment will be automatically captured during the authorisation process.

Request
PUT /checkout/rest/v1/payment-requests/PRAFY24n-UBgSkiRCL-h_CVAAvj4MEkj/authorize HTTP/1.1
Host: checkout-eu-a.paysera.com
Content-Type: application/json;charset=utf-8
User-Agent: Paysera WalletApi PHP library
Authorization: MAC id="wkVd93h2uS", ts="1343811600", nonce="nQnNaSNyubfPErjRO55yaaEYo9YZfKHN", mac="aZephpu0zuODCpbBCBrczrURdPU70LbMr9NmX5ODj9c=", ext="body_hash=h6MKIejzp0bjEIQXAGtDoPwwb7y9tMG2jJYjtib7qnY%3D"
{
    "token": "vLUGdTtnDjQs7Yv0fjYQyYfG60m"
}
Response body
{
    "id": "PRAFY24n-UBgSkiRCL-h_CVAAvj4MEkj",
    "payer": {
        "name": "John",
        "surname": "Doe",
        "email": "payer@email.com"
    },
    "authorization_url": "https://checkout.paysera.com/PRAFY24n-UBgSkiRCL-h_CVAAvj4MEkj",
    "price": {
        "amount": "10.00",
        "currency": "EUR"
    },
    "price_paid": {
        "amount": "10.00",
        "currency": "EUR"
    },
    "locale": "en",
    "business_id": "LcKB4rs-pNVLgQKxZTaGzfZRAuiQPuyE",
    "order_id": "12345447",
    "unique_identifier": null,
    "valid_until": null,
    "description": "Payment for goods on order 12345447 on the website https://shop.com.",
    "method_key": "card",
    "method_country": null,
    "accept_url": "https://shop.com/accept-url",
    "cancel_url": "https://shop.com/cancel-url",
    "callback_url": "https://shop.com/callback-url",
    "affiliate_key": null,
    "parameters": null,
    "status": "captured",
    "gateway_key": "card",
    "token_strategy": null
}

Note that the Payment Request status is captured, which means that the Payment Request has been automatically captured during authorisation and money was charged.

You still need to wait for notification and mark it as read, to fully finish flow

Step 3

After the payment is captured during authorisation, we will send a notification_id in POST body (application/x-www-form-urlencoded format) to callback_url provided (ex. https://shop.com/callback-url will receive notification_id: O2qQQQQ-rWzLgQKxZTamdfZRApsrPuyE) Notification body example:

notification_id=O2qQQQQ-rWzLgQKxZTamdfZRApsrPuyE

Then you have to either check what inside and mark that notification as read, or mark that notification as read in one call. We suggest you to check first and mark after, but it's up to you.

Request
GET /notification/rest/v1/notifications/O2qQQQQ-rWzLgQKxZTamdfZRApsrPuyE HTTP/1.1
Host: checkout-eu-a.paysera.com
User-Agent: Paysera WalletApi PHP library
Authorization: MAC id="wkVd93h2uS", ts="1343811600", nonce="nQnNaSNyubfPErjRO55yaaEYo9YZfKHN", mac="1mDqthCSVcq7Zfcx9T58YnBKHMMTSkhFIE8UjpLwCfM="
Response body
{
  "id": "O2qQQQQ-rWzLgQKxZTamdfZRApsrPuyE",
  "event": "payment_request.captured",
  "status": "new",
  "data": {
    "id": "PRAFY24n-UBgSkiRCL-h_CVAAvj4MEkj",
    "payer": {
      "name": "John",
      "surname": "Doe",
      "full_name": "John Doe",
      "email": "payer@email.com",
      "account_number": "123456XXXXXX1234"
    },
    "authorization_url": "https://checkout.paysera.com/PRAFY24n-UBgSkiRCL-h_CVAAvj4MEkj",
    "price": {
      "amount": "10.00",
      "currency": "EUR"
    },
    "price_paid": {
      "amount": "10.00",
      "currency": "EUR"
    },
    "locale": "en",
    "business_id": "LcKB4rs-pNVLgQKxZTaGzfZRAuiQPuyE",
    "order_id": "12345446",
    "unique_identifier": null,
    "valid_until": null,
    "description": "Payment for goods on order 12345446 on the website https://shop.com.",
    "method_key": "card",
    "method_country": null,
    "accept_url": "https://shop.com/accept-url",
    "cancel_url": "https://shop.com/cancel-url",
    "callback_url": "https://shop.com/callback-url",
    "affiliate_key": null,
    "parameters": null,
    "status": "captured",
    "gateway_key": "card",
    "token_strategy": null
  }
}

As you can see you get notification data about Payment Request. Status is captured, that means that payment is successfully finished.
We provide additional information about payer such as name, surname, card number if those are available.

After processing data you have to mark notification as read, or callback will be repeated few times until you mark it as read.
To do so you have to make API call to Notification Event API

Request
PUT /notification/rest/v1/notifications/O2qQQQQ-rWzLgQKxZTamdfZRApsrPuyE/read HTTP/1.1
Host: checkout-eu-a.paysera.com
User-Agent: Paysera WalletApi PHP library
Authorization: MAC id="wkVd93h2uS", ts="1343811600", nonce="nQnNaSNyubfPErjRO55yaaEYo9YZfKHN", mac="b3M2o/cdgPk37BYplUOGL/LUdu+95EaL402ROfn8jx0="
Response body
{
  "id": "O2qQQQQ-rWzLgQKxZTamdfZRApsrPuyE",
  "event": "payment_request.captured",
  "status": "read",
  "data": {
    "id": "PRAFY24n-UBgSkiRCL-h_CVAAvj4MEkj",
    "payer": {
      "name": "John",
      "surname": "Doe",
      "full_name": "John Doe",
      "email": "payer@email.com",
      "account_number": "123456XXXXXX1234"
    },
    "authorization_url": "https://checkout.paysera.com/PRAFY24n-UBgSkiRCL-h_CVAAvj4MEkj",
    "price": {
        "amount": "10.00",
        "currency": "EUR"
    },
    "price_paid": {
      "amount": "10.00",
      "currency": "EUR"
    },
    "locale": "en",
    "business_id": "LcKB4rs-pNVLgQKxZTaGzfZRAuiQPuyE",
    "order_id": "12345446",
    "unique_identifier": null,
    "valid_until": null,
    "description": "Payment for goods on order 12345446 on the website https://shop.com.",
    "method_key": "card",
    "method_country": null,
    "accept_url": "https://shop.com/accept-url",
    "cancel_url": "https://shop.com/cancel-url",
    "callback_url": "https://shop.com/callback-url",
    "affiliate_key": null,
    "parameters": null,
    "status": "captured",
    "gateway_key": "card",
    "token_strategy": null
  }
}

As you can see response is almost identical(that's why you can just read it without pre-reading) as when just getting notification data, except that this time status is read, that identifies that no more callbacks about this notification will be sent from our system