Skip to content

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

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 tokenPOST …/oauth/token or POST …/api/oauth/token (host-dependent). Reauthorize on your server before checkout calls (workflow); use the returned access_token as Authorization: Bearer ….
  • Embedded / Hosted / SubscriptionsPOST {API origin}/api/{business_id}/checkout/create (JSON).
  • RapidPayPOST {API origin}/api/{business_id}/v1/checkout-pay (JSON).
  • Session detailsGET {API origin}/api/{business_id}/checkout/{session_token}/details (Bearer token, same Origin rules as create/pay). Use the session token from your create or pay response. After the shopper pays, this returns updated checkout_session state and, when available, a transaction object with the approved charge. Optional: ?expand=refunds to 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_id and client_secret on the server only.
  • Persist the latest access_token and refresh_token securely (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_token
  • refresh_token — your stored refresh token
  • client_id, client_secret
  • redirect_uri — empty string ("") when not used
  • scope — 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=password
  • client_id, client_secret
  • username, 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.

POST https://uatstage00-api.rapidcents.com/api/oauth/token

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
Required

Must match URL-encoded form body (e.g. cURL --data-urlencode).

application/x-www-form-urlencoded

Accept string
Required

JSON response.

application/json

Authorization string

Bearer access token when your deployment requires this header on the token endpoint.

Bearer <token> · e.g. Bearer eyJ…

Body

Content-Typeapplication/x-www-form-urlencoded

Form fields are sent as application/x-www-form-urlencoded (not JSON). This table covers grant_type=refresh_token only.

grant_type string
Required

Must be refresh_token for the primary reauthorization step.

refresh_token

client_id string
Required

Public client id from the dashboard.

Non-empty string · e.g. "rc_…"

client_secret string
Required

Secret; server-side only—never in browsers or logs.

String from dashboard · e.g. "…"

refresh_token string
Required

Current refresh token; store encrypted at rest.

Opaque string · e.g. "def50200…"

redirect_uri string
Required

Send an empty string when your integration does not use redirect-based OAuth on refresh.

""

scope string

Often sent as an empty string; include a value only if your deployment requires scope on refresh.

"" or space-delimited string

Responses

200 422

Typical success body from the token endpoint:

Body

Content-Typeapplication/json
access_token string
Required

Use as Authorization: Bearer on API calls. Server only.

Opaque string · e.g. "eyJ…"

token_type string
Required

Usually Bearer.

e.g. "Bearer"

expires_in integer
Required

Access token lifetime in seconds; refresh before expiry.

e.g. 3600

refresh_token string

For refresh grants; may rotate each use.

Opaque string · e.g. "…"

cURL — refresh token (primary)

Refresh token
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

Content-Typeapplication/x-www-form-urlencoded

Same endpoint and headers as refresh; only the form fields differ.

grant_type string
Required

Password grant fallback when refresh is no longer valid.

password

client_id string
Required

Same API client as refresh.

Non-empty string

client_secret string
Required

Server-side only.

String from dashboard

username string
Required

RapidCents account email stored on your server.

e.g. merchant@example.com

password string
Required

RapidCents account password stored on your server (encrypted at rest).

Non-empty string

cURL — password grant (fallback)

Password grant
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:

Header
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 to grant_type=password with 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_token and refresh_token returned 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 example https://shop.example.com). It must match the origin registered for your API client in RapidCents.
  • Content-Type: application/json and Accept: application/json unless 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
Required

Access token from POST …/oauth/token. Server only.

Bearer <token> · e.g. Bearer eyJhbG…

Origin string
Required

Your app’s public HTTPS origin; must match the OAuth client registration.

HTTPS URL · e.g. https://shop.example.com

Content-Type string
Required

JSON request body.

application/json

Accept string
Required

JSON response.

application/json

Example: create session (embedded)

Staging. Full body field tables are in each mode guide.

cURL
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:

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.

GET {API origin}/api/{business_id}/checkout/{session_token}/details

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 (staging)
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.

Example response (illustrative, paid)
{
    "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_status reflect completion.
  • transactionnull if no card attempt yet; when paid, includes approval fields and transactionID for support and reconciliation.
  • Optional query ?expand=refunds — when the session has a successful charge, includes a refunds array 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) — Required checkout.js at {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_url after create succeeds.
  • RapidPay — After server v1/checkout-pay, use required rapid.js with data-checkout-url to inject the checkout_url in an iframe ({API origin}/js/rapid.js).
  • If you use postMessage, verify event.origin matches the checkout URL origin (and for embedded, that event.source is 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.create with ui_mode: embedded) so the library mounts the iframe and handles postMessage (rc:checkout_height, rc:checkout_result), or create the session on your server and set the iframe src to checkout_url yourself. Always validate e.source and e.origin if you listen for messages. See Embedded → checkout.js.
  • Hosted — After 200, send the browser to checkout_url with 302 or 303 (prefer 303 after a POST “start checkout” so the form is not resubmitted). The shopper returns to your success_url or cancel_url when checkout finishes.
  • RapidPayv1/checkout-pay does not accept success_url / cancel_url in the body. Mount checkout_url in the browser with rapid.js (data-checkout-url), then handle postMessage (or the rapidcents-checkout event) as needed; confirm payment server-side before fulfillment.
  • Subscriptions — Same success_url / cancel_url behaviour as one-time checkout/create when 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.
  • Origin must 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 token and 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 mismatchOrigin does 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 URLssuccess_url / cancel_url not absolute HTTPS where the API requires them.
  • Amounts — Use decimal amounts to the precision the API expects; avoid floating-point drift in application code.