> For the complete documentation index, see [llms.txt](https://pivot-payment.gitbook.io/pivot-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://pivot-payment.gitbook.io/pivot-docs/payments/accept-payment/build-card-payment-use-case/subscription-and-automated-billing-recurring.md).

# Subscription and Automated Billing (Recurring)

Enables merchants to charge customers on a recurring basis automatically. By setting up plans, pricing, and billing schedules, merchants can create a seamless subscription experience without manual payments. It helps ensure predictable revenue, reduce missed payments, and maintain ongoing customer subscriptions even when payment methods are updated.

<pre class="language-mermaid"><code class="lang-mermaid"><strong>sequenceDiagram
</strong>    autonumber
    participant M as Merchant
    participant RM as Recurring API
    participant U as Payment API
    participant C as Customer
 
    %% ========== RECURRING CREATION ==========
    M->>RM: POST /recurring&#x3C;br/>(type=SELF_MANAGED,&#x3C;br/>schedule, amount, customer info,&#x3C;br/>firstAuthorization=FIRST_PAYMENT / ONE_DOLLAR)
    RM-->>M: 200 OK (recurringId, status=CREATED)
 
    %% ========== FIRST AUTHORIZATION (CARD ENCRYPTION FLOW) ==========
    M->>U: Create Session&#x3C;br/>(mode=API,&#x3C;br/>recurringId,&#x3C;br/>firstAuthorization=true)
    U-->>M: 200 OK (paymentSessionId, encryptionKey)
 
    M-->>C: Request card input (merchant UI)
    C->>M: Input card details
 
    M->>M: Encrypt card data using encryptionKey
 
    M->>U: Confirm Session&#x3C;br/>(paymentSessionId,&#x3C;br/>encryptedCardDetail)
 
    %% Authentication &#x26; Authorization handled by Pivot
    U->>C: Authentication (3DS / OTP / App Redirect)
    C->>U: Authentication Success
 
    U->>U: Authorization&#x3C;br/>(FIRST_PAYMENT or ONE_DOLLAR logic)
    U-->>M: Authorization Result&#x3C;br/>(success + paymentMethodToken)
 
    Note over U,RM: Recurring API retrieves paymentMethodToken internally from Payment API
    RM->>RM: Store paymentMethodToken&#x3C;br/>Update recurring = ACTIVE
 
    %% ========== RECURRING BILLING (MERCHANT MANAGED) ==========
    loop Merchant Scheduler (cron / logic)
        M->>U: Create Session&#x3C;br/>(recurringId,&#x3C;br/>mode=API)
        U->>U: Authorization using stored token
        U-->>M: Charge Result
 
        alt Charge Successful
            Note over U,RM: Payment API optionally notifies Recurring API to record charge
            RM->>M: Webhook charge_success
        else Charge Failed
            M-->>M: Merchant retries or reschedules&#x3C;br/>(Recurring API is not involved)
        end
    end
</code></pre>

## Create Recurring

Create your plans, pricing, intervals, and trial settings

<details>

<summary>Create Recurring</summary>

API Reference: [Create Recurring](/pivot-docs/api-references/api-lists/payments/recurring/create-recurring.md)

```json
POST [BASE_URL]/v1/recurring

{
    "clientReferenceId": "REF001",
    "mode": "SELF_MANAGED",
    "plan": {
        "planId": "PLAN001",
        "planName": "Diamond"
    },
    "amount": {
        "currency": "IDR",
        "value": 100000
    },
    "trials": [
        {
            "trialStart": 1,
            "trialEnd": 1, 
            "type": "FREE / FIXED / PERCENTAGE",
            "percentage": 50, // applicable for trials.type = PERCENTAGE, maximum value is 100
            "amount": 50000 // applicable for trials.type = FIXED, maximum value is not greater than amount.value
        }
    ],
    "billingInterval": 1,
    "billingIntervalUnit": "MONTH",
    "endDate": "2026-08-31T16:59:59Z",
    "firstAuthorization": "FIRST_PAYMENT / ONE_DOLLAR",
    "customerId": "019cff2f-b8ab-7b44-85e7-0c5d2d3c7a51", // applicable for existing customer
    "customer": { // applicable for new customer
        "givenName": "Reforza Jordan",
        "surname": "Geotama",
        "email": "reforza@pivot-payment.com",
        "phoneNumber": {
            "countryCode": "+62",
            "number": "89557262933"
        }
    }
}
```

</details>

<details>

<summary>Define your Plan</summary>

Set the plan and price that you want to charge your Customer

```json
{
  "plan": {
    "planId": "PLAN001",
    "planName": "Diamond"
  },
  "amount": {
    "currency": "IDR",
    "value": 100000
  }
}
```

</details>

<details>

<summary>Create a trial or promotional program (*optional)</summary>

Set <mark style="color:orange;">`trialEnd`</mark> = how many billing intervals of the trial or promotional program apply to the Customer, and configure the <mark style="color:orange;">`type`</mark> of promotional program, whether you want to give your Customer "FREE", a "FIXED" discount amount, or a "PERCENTAGE" discount

```json
{
  "trials": [
    {
      "trialStart": 1,
      "trialEnd": 1,
      "type": "FREE / FIXED / PERCENTAGE",
      "percentage": 50, // applicable for trials.type = PERCENTAGE, maximum value is 100
      "amount": 50000 // applicable for trials.type = FIXED, maximum value is not greater than amount.value
    }
  ]
}
```

</details>

<details>

<summary>Schedule your billing</summary>

Set when the billing will be charged and when the billing will end

```json
{
  "billingInterval": 1,
  "billingIntervalUnit": "MONTH",
  "endDate": "2026-08-31T16:59:59Z"
}
```

</details>

<details>

<summary>Choose the first authorization method</summary>

* <mark style="color:orange;">`FIRST_PAYMENT`</mark> = Authorized Amount based on the Billing Amount and Trials Program
* <mark style="color:orange;">`ONE_DOLLAR`</mark> = Authorized Amount value is IDR 10.000, then Pivot will void the transaction to the card owner's limit

```json
{
  "firstAuthorization": "FIRST_PAYMENT / ONE_DOLLAR"
}
```

</details>

<details>

<summary>Fill Customer Information</summary>

Recurring Plan & Stored Payment Method links to your <mark style="color:orange;">`customerId`</mark>

Object Reference: [Customers](/pivot-docs/api-references/api-lists/core-resources/customers.md)

```json
{
  "customerId": "019cff2f-b8ab-7b44-85e7-0c5d2d3c7a51", // applicable for existing customer
  "customer": { // applicable for new customer
    "givenName": "Reforza Jordan",
    "surname": "Geotama",
    "email": "reforza@pivot-payment.com",
    "phoneNumber": {
      "countryCode": "+62",
      "number": "89557262933"
    }
  }
}
```

</details>

<details>

<summary>Manage your Recurring ID </summary>

After creating a recurring plan, you need to initiate the first Authorization of your Customer's Card Information

```json
{
  "recurringId": "019d6ca3-fe0a-7a6b-88f2-e813292ea491"
}
```

</details>

## First Authorization

Initiate the first Authorization of your Customer's Card Information

{% hint style="info" %}
Authorize your Customer's Card Information using the Card Encryption flow: [Card Customized Payment Page (Encryption)](/pivot-docs/payments/accept-payment/build-card-payment-use-case/card-customized-payment-page-encryption.md)
{% endhint %}

<details>

<summary>Create Payment Session</summary>

A windowed time for the end customer to complete the payment, starting when the client initiates the payment request through your app. The payment session duration is customizable, with a default duration of 15 minutes.

API Reference: [Create Payment Session](/pivot-docs/api-references/api-lists/payments/payment-session/create-payment-session.md)

```json
POST [BASE_URL]/v2/payments

{
  "clientReferenceId": "1751620870",
  "paymentMethod": {
    "type": "CARD"
  },
  "mode": "API",
  "redirectUrl": {
    "successReturnUrl": "https://merchant.com/success",
    "failureReturnUrl": "https://merchant.com/failure",
    "expirationReturnUrl": "https://merchant.com/expiration"
  },
  "autoConfirm": false,
  "expiryAt": "2025-12-30T23:59:00Z",
  "recurringId": "019d619e-3269-76ca-ac0c-07a2252de309", 
  "initiateFirstAuthorization": true,
  "metadata": {
    "invoiceNo": "INV001"
  }
}
```

</details>

<details>

<summary>Initiate First Authorization</summary>

To initiate the first authorization, choose <mark style="color:orange;">`true`</mark>. We charge the billing amount based on your previous authorization method configuration

```json
{
  "recurringId": "019d619e-3269-76ca-ac0c-07a2252de309",
  "initiateFirstAuthorization": true
}
```

</details>

## **Subsequent Transaction**&#x20;

### **Merchant managed scheduler**

Once the card is authorized and stored as a token, your scheduler is ready to charge the customer's bill

{% hint style="info" %}
Recurring Plan & Stored Payment Method links to your <mark style="color:orange;">`customerId`</mark>
{% endhint %}

```json
POST [BASE_URL]/v2/payments

{
  "clientReferenceId": "1751620870",
  "mode": "API",  
  "redirectUrl": {
    "successReturnUrl": "https://merchant.com/success",
    "failureReturnUrl": "https://merchant.com/failure",
    "expirationReturnUrl": "https://merchant.com/expiration"
  },
  "autoConfirm": true,
  "expiryAt": "2025-12-30T23:59:00Z",
  "recurringId": "019d619e-3269-76ca-ac0c-07a2252de309", // authorized Customer's card information
  "metadata": {
    "invoiceNo": "INV001"
  }
}
```

## **Update Payment Method for ongoing Recurring Plan**

You need to re-authorize your new Customer's Card Information without disrupting the ongoing Billing cycle. Default authorization is <mark style="color:orange;">`ONE_DOLLAR`</mark>

<details>

<summary>Create Payment Session</summary>

A windowed time for the end customer to complete the payment, starting when the client initiates the payment request through your app. The payment session duration is customizable, with a default duration of 15 minutes.

API Reference: [Create Payment Session](/pivot-docs/api-references/api-lists/payments/payment-session/create-payment-session.md)

```json
Update New Payment Method (Card Encryption Flow)

{
  "clientReferenceId": "1751620870",
  "paymentMethod": {
    "type": "CARD"
  },
  "mode": "API",
  "redirectUrl": {
    "successReturnUrl": "https://merchant.com/success",
    "failureReturnUrl": "https://merchant.com/failure",
    "expirationReturnUrl": "https://merchant.com/expiration"
  },
  "autoConfirm": false,
  "expiryAt": "2025-12-30T23:59:00Z",
  "recurringId": "019d619e-3269-76ca-ac0c-07a2252de309",
  "initiateFirstAuthorization": true,
  "metadata": {
    "invoiceNo": "INV001"
  }
}

Update Payment Method with saved Tokenized Card
{
  "clientReferenceId": "1751620870",
  "paymentMethod": {
    "type": "CARD",
    "card": {
      "token": "020027de-134e-45ed-8f0d-7ae0506a7133",
      "cvc": "123"
    }
  },
  "mode": "API",
  "redirectUrl": {
    "successReturnUrl": "https://merchant.com/success",
    "failureReturnUrl": "https://merchant.com/failure",
    "expirationReturnUrl": "https://merchant.com/expiration"
  },
  "autoConfirm": true,
  "expiryAt": "2025-12-30T23:59:00Z",
  "recurringId": "019d619e-3269-76ca-ac0c-07a2252de309",
  "initiateFirstAuthorization": true,
  "metadata": {
    "invoiceNo": "INV001"
  }
}
```

</details>

<details>

<summary> Re-authorize a new Customer's Card information</summary>

Utilize ongoing <mark style="color:orange;">`recurringId`</mark> to update your customers' Payment Method

```json
{
  "recurringId": "019d619e-3269-76ca-ac0c-07a2252de309",
  "initiateFirstAuthorization": true
}
```

</details>
