Manage Plans
A plan is the offer: what you charge, in which currency, and on what rhythm. You create it once and every customer on that tier subscribes to the same plan, so changing your pricing is a matter of creating a new plan rather than editing thousands of subscriptions.
Plans are the foundation of the subscription flow. Nothing can be subscribed to until a plan exists.
Create a plan
| Field | Required | What it does |
|---|---|---|
name | Yes | The plan name. |
description | Yes | The plan description. |
currency | Yes | ISO 4217 alphabetic code, for example SAR. |
amount | Yes | The base amount charged on each subscription invoice. |
recurrency | Yes | How many recurrency_units sit between charges. Subscribers pay every recurrency x recurrency_unit. |
recurrency_unit | Yes | The time unit. DAY and MONTH are supported. |
recurring_cycles | No | Total number of payment cycles in the subscription lifetime. Leave it empty and the subscription is charged forever, until cancelled. |
trial_period | No | Number of trial days before the first recurring cycle. |
one_time_fee | No | An upfront fee added once, to the first invoice only. |
discount_amount | No | A fixed discount. Cannot be set together with discount_percentage. |
discount_percentage | No | A percentage discount. Cannot be set together with discount_amount. |
discount_cycles | No | How many cycles the discount applies to. |
curl -X POST https://web.moneyhash.io/api/v1.4/subscriptions/plans/ \
-H "x-api-key: <YOUR_ACCOUNT_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"name": "Basic Monthly",
"description": "Basic tier, billed monthly",
"currency": "SAR",
"amount": "49.00",
"recurrency": 1,
"recurrency_unit": "MONTH",
"recurring_cycles": 12,
"trial_period": 14,
"one_time_fee": "99.00",
"discount_percentage": "10.00",
"discount_cycles": 3
}'{
"status": { "code": 200, "message": "success", "errors": [] },
"data": {
"id": "<YOUR_PLAN_ID>",
"name": "Basic Monthly",
"description": "Basic tier, billed monthly",
"currency": "SAR",
"amount": 49,
"one_time_fee": 99,
"trial_period": 14,
"recurrency": 1,
"recurrency_unit": "MONTH",
"recurring_cycles": 12,
"discount_amount": null,
"discount_percentage": 10,
"discount_cycles": 3,
"is_live": false,
"created": "2026-09-20T23:07:06.833157Z"
},
"count": 1, "next": null, "previous": null
}Keep the returned id. It is what you pass as plan when you subscribe a customer.
Setting the billing rhythm
recurrency and recurrency_unit multiply. Subscribers pay every recurrency x recurrency_unit, and only DAY and MONTH are supported as units, so anything longer is expressed in months.
| You want | recurrency | recurrency_unit |
|---|---|---|
| Weekly | 7 | DAY |
| Every 10 days | 10 | DAY |
| Monthly | 1 | MONTH |
| Quarterly | 3 | MONTH |
| Every 6 months | 6 | MONTH |
| Yearly | 12 | MONTH |
recurring_cycles then decides how long it runs. Set it to 12 on a monthly plan for a one-year commitment. Leave it out entirely and the subscription bills indefinitely until somebody cancels it.
The two billing models
Whether you set trial_period decides which of these your plan is.
Pay up front. No trial_period. You collect payment details and charge before the customer gets access. The first invoice lands on the subscription's start_date, and every recurrence date after that issues another. Best when the value is obvious and you want committed customers from day one.
Free trial. Set trial_period to a number of days. The customer gets access from the start_date with nothing billed. When the trial ends, the first invoice is issued and normal billing begins. Best when the product needs to be experienced before anyone will pay for it.
Either model can carry a one_time_fee, which is added once to the first invoice, and a discount.
Discounts
A discount is two decisions: how much, and for how long.
- How much - either
discount_amount(a fixed sum off each invoice) ordiscount_percentage(a proportion). These cannot be set together. Pick one. - How long -
discount_cyclesis the number of billing cycles the discount applies to. After that the invoices go back to the fullamount.
{
"name": "Basic Monthly - launch offer",
"description": "Basic tier with 3 months at 25 percent off",
"currency": "SAR",
"amount": "49.00",
"recurrency": 1,
"recurrency_unit": "MONTH",
"discount_percentage": "25.00",
"discount_cycles": 3
}A subscription tracks how much of the discount is left in remaining_discount_cycles, alongside remaining_recurring_cycles for the plan itself.
Listing plans
curl "https://web.moneyhash.io/api/v1.4/subscriptions/plans/?limit=50&offset=0" \
-H "x-api-key: <YOUR_ACCOUNT_API_KEY>"Paging follows the standard envelope: limit (max 100) and offset, with next and previous in the response. Follow next until it is null.
Changing a plan's price
The published API has no edit-in-place for a plan's pricing: plans are create-and-list only. In practice that is the safer shape anyway, since a plan that thousands of subscriptions point at cannot change underneath them without silently repricing every one of those customers.
Two ways to reprice, depending on scope:
- One customer - override the amount on their subscription. Either
customization.amountat creation, or the update-amount call afterwards. The plan is untouched. See Update Subscriptions. - A whole tier - create a new plan at the new price, then move subscriptions onto it with the change-plan call. Existing subscribers stay on the old plan until you move them, which is usually what you want for grandfathered pricing.
Plans can also be created and managed from the MoneyHash dashboard, which is often the faster route while you are still shaping the offer.
Where to next
- Manage Subscriptions - subscribe a customer to the plan you just created.
- Update Subscriptions - move a subscription onto a different plan.
- Subscription Plans in the SDK - render your plans in your own app and let the customer choose one.
Updated 22 days ago