Quickstart: Recurring Payments

📘

This guide assumes a basic understanding of PPRO's API core objects and common functionality.

A Payment Agreement enables funds to be subsequently deducted from an end-consumer account without requiring them re-enter their payment information.

The following examples use the payment method UPI_AUTOPAY to explain the flows. However, the same steps apply to any PPRO-supported payment method.

The flow consists of three simple steps:

  1. Create the Payment Agreement entity with the necessary information for consumer authentication.
  2. Ask the consumer to authenticate the Payment Agreement and/or an initial charge.
  3. Referencing the authenticated Payment Agreement using the returned agreement id, create Payment Charges as needed for each deduction.

1. Create your first Payment Agreement

POST /v1/payment-agreements:

{
  "paymentMethod": "UPI_AUTOPAY",
  "consumer": {
    "name": "John Smith",
    "country": "US"
  },
  "description": "Acme Digital - Monthly Subscription",
  "startDate": "2023-03-26T20:24:27Z",
  "endDate": "2023-11-27T09:30:00Z",
  "frequency": {
    "type": "MONTHLY",
    "interval": 1
  },
  "amount": {
    "value": 1000,
    "currency": "USD"
  },
  "amountType": "MAX",
  "authenticationSettings": [
    {
      "type": "REDIRECT",
      "settings": {
        "returnUrl": "https://merchant-website.com"
      }
    }
  ]
}

Response:

{
    "id": "agr_xcaX4Q34RCB6ikJOMOhb5",
    "status": "AUTHENTICATION_PENDING",
    "description": "Acme Digital - Monthly Subscription",
    "paymentMethod": "UPI_AUTOPAY",
    "frequency": {
        "type": "MONTHLY",
        "interval": 1
    },
    "startDate": "2024-01-26T12:18:08.192Z",
    "endDate": "2025-01-25T12:18:08.192Z",
    "amount": {
        "value": 1000,
        "currency": "USD"
    },
    "instrumentId": "instr_KyHjgragHyMPqRBHamCxw",
    "amountType": "MAX",
    "consumer": {
        "name": "John Smith",
        "country": "US"
    },
    "authenticationMethods": [
        {
            "details": {
                "requestUrl": "https://redirect.ppro.com/?merchantRedirectionUrl=aHR0cHM6Ly9tZXJjaGFudC13ZWJzaXRlLmNvbQ==",
                "requestMethod": "GET"
            },
            "type": "REDIRECT"
        }
    ],
    "history": [
        {
            "id": "ahist_imQGkKzDdHuqstvjjtIWC",
            "status": "AUTHENTICATION_PENDING",
            "createdAt": "2024-01-26T12:18:08.192Z"
        }
    ],
    "createdAt": "2024-01-26T12:18:08.192Z",
    "updatedAt": "2024-01-26T12:18:08.192Z"
}

Notice the status with AUTHENTICATION_PENDING; the payment agreement isn’t ready yet to accept charges and is pending the consumer authentication to confirm the agreement details with their provider, which takes us to the next step.

You can find the documentation for creating a payment agreement in our API reference.

2. Ask the end consumer to authenticate

Redirect the customer to the request URL or the Intent URI for native applications returned in the authenticationMethods. The consumer will be guided through their bank’s application to review the details of the payment agreement.

Recurring Payment Scheme

Asynchronously, the provider will ping PPRO that the consumer completed authentication successfully. Then the Payment Agreement status changes to ACTIVE and you're notified via a PPRO Webhook.

You can fetch the Payment Agreement by the returned id (i.e., GET /v1/payment-agreements/agr_xcaX4Q34RCB6ikJOMOhb5) to see the current state.

3. Create one or more Payment Charges against the Payment Agreement object

POST /v1/payment-agreements/agr_xcaX4Q34RCB6ikJOMOhb5/payment-charges:

{
  "amount": {
    "value": 1000,
    "currency": "USD"
  },
  "paymentDescriptor": "Acme Digital - Monthly Subscription",
  "merchantPaymentChargeReference": "WEBSHOP-TX-242142323432"
}

Each initiated payment charge must conform to the constraints defined earlier during the Payment Agreement setup, e.g., the amount can’t exceed 10 USD in this example flow.

You can find the documentation for creating a Payment Charge using a Payment Agreement in our API reference.

Other notable API endpoints

Retrieve associated Payment Charges to a given Payment Agreement

GET /v1/payment-agreements/agr_iRwoeyCv1EDPL7sUZmvqw/payment-charges:

[
    {
        "id": "charge_QEdHCG2r4TND26dgUpm8u",
        "amount": {
            "amount": 9900,
            "currency": "USD"
        },
        ...
    },
    {
        "id": "charge_qHw0dhKO20PzjJT0ltERA",
        "amount": {
            "amount": 9500,
            "currency": "USD"
        },
        ...
    },
    ...
]

Refunding a Payment Charge

POST /v1/payment-charges/charge_qHw0dhKO20PzjJT0ltERA:

{
    "merchantRefundReference":    
        "5c019979-0751-469e-96e0-b67f1d95c577",
    "amount": 1000
}