Developer documentationGet API keys

API reference

Every endpoint, with the request and response you can expect. All examples use test keys; swap in a live key and the same calls move real money.

Customers

The people who pay you. Created automatically at checkout, or by hand.

POST/v1/customersscope: customers:write

Create a customer

Request
{
  "email": "anna@example.am",
  "name": "Anna Hakobyan",
  "metadata": { "crm_id": "8891" }
}
Response
{
  "id": "cus_1b4cf2ceec9356f1e53a3cab",
  "object": "customer",
  "email": "anna@example.am",
  "name": "Anna Hakobyan",
  "credit_balance": 0,
  "metadata": { "crm_id": "8891" },
  "created": 1786998562
}
GET/v1/customersscope: customers:read

List customers — supports ?email=

GET/v1/customers/:idscope: customers:read

Retrieve a customer

POST/v1/customers/:idscope: customers:write

Update a customer

DELETE/v1/customers/:idscope: customers:write

Delete a customer — clears personal data, deactivates saved cards, keeps the financial record

Products

What you sell. A product owns its prices, so one product can be sold monthly and yearly without pretending to be two unrelated things.

POST/v1/productsscope: plans:write

Create a product

Request
{
  "name": "Pro",
  "description": "For growing teams"
}
Response
{
  "id": "prod_6f21…",
  "object": "product",
  "name": "Pro",
  "description": "For growing teams",
  "active": true,
  "created": 1786998563
}
GET/v1/productsscope: plans:read

List products

GET/v1/products/:idscope: plans:read

Retrieve a product

POST/v1/products/:idscope: plans:write

Update a product

DELETE/v1/products/:idscope: plans:write

Archive a product and every price under it. Existing subscriptions keep billing.

Prices (plans)

An amount and an interval, belonging to a product. Changing a price never re-prices an existing subscription — the next cycle picks it up. Omit `product` and the `name` creates one, so selling something takes a single call.

POST/v1/plansscope: plans:write

Create a price

Request
{
  "product": "prod_6f21…",
  "name": "Monthly",
  "amount": 12900,
  "currency": "AMD",
  "interval": "month",
  "interval_count": 1,
  "trial_days": 14
}
Response
{
  "id": "plan_3911175476653e621be07025",
  "object": "plan",
  "product": "prod_6f21…",
  "product_name": "Pro",
  "nickname": "Monthly",
  "name": "Pro — Monthly",
  "amount": 12900,
  "currency": "AMD",
  "interval": "month",
  "interval_count": 1,
  "trial_days": 14,
  "active": true,
  "created": 1786998563
}
GET/v1/plansscope: plans:read

List prices

GET/v1/plans/:idscope: plans:read

Retrieve a price

POST/v1/plans/:idscope: plans:write

Update or archive a price

Subscriptions

The recurring core. A customer, a plan, a saved card and a schedule.

POST/v1/subscriptionsscope: subscriptions:write

Create a subscription. Without a trial, a payment method is required and the first period is charged now.

Request
{
  "customer": "cus_1b4c…",
  "plan": "plan_3911…",
  "payment_method": "pm_77a2…",
  "quantity": 1
}
Response
{
  "id": "sub_5c1e…",
  "object": "subscription",
  "status": "active",
  "plan": "plan_3911…",
  "quantity": 1,
  "current_period_start": 1786998600,
  "current_period_end": 1789590600,
  "trial_end": null,
  "cancel_at_period_end": false,
  "dunning_attempt": 0
}
GET/v1/subscriptionsscope: subscriptions:read

List subscriptions — supports ?status=

GET/v1/subscriptions/:idscope: subscriptions:read

Retrieve a subscription

POST/v1/subscriptions/:id/change_planscope: subscriptions:write

Change plan with proration. An upgrade charges the difference now; a downgrade credits the customer.

Request
{ "plan": "plan_bigger…", "prorate": true }
Response
{
  "id": "sub_5c1e…",
  "status": "active",
  "plan": "plan_bigger…",
  "proration": { "charged": 19677, "credited": 0, "payment": "pay_aa31…" }
}
POST/v1/subscriptions/:id/cancelscope: subscriptions:write

Cancel now, or at period end with { "at_period_end": true }

POST/v1/subscriptions/:id/pausescope: subscriptions:write

Pause billing without canceling

POST/v1/subscriptions/:id/resumescope: subscriptions:write

Resume — the paused gap is never billed

Payments

Every charge, one-off and recurring.

POST/v1/paymentsscope: payments:write

Charge a saved card off-session — the same call the recurring engine makes

Request
{
  "amount": 45000,
  "currency": "AMD",
  "customer": "cus_1b4c…",
  "description": "September retainer"
}
Response
{
  "id": "pay_a348cb5b0664660d4c29d890",
  "object": "payment",
  "amount": 45000,
  "currency": "AMD",
  "status": "succeeded",
  "type": "one_off",
  "attempt": 1,
  "is_recovery": false,
  "created": 1786998900
}
GET/v1/paymentsscope: payments:read

List payments — supports ?status=

GET/v1/payments/:idscope: payments:read

Retrieve a payment

POST/v1/payments/:id/refundscope: refunds:write

Refund in whole or part. The platform fee on the refunded amount is reversed.

Request
{ "amount": 20000, "reason": "duplicate" }
Response
{
  "id": "re_66b1…",
  "object": "refund",
  "payment": "pay_a348…",
  "amount": 20000,
  "status": "succeeded"
}
GET/v1/refundsscope: payments:read

List refunds

Checkout sessions

The only way a card enters the system. Works with a publishable key.

POST/v1/checkout/sessionsscope: publishable or payments:write

Open a hosted checkout. type is payment, setup or subscription.

Request
{
  "type": "payment",
  "amount": 25000,
  "currency": "AMD",
  "description": "September membership",
  "customer_email": "anna@example.am",
  "save_card": true,
  "success_url": "https://yourapp.am/thanks"
}
Response
{
  "id": "cs_f4accee46724b73fae2ced5a",
  "object": "checkout_session",
  "status": "processing",
  "amount": 25000,
  "url": "https://ronda.sh/checkout/cs_f4ac…",
  "expires_at": 1787000363
}
GET/v1/checkout/sessions/:id

Retrieve a session and its outcome

Payment methods

Saved cards. Ronda holds the bank's token, brand and last four digits — never a card number.

GET/v1/payment_methodsscope: customers:read

List saved cards — supports ?customer=

DELETE/v1/payment_methods/:idscope: customers:write

Detach a card and deactivate the binding at the bank

Payment links

A shareable URL. Point one at a plan and it starts a real subscription.

POST/v1/payment_linksscope: links:write

Create a payment link

Request
{ "name": "September invoice", "amount": 45000 }
Response
{
  "id": "link_71c2…",
  "object": "payment_link",
  "url": "https://ronda.sh/pay/pl_8f1c…",
  "amount": 45000,
  "status": "active",
  "use_count": 0
}
GET/v1/payment_linksscope: links:read

List links

POST/v1/payment_links/:idscope: links:write

Activate or deactivate a link

Invoices

The document behind a charge — and the way to bill a company that will not hand over a card. Every subscription cycle writes one; you can also raise one directly. Sent invoices carry a due date and a hosted page the customer can pay from.

POST/v1/invoicesscope: payments:write

Raise an invoice and send it

Request
{
  "customer": "cus_1b4c…",
  "collection_method": "send_invoice",
  "days_until_due": 14,
  "memo": "Thank you",
  "lines": [
    { "description": "Consulting, March", "quantity": 2, "unit_amount": 150000 }
  ]
}
Response
{
  "id": "inv_9d02…",
  "object": "invoice",
  "number": "2026-0042",
  "status": "open",
  "collection_method": "send_invoice",
  "subtotal": 300000,
  "discount": 0,
  "total": 300000,
  "due": 1788208563,
  "hosted_url": "https://ronda.sh/invoice/ivt_…",
  "created": 1786998563
}
GET/v1/invoicesscope: payments:read

List invoices, filterable by status and customer

GET/v1/invoices/:idscope: payments:read

Retrieve an invoice with its line items

POST/v1/invoices/:id/voidscope: payments:write

Void an invoice. It keeps its number — the sequence stays gapless — and stops being payable.

Coupons

A reusable discount rule. Attaching one to a subscription creates a discount with its own clock, so archiving the coupon never re-prices someone already on it. Discounts do not stack.

POST/v1/couponsscope: plans:write

Create a coupon — a percentage or a fixed amount, never both

Request
{
  "code": "SUMMER25",
  "percent_off": 25,
  "duration": "repeating",
  "duration_in_months": 3,
  "max_redemptions": 100
}
Response
{
  "id": "cpn_74b1…",
  "object": "coupon",
  "code": "SUMMER25",
  "percent_off": 25,
  "duration": "repeating",
  "duration_in_months": 3,
  "max_redemptions": 100,
  "times_redeemed": 0,
  "valid": true,
  "created": 1786998563
}
GET/v1/couponsscope: plans:read

List coupons

GET/v1/coupons/:idscope: plans:read

Retrieve a coupon by id or by code

DELETE/v1/coupons/:idscope: plans:write

Archive a coupon

POST/v1/subscriptions/:id/discountscope: subscriptions:write

Apply a coupon to a subscription. It takes effect from the next renewal.

Request
{ "coupon": "SUMMER25" }

Webhooks, events, disputes and balance

Everything else you need to reconcile.

POST/v1/webhook_endpointsscope: webhooks:write

Register an endpoint. The signing secret is returned once.

Request
{ "url": "https://yourapp.am/ronda/webhook", "enabled_events": ["payment.succeeded"] }
GET/v1/webhook_endpointsscope: webhooks:read

List endpoints

DELETE/v1/webhook_endpoints/:idscope: webhooks:write

Delete an endpoint

GET/v1/eventsscope: events:read

List events — supports ?type=

GET/v1/events/:idscope: events:read

Retrieve an event

GET/v1/disputesscope: payments:read

List chargebacks

GET/v1/balancescope: payments:read

Collected, pending, settled and fees — derived from the ledger

Response
{
  "object": "balance",
  "currency": "AMD",
  "available": 1284000,
  "pending": 96000,
  "gross": 1420000,
  "refunded": 25000,
  "fees": 7100,
  "settled": 1180000,
  "mode": "live"
}