RapidCents
Checkout overview
Your backend creates a checkout session with RapidCents. The response includes checkout_url (where the shopper pays) and a session token. Never call session APIs from the browser with your access token.
Checkout modes
Payment UI on your domain. Cart and subscription checkout.
Integration guide → Hosted checkoutFull-page handoff to RapidCents; return via success_url / cancel_url.
Quick payment (modal, iframe, or new window); one-time charges, minimal JSON. No subscriptions.
Integration guide →
Subscription checkout — same checkout/create API with mode: subscription (embedded or hosted). See the guide for plan fields and line_items.
APIs you need
- OAuth token —
POST …/oauth/tokenorPOST …/api/oauth/token(host-dependent). Reauthorize on your server before checkout calls (workflow); use the returnedaccess_tokenasAuthorization: Bearer …. - Embedded / Hosted / Subscriptions —
POST {API origin}/api/{business_id}/checkout/create(JSON). - RapidPay —
POST {API origin}/api/{business_id}/v1/checkout-pay(JSON). - Session details —
GET {API origin}/api/{business_id}/checkout/{session_token}/details(Bearer token, sameOriginrules as create/pay). Use the sessiontokenfrom your create or pay response. After the shopper pays, this returns updatedcheckout_sessionstate and, when available, atransactionobject with the approved charge. Optional:?expand=refundsto include refund rows for that charge.
Replace {business_id} with your business id. Staging vs production base URLs:
Staging
API origin (no path)
https://uatstage00-api.rapidcents.com
Typical base URL to configure
https://uatstage00-api.rapidcents.com/api
Production
API origin (no path)
https://api.rapidcents.com
Typical base URL to configure
https://api.rapidcents.com/api
Auth & tokens
Checkout APIs require a valid OAuth access token on every server-side call. RapidCents refresh tokens typically expire after about 24 hours, so your backend should reauthorize automatically immediately before protected API calls—not only when the short-lived access token expires.
- Create an API client in the RapidCents dashboard; keep
client_idandclient_secreton the server only. - Persist the latest
access_tokenandrefresh_tokensecurely (encrypted at rest). - Keep RapidCents account credentials on the server for the password-grant fallback when refresh is no longer valid.
Automatic reauthorization workflow
Run this on your server before checkout/create, v1/checkout-pay, session details, and other Bearer-protected RapidCents APIs. Never expose refresh tokens, client secrets, or password-grant credentials to the browser.
Refresh token grant (primary)
POST {API origin}/api/oauth/token (some hosts use /oauth/token).
Form body:
grant_type=refresh_tokenrefresh_token— your stored refresh tokenclient_id,client_secretredirect_uri— empty string ("") when not usedscope— empty string ("") unless your deployment requires scope
On success, save the new access_token and refresh_token from the response, then call the checkout API with Authorization: Bearer <access_token>.
Password grant (fallback)
If the refresh response includes an error (for example invalid_grant, refresh token revoked, or expired after ~24h), call the same token endpoint with:
grant_type=passwordclient_id,client_secretusername,password— RapidCents account credentials stored on your server
On success, again persist access_token and refresh_token, then proceed with the API call. This fallback is for OAuth token expiry only—not card expiry or payment-method failures.
Flow summary: protected API call needed → try refresh → save tokens → Bearer request → if refresh fails with an expired/revoked token → password grant → save tokens → Bearer request.
Token endpoint reference
Content-Type: application/x-www-form-urlencoded, Accept: application/json. See Automatic reauthorization workflow for when to call this endpoint.
Production: https://api.rapidcents.com/oauth/token
— some hosts use POST …/api/oauth/token instead; use the path your deployment documents.
First-time tokens (dashboard or other OAuth grants) follow RapidCents’ general OAuth docs.
Request
Headers
Content-Type
string
Accept
string
Authorization
string
Body
Form fields are sent as application/x-www-form-urlencoded (not JSON). This table covers grant_type=refresh_token only.
grant_type
string
client_id
string
client_secret
string
refresh_token
string
redirect_uri
string
scope
string
Responses
Typical success body from the token endpoint:
Body
access_token
string
token_type
string
expires_in
integer
refresh_token
string
cURL — refresh token (primary)
curl -sS --request POST "https://uatstage00-api.rapidcents.com/api/oauth/token" \
-H "Accept: application/json" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=refresh_token" \
--data-urlencode "client_id=YOUR_CLIENT_ID" \
--data-urlencode "client_secret=YOUR_CLIENT_SECRET" \
--data-urlencode "refresh_token=YOUR_REFRESH_TOKEN" \
--data-urlencode "redirect_uri=" \
--data-urlencode "scope="
Password grant (fallback)
Call only when the refresh grant fails with an expired, revoked, or invalid refresh token—not for card expiry or payment declines. On success, persist the new access_token and refresh_token the same way as refresh.
Request (password grant)
Body
Same endpoint and headers as refresh; only the form fields differ.
grant_type
string
client_id
string
client_secret
string
username
string
password
string
cURL — password grant (fallback)
curl -sS --request POST "https://uatstage00-api.rapidcents.com/api/oauth/token" \
-H "Accept: application/json" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=password" \
--data-urlencode "client_id=YOUR_CLIENT_ID" \
--data-urlencode "client_secret=YOUR_CLIENT_SECRET" \
--data-urlencode "username=YOUR_RAPIDCENTS_EMAIL" \
--data-urlencode "password=YOUR_RAPIDCENTS_PASSWORD"
Use the new access token on checkout APIs:
Authorization: Bearer <access_token>
Token refresh failures & operational impact
Treat OAuth reauthorization as part of your integration’s reliability. Access tokens expire quickly; refresh tokens can rotate or expire (often within ~24 hours). If refresh does not run successfully before a protected API call, checkout and payment APIs will fail until valid tokens are restored.
If refresh fails
- Try password grant automatically. When the refresh response indicates an invalid or expired refresh token (
invalid_grant, revoked, etc.), your server should fall back togrant_type=passwordwith stored RapidCents credentials, then save the new token pair before retrying the API call. - Not for payment-method errors. Password grant recovers OAuth credentials only. Card expiry, declines, and processor errors are separate from token reauthorization.
- Payment processing risk. If both refresh and password grant fail, session creation and other Bearer-protected calls remain blocked until an operator fixes client credentials or account access.
Recommendations
- Automate before every protected call. Run refresh (then password fallback if needed) immediately before
checkout/create,v1/checkout-pay, and similar APIs—not on a fixed cron alone. - Persist rotated tokens. Save every new
access_tokenandrefresh_tokenreturned by RapidCents (encrypted at rest). - Handle errors explicitly. Log failed refresh and fallback attempts, alert operators when both grants fail, and avoid sending stale bearer tokens to checkout APIs.
Checkout request headers
All checkout API requests require:
-
Authorization: Bearer <access_token>— from OAuth (see Overview → OAuth). -
Origin— HTTPS origin of your app (for examplehttps://shop.example.com). It must match the origin registered for your API client in RapidCents. -
Content-Type: application/jsonandAccept: application/jsonunless the API specifies otherwise.
Never expose tokens in the browser
Create checkout sessions on your server only. Do not send the access token to client-side JavaScript.
HTTP headers
On every checkout/create and v1/checkout-pay call from your backend.
Authorization
string
Origin
string
Content-Type
string
Accept
string
Example: create session (embedded)
Staging. Full body field tables are in each mode guide.
curl -sS -X POST "https://uatstage00-api.rapidcents.com/api/YOUR_BUSINESS_ID/checkout/create" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Origin: https://your-https-app.example.com" \
-d '{
"ui_mode": "embedded",
"mode": "payment",
"amount_total": 49.99,
"amount_subtotal": 49.99,
"currency": "CAD",
"success_url": "https://your-https-app.example.com/thank-you?order=1",
"cancel_url": "https://your-https-app.example.com/cart",
"customer_email": "buyer@example.com",
"line_items": [
{ "name": "Item", "quantity": 1, "unit_amount": 49.99, "total": 49.99 }
]
}'
Example response
HTTP 200, JSON with ok: true and checkout_session:
{
"ok": true,
"message": "Checkout session created successfully",
"status": "PENDING",
"checkout_session": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"token": "a1b2c3d4e5f6789012345678901234567890abcdef0123456789abcdef012345",
"checkout_url": "https://checkout.rapidcents.com/session/a1b2c3d4\u2026/embedded",
"allowed_origins": [
"https://shop.example.com"
],
"expires_at": "2026-04-21T18:00:00.000000Z",
"session_status": "PENDING",
"payment_status": "UNPAID",
"amount_total": 49.99,
"amount_subtotal": 49.99,
"amount_tax": 0,
"amount_discount": 0,
"surcharge": false,
"amount_surcharge": 0,
"surcharge_rate": null,
"currency": "CAD",
"mode": "payment",
"description": null,
"customer_id": null,
"customer_email": "buyer@example.com",
"customer_name": "Alex Rivera",
"client_reference_id": null,
"success_url": "https://shop.example.com/thank-you?order=1",
"cancel_url": "https://shop.example.com/cart",
"return_url": null,
"metadata": [],
"ui_mode": "embedded",
"created_at": "2026-04-21T12:00:00.000000Z",
"billing_address_collection": null,
"shipping_address_collection": null,
"billing_address": null,
"shipping_address": null,
"consent": null,
"consent_collection": null,
"phone_number_collection": null,
"line_items": [
{
"name": "Premium plan (monthly)",
"quantity": 1,
"unit_amount": 49.99,
"total": 49.99
}
],
"discounts": null,
"apply_discount": null,
"total_details": null,
"invoice_creation": null,
"tax_id_collection": null
},
"transaction": null
}
checkout_session.token— store as your external session or order correlation id.checkout_session.checkout_url— load in an iframe, new tab, or follow as a redirect depending on the mode.
Retrieve checkout details after payment
Do not rely on the success page or iframe postMessage alone to prove payment. On your server, call the session details endpoint with the same OAuth access token, passing the token from checkout_session (returned by checkout/create or v1/checkout-pay). Poll or call once after redirect/notification until payment_status and session_status reflect the outcome; use transaction (when present) for the processor reference and amount. Webhooks, if enabled for your integration, remain the preferred source of truth for fulfillment—use details to reconcile in-app state.
Replace {session_token} with the session token string. Optional query: expand=refunds (include refund list when a successful charge exists).
Staging example (same headers as Checkout request headers):
curl -sS -G "https://uatstage00-api.rapidcents.com/api/YOUR_BUSINESS_ID/checkout/SESSION_TOKEN_FROM_CHECKOUT_SESSION/details" \
--data-urlencode "expand=refunds" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Origin: https://your-https-app.example.com"
Omit --data-urlencode "expand=refunds" and the ? query if you do not need refund rows.
{
"ok": true,
"message": "Checkout session created successfully",
"status": "COMPLETED",
"checkout_session": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"token": "a1b2c3d4e5f6789012345678901234567890abcdef0123456789abcdef012345",
"checkout_url": "https://checkout.rapidcents.com/session/a1b2c3d4\u2026/embedded",
"allowed_origins": [
"https://shop.example.com"
],
"expires_at": "2026-04-21T18:00:00.000000Z",
"session_status": "COMPLETED",
"payment_status": "PAID",
"amount_total": 49.99,
"amount_subtotal": 49.99,
"amount_tax": 0,
"amount_discount": 0,
"surcharge": false,
"amount_surcharge": 0,
"surcharge_rate": null,
"currency": "CAD",
"mode": "payment",
"description": null,
"customer_id": 1001,
"customer_email": "buyer@example.com",
"customer_name": "Alex Rivera",
"client_reference_id": null,
"success_url": "https://shop.example.com/thank-you?order=1",
"cancel_url": "https://shop.example.com/cart",
"return_url": null,
"metadata": {
"order_id": "42"
},
"ui_mode": "embedded",
"created_at": "2026-04-21T12:00:00.000000Z",
"line_items": [
{
"name": "Premium plan (monthly)",
"quantity": 1,
"unit_amount": 49.99,
"total": 49.99
}
]
},
"transaction": {
"code": "AA",
"message": "Approved Transaction (Auths / Reversals)",
"receiptID": 50001,
"transactionID": 90001,
"details": {
"merchant_name": "Example Merchant",
"merchant_address": "123 Main St",
"merchant_number": "+1-555-0100",
"card": "VISA 4242",
"date": "Mon, Apr 21, 2026 1:15 PM",
"association": "Visa",
"amount": 49.99,
"customer": {
"id": 1001,
"name": "Alex Rivera",
"email": "buyer@example.com"
},
"issuer_reference": "AUTH123456",
"source": "checkout_session"
}
}
}
checkout_session— current session and payment state;session_status/payment_statusreflect completion.transaction—nullif no card attempt yet; when paid, includes approval fields andtransactionIDfor support and reconciliation.- Optional query
?expand=refunds— when the session has a successful charge, includes arefundsarray on the transaction object (shape varies; omitted in this example).
Browser / frontend
- Prefer keeping the access token, client secret, and refresh token off the public web; your UI should talk to your backend and let the backend call RapidCents when possible.
- Embedded (
checkout/create) — Requiredcheckout.jsat{API origin}/js/checkout.js(RapidCentsCheckout). Staging / production:https://uatstage00-api.rapidcents.com/js/checkout.js·https://api.rapidcents.com/js/checkout.js. Guide + sample: Embedded → checkout.js, embedded sample HTML. (The payment-testing-app cart uses server-side session creation + a manual iframe instead—also valid if you do not put a bearer token in the browser.) - Hosted — Redirect to
checkout_urlafter create succeeds. - RapidPay — After server
v1/checkout-pay, use requiredrapid.jswithdata-checkout-urlto inject thecheckout_urlin aniframe({API origin}/js/rapid.js). - If you use
postMessage, verifyevent.originmatches the checkout URL origin (and for embedded, thatevent.sourceis the checkout iframe).
Success & cancel URLs
Creating a session returns payment UI (checkout_url) and a token. Redirects and postMessage improve UX only—confirm capture on your server using the mechanism RapidCents documents for your integration before fulfilling orders.
By checkout mode
- Embedded — Use required
checkout.js(RapidCentsCheckout.createwithui_mode: embedded) so the library mounts the iframe and handlespostMessage(rc:checkout_height,rc:checkout_result), or create the session on your server and set the iframesrctocheckout_urlyourself. Always validatee.sourceande.originif you listen for messages. See Embedded → checkout.js. - Hosted — After
200, send the browser tocheckout_urlwith302or303(prefer303after a POST “start checkout” so the form is not resubmitted). The shopper returns to yoursuccess_urlorcancel_urlwhen checkout finishes. - RapidPay —
v1/checkout-paydoes not acceptsuccess_url/cancel_urlin the body. Mountcheckout_urlin the browser withrapid.js(data-checkout-url), then handlepostMessage(or therapidcents-checkoutevent) as needed; confirm payment server-side before fulfillment. - Subscriptions — Same
success_url/cancel_urlbehaviour as one-timecheckout/createwhen the API requires those fields.
success_url
- Absolute
https://URL; add your own id in the query if needed. - Not proof of payment—users can open or replay the URL. Keep “thank you” logic idempotent.
cancel_url
- Absolute
https://URL where RapidCents may send the shopper if they abandon checkout (when the API requires it).
Security
- Never send client secret, refresh token, or bearer access token to the browser or mobile app.
- Rotate access tokens before expiry; handle refresh failures with re-auth or new tokens from the dashboard.
Originmust be HTTPS and match the origin registered for your API client.- Call RapidCents only over TLS; do not disable certificate checks in production.
- Log session
tokenand your own order ids for support.
Common errors
Common HTTP status codes
- 401 Unauthorized — Missing or invalid bearer token, or expired access token. Refresh via OAuth.
- 403 Forbidden — Token accepted but not allowed for this business or operation.
- 422 Unprocessable Entity — Validation failed (missing fields, wrong types, amounts out of range, invalid currency). Read the response body for field errors.
- 400 Bad Request — Malformed JSON or an invalid combination of fields (for example,
ui_mode/mode).
Common integration mistakes
- Origin mismatch —
Origindoes not match a registered HTTPS origin for the OAuth client. - Wrong environment — Staging credentials or base URL used against production, or the reverse.
- Invalid return URLs —
success_url/cancel_urlnot absolute HTTPS where the API requires them. - Amounts — Use decimal amounts to the precision the API expects; avoid floating-point drift in application code.