Recurring
How it works
PaysafeCard supports recurring payments based on following two flows, and we streamline both with Payment agreements:
-
One-Click Payments: A streamlined checkout that lets consumers complete future purchases with a single click, bypassing the need for re-authentication.
-
Recurring Payments: Simplifies subscriptions by allowing merchants to automatically charge the tokenized card without needing the consumer's active involvement.
Once a consumer authorizes their initial payment, PPRO then stores a multi-use payment handle token linked to the consumer, which backs all subsequent charges.
Create the payment agreement
To create a Paysafecard payment agreement, provide the following information when calling our payment agreements endpoint:
| Field | Description |
|---|---|
paymentMethod | PAYSAFECARD |
amount.type | EXACT |
amount.value | The recurring charge amount in the smallest currency unit. This becomes the authorized amount for all subsequent charges. |
amount.currency | CHF, EUR, GBP, HUF, NOK, PLN, RON, SEK. |
consumer.country | AE, AT, AU, BE, BG, CA, CH, CY, CZ, DE, DK, EE, ES, FI, FR, GB, GE, GI, GR, HR, HU, IE, IS, IT, KW, LI, LT, LU, LV, MD, MT, MX, NL, NO, NZ, PE, PL, PT, PY, RO, SA, SE, SI, SK, UY |
authenticationSettings: REDIRECT settings.returnUrl | Specify the URL to which the consumer should be redirected after completing the payment. This is required for the REDIRECT payment flow. |
initiator | CONSUMER for One-click, or MERCHANT for Recurring. |
scheduleType | UNSCHEDULED (optional) for One-click, or SCHEDULED for Recurring. |
For Recurring, the following fields are also mandatory:
| Field | Description |
|---|---|
frequency.type | For Recurring, only. The type of frequency between consecutive payment charges. Allowed: WEEKLY, MONTHLY or YEARLY. |
frequency.interval | For Recurring, only. The interval between consecutive payment charges. |
In this flow, you can also include the initialPaymentCharge object in this agreement creation call to immediately initiate the first payment without making a separate call. If you include this object, you'll need to specify:
- The exact
amount.valueandamount.currencyof the first payment.
If you don't include an initialPaymentChargeduring agreement creation, you'll need to make a separate API call to /v1/payment-agreements/{agreement_id}/payment-charges to create the first charge.
Request
POST /v1/payment-agreements
{
"paymentMethod": "PAYSAFECARD",
"description": "Description",
"amountType": "EXACT",
"amount": {
"value": 1000,
"currency": "EUR"
},
"consumer": {
"name": "John Smith",
"country": "DE"
},
"initialPaymentCharge": {
"initiator": "CONSUMER",
"scheduleType": "UNSCHEDULED",
"amount": {
"value": 1000,
"currency": "EUR"
}
},
"authenticationSettings": [
{
"type": "REDIRECT",
"settings": {
"returnUrl": "https://merchant.com/paysafecard/return"
}
}
]
}{
"paymentMethod": "PAYSAFECARD",
"description": "Monthly subscription",
"amountType": "EXACT",
"frequency": {
"interval": 1,
"type": "MONTHLY"
},
"amount": {
"value": 1000,
"currency": "EUR"
},
"consumer": {
"name": "John Smith",
"country": "DE"
},
"initialPaymentCharge": {
"initiator": "MERCHANT",
"scheduleType": "SCHEDULED",
"amount": {
"value": 1000,
"currency": "EUR"
}
},
"authenticationSettings": [
{
"type": "REDIRECT",
"settings": {
"returnUrl": "https://merchant.com/paysafecard/return"
}
}
]
}{
"paymentMethod": "PAYSAFECARD",
"description": "Monthly subscription",
"amountType": "EXACT",
"frequency": {
"interval": 1,
"type": "MONTHLY"
},
"amount": {
"value": 1000,
"currency": "EUR"
},
"consumer": {
"name": "John Smith",
"country": "DE"
},
"authenticationSettings": [
{
"type": "REDIRECT",
"settings": {
"returnUrl": "https://merchant.com/paysafecard/return"
}
}
]
}Response
You'll receive our standard payment agreement response:
{
"id": "agr_dqLrOcwMiuYOAbMCzihGa",
"status": "AUTHENTICATION_PENDING",
"description": "Description",
"paymentMethod": "PAYSAFECARD"
},
"startDate": "2026-10-16T19:40:11.845Z",
"amount": {
"value": 1000,
"currency": "EUR"
},
"instrumentId": "instr_GcZjyRVEI69vKqyyxiJCv",
"amountType": "EXACT",
"consumer": {
"name": "John Smith",
"country": "DE"
},
"authenticationMethods": [
{
"details": {
"requestUrl": "https://redirections/example.mukEmRm4iRxIe0tu5aAbbZY6Sw",
"requestMethod": "GET"
},
"type": "REDIRECT"
}
],
"history": [
{
"id": "ahist_aaMSpSkw99sEzlaNnuh83",
"status": "AUTHENTICATION_PENDING",
"createdAt": "2026-10-16T19:40:12.313Z"
}
],
"revocations": [],
"createdAt": "2026-10-16T19:40:12.313Z",
"updatedAt": "2026-10-16T19:40:12.313Z"
}{
"id": "agr_dqLrOcwMiuYOAbMCzihGa",
"status": "AUTHENTICATION_PENDING",
"description": "Description",
"paymentMethod": "PAYSAFECARD",
"frequency": {
"type": "MONTHLY",
"interval": 1
},
"startDate": "2026-10-16T19:40:11.845Z",
"amount": {
"value": 1000,
"currency": "EUR"
},
"instrumentId": "instr_GcZjyRVEI69vKqyyxiJCv",
"amountType": "EXACT",
"consumer": {
"name": "John Smith",
"country": "DE"
},
"authenticationMethods": [
{
"details": {
"requestUrl": "https://redirections/example.mukEmRm4iRxIe0tu5aAbbZY6Sw",
"requestMethod": "GET"
},
"type": "REDIRECT"
}
],
"history": [
{
"id": "ahist_aaMSpSkw99sEzlaNnuh83",
"status": "AUTHENTICATION_PENDING",
"createdAt": "2026-10-16T19:40:12.313Z"
}
],
"revocations": [],
"createdAt": "2026-10-16T19:40:12.313Z",
"updatedAt": "2026-10-16T19:40:12.313Z"
}Pick the desired authentication method
REDIRECT
Redirect your consumer to the returned $.authenticationMethods[?(@.type == "REDIRECT")].details.requestUrl . For example, with the value of https://redirection-target.ppro.com/ using the returned $.authenticationMethods[?(@.type == "REDIRECT")].details.requestMethod HTTP method.
Handling the result
REDIRECT
- After the consumer completes the authentication, they are redirected to the
returnUrlspecified in the payment charge creation request. - Upon redirect back to your site, retrieve the latest agreement status by performing a
GET /v1/payment-agreements/{agreementId}. Use the returned status field to determine and display the final payment outcome to the consumer. - Additionally, webhooks are triggered to notify you of the payment result. This ensures you receive the outcome even if the consumer closes their browser or fails to return to your website.
Create a recurring payment
To initiate a subsequent recurring payment, send a request against an active agreement using our payment agreements API.
Request
POST /v1/payment-agreements/{agreement-id}/payment-charges
{
"amount": {
"value": 1999,
"currency": "EUR"
}Response
{
"id": "charge_N9lRrX0aCxIjO21fkPHSh",
"paymentMethod": "PAYSAFECARD",
"currency": "EUR",
"country": "DE",
"paymentDescriptor": "Payment Descriptor",
"instrumentId": "instr_Nb7O43ofycs0JJhPZPeEg",
"status": "CAPTURED",
"consumer": {
"name": "John Smith",
"country": "DE"
},
"order": {
"orderItems": [
{
"name": "Product Name 1",
"quantity": 1,
"amount": 1
}
],
"industryData": []
},
"authorizations": [
{
"id": "authz_OOS1uQABVWpzda0ZcV9ym",
"amount": 10,
"status": "AUTHORIZED",
"merchantPaymentChargeReference": "ed3eab7e-8712-405b-a1ec-337d228fd5b0",
"createdAt": "2026-10-20T10:07:49.788Z",
"updatedAt": "2026-10-20T10:07:49.788Z"
}
],
"captures": [
{
"id": "capture_2fuM45oxMt55fnD1UvRGU",
"amount": 10,
"status": "CAPTURED",
"merchantCaptureReference": "ed3eab7e-8712-405b-a1ec-337d228fd5b0",
"createdAt": "2026-10-20T10:07:49.788Z",
"updatedAt": "2026-10-20T10:07:49.788Z"
}
],
"refunds": [],
"voids": [],
"createdAt": "2026-10-20T10:07:49.714Z",
"updatedAt": "2026-10-20T10:07:49.788Z"
}Handling insufficient balance
One-click top-up
For a One-click charge ( where initiator = CONSUMER), a decline on insufficient balance does not necessarily fail the charge outright. This top-up redirect only happens for consumer-initiated charges declined specifically on insufficient balance where Paysafecard provides a top-up URL. Every other decline reason and every decline on a merchant-initiated charge — fails immediately.
For Initial One-Click charge
Redirect the consumer as usual to the requestUrl, where they can top up their card balance and complete the authentication from there.
For a subsequent One-Click charge
Redirect the consumer to the requestUrl the same way you would for the original payment. They can top up their balance and complete the charge from there.
Recurring charge
A recurring charge (where initiator = MERCHANT), is processed off session where the consumer is not present. When such a recurring charge is declined due to insufficient balance, the charge status may go PENDING instead of it going to FAILED immediately, this gives the consumer an opportunity to top up the card balance, this happens out of band & post a stipulated grace period, PPRO notifies you with the webhooks for the final outcome of this recurring charge (either FAILED or CAPTURED)
Revoking an active agreement
Token lifecycleThe payment handle token backing an agreement is subject to PaysafeCard's own lifecycle rules, independent of your agreement's
endDate. The token expires in 365 days after creation. PPRO marks the agreement as REVOKED_BY_PROVIDER and blocks further charge attempts against it. You'll need to process a new consent from the consumer to continue billing them.
Revoking an agreement
Consumer-initiated revocation
Consumers can revoke the consent at any time from the payment method app. When such a consumer initiated revocation occurs, PPRO sends a webhook notification to you. A revoked agreement cannot process further charges. If the consumer wants to resubscribe, you can simply create a new agreement again.
Merchant-initiated revocation
Consumers can also cancel the subscription on a merchant provided surface (i.e. app or website), in this scenario you as a merchant can also initiate the revocation by calling the Agreements revoke endpoint as below.
Request
POST /v1/payment-agreements/agrId/revocations
{}Response
{
"id": "agr_wRk9mXtYpQzLvN3cJbD7F",
"status": "REVOKED_BY_MERCHANT",
Additional Information
Before you go live
- While Paysafecard recurring is available for merchants processing Paysafecard one time payments, but contract your PPRO Account Manager to activate for your account.
- Request the PPRO Account Manager for the staging account to test in Sandbox.
Updated about 1 hour ago