# Set up repeat payments

Set up repeat payments via the Hosted Payment Page by creating a payment plan and subscription using POST requests to the Payment Plans and Subscriptions endpoints.

**Prerequisites:** [Authentication](/api/authentication) · [Save a Customer’s Payment Details](/guides/payments/hosted-payment-page/save-payment-details)

An AI skill is available for this guide, get it on the [Skills Marketplace (GitHub)](https://github.com/payroc/skills).

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.

<a id="how-it-works"></a>
## How it works

```mermaid
sequenceDiagram
    actor C as Customer
    participant HPP as Hosted Payment Page
    participant MS as Merchant's server
    participant GW as Gateway

    rect rgba(0, 81, 194, 0.4)
        Note over C,HPP: Step 1 — Save payment details
        C->>HPP: Enter card details
        HPP->>GW: Tokenize card
        GW-->>HPP: CARDREFERENCE
        HPP-->>MS: Redirect with CARDREFERENCE
        Note right of MS: Store CARDREFERENCE
    end

    rect rgba(0, 224, 184, 0.3)
        Note over MS,GW: Step 2 — Create payment plan
        MS->>GW: POST /payment-plans
        Note over MS,GW: name, currency, type, frequency,<br />length, recurringOrder.amount
        GW-->>MS: paymentPlanId
        Note right of MS: Store paymentPlanId
    end

    rect rgba(0, 224, 184, 0.3)
        Note over MS,GW: Step 3 — Create subscription
        MS->>GW: POST /subscriptions
        Note over MS,GW: paymentPlanId,<br />paymentMethod.secureToken.token = CARDREFERENCE,<br />startDate
        GW-->>MS: subscriptionId
        Note right of MS: Store subscriptionId
    end

    rect rgba(0, 224, 184, 0.3)
        Note over MS,GW: Step 4 — Collect payments
        alt Automatic plan
            GW-->>C: Gateway collects on schedule
        else Manual plan
            MS->>GW: POST /subscriptions/{subscriptionId}/pay
            Note over MS,GW: order.orderId, order.amount
            GW-->>MS: Payment confirmed
        end
    end
```

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.

<a id="integration-journey"></a>
## 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.

<a id="before-you-begin"></a>
## Before you begin

[Authenticate your requests](/api/authentication) before making API calls. If your request fails, see [Errors](/api/errors).

<a id="step-1-save-a-customers-payment-details"></a>
## 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](/guides/payments/hosted-payment-page/save-payment-details).

<a id="step-2-create-a-payment-plan"></a>
## Step 2. Create a payment plan

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

| Environment | URL |
| --- | --- |
| Test | [https://api.uat.payroc.com/v1/processing-terminals/\{processingTerminalId\}/payment-plans](https://api.uat.payroc.com/v1/processing-terminals/%7BprocessingTerminalId%7D/payment-plans) |
| Production | [https://api.payroc.com/v1/processing-terminals/\{processingTerminalId\}/payment-plans](https://api.payroc.com/v1/processing-terminals/%7BprocessingTerminalId%7D/payment-plans) |

**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](/guides/payments/add-custom-fields).

<a id="request-parameters"></a>
### Request parameters

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

<a id="schema-requestbody"></a>
### Schema (`request.body`)

[Request body schema for `POST /processing-terminals/{processingTerminalId}/payment-plans`](/api/create-payment-plan)

<a id="example-request"></a>
### Example request

<a id="request"></a>
### Request

POST https://api.payroc.com/v1/processing-terminals/\{processingTerminalId\}/payment-plans

```curl
curl -X POST https://api.payroc.com/v1/processing-terminals/1234001/payment-plans \
     -H "Idempotency-Key: 8e03978e-40d5-43e8-bc93-6894a57f9324" \
     -H "Authorization: Bearer <token>" \
     -H "Content-Type: application/json" \
     -d '{
  "paymentPlanId": "PlanRef8765",
  "name": "Premium Club",
  "currency": "USD",
  "type": "automatic",
  "frequency": "monthly",
  "onUpdate": "continue",
  "onDelete": "complete",
  "description": "Monthly Premium Club subscription",
  "length": 12,
  "customFieldNames": [
    "yourCustomField"
  ],
  "setupOrder": {
    "amount": 4999,
    "description": "Initial setup fee for Premium Club subscription",
    "breakdown": {
      "subtotal": 4347,
      "taxes": [
        {
          "name": "Sales Tax",
          "rate": 5
        }
      ]
    }
  },
  "recurringOrder": {
    "amount": 4999,
    "description": "Monthly Premium Club subscription",
    "breakdown": {
      "subtotal": 4347,
      "taxes": [
        {
          "name": "Sales Tax",
          "rate": 5
        }
      ]
    }
  }
}'
```

**`Payment Plan`**

```python
import requests

url = "https://api.payroc.com/v1/processing-terminals/1234001/payment-plans"

payload = {
    "paymentPlanId": "PlanRef8765",
    "name": "Premium Club",
    "currency": "USD",
    "type": "automatic",
    "frequency": "monthly",
    "onUpdate": "continue",
    "onDelete": "complete",
    "description": "Monthly Premium Club subscription",
    "length": 12,
    "customFieldNames": ["yourCustomField"],
    "setupOrder": {
        "amount": 4999,
        "description": "Initial setup fee for Premium Club subscription",
        "breakdown": {
            "subtotal": 4347,
            "taxes": [
                {
                    "name": "Sales Tax",
                    "rate": 5
                }
            ]
        }
    },
    "recurringOrder": {
        "amount": 4999,
        "description": "Monthly Premium Club subscription",
        "breakdown": {
            "subtotal": 4347,
            "taxes": [
                {
                    "name": "Sales Tax",
                    "rate": 5
                }
            ]
        }
    }
}
headers = {
    "Idempotency-Key": "8e03978e-40d5-43e8-bc93-6894a57f9324",
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

**`Payment Plan`**

```javascript
const url = 'https://api.payroc.com/v1/processing-terminals/1234001/payment-plans';
const options = {
  method: 'POST',
  headers: {
    'Idempotency-Key': '8e03978e-40d5-43e8-bc93-6894a57f9324',
    Authorization: 'Bearer <token>',
    'Content-Type': 'application/json'
  },
  body: '{"paymentPlanId":"PlanRef8765","name":"Premium Club","currency":"USD","type":"automatic","frequency":"monthly","onUpdate":"continue","onDelete":"complete","description":"Monthly Premium Club subscription","length":12,"customFieldNames":["yourCustomField"],"setupOrder":{"amount":4999,"description":"Initial setup fee for Premium Club subscription","breakdown":{"subtotal":4347,"taxes":[{"name":"Sales Tax","rate":5}]}},"recurringOrder":{"amount":4999,"description":"Monthly Premium Club subscription","breakdown":{"subtotal":4347,"taxes":[{"name":"Sales Tax","rate":5}]}}}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

**`Payment Plan`**

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.payroc.com/v1/processing-terminals/1234001/payment-plans"

	payload := strings.NewReader("{\n  \"paymentPlanId\": \"PlanRef8765\",\n  \"name\": \"Premium Club\",\n  \"currency\": \"USD\",\n  \"type\": \"automatic\",\n  \"frequency\": \"monthly\",\n  \"onUpdate\": \"continue\",\n  \"onDelete\": \"complete\",\n  \"description\": \"Monthly Premium Club subscription\",\n  \"length\": 12,\n  \"customFieldNames\": [\n    \"yourCustomField\"\n  ],\n  \"setupOrder\": {\n    \"amount\": 4999,\n    \"description\": \"Initial setup fee for Premium Club subscription\",\n    \"breakdown\": {\n      \"subtotal\": 4347,\n      \"taxes\": [\n        {\n          \"name\": \"Sales Tax\",\n          \"rate\": 5\n        }\n      ]\n    }\n  },\n  \"recurringOrder\": {\n    \"amount\": 4999,\n    \"description\": \"Monthly Premium Club subscription\",\n    \"breakdown\": {\n      \"subtotal\": 4347,\n      \"taxes\": [\n        {\n          \"name\": \"Sales Tax\",\n          \"rate\": 5\n        }\n      ]\n    }\n  }\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324")
	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

**`Payment Plan`**

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.payroc.com/v1/processing-terminals/1234001/payment-plans")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '8e03978e-40d5-43e8-bc93-6894a57f9324'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"paymentPlanId\": \"PlanRef8765\",\n  \"name\": \"Premium Club\",\n  \"currency\": \"USD\",\n  \"type\": \"automatic\",\n  \"frequency\": \"monthly\",\n  \"onUpdate\": \"continue\",\n  \"onDelete\": \"complete\",\n  \"description\": \"Monthly Premium Club subscription\",\n  \"length\": 12,\n  \"customFieldNames\": [\n    \"yourCustomField\"\n  ],\n  \"setupOrder\": {\n    \"amount\": 4999,\n    \"description\": \"Initial setup fee for Premium Club subscription\",\n    \"breakdown\": {\n      \"subtotal\": 4347,\n      \"taxes\": [\n        {\n          \"name\": \"Sales Tax\",\n          \"rate\": 5\n        }\n      ]\n    }\n  },\n  \"recurringOrder\": {\n    \"amount\": 4999,\n    \"description\": \"Monthly Premium Club subscription\",\n    \"breakdown\": {\n      \"subtotal\": 4347,\n      \"taxes\": [\n        {\n          \"name\": \"Sales Tax\",\n          \"rate\": 5\n        }\n      ]\n    }\n  }\n}"

response = http.request(request)
puts response.read_body
```

**`Payment Plan`**

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.payroc.com/v1/processing-terminals/1234001/payment-plans")
  .header("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"paymentPlanId\": \"PlanRef8765\",\n  \"name\": \"Premium Club\",\n  \"currency\": \"USD\",\n  \"type\": \"automatic\",\n  \"frequency\": \"monthly\",\n  \"onUpdate\": \"continue\",\n  \"onDelete\": \"complete\",\n  \"description\": \"Monthly Premium Club subscription\",\n  \"length\": 12,\n  \"customFieldNames\": [\n    \"yourCustomField\"\n  ],\n  \"setupOrder\": {\n    \"amount\": 4999,\n    \"description\": \"Initial setup fee for Premium Club subscription\",\n    \"breakdown\": {\n      \"subtotal\": 4347,\n      \"taxes\": [\n        {\n          \"name\": \"Sales Tax\",\n          \"rate\": 5\n        }\n      ]\n    }\n  },\n  \"recurringOrder\": {\n    \"amount\": 4999,\n    \"description\": \"Monthly Premium Club subscription\",\n    \"breakdown\": {\n      \"subtotal\": 4347,\n      \"taxes\": [\n        {\n          \"name\": \"Sales Tax\",\n          \"rate\": 5\n        }\n      ]\n    }\n  }\n}")
  .asString();
```

**`Payment Plan`**

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.payroc.com/v1/processing-terminals/1234001/payment-plans', [
  'body' => '{
  "paymentPlanId": "PlanRef8765",
  "name": "Premium Club",
  "currency": "USD",
  "type": "automatic",
  "frequency": "monthly",
  "onUpdate": "continue",
  "onDelete": "complete",
  "description": "Monthly Premium Club subscription",
  "length": 12,
  "customFieldNames": [
    "yourCustomField"
  ],
  "setupOrder": {
    "amount": 4999,
    "description": "Initial setup fee for Premium Club subscription",
    "breakdown": {
      "subtotal": 4347,
      "taxes": [
        {
          "name": "Sales Tax",
          "rate": 5
        }
      ]
    }
  },
  "recurringOrder": {
    "amount": 4999,
    "description": "Monthly Premium Club subscription",
    "breakdown": {
      "subtotal": 4347,
      "taxes": [
        {
          "name": "Sales Tax",
          "rate": 5
        }
      ]
    }
  }
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
    'Idempotency-Key' => '8e03978e-40d5-43e8-bc93-6894a57f9324',
  ],
]);

echo $response->getBody();
```

**`Payment Plan`**

```csharp
using RestSharp;

var client = new RestClient("https://api.payroc.com/v1/processing-terminals/1234001/payment-plans");
var request = new RestRequest(Method.POST);
request.AddHeader("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324");
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"paymentPlanId\": \"PlanRef8765\",\n  \"name\": \"Premium Club\",\n  \"currency\": \"USD\",\n  \"type\": \"automatic\",\n  \"frequency\": \"monthly\",\n  \"onUpdate\": \"continue\",\n  \"onDelete\": \"complete\",\n  \"description\": \"Monthly Premium Club subscription\",\n  \"length\": 12,\n  \"customFieldNames\": [\n    \"yourCustomField\"\n  ],\n  \"setupOrder\": {\n    \"amount\": 4999,\n    \"description\": \"Initial setup fee for Premium Club subscription\",\n    \"breakdown\": {\n      \"subtotal\": 4347,\n      \"taxes\": [\n        {\n          \"name\": \"Sales Tax\",\n          \"rate\": 5\n        }\n      ]\n    }\n  },\n  \"recurringOrder\": {\n    \"amount\": 4999,\n    \"description\": \"Monthly Premium Club subscription\",\n    \"breakdown\": {\n      \"subtotal\": 4347,\n      \"taxes\": [\n        {\n          \"name\": \"Sales Tax\",\n          \"rate\": 5\n        }\n      ]\n    }\n  }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

**`Payment Plan`**

```swift
import Foundation

let headers = [
  "Idempotency-Key": "8e03978e-40d5-43e8-bc93-6894a57f9324",
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "paymentPlanId": "PlanRef8765",
  "name": "Premium Club",
  "currency": "USD",
  "type": "automatic",
  "frequency": "monthly",
  "onUpdate": "continue",
  "onDelete": "complete",
  "description": "Monthly Premium Club subscription",
  "length": 12,
  "customFieldNames": ["yourCustomField"],
  "setupOrder": [
    "amount": 4999,
    "description": "Initial setup fee for Premium Club subscription",
    "breakdown": [
      "subtotal": 4347,
      "taxes": [
        [
          "name": "Sales Tax",
          "rate": 5
        ]
      ]
    ]
  ],
  "recurringOrder": [
    "amount": 4999,
    "description": "Monthly Premium Club subscription",
    "breakdown": [
      "subtotal": 4347,
      "taxes": [
        [
          "name": "Sales Tax",
          "rate": 5
        ]
      ]
    ]
  ]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.payroc.com/v1/processing-terminals/1234001/payment-plans")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: \{ (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

<a id="response-fields"></a>
### 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:

<a id="schema-responsebody"></a>
### Schema (`response.body`)

[Response body schema for `POST /processing-terminals/{processingTerminalId}/payment-plans`](/api/create-payment-plan)

<a id="example-response"></a>
### Example response

<a id="response-201"></a>
### Response (201)

```json
{
  "paymentPlanId": "PlanRef8765",
  "name": "Premium Club",
  "currency": "USD",
  "type": "automatic",
  "frequency": "monthly",
  "onUpdate": "continue",
  "onDelete": "complete",
  "processingTerminalId": "1234001",
  "description": "Monthly Premium Club subscription",
  "length": 12,
  "customFieldNames": [
    "yourCustomField"
  ],
  "setupOrder": {
    "amount": 4999,
    "description": "Initial setup fee for Premium Club subscription",
    "breakdown": {
      "subtotal": 4347,
      "taxes": [
        {
          "name": "Sales Tax",
          "rate": 5
        }
      ]
    }
  },
  "recurringOrder": {
    "amount": 4999,
    "description": "Monthly Premium Club subscription",
    "breakdown": {
      "subtotal": 4347,
      "taxes": [
        {
          "name": "Sales Tax",
          "rate": 5
        }
      ]
    }
  }
}
```

<a id="step-3-create-a-subscription"></a>
## 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.

| Environment | URL |
| --- | --- |
| Test | https://api.uat.payroc.com/v1/processing-terminals/\{processingTerminalId\}/subscriptions |
| Production | https://api.payroc.com/v1/processing-terminals/\{processingTerminalId\}/subscriptions |

<a id="request-parameters-1"></a>
### Request parameters

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

<a id="schema-requestbody-1"></a>
### Schema (`request.body`)

[Request body schema for `POST /processing-terminals/{processingTerminalId}/subscriptions`](/api/create-subscription)

<a id="example-request-1"></a>
### Example request

<a id="request-1"></a>
### Request

POST https://api.payroc.com/v1/processing-terminals/\{processingTerminalId\}/subscriptions

```curl
curl -X POST https://api.payroc.com/v1/processing-terminals/1234001/subscriptions \
     -H "Idempotency-Key: 8e03978e-40d5-43e8-bc93-6894a57f9324" \
     -H "Authorization: Bearer <token>" \
     -H "Content-Type: application/json" \
     -d '{
  "subscriptionId": "SubRef7654",
  "paymentPlanId": "PlanRef8765",
  "paymentMethod": {
    "type": "secureToken",
    "token": "296753123456"
  },
  "startDate": "2024-07-02",
  "name": "Premium Club",
  "description": "Premium Club subscription",
  "setupOrder": {
    "orderId": "OrderRef6543",
    "amount": 4999,
    "description": "Initial setup fee for Premium Club subscription"
  },
  "recurringOrder": {
    "amount": 4999,
    "description": "Monthly Premium Club subscription",
    "breakdown": {
      "subtotal": 4347,
      "taxes": [
        {
          "rate": 5,
          "name": "Sales Tax",
          "type": "rate"
        }
      ]
    }
  },
  "endDate": "2025-07-01",
  "length": 12,
  "pauseCollectionFor": 0
}'
```

**`Subscription with surcharge`**

```python
import requests

url = "https://api.payroc.com/v1/processing-terminals/1234001/subscriptions"

payload = {
    "subscriptionId": "SubRef7654",
    "paymentPlanId": "PlanRef8765",
    "paymentMethod": {
        "type": "secureToken",
        "token": "296753123456"
    },
    "startDate": "2024-07-02",
    "name": "Premium Club",
    "description": "Premium Club subscription",
    "setupOrder": {
        "orderId": "OrderRef6543",
        "amount": 4999,
        "description": "Initial setup fee for Premium Club subscription"
    },
    "recurringOrder": {
        "amount": 4999,
        "description": "Monthly Premium Club subscription",
        "breakdown": {
            "subtotal": 4347,
            "taxes": [
                {
                    "rate": 5,
                    "name": "Sales Tax",
                    "type": "rate"
                }
            ]
        }
    },
    "endDate": "2025-07-01",
    "length": 12,
    "pauseCollectionFor": 0
}
headers = {
    "Idempotency-Key": "8e03978e-40d5-43e8-bc93-6894a57f9324",
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

**`Subscription with surcharge`**

```javascript
const url = 'https://api.payroc.com/v1/processing-terminals/1234001/subscriptions';
const options = {
  method: 'POST',
  headers: {
    'Idempotency-Key': '8e03978e-40d5-43e8-bc93-6894a57f9324',
    Authorization: 'Bearer <token>',
    'Content-Type': 'application/json'
  },
  body: '{"subscriptionId":"SubRef7654","paymentPlanId":"PlanRef8765","paymentMethod":{"type":"secureToken","token":"296753123456"},"startDate":"2024-07-02","name":"Premium Club","description":"Premium Club subscription","setupOrder":{"orderId":"OrderRef6543","amount":4999,"description":"Initial setup fee for Premium Club subscription"},"recurringOrder":{"amount":4999,"description":"Monthly Premium Club subscription","breakdown":{"subtotal":4347,"taxes":[{"rate":5,"name":"Sales Tax","type":"rate"}]}},"endDate":"2025-07-01","length":12,"pauseCollectionFor":0}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

**`Subscription with surcharge`**

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.payroc.com/v1/processing-terminals/1234001/subscriptions"

	payload := strings.NewReader("{\n  \"subscriptionId\": \"SubRef7654\",\n  \"paymentPlanId\": \"PlanRef8765\",\n  \"paymentMethod\": {\n    \"type\": \"secureToken\",\n    \"token\": \"296753123456\"\n  },\n  \"startDate\": \"2024-07-02\",\n  \"name\": \"Premium Club\",\n  \"description\": \"Premium Club subscription\",\n  \"setupOrder\": {\n    \"orderId\": \"OrderRef6543\",\n    \"amount\": 4999,\n    \"description\": \"Initial setup fee for Premium Club subscription\"\n  },\n  \"recurringOrder\": {\n    \"amount\": 4999,\n    \"description\": \"Monthly Premium Club subscription\",\n    \"breakdown\": {\n      \"subtotal\": 4347,\n      \"taxes\": [\n        {\n          \"rate\": 5,\n          \"name\": \"Sales Tax\",\n          \"type\": \"rate\"\n        }\n      ]\n    }\n  },\n  \"endDate\": \"2025-07-01\",\n  \"length\": 12,\n  \"pauseCollectionFor\": 0\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324")
	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

**`Subscription with surcharge`**

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.payroc.com/v1/processing-terminals/1234001/subscriptions")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '8e03978e-40d5-43e8-bc93-6894a57f9324'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"subscriptionId\": \"SubRef7654\",\n  \"paymentPlanId\": \"PlanRef8765\",\n  \"paymentMethod\": {\n    \"type\": \"secureToken\",\n    \"token\": \"296753123456\"\n  },\n  \"startDate\": \"2024-07-02\",\n  \"name\": \"Premium Club\",\n  \"description\": \"Premium Club subscription\",\n  \"setupOrder\": {\n    \"orderId\": \"OrderRef6543\",\n    \"amount\": 4999,\n    \"description\": \"Initial setup fee for Premium Club subscription\"\n  },\n  \"recurringOrder\": {\n    \"amount\": 4999,\n    \"description\": \"Monthly Premium Club subscription\",\n    \"breakdown\": {\n      \"subtotal\": 4347,\n      \"taxes\": [\n        {\n          \"rate\": 5,\n          \"name\": \"Sales Tax\",\n          \"type\": \"rate\"\n        }\n      ]\n    }\n  },\n  \"endDate\": \"2025-07-01\",\n  \"length\": 12,\n  \"pauseCollectionFor\": 0\n}"

response = http.request(request)
puts response.read_body
```

**`Subscription with surcharge`**

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.payroc.com/v1/processing-terminals/1234001/subscriptions")
  .header("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"subscriptionId\": \"SubRef7654\",\n  \"paymentPlanId\": \"PlanRef8765\",\n  \"paymentMethod\": {\n    \"type\": \"secureToken\",\n    \"token\": \"296753123456\"\n  },\n  \"startDate\": \"2024-07-02\",\n  \"name\": \"Premium Club\",\n  \"description\": \"Premium Club subscription\",\n  \"setupOrder\": {\n    \"orderId\": \"OrderRef6543\",\n    \"amount\": 4999,\n    \"description\": \"Initial setup fee for Premium Club subscription\"\n  },\n  \"recurringOrder\": {\n    \"amount\": 4999,\n    \"description\": \"Monthly Premium Club subscription\",\n    \"breakdown\": {\n      \"subtotal\": 4347,\n      \"taxes\": [\n        {\n          \"rate\": 5,\n          \"name\": \"Sales Tax\",\n          \"type\": \"rate\"\n        }\n      ]\n    }\n  },\n  \"endDate\": \"2025-07-01\",\n  \"length\": 12,\n  \"pauseCollectionFor\": 0\n}")
  .asString();
```

**`Subscription with surcharge`**

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.payroc.com/v1/processing-terminals/1234001/subscriptions', [
  'body' => '{
  "subscriptionId": "SubRef7654",
  "paymentPlanId": "PlanRef8765",
  "paymentMethod": {
    "type": "secureToken",
    "token": "296753123456"
  },
  "startDate": "2024-07-02",
  "name": "Premium Club",
  "description": "Premium Club subscription",
  "setupOrder": {
    "orderId": "OrderRef6543",
    "amount": 4999,
    "description": "Initial setup fee for Premium Club subscription"
  },
  "recurringOrder": {
    "amount": 4999,
    "description": "Monthly Premium Club subscription",
    "breakdown": {
      "subtotal": 4347,
      "taxes": [
        {
          "rate": 5,
          "name": "Sales Tax",
          "type": "rate"
        }
      ]
    }
  },
  "endDate": "2025-07-01",
  "length": 12,
  "pauseCollectionFor": 0
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
    'Idempotency-Key' => '8e03978e-40d5-43e8-bc93-6894a57f9324',
  ],
]);

echo $response->getBody();
```

**`Subscription with surcharge`**

```csharp
using RestSharp;

var client = new RestClient("https://api.payroc.com/v1/processing-terminals/1234001/subscriptions");
var request = new RestRequest(Method.POST);
request.AddHeader("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324");
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"subscriptionId\": \"SubRef7654\",\n  \"paymentPlanId\": \"PlanRef8765\",\n  \"paymentMethod\": {\n    \"type\": \"secureToken\",\n    \"token\": \"296753123456\"\n  },\n  \"startDate\": \"2024-07-02\",\n  \"name\": \"Premium Club\",\n  \"description\": \"Premium Club subscription\",\n  \"setupOrder\": {\n    \"orderId\": \"OrderRef6543\",\n    \"amount\": 4999,\n    \"description\": \"Initial setup fee for Premium Club subscription\"\n  },\n  \"recurringOrder\": {\n    \"amount\": 4999,\n    \"description\": \"Monthly Premium Club subscription\",\n    \"breakdown\": {\n      \"subtotal\": 4347,\n      \"taxes\": [\n        {\n          \"rate\": 5,\n          \"name\": \"Sales Tax\",\n          \"type\": \"rate\"\n        }\n      ]\n    }\n  },\n  \"endDate\": \"2025-07-01\",\n  \"length\": 12,\n  \"pauseCollectionFor\": 0\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

**`Subscription with surcharge`**

```swift
import Foundation

let headers = [
  "Idempotency-Key": "8e03978e-40d5-43e8-bc93-6894a57f9324",
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "subscriptionId": "SubRef7654",
  "paymentPlanId": "PlanRef8765",
  "paymentMethod": [
    "type": "secureToken",
    "token": "296753123456"
  ],
  "startDate": "2024-07-02",
  "name": "Premium Club",
  "description": "Premium Club subscription",
  "setupOrder": [
    "orderId": "OrderRef6543",
    "amount": 4999,
    "description": "Initial setup fee for Premium Club subscription"
  ],
  "recurringOrder": [
    "amount": 4999,
    "description": "Monthly Premium Club subscription",
    "breakdown": [
      "subtotal": 4347,
      "taxes": [
        [
          "rate": 5,
          "name": "Sales Tax",
          "type": "rate"
        ]
      ]
    ]
  ],
  "endDate": "2025-07-01",
  "length": 12,
  "pauseCollectionFor": 0
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.payroc.com/v1/processing-terminals/1234001/subscriptions")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: \{ (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

<a id="response-fields-1"></a>
### 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:

<a id="schema-responsebody-1"></a>
### Schema (`response.body`)

[Response body schema for `POST /processing-terminals/{processingTerminalId}/subscriptions`](/api/create-subscription)

<a id="example-response-1"></a>
### Example response

<a id="response-201-1"></a>
### Response (201)

```json
{
  "subscriptionId": "SubRef7654",
  "processingTerminalId": "1234001",
  "paymentPlan": {
    "paymentPlanId": "PlanRef8765",
    "name": "Monthly Premium Club subscription",
    "link": {
      "rel": "self",
      "method": "GET",
      "href": "https://api.payroc.com/v1/processing-terminals/1234001/payment-plans/PlanRef8765"
    }
  },
  "secureToken": {
    "secureTokenId": "MREF_abc1de23-f4a5-6789-bcd0-12e345678901fa",
    "customerName": "Sarah Hazel Hopper",
    "token": "296753123456",
    "status": "notValidated",
    "link": {
      "rel": "self",
      "method": "GET",
      "href": "https://api.payroc.com/v1/processing-terminals/1234001/secure-tokens/MREF_abc1de23-f4a5-6789-bcd0-12e345678901fa"
    }
  },
  "name": "Premium Club",
  "currency": "USD",
  "currentState": {
    "status": "active",
    "paidInvoices": 0,
    "nextDueDate": "2024-08-02",
    "outstandingInvoices": 3
  },
  "startDate": "2024-07-02",
  "type": "automatic",
  "frequency": "monthly",
  "description": "Premium Club subscription",
  "setupOrder": {
    "orderId": "OrderRef6543",
    "amount": 4999,
    "description": "Initial setup fee for Premium Club subscription",
    "breakdown": {
      "subtotal": 4347,
      "surcharge": {
        "amount": 217,
        "percentage": 5
      },
      "taxes": [
        {
          "name": "Sales Tax",
          "rate": 5
        }
      ]
    }
  },
  "recurringOrder": {
    "amount": 4999,
    "description": "Premium Club subscription",
    "breakdown": {
      "subtotal": 4347,
      "surcharge": {
        "amount": 217,
        "percentage": 5
      },
      "taxes": [
        {
          "name": "Sales Tax",
          "rate": 5
        }
      ]
    }
  },
  "endDate": "2025-07-01",
  "length": 12,
  "pauseCollectionFor": 0,
  "customFields": [
    {
      "name": "yourCustomField",
      "value": "abc123"
    }
  ]
}
```

<a id="step-4-optional-manually-collect-a-payment"></a>
## 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.

| Environment | URL |
| --- | --- |
| Test | https://api.uat.payroc.com/v1/processing-terminals/\{processingTerminalId\}/subscriptions/\{subscriptionId\}/pay |
| Production | https://api.payroc.com/v1/processing-terminals/\{processingTerminalId\}/subscriptions/\{subscriptionId\}/pay |

<a id="request-parameters-2"></a>
### Request parameters

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

<a id="schema-requestbody-2"></a>
### Schema (`request.body`)

[Request body schema for `POST /processing-terminals/{processingTerminalId}/subscriptions/{subscriptionId}/pay`](/api/pay-subscription)

<a id="example-request-2"></a>
### Example request

<a id="request-2"></a>
### Request

POST https://api.payroc.com/v1/processing-terminals/\{processingTerminalId\}/subscriptions/\{subscriptionId\}/pay

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

**`Subscription manual payment`**

```python
import requests

url = "https://api.payroc.com/v1/processing-terminals/1234001/subscriptions/SubRef7654/pay"

payload = {
    "order": {
        "orderId": "OrderRef6543",
        "amount": 4999,
        "description": "Monthly Premium Club subscription"
    },
    "operator": "Jane"
}
headers = {
    "Idempotency-Key": "8e03978e-40d5-43e8-bc93-6894a57f9324",
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

**`Subscription manual payment`**

```javascript
const url = 'https://api.payroc.com/v1/processing-terminals/1234001/subscriptions/SubRef7654/pay';
const options = {
  method: 'POST',
  headers: {
    'Idempotency-Key': '8e03978e-40d5-43e8-bc93-6894a57f9324',
    Authorization: 'Bearer <token>',
    'Content-Type': 'application/json'
  },
  body: '{"order":{"orderId":"OrderRef6543","amount":4999,"description":"Monthly Premium Club subscription"},"operator":"Jane"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

**`Subscription manual payment`**

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.payroc.com/v1/processing-terminals/1234001/subscriptions/SubRef7654/pay"

	payload := strings.NewReader("{\n  \"order\": {\n    \"orderId\": \"OrderRef6543\",\n    \"amount\": 4999,\n    \"description\": \"Monthly Premium Club subscription\"\n  },\n  \"operator\": \"Jane\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324")
	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

**`Subscription manual payment`**

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.payroc.com/v1/processing-terminals/1234001/subscriptions/SubRef7654/pay")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '8e03978e-40d5-43e8-bc93-6894a57f9324'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"order\": {\n    \"orderId\": \"OrderRef6543\",\n    \"amount\": 4999,\n    \"description\": \"Monthly Premium Club subscription\"\n  },\n  \"operator\": \"Jane\"\n}"

response = http.request(request)
puts response.read_body
```

**`Subscription manual payment`**

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.payroc.com/v1/processing-terminals/1234001/subscriptions/SubRef7654/pay")
  .header("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"order\": {\n    \"orderId\": \"OrderRef6543\",\n    \"amount\": 4999,\n    \"description\": \"Monthly Premium Club subscription\"\n  },\n  \"operator\": \"Jane\"\n}")
  .asString();
```

**`Subscription manual payment`**

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.payroc.com/v1/processing-terminals/1234001/subscriptions/SubRef7654/pay', [
  'body' => '{
  "order": {
    "orderId": "OrderRef6543",
    "amount": 4999,
    "description": "Monthly Premium Club subscription"
  },
  "operator": "Jane"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
    'Idempotency-Key' => '8e03978e-40d5-43e8-bc93-6894a57f9324',
  ],
]);

echo $response->getBody();
```

**`Subscription manual payment`**

```csharp
using RestSharp;

var client = new RestClient("https://api.payroc.com/v1/processing-terminals/1234001/subscriptions/SubRef7654/pay");
var request = new RestRequest(Method.POST);
request.AddHeader("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324");
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"order\": {\n    \"orderId\": \"OrderRef6543\",\n    \"amount\": 4999,\n    \"description\": \"Monthly Premium Club subscription\"\n  },\n  \"operator\": \"Jane\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

**`Subscription manual payment`**

```swift
import Foundation

let headers = [
  "Idempotency-Key": "8e03978e-40d5-43e8-bc93-6894a57f9324",
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "order": [
    "orderId": "OrderRef6543",
    "amount": 4999,
    "description": "Monthly Premium Club subscription"
  ],
  "operator": "Jane"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.payroc.com/v1/processing-terminals/1234001/subscriptions/SubRef7654/pay")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: \{ (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

<a id="response-fields-2"></a>
### Response fields

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

<a id="schema-responsebody-2"></a>
### Schema (`response.body`)

[Response body schema for `POST /processing-terminals/{processingTerminalId}/subscriptions/{subscriptionId}/pay`](/api/pay-subscription)

<a id="example-response-2"></a>
### Example response

<a id="response-201-2"></a>
### Response (201)

```json
{
  "subscriptionId": "SubRef7654",
  "processingTerminalId": "1234001",
  "payment": {
    "paymentId": "M2MJOG6O2Y",
    "dateTime": "2024-07-02T15:30:00Z",
    "currency": "USD",
    "amount": 4999,
    "status": "ready",
    "responseCode": "A",
    "responseMessage": "Transaction approved",
    "link": {
      "rel": "self",
      "method": "GET",
      "href": "https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y"
    }
  },
  "secureToken": {
    "secureTokenId": "MREF_abc1de23-f4a5-6789-bcd0-12e345678901fa",
    "customerName": "Sarah Hazel Hopper",
    "token": "296753123456",
    "status": "notValidated",
    "link": {
      "rel": "self",
      "method": "GET",
      "href": "https://api.payroc.com/v1/processing-terminals/1234001/secure-tokens/MREF_abc1de23-f4a5-6789-bcd0-12e345678901fa"
    }
  },
  "currentState": {
    "status": "active",
    "paidInvoices": 1,
    "nextDueDate": "2024-08-02",
    "outstandingInvoices": 2
  },
  "customFields": [
    {
      "name": "yourCustomField",
      "value": "abc123"
    }
  ]
}
```
