RapidCents Developer Documentation
Merchant API — Server-to-Server REST
v1.0 · REST API

Merchant API

Server-to-server REST · Secret API keys (rc_sk_) · Stripe-style objects · No raw card data

Summary

The RapidCents Merchant API v1 is a server-to-server REST API for managing customers, products, prices, subscriptions, refunds, and voids. Authenticate with a secret API key (rc_sk_…). The business is resolved from the key and is never accepted from the request body.

🔒

No raw card data on this API. Payment methods are stored cards collected via hosted checkout or the dashboard. Requests that include PAN, CVC, or similar fields are rejected with raw_card_data_not_supported.

Integration Flow

Typical recurring billing flow with the Merchant API:

Your ServerPOST /customers
RapidCentsCustomer created
Your ServerPOST /products + /prices
Your ServerPOST /subscriptions
RapidCentsCharge or hosted link
CustomerPays via hosted page
RapidCentsWebhook events
Your ServerFulfill / reconcile
  1. Create a customerPOST /api/v1/customers with name and/or email.
  2. Create product & recurring price — Catalog items first; amounts live on prices (cents).
  3. Create a subscription — Pass customer, recurring price, and optionally a stored payment_method.
  4. Collect payment method if needed — Without a stored card, RapidCents returns a hosted checkout_url.
  5. Reconcile via webhooks & payments API — Listen for subscription/payment events; list payments under the subscription.

API Key Authentication

All Merchant API endpoints require a secret API key in the Authorization header. Keys are created in the RapidCents dashboard and start with rc_sk_.

Required Headers

Headers
Authorization: Bearer rc_sk_…
Content-Type: application/json
Accept: application/json

Base URL Pattern

All Merchant API endpoints are under /api/v1/…. Business scope comes from the key — do not send business_id in the body.

Keep secret keys on the server only. Never ship rc_sk_ keys to browsers, mobile apps, or public repos. Rotate compromised keys immediately from the dashboard.

Smoke Test

GET /api/v1/account

Response — 200 OK
{
  "data": {
    "object": "account",
    "business_id": "biz-uuid",
    "business_name": "Acme Store",
    "api_key_id": "key-uuid",
    "api_key_name": "Production",
    "api_key_last_four": "a1b2"
  }
}

IP Whitelisting

🛡

Required: Each API key must be activated with at least one allowed IP. Requests from non-allowlisted IPs are rejected.

Configure allowed_ips when creating or rotating keys in the dashboard (1–2 IPs per key). Staging and production keys have separate allowlists.

EnvironmentBase URLWhitelist
Staging https://uatstage00-api.rapidcents.com Separate — add your staging server IPs
Production https://api.rapidcents.com Separate — add your production server IPs

Rate Limits

Limits are enforced per API key / business. Exceeding a limit returns 429 with rate_limit_error.

ScopeDefault
Overall60 requests / minute
Subscription create20 / minute
Refunds5 / minute
Voids5 / minute
Invalid-key attempts (per IP)10 / minute

HTTP Idempotency-Key support is intentionally deferred to a later phase. Design writes so retries are safe (e.g. customer create is idempotent by email).

Account

GET /api/v1/account

Returns safe identifiers for the authenticated key and its business. Use this to verify credentials after onboarding.

Customers

Create a Customer

POST /api/v1/customers

Request
POST /api/v1/customers
Authorization: Bearer rc_sk_…
Content-Type: application/json

{
  "name": "Jane Doe",
  "email": "[email protected]",
  "phone": "+1-555-0100",
  "metadata": { "crm_id": "123" }
}

Request Fields

FieldTypeRequiredDescription
namestringConditionalMax 255. Either name or email is required.
emailstringConditionalValid email. Used for firstOrCreate dedupe.
phonestringNoMax 50.
metadataobjectNoArbitrary key/value map.
Response — 201 Created / 200 Existing
{
  "id": "cust-uuid",
  "object": "customer",
  "name": "Jane Doe",
  "email": "[email protected]",
  "phone": "+1-555-0100",
  "metadata": { "crm_id": "123" },
  "created": 1710000000
}

List / Show / Update

MethodEndpointNotes
GET/api/v1/customersCursor pagination
GET/api/v1/customers/{id}Single customer
PATCH/api/v1/customers/{id}Same fields as create (sometimes)

Payment Methods

Read and delete stored cards. Raw card create is not supported on Merchant API v1.

MethodEndpointDescription
GET/api/v1/payment_methodsList; optional ?customer=
GET/api/v1/customers/{id}/payment_methodsList for one customer
GET/api/v1/payment_methods/{id}Show one
DELETE/api/v1/payment_methods/{id}Soft-detach (on_file=false)
Example object
{
  "id": "pm-uuid",
  "object": "payment_method",
  "type": "card",
  "customer": "cust-uuid",
  "card": {
    "brand": "visa",
    "last4": "4242",
    "exp_month": 12,
    "exp_year": 2030
  },
  "status": "active",
  "created": 1710000000
}

Collect cards via hosted subscription checkout or the dashboard. Sending card, cvc, pan, etc. returns 422 raw_card_data_not_supported.

Products

POST /api/v1/products

Request
{
  "name": "Pro Plan",
  "description": "Monthly subscription",
  "active": true,
  "metadata": {}
}
FieldTypeRequiredDescription
namestringYesMax 255
descriptionstringNoMax 2000
activebooleanNoDefault true
metadataobjectNoArbitrary map

Also: GET /products, GET /products/{id}, PATCH /products/{id}. List filter: ?active=true|false.

Amounts live on Prices, not Products. Creating a product does not charge anything.

Prices

POST /api/v1/prices

Request — recurring monthly
{
  "product": "prod-uuid",
  "unit_amount": 2999,
  "recurring": {
    "interval": "month",
    "interval_count": 1
  },
  "nickname": "Pro Monthly",
  "active": true
}
FieldTypeRequiredDescription
productstringYesProduct id
unit_amountintegerYesAmount in cents (≥ 1)
recurring.intervalstringFor recurringday | week | month | year
recurring.interval_countintegerNoDefault 1
nicknamestringNoDisplay label
activebooleanNoDefault true
metadataobjectNoArbitrary map

Supported cadences

day:1, week:1, week:2, month:1, month:3, month:6, year:1

Amount, currency, and recurring cadence are immutable after create. PATCH only allows nickname, active, and metadata.

Subscriptions

POST /api/v1/subscriptions

Request — with stored payment method
{
  "customer": "cust-uuid",
  "price": "price-uuid",
  "payment_method": "pm-uuid",
  "start_date": "2026-08-01",
  "tax_rate": 13,
  "surcharge_rate": 2.4
}

Request Fields

FieldTypeRequiredDescription
customerstringYesCustomer id
pricestringYesMust be recurring + active
payment_methodstringNoStored card id — never raw PAN
start_datedateNoDefaults to today
installmentsintegerNo≥ 1 if set
surcharge_ratenumberNoHuman % 0–2.4 (e.g. 2.4)
tax_ratenumberNoHuman % 0–30 (e.g. 13)
send_payment_linkbooleanNoDefault true when no PM

active

Billing is live; first charge succeeded or card on file.

pending_payment_method

Hosted checkout_url returned; waiting for card.

completed

Installment plan finished all bills.

canceled

Cancelled via DELETE /subscriptions/{id}.

Create behavior

  • With payment_method — Attempts first charge. Decline deletes the subscription and returns 402.
  • Without payment_method — Creates inactive subscription + hosted link; optionally emails the customer.
  • Emits webhook subscription.created.

Cancel

DELETE /api/v1/subscriptions/{id}

Deactivates the subscription, clears next billing, unfulfills pending queue rows, and emits subscription.cancelled.

List filters

?customer= and ?status=active|canceled|pending_payment_method (aliases: cancelled, incomplete).

Subscription Payments

Read-only history of sales for a subscription.

MethodEndpoint
GET/api/v1/subscriptions/{id}/payments
GET/api/v1/subscriptions/{id}/payments/{payment}
Example payment
{
  "id": "pay-uuid",
  "object": "payment",
  "subscription": "sub-uuid",
  "amount": 2999,
  "currency": "CAD",
  "status": "succeeded",
  "refunded_amount": 0,
  "created": 1710000000
}

Statuses: succeeded, failed, refunded, voided. Refund ledger rows are excluded; use refunded_amount on the original payment.

Refunds

POST /api/v1/refunds

Request
{
  "payment": "pay-uuid",
  "amount": 1000
}
FieldTypeRequiredDescription
paymentstringYesSubscription History sale id
amountintegerNoCents; omit for full remaining balance
  • Subscription payments only (not VT / payment-link)
  • Webhooks: payment.refunded or payment.partially_refunded
  • Customer email: refund notification
  • Show: GET /api/v1/refunds/{id}

Voids

POST /api/v1/voids

Request
{
  "payment": "pay-uuid"
}

Voids an open-batch subscription payment. Returns the updated payment object with status: "voided" and emits payment.voided.

If the batch is already settled, use a refund instead of a void.

All Endpoints

Account

MethodEndpointAuthDescription
GET/api/v1/accountAPI keyAuth smoke test

Customers

MethodEndpointAuthDescription
POST/api/v1/customersAPI keyCreate customer
GET/api/v1/customersAPI keyList customers
GET/api/v1/customers/{id}API keyRetrieve customer
PATCH/api/v1/customers/{id}API keyUpdate customer

Payment Methods

MethodEndpointAuthDescription
GET/api/v1/payment_methodsAPI keyList stored cards
GET/api/v1/customers/{id}/payment_methodsAPI keyList by customer
GET/api/v1/payment_methods/{id}API keyRetrieve card
DELETE/api/v1/payment_methods/{id}API keyDetach card

Products & Prices

MethodEndpointAuthDescription
POST/api/v1/productsAPI keyCreate product
GET/api/v1/productsAPI keyList products
GET/api/v1/products/{id}API keyRetrieve product
PATCH/api/v1/products/{id}API keyUpdate product
POST/api/v1/pricesAPI keyCreate price
GET/api/v1/pricesAPI keyList prices
GET/api/v1/prices/{id}API keyRetrieve price
PATCH/api/v1/prices/{id}API keyUpdate price metadata

Subscriptions & Payments

MethodEndpointAuthDescription
POST/api/v1/subscriptionsAPI keyCreate subscription
GET/api/v1/subscriptionsAPI keyList subscriptions
GET/api/v1/subscriptions/{id}API keyRetrieve subscription
DELETE/api/v1/subscriptions/{id}API keyCancel subscription
GET/api/v1/subscriptions/{id}/paymentsAPI keyList payments
GET/api/v1/subscriptions/{id}/payments/{payment}API keyRetrieve payment

Refunds & Voids

MethodEndpointAuthDescription
POST/api/v1/refundsAPI keyCreate refund
GET/api/v1/refunds/{id}API keyRetrieve refund
POST/api/v1/voidsAPI keyVoid open-batch payment

Pagination

List endpoints return a Stripe-style list envelope with cursor pagination:

List response
{
  "object": "list",
  "data": [ … ],
  "has_more": false
}
ParamRules
limit1–100, default 10
starting_afterResource UUID — older page
ending_beforeResource UUID — newer page

Order: created_at DESC, id tiebreaker.

Environment Configuration

EnvironmentBase URLPurpose
Staging https://uatstage00-api.rapidcents.com Development, testing, and integration
Production https://api.rapidcents.com Live transactions

Each environment has separate API keys and IP allowlists. Do not use staging keys in production.

Error Handling

Errors use a consistent envelope (not the dashboard { ok, status } shape):

Error response
{
  "error": {
    "type": "validation_error",
    "code": "parameter_invalid",
    "message": "The email must be a valid email address.",
    "param": "email"
  }
}
HTTPTypeExamples
401authentication_errorinvalid_api_key
402card_errorcard_declined
403permission_errorpermission_denied
404invalid_request_errorresource_missing
409conflict_errorconflict
422validation_errorparameter_invalid, raw_card_data_not_supported
429rate_limit_errorrate_limit_exceeded
500api_errorinternal_error

Security Best Practices

  • Secret keys stay on the server — Never expose rc_sk_ keys in frontend code or mobile apps.
  • Use HTTPS exclusively — All API traffic must use TLS.
  • Whitelist server IPs — Activate keys with allowlisted outbound IPs; update before infrastructure changes.
  • Never send raw card data — Collect cards via hosted checkout; use stored payment method IDs only.
  • Money in cents — Send integer minor units for amounts; tax/surcharge rates as human percentages.
  • Verify webhooks — Treat webhook deliveries as the source of truth for payment state changes.
  • Rotate compromised keys — Revoke and reissue from the dashboard immediately.

Integration Checklist

Complete all items before going live with production transactions.

Authentication & Setup

  • Secret API key created and stored in a secrets manager
  • Server IP(s) allowlisted and key activated
  • GET /api/v1/account succeeds from your server
  • Staging and production keys stored separately

Catalog & Customers

  • Products and recurring prices created with amounts in cents
  • Customer create/update/list wired to your CRM
  • Email conflict / firstOrCreate behavior understood

Subscriptions

  • Create with stored payment_method path tested (including 402 declines)
  • Create without PM returns checkout_url; hosted flow completes
  • Cancel path tested; pending queue rows cleared
  • Webhooks for subscription.created / subscription.cancelled handled

Refunds & Voids

  • Full and partial refunds tested on subscription payments
  • Void only used for open-batch payments
  • payment.refunded / payment.voided webhooks handled