> ## Documentation Index
> Fetch the complete documentation index at: https://docs.payaza.africa/llms.txt
> Use this file to discover all available pages before exploring further.

# Subscription Plans

> Create and manage the pricing plans that power your recurring billing. A plan must exist before any customer can be subscribed.

## Overview

A **Subscription Plan** is the template that defines how much to charge, how often, and for how long. Think of it as the product you are selling on a recurring basis — for example, "Pro Plan at ₦5,000/month" or "Annual Access at ₦50,000/year".

Before you can subscribe a customer and start billing them, you must first create a plan. The plan generates a unique `planCode` which is the only thing you need when creating a subscription later.

**How it fits into the bigger picture:**

1. You create a plan → get a `planCode`
2. You create a subscription using that `planCode` + the customer's card details → billing begins

This page covers everything you need to manage plans. See [Create a Subscription](/guides/subscriptions) for the next step.

***

## Key Requirements

<Info>
  Retrieve your API keys from your dashboard by following the steps on our [Authentication](/guides/authentication) page. Use your **public API key** for all subscription plan requests.
</Info>

Set the following headers on every request:

```json theme={null}
{
  "Authorization": "Payaza <Public API Key encoded in base 64>"
}
```

<Note>
  Set `X-TenantID` to `test` while developing and `live` when processing real payments.
</Note>

***

## Billing intervals

When creating a plan, you set how often the customer is billed using the `interval` field:

| `interval`  | Billing frequency |
| ----------- | ----------------- |
| `DAILY`     | Every day         |
| `WEEKLY`    | Every week        |
| `MONTHLY`   | Every month       |
| `QUARTERLY` | Every 3 months    |
| `ANNUAL`    | Every year        |

***

## Step 1 — Create a Plan

Creates a new subscription plan. The `planCode` in the response is what you pass when subscribing a customer — **save it**.

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.payaza.africa/live/subscription/api/v1/subscription-plans \
    --header 'Authorization: Payaza <Public API Key encoded in base 64>' \
    --header 'Content-Type: application/json' \
    --data '{
      "name": "Pro Monthly",
      "description": "Full access billed monthly",
      "amount": 5000,
      "currency": "NGN",
      "interval": "MONTHLY",
      "trialPeriodDays": 7,
      "billingLimit": 12
    }'
  ```
</CodeGroup>

**Request body parameters**

| Parameter         | Type    | Required | Description                                                                   |
| ----------------- | ------- | -------- | ----------------------------------------------------------------------------- |
| `name`            | String  | ✓        | Display name for the plan (e.g. "Pro Monthly")                                |
| `description`     | String  | No       | A short description of what the plan includes                                 |
| `amount`          | Number  | ✓        | Amount to charge per billing cycle in the smallest currency unit              |
| `currency`        | String  | ✓        | ISO 4217 currency code (e.g. `NGN`)                                           |
| `interval`        | String  | ✓        | Billing frequency — `DAILY`, `WEEKLY`, `MONTHLY`, `QUARTERLY`, or `ANNUAL`    |
| `trialPeriodDays` | Integer | ✓        | Number of free trial days before billing begins. Use `0` for no trial         |
| `billingLimit`    | Integer | No       | Maximum number of billing cycles. Leave empty for unlimited recurring billing |

**Sample response**

```json theme={null}
{
  "success": true,
  "message": "Plan created",
  "data": {
    "id": 69,
    "name": "Pro Monthly",
    "description": "Full access billed monthly",
    "amount": 5000,
    "currency": "NGN",
    "interval": "MONTHLY",
    "intervalCount": 1,
    "trialPeriodDays": 7,
    "billingLimit": 12,
    "status": "ACTIVE",
    "planCode": "PLN_821DCFD",
    "billingDaysOfWeek": null,
    "metadata": null,
    "createdAt": "2026-07-08T17:17:14.173360552",
    "updatedAt": "2026-07-08T17:17:14.173362175"
  }
}
```

<Warning>
  Save `data.planCode` immediately after creating a plan. This is the identifier you pass when creating a subscription — without it, you cannot subscribe customers to this plan.
</Warning>

**API reference:** [Create Plan](/api-reference/subscription-plans/create-plan)

***

## Step 2 — List Plans

Retrieve a paginated list of all plans you have created. Useful for displaying available pricing tiers in your UI or confirming a plan exists before subscribing a customer.

<CodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://api.payaza.africa/live/subscription/api/v1/subscription-plans?page=0&size=10&status=ACTIVE' \
    --header 'Authorization: Payaza <Public API Key encoded in base 64>' \
  ```
</CodeGroup>

**Query parameters**

| Parameter | Required | Description                                   |
| --------- | -------- | --------------------------------------------- |
| `page`    | ✓        | Page number — starts at `0`                   |
| `size`    | ✓        | Number of records per page                    |
| `status`  | No       | Filter by plan status: `ACTIVE` or `ARCHIVED` |

**Sample response**

```json theme={null}
{
  "success": true,
  "message": "Success",
  "data": {
    "content": [
      {
        "id": 69,
        "name": "Pro Monthly",
        "description": "Full access billed monthly",
        "amount": 5000,
        "currency": "NGN",
        "interval": "MONTHLY",
        "intervalCount": 1,
        "trialPeriodDays": 7,
        "billingLimit": 12,
        "status": "ACTIVE",
        "planCode": "PLN_821DCFD",
        "billingDaysOfWeek": null,
        "metadata": null,
        "createdAt": "2026-07-08T17:17:14.173361",
        "updatedAt": "2026-07-08T17:17:14.173362"
      }
    ],
    "totalPages": 4,
    "totalElements": 4,
    "first": true,
    "last": false
  }
}
```

**API reference:** [List Plans](/api-reference/subscription-plans/list-plans)

***

## Step 3 — Get Plan Details

Retrieve the full details of a specific plan using its `planCode`.

<CodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url https://api.payaza.africa/live/subscription/api/v1/subscription-plans/PLN_821DCFD \
    --header 'Authorization: Payaza <Public API Key encoded in base 64>' \
  ```
</CodeGroup>

**Path parameter**

| Parameter  | Type   | Description                                                                  |
| ---------- | ------ | ---------------------------------------------------------------------------- |
| `planCode` | String | The unique plan code returned when the plan was created (e.g. `PLN_821DCFD`) |

**Sample response**

```json theme={null}
{
  "success": true,
  "message": "Success",
  "data": {
    "id": 69,
    "name": "Pro Monthly",
    "description": "Full access billed monthly",
    "amount": 5000,
    "currency": "NGN",
    "interval": "MONTHLY",
    "intervalCount": 1,
    "trialPeriodDays": 7,
    "billingLimit": 12,
    "status": "ACTIVE",
    "planCode": "PLN_821DCFD",
    "billingDaysOfWeek": null,
    "metadata": null,
    "createdAt": "2026-07-08T16:42:53.051861",
    "updatedAt": "2026-07-08T17:25:31.342978"
  }
}
```

**API reference:** [Get Plan Details](/api-reference/subscription-plans/get-plan-details)

***

## Step 4 — Update Plan Details *(optional)*

Update the editable properties of an existing plan. All body fields are optional — include only what you want to change. Fields you omit keep their current values.

<Note>
  You can only update `name`, `description`, `trialPeriodDays`, and `billingLimit`. The plan's `amount`, `currency`, and `interval` cannot be changed after creation. To change pricing or frequency, create a new plan and use Change Plan to move active subscribers to it.
</Note>

<CodeGroup>
  ```bash cURL theme={null}
  curl --request PATCH \
    --url https://api.payaza.africa/live/subscription/api/v1/subscription-plans/PLN_821DCFD \
    --header 'Authorization: Payaza <Public API Key encoded in base 64>' \
    --header 'Content-Type: application/json' \
    --data '{
      "name": "Pro Monthly Plus",
      "description": "Full access with priority support, billed monthly",
      "trialPeriodDays": 14,
      "billingLimit": 24
    }'
  ```
</CodeGroup>

**Path parameter**

| Parameter  | Type   | Description                                |
| ---------- | ------ | ------------------------------------------ |
| `planCode` | String | The unique plan code of the plan to update |

**Updatable body parameters** *(all optional)*

| Parameter         | Type    | Description                              |
| ----------------- | ------- | ---------------------------------------- |
| `name`            | String  | Updated display name for the plan        |
| `description`     | String  | Updated description                      |
| `trialPeriodDays` | Integer | Updated number of free trial days        |
| `billingLimit`    | Integer | Updated maximum number of billing cycles |

**Sample response**

```json theme={null}
{
  "success": true,
  "message": "Plan updated",
  "data": {
    "id": 69,
    "name": "Pro Monthly Plus",
    "description": "Full access with priority support, billed monthly",
    "amount": 5000,
    "currency": "NGN",
    "interval": "MONTHLY",
    "intervalCount": 1,
    "trialPeriodDays": 14,
    "billingLimit": 24,
    "status": "ACTIVE",
    "planCode": "PLN_821DCFD",
    "billingDaysOfWeek": null,
    "metadata": null,
    "createdAt": "2026-07-08T16:42:53.051861",
    "updatedAt": "2026-07-08T17:25:31.342977889"
  }
}
```

**API reference:** [Update Plan Details](/api-reference/subscription-plans/update-plan-details)

***

## Developer notes

* Always save `data.planCode` from the Create Plan response — it is the only way to reference the plan when subscribing customers.
* Plans are reusable across unlimited customers. Create a plan once and reference it for every customer who subscribes to that pricing tier.
* `amount` and `currency` cannot be updated after a plan is created. If you need to change pricing, create a new plan and migrate existing subscribers using the [Change Plan](/guides/subscription-lifecycle) endpoint.
* Setting `billingLimit` to `null` or leaving it empty creates an unlimited recurring plan — the customer will be charged every billing cycle until cancelled.
* `trialPeriodDays: 0` means no trial — the first charge is attempted immediately when the subscription is created.
* Plans can be filtered by `status` on the List Plans endpoint. `ACTIVE` plans are available for new subscriptions; `ARCHIVED` plans can no longer accept new subscribers.

***

## What's next

Now that you have a plan and its `planCode`, you are ready to subscribe your first customer.

<Card title="Create a Subscription" icon="user-plus" href="/guides/subscriptions">
  Enrol a customer's card against a plan and start recurring billing.
</Card>
