API reference
Base URL: https://rollopayments.com/v1. Authenticate with a bearer API key on every request. Never use internal infrastructure hostnames in client apps.
Sandbox vs live
Test and live keys expose the same endpoints and payloads. The key selects the data plane: rk_test_ only reads and writes sandbox data; rk_live_ only touches live.
Authentication
Authorization: Bearer rk_test_... Authorization: Bearer rk_live_...
Resource identifiers
| Prefix | Resource |
|---|---|
| rk_test_ / rk_live_ | API keys |
| cs_ | Checkout sessions |
| plink_ | Payment links |
| pay_ | Payments |
| prod_ | Products |
| price_ | Prices |
| sub_ | Subscriptions |
| cus_ | Customers |
| po_ | Payouts |
| disc_ | Discount codes |
| we_ | Webhook endpoints |
| evt_ | Events |
| acct_ | Accounts |
Endpoints overview
POST /checkout_sessions— create hosted checkout (201)GET /checkout_sessions/:idPOST /products— create product + default price (201)POST /payment_links/DELETE /payment_links/:idPOST /discount_codes/DELETE /discount_codes/:idGET /payments/:idGET /customers,GET /customers/:idGET /subscriptions/:idGET /payouts,GET /payout_methods
/v1 writes. See each guide for how to handle the related webhooks.POST /checkout_sessions
Example request
POST /v1/checkout_sessions
Authorization: Bearer rk_live_...
Content-Type: application/json
{
"amount": 4900,
"currency": "usd",
"mode": "payment",
"success_url": "https://example.com/thanks",
"merchant_fee": {
"label": "Platform fee",
"percent": 2.5,
"amount": 100
}
}Example response
{
"id": "cs_...",
"object": "checkout_session",
"amount": 5430,
"currency": "usd",
"status": "open",
"mode": "live",
"plan_type": "one_time",
"url": "https://rollopayments.com/pay/cs_...",
"merchant_fee": { "label": "Platform fee", "amount": 223 },
"expires_at": 1723014400000,
"livemode": true
}How to handle it
Redirect to url. Optional merchant_fee: label / name, percent, and/or amount (fixed cents) — per session, Settings toggle not required. Use null to skip Settings defaults. Guides: Payments & fees, Checkout, Subscriptions.
merchant_fee (checkout sessions)
| Field | Type | Description |
|---|---|---|
| label / name | string | Shown at checkout (e.g. Platform fee) |
| percent | number | Percent of product (0–50). Optional. |
| amount / fixed | integer | Fixed fee in cents. Optional. |
| merchant_fee: null | null | Skip Settings global fee for this session only |
Provide at least percent or amount when enabling a fee. Works for one-time and recurring checkouts; recurring keeps the fee on renewals.
POST /products
Example request
POST /v1/products
Authorization: Bearer rk_live_...
Content-Type: application/json
{
"name": "Pro plan",
"amount": 2900,
"currency": "usd",
"type": "recurring",
"interval": "month",
"trial_days": 14
}Example response
{
"id": "prod_...",
"object": "product",
"name": "Pro plan",
"description": null,
"active": true,
"default_price": {
"id": "price_...",
"amount": 2900,
"currency": "usd",
"type": "recurring",
"interval": "month"
}
}How to handle it
Save default_price.id and pass it as price when creating checkout sessions or payment links.
GET /payments/:id
Example request
GET /v1/payments/pay_... Authorization: Bearer rk_live_...
Example response
{
"id": "pay_...",
"object": "payment",
"amount": 4900,
"currency": "usd",
"status": "succeeded",
"fee": 339,
"net_amount": 4561,
"customer_email": "buyer@example.com",
"refunded_amount": 0,
"created": 1723000000000,
"livemode": true
}How to handle it
Amounts are minor units. Use net_amount for your ledger; fee is Rollo's take.
GET /customers
Example request
GET /v1/customers?limit=50 Authorization: Bearer rk_live_...
Example response
{
"object": "list",
"livemode": true,
"data": [
{
"id": "cus_...",
"object": "customer",
"email": "buyer@example.com",
"name": "Ada Lovelace",
"total_spent": 14900,
"payment_count": 3,
"created": 1722000000000,
"livemode": true
}
]
}How to handle it
List is scoped to the key mode (test vs live). Paginate with limit (max 100).
GET /subscriptions/:id
Example request
GET /v1/subscriptions/sub_... Authorization: Bearer rk_live_...
Example response
{
"id": "sub_...",
"object": "subscription",
"status": "active",
"amount": 2900,
"currency": "usd",
"interval": "month",
"cancel_at_period_end": false,
"payment_collection_paused": false,
"trial_ends_at": null,
"current_period_end": 1725680000000,
"customer": "cus_...",
"customer_email": "ada@example.com",
"created": 1723000100000,
"livemode": true
}How to handle it
Create subscriptions via checkout — see Subscriptions.
GET /payouts
Example request
GET /v1/payouts Authorization: Bearer rk_live_...
Example response
{
"object": "list",
"livemode": true,
"data": [
{
"id": "po_...",
"object": "payout",
"amount": 50000,
"currency": "usd",
"status": "paid",
"speed": "standard",
"created": 1723100000000,
"livemode": true
}
]
}How to handle it
Read-only listing. Create payouts in Dashboard → Payouts. Listen for payout.paid / payout.failed.
Errors
Example request
POST /v1/checkout_sessions
Authorization: Bearer rk_live_...
Content-Type: application/json
{ "amount": -1 }Example error response
{
"error": {
"type": "invalid_request",
"message": "Amount must be greater than zero",
"code": "amount_invalid"
}
}How to handle it
Surface error.message to operators. Treat 401 as bad/revoked key; 403 as verification / account restriction; 404 as missing resource.