Set up repeat payments

An AI skill is available for this guide, get it on the Skills Marketplace (GitHub).

Repeat payments are payments that a merchant takes from a customer on a regular schedule. For example, a merchant can offer a monthly product such as a magazine subscription or a merchant can allow customers to split large payments into smaller regular payments.

To schedule repeat payments, you need to complete the following steps:

  • Save the customer’s payment details to use instead of their raw payment details.
  • Create a payment plan to indicate how a merchant takes payments from their customer. It defines the frequency, amount, length, and collection method for each payment.
  • Use a subscription to assign a customer to a payment plan. A merchant can personalize a subscription for a specific customer, for example, add a discount or collect a one-off setup fee.

How it works

  1. The customer submits their card details on the Hosted Payment Page (HPP) tokenization page. Our gateway stores the payment details and returns a CARDREFERENCE.
  2. You create a payment plan with our API. Our gateway returns a paymentPlanId.
  3. You create a subscription with our API to assign the customer to the payment plan. In your request, send the CARDREFERENCE and the paymentPlanId.
  4. Our gateway collects payments automatically according to the plan schedule. If the payment plan uses manual collection, use the subscriptionId to collect each payment.

Integration journey

  1. Integrate with the Hosted Payment Page to save a customer’s payment details.
  2. Integrate with our API to:
    • Create a payment plan.
    • Assign a customer to a payment plan.
    • (Optional) Manually collect a payment from a customer.

Before you begin

Authenticate your requests before making API calls. If your request fails, see Errors.

Step 1. Save a customer’s payment details

Before you can schedule repeat payments, you need to save the customer’s payment details using the Hosted Payment Page. The Hosted Payment Page captures the card details and stores them in our vault. Our gateway returns a value for the CARDREFERENCE parameter, which is a secure token that represents the customer’s payment details. Store the CARDREFERENCE and use it when you create a subscription.

To integrate with the Hosted Payment Page to save a customer’s payment details, go to Save a customer’s payment details.

Step 2. Create a payment plan

To create a payment plan, send a POST request to our Payment Plans endpoint.

Note: To allow merchants to add their own information to the payment plan, use custom fields. For more information about how to add custom fields, go to Add custom fields to your integration.

Request parameters

To create the body of your request, use the following parameters:

Request

paymentPlanIdstringRequired1-48 characters
Unique identifier that the merchant assigns to the payment plan.
namestringRequired5-128 characters
Name of the payment plan.
currencyenumRequired
Currency of the transaction. The value for the currency follows the [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) standard.
typeenumRequiredDefaults to automatic
Indicates how the merchant takes the payment from the customer's account. - `manual` - The merchant manually collects payments from the customer. - `automatic` - The terminal automatically collects payments from the customer.
frequencyenumRequired
Indicates how often the merchant or the terminal collects a payment from the customer.
onUpdateenumRequiredDefaults to continue
Indicates whether any changes that the merchant makes to the payment plan apply to existing subscriptions. - `update` - Changes apply to existing subscriptions. - `continue` - Changes don't apply to existing subscriptions.
onDeleteenumRequiredDefaults to complete
Indicates what happens to existing subscriptions if the merchant deletes the payment plan. - `complete` - Stops existing subscriptions. - `continue` - Continues existing subscriptions.
descriptionstringOptional0-128 characters
Description of the payment plan.
lengthintegerOptional>=0Defaults to 0
Number of payments for the payment plan. To indicate that the payment plan should run indefinitely, send a value of `0`.
customFieldNameslist of stringsOptional
Array of custom fields that you can use in subscriptions linked to the payment plan.
setupOrderobjectOptional
Object that contains information about the initial cost that a customer pays to set up the subscription.
recurringOrderobjectOptional
Object that contains information about the cost of each payment. **Note:** Send this object only if the value for **type** is `automatic`.

Example request

POST
/v1/processing-terminals/:processingTerminalId/payment-plans
1curl -X POST https://api.payroc.com/v1/processing-terminals/1234001/payment-plans \
2 -H "Idempotency-Key: 8e03978e-40d5-43e8-bc93-6894a57f9324" \
3 -H "Authorization: Bearer <token>" \
4 -H "Content-Type: application/json" \
5 -d '{
6 "paymentPlanId": "PlanRef8765",
7 "name": "Premium Club",
8 "currency": "USD",
9 "type": "automatic",
10 "frequency": "monthly",
11 "onUpdate": "continue",
12 "onDelete": "complete",
13 "description": "Monthly Premium Club subscription",
14 "length": 12,
15 "customFieldNames": [
16 "yourCustomField"
17 ],
18 "setupOrder": {
19 "amount": 4999,
20 "description": "Initial setup fee for Premium Club subscription",
21 "breakdown": {
22 "subtotal": 4347,
23 "taxes": [
24 {
25 "name": "Sales Tax",
26 "rate": 5
27 }
28 ]
29 }
30 },
31 "recurringOrder": {
32 "amount": 4999,
33 "description": "Monthly Premium Club subscription",
34 "breakdown": {
35 "subtotal": 4347,
36 "taxes": [
37 {
38 "name": "Sales Tax",
39 "rate": 5
40 }
41 ]
42 }
43 }
44}'

Response fields

If your request is successful, we create the payment plan and return a response. Store the paymentPlanId and send it when you create the subscription. The response contains the following fields:

Response

paymentPlanIdstringRequired1-48 characters
Unique identifier that the merchant assigns to the payment plan.
namestringRequired5-128 characters
Name of the payment plan.
currencyenumRequired
Currency of the transaction. The value for the currency follows the [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) standard.
typeenumRequiredDefaults to automatic
Indicates how the merchant takes the payment from the customer's account. - `manual` - The merchant manually collects payments from the customer. - `automatic` - The terminal automatically collects payments from the customer.
frequencyenumRequired
Indicates how often the merchant or the terminal collects a payment from the customer.
onUpdateenumRequiredDefaults to continue
Indicates whether any changes that the merchant makes to the payment plan apply to existing subscriptions. - `update` - Changes apply to existing subscriptions. - `continue` - Changes don't apply to existing subscriptions.
onDeleteenumRequiredDefaults to complete
Indicates what happens to existing subscriptions if the merchant deletes the payment plan. - `complete` - Stops existing subscriptions. - `continue` - Continues existing subscriptions.
processingTerminalIdstringOptionalRead-only4-50 characters
Unique identifier of the terminal that the payment plan is assigned to.
descriptionstringOptional0-128 characters
Description of the payment plan.
lengthintegerOptional>=0Defaults to 0
Number of payments for the payment plan. To indicate that the payment plan should run indefinitely, send a value of `0`.
customFieldNameslist of stringsOptional
Array of custom fields that you can use in subscriptions linked to the payment plan.
setupOrderobjectOptional
Object that contains information about the initial cost that a customer pays to set up the subscription.
recurringOrderobjectOptional
Object that contains information about the cost of each payment. **Note:** Send this object only if the value for **type** is `automatic`.

Example response

Response
1{
2 "paymentPlanId": "PlanRef8765",
3 "name": "Premium Club",
4 "currency": "USD",
5 "type": "automatic",
6 "frequency": "monthly",
7 "onUpdate": "continue",
8 "onDelete": "complete",
9 "processingTerminalId": "1234001",
10 "description": "Monthly Premium Club subscription",
11 "length": 12,
12 "customFieldNames": [
13 "yourCustomField"
14 ],
15 "setupOrder": {
16 "amount": 4999,
17 "description": "Initial setup fee for Premium Club subscription",
18 "breakdown": {
19 "subtotal": 4347,
20 "taxes": [
21 {
22 "name": "Sales Tax",
23 "rate": 5
24 }
25 ]
26 }
27 },
28 "recurringOrder": {
29 "amount": 4999,
30 "description": "Monthly Premium Club subscription",
31 "breakdown": {
32 "subtotal": 4347,
33 "taxes": [
34 {
35 "name": "Sales Tax",
36 "rate": 5
37 }
38 ]
39 }
40 }
41}

Step 3. Create a subscription

To assign a customer to a payment plan, send a POST request to our Subscriptions endpoint. Send the CARDREFERENCE from Step 1 in the token parameter. You can also use this request to personalize the payment plan for each customer, for example, apply a discount on each payment or add a one-off setup fee.

Request parameters

To create the body of your request, use the following parameters:

Request

Example request

POST
/v1/processing-terminals/:processingTerminalId/subscriptions
1curl -X POST https://api.payroc.com/v1/processing-terminals/1234001/subscriptions \
2 -H "Idempotency-Key: 8e03978e-40d5-43e8-bc93-6894a57f9324" \
3 -H "Authorization: Bearer <token>" \
4 -H "Content-Type: application/json" \
5 -d '{
6 "subscriptionId": "SubRef7654",
7 "paymentPlanId": "PlanRef8765",
8 "paymentMethod": {
9 "type": "secureToken",
10 "token": "296753123456"
11 },
12 "startDate": "2024-07-02",
13 "name": "Premium Club",
14 "description": "Premium Club subscription",
15 "setupOrder": {
16 "orderId": "OrderRef6543",
17 "amount": 4999,
18 "description": "Initial setup fee for Premium Club subscription"
19 },
20 "recurringOrder": {
21 "amount": 4999,
22 "description": "Monthly Premium Club subscription",
23 "breakdown": {
24 "subtotal": 4347,
25 "taxes": [
26 {
27 "rate": 5,
28 "name": "Sales Tax",
29 "type": "rate"
30 }
31 ]
32 }
33 },
34 "endDate": "2025-07-01",
35 "length": 12,
36 "pauseCollectionFor": 0
37}'

Response fields

If your request is successful, we assign the customer to the payment plan and return a response. Store the subscriptionId. The response contains the following fields:

Response

Example response

Response
1{
2 "subscriptionId": "SubRef7654",
3 "processingTerminalId": "1234001",
4 "paymentPlan": {
5 "paymentPlanId": "PlanRef8765",
6 "name": "Monthly Premium Club subscription",
7 "link": {
8 "rel": "self",
9 "method": "GET",
10 "href": "https://api.payroc.com/v1/processing-terminals/1234001/payment-plans/PlanRef8765"
11 }
12 },
13 "secureToken": {
14 "secureTokenId": "MREF_abc1de23-f4a5-6789-bcd0-12e345678901fa",
15 "customerName": "Sarah Hazel Hopper",
16 "token": "296753123456",
17 "status": "notValidated",
18 "link": {
19 "rel": "self",
20 "method": "GET",
21 "href": "https://api.payroc.com/v1/processing-terminals/1234001/secure-tokens/MREF_abc1de23-f4a5-6789-bcd0-12e345678901fa"
22 }
23 },
24 "name": "Premium Club",
25 "currency": "USD",
26 "currentState": {
27 "status": "active",
28 "paidInvoices": 0,
29 "nextDueDate": "2024-08-02",
30 "outstandingInvoices": 3
31 },
32 "startDate": "2024-07-02",
33 "type": "automatic",
34 "frequency": "monthly",
35 "description": "Premium Club subscription",
36 "setupOrder": {
37 "orderId": "OrderRef6543",
38 "amount": 4999,
39 "description": "Initial setup fee for Premium Club subscription",
40 "breakdown": {
41 "subtotal": 4347,
42 "surcharge": {
43 "amount": 217,
44 "percentage": 5
45 },
46 "taxes": [
47 {
48 "name": "Sales Tax",
49 "rate": 5
50 }
51 ]
52 }
53 },
54 "recurringOrder": {
55 "amount": 4999,
56 "description": "Premium Club subscription",
57 "breakdown": {
58 "subtotal": 4347,
59 "surcharge": {
60 "amount": 217,
61 "percentage": 5
62 },
63 "taxes": [
64 {
65 "name": "Sales Tax",
66 "rate": 5
67 }
68 ]
69 }
70 },
71 "endDate": "2025-07-01",
72 "length": 12,
73 "pauseCollectionFor": 0,
74 "customFields": [
75 {
76 "name": "yourCustomField",
77 "value": "abc123"
78 }
79 ]
80}

Step 4. (Optional) Manually collect a payment

Our gateway can automatically collect payments, or the merchant can manually collect payments.

  • If the payment plan has a value of automatic for the type parameter, our gateway automatically collects payments from the customer.
  • If the payment plan has a value of manual for the type parameter, send a POST request to the Subscriptions endpoint to collect a payment from a customer.

Request parameters

To create the body of your request, use the following parameters:

Request

Example request

POST
/v1/processing-terminals/:processingTerminalId/subscriptions/:subscriptionId/pay
1curl -X POST https://api.payroc.com/v1/processing-terminals/1234001/subscriptions/SubRef7654/pay \
2 -H "Idempotency-Key: 8e03978e-40d5-43e8-bc93-6894a57f9324" \
3 -H "Authorization: Bearer <token>" \
4 -H "Content-Type: application/json" \
5 -d '{
6 "order": {
7 "orderId": "OrderRef6543",
8 "amount": 4999,
9 "description": "Monthly Premium Club subscription"
10 },
11 "operator": "Jane"
12}'

Response fields

If your request is successful, we take the payment from the customer and return a response. The response contains the following fields:

Response

Example response

Response
1{
2 "subscriptionId": "SubRef7654",
3 "processingTerminalId": "1234001",
4 "payment": {
5 "paymentId": "M2MJOG6O2Y",
6 "dateTime": "2024-07-02T15:30:00Z",
7 "currency": "USD",
8 "amount": 4999,
9 "status": "ready",
10 "responseCode": "A",
11 "responseMessage": "Transaction approved",
12 "link": {
13 "rel": "self",
14 "method": "GET",
15 "href": "https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y"
16 }
17 },
18 "secureToken": {
19 "secureTokenId": "MREF_abc1de23-f4a5-6789-bcd0-12e345678901fa",
20 "customerName": "Sarah Hazel Hopper",
21 "token": "296753123456",
22 "status": "notValidated",
23 "link": {
24 "rel": "self",
25 "method": "GET",
26 "href": "https://api.payroc.com/v1/processing-terminals/1234001/secure-tokens/MREF_abc1de23-f4a5-6789-bcd0-12e345678901fa"
27 }
28 },
29 "currentState": {
30 "status": "active",
31 "paidInvoices": 1,
32 "nextDueDate": "2024-08-02",
33 "outstandingInvoices": 2
34 },
35 "customFields": [
36 {
37 "name": "yourCustomField",
38 "value": "abc123"
39 }
40 ]
41}