Products · Billing
Subscriptions & Billing
Products, prices, invoices, dunning, proration — a complete billing stack on top of Meras payment rails. Model SaaS, seats, usage, or any combination.
8 endpointssub_in_
ℹ
Resource hierarchy
Product → Price → Subscription → Invoice → PaymentIntent. Each level is optional — you can create invoices without subscriptions, or charge one-time prices. You do not need a subscription to issue an invoice.
Key resources
| Prefix | Resource | Description |
|---|---|---|
prod_ | Product | A good or service you sell. Has a name, description, and optional image. Does not contain pricing. |
price_ | Price | A pricing configuration attached to a Product. Specifies currency, amount, and optionally a recurring interval. |
cus_ | Customer | Represents a paying customer. Holds default payment methods and billing address. |
sub_ | Subscription | Links a Customer to one or more Prices. Auto-generates Invoices at each billing cycle. |
in_ | Invoice | A bill issued to a Customer. Can be created manually or auto-generated by a Subscription. |
How subscriptions work
- 1
Create a Product and Price
POST to/v1/productsto define what you are selling. Then POST to/v1/priceswith arecurringobject specifying the billing interval. A single product can have multiple prices (monthly, annual, regional). - 2
Create or attach a Customer
POST to/v1/customersto create a customer record. Attach a default PaymentMethod viaPOST /v1/customers/{id}/payment_methodsso that auto-collection works without manual intervention at each cycle. - 3
Create the Subscription
POST to/v1/subscriptionswithcustomer_idandprice_id. Optionally passtrial_end(unix timestamp) to start with a free trial period, andproration_behaviorif the subscription starts mid-cycle. - 4
Meras auto-generates the Invoice
At the start of each billing period, Meras generates a draft Invoice for the subscription. The invoice is automatically finalised and transitions toopenstatus unless you have disabled auto-collection. - 5
Invoice payment is attempted automatically
Meras attempts to pay the invoice using the customer's default PaymentMethod. This creates a PaymentIntent on the underlying payment rail. On success the invoice transitions topaid. - 6
Webhooks fire
invoice.paidfires when payment succeeds.invoice.payment_failedfires on failure and triggers the dunning schedule. Subscribe to both events to keep your system in sync.
Dunning schedule
When an invoice payment fails, Meras retries automatically on the following schedule (configurable in merchant settings):
| Retry | Day after initial failure | Subscription status |
|---|---|---|
| 1st retry | Day 1 | active |
| 2nd retry | Day 3 | active |
| 3rd retry | Day 7 | active |
| 4th retry | Day 14 | past_due |
| Final | Day 14 (no retry) | canceled |
Endpoints
POST
/v1/productsCreate a product.
POST
/v1/pricesCreate a price (one-time or recurring) attached to a product.
POST
/v1/subscriptionsCreate a subscription for a customer.
GET
/v1/subscriptions/{id}Retrieve a subscription and its current billing state.
POST
/v1/subscriptions/{id}/cancelCancel a subscription immediately or at period end.
POST
/v1/invoicesManually create a draft invoice.
POST
/v1/invoices/{id}/finalizeTransition a draft invoice to open and lock its line items.
POST
/v1/invoices/{id}/payManually trigger a payment attempt on an open invoice.
Price parameters
| Name | Type | Description |
|---|---|---|
product_idrequired | prod_ | The product this price belongs to. |
currencyrequired | ISO 4217 | Billing currency, e.g. "DJF" or "USD". |
unit_amount_minor | integer | Fixed price in minor units. Required when billing_scheme is per_unit. |
recurring | object | Recurring schedule: interval (day · week · month · year) and interval_count (default 1). Omit for one-time prices. |
billing_scheme | enum | per_unit (default) or tiered. Use tiered for volume or graduated pricing. |
tiers | array | Required when billing_scheme is tiered. Each tier has up_to, unit_amount, and flat_amount. |
nickname | string | Internal label for the price. Not shown to customers. |
Subscription parameters
| Name | Type | Description |
|---|---|---|
customer_idrequired | cus_ | The customer to bill. |
price_idrequired | price_ | The recurring price to subscribe the customer to. |
trial_end | unix ts | Timestamp at which the free trial ends. During the trial no invoices are generated. |
proration_behavior | enum | create_prorations (default) or none. Controls how mid-cycle changes are billed. |
cancel_at_period_end | boolean | Set to true to cancel the subscription at the end of the current billing period rather than immediately. |
metadata | map | Free-form string-string map attached to the subscription and all generated invoices. |
⚠
DJF is zero-decimal
Subscriptions denominated in DJF use integer minor units, but DJF has no sub-unit — the minor unit equals one franc. A price of
unit_amount_minor: 5000means DJF 5,000 per interval. Do not multiply by 100 as you would for USD or EUR.Example — create product, price, and subscription
1. Create productbash
curl -X POST https://api.merashub.com/v1/products \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Business Plan",
"description": "Up to 50 staff, unlimited transactions"
}'201 — productjson
{
"id": "prod_01HZGQ7PNRS5T8VW3XE6YK4MA",
"name": "Business Plan",
"description": "Up to 50 staff, unlimited transactions",
"active": true,
"created_at": "2026-05-25T13:00:00Z"
}2. Create monthly pricebash
curl -X POST https://api.merashub.com/v1/prices \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"product_id": "prod_01HZGQ7PNRS5T8VW3XE6YK4MA",
"currency": "DJF",
"unit_amount_minor": 15000,
"billing_scheme": "per_unit",
"recurring": {
"interval": "month",
"interval_count": 1
},
"nickname": "Business Monthly"
}'201 — pricejson
{
"id": "price_01HZGR8QNST6V9WX4YE7ZK5NB",
"product_id": "prod_01HZGQ7PNRS5T8VW3XE6YK4MA",
"currency": "DJF",
"unit_amount_minor": 15000,
"recurring": {
"interval": "month",
"interval_count": 1
},
"active": true
}3. Create subscriptionbash
curl -X POST https://api.merashub.com/v1/subscriptions \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cus_01HZGS9RNTU7W0XY5ZE8AK6PC",
"price_id": "price_01HZGR8QNST6V9WX4YE7ZK5NB",
"proration_behavior": "create_prorations"
}'201 — subscription activejson
{
"id": "sub_01HZGT0SNUV8X1YZ6AE9BL7QD",
"status": "active",
"customer_id": "cus_01HZGS9RNTU7W0XY5ZE8AK6PC",
"price_id": "price_01HZGR8QNST6V9WX4YE7ZK5NB",
"current_period_start": "2026-05-25T13:05:00Z",
"current_period_end": "2026-06-25T13:05:00Z",
"cancel_at_period_end": false
}