Checkouts
Create reusable checkout pages from your own code and get the slug a buy button takes. Every buyer who pays one gets their own payment. The same checkouts you make in the dashboard.
On this page
The checkout object
A checkout is a reusable page with a fixed price, such as a product, a course or a donation: share its link, or put a buy button on your site, and every buyer who pays gets their own payment and order. It's the same checkout you can make under Checkouts in the dashboard. For one amount from one payer, use a payment link; for an order your server prices, a checkout session.
| Field | Type | Description |
|---|---|---|
id | string | The checkout's id, chk_… |
object | string | "checkout" |
kind | string | page, pricing_table or widget. The API creates pages; the others are made in the dashboard |
slug | string | What a buy button takes: <railbed-button checkout="mug4k7tq2z"> |
url | string | The hosted checkout page. Share it, or link to it |
livemode | boolean | false for Test mode, true for Live mode |
active | boolean | false once it was deleted in the dashboard; a deleted checkout takes no new buyers |
name | string | Shown to buyers |
description | string or null | Shown under the name |
amount | string | The price. A pricing table's lowest plan price |
currency | string | USD, EUR, GBP, CAD or AUD |
success_url | string or null | Where buyers land once paid |
theme | string | light or dark |
button_label | string or null | The pay button's text, or null for "Continue to pay" and the price |
crypto | boolean | Whether buyers may pay in crypto, when crypto payments are on for the account |
routing | object | How buyers reach a card provider: choice is smart (Smart Routing), buyer (buyers choose) or fixed (one provider, with fallback to Smart Routing when it can't take a buyer) |
collect | object or null | What the page asks buyers for besides their email, or null for nothing more. See The collect field |
options | array or null | A pricing table's two-way switch, such as ["Monthly", "Yearly"] |
plans | array | A pricing table's plans: id, name, description, prices (amount and unit), features and recommended. Empty for pages |
created | integer | When it was created, in Unix seconds |
updated | integer | When it last changed, in Unix seconds |
{
"id": "chk_Mg7tR2vX9kQp4WnZc8Lb",
"object": "checkout",
"kind": "page",
"slug": "mug4k7tq2z",
"url": "https://pay.railbed.io/c/mug4k7tq2z",
"livemode": false,
"active": true,
"name": "Ceramic mug",
"description": "Hand-thrown, 350 ml.",
"amount": "18.00",
"currency": "USD",
"success_url": "https://mugs.example/thanks",
"theme": "light",
"button_label": null,
"crypto": true,
"routing": {
"choice": "smart",
"provider": null,
"fallback": true
},
"collect": null,
"options": null,
"plans": [],
"created": 1790380525,
"updated": 1790380525
}Create a checkout
POST/v1/checkouts
Creates a checkout page in the key's mode, with the settings a new checkout starts with in the dashboard unless you send others.
| Parameter | Type | Description |
|---|---|---|
name | string Required | Shown to buyers, up to 80 characters |
amount | string Required | A decimal string from "1.00" to "100000.00", at most two decimals |
currency | string Required | USD, EUR, GBP, CAD or AUD, in any letter case |
description | string | Up to 280 characters |
success_url | string | Where buyers land once paid. Live mode needs https:// |
kind | string | page, the only kind the API creates for now |
theme | string | light (default) or dark |
button_label | string | The pay button's text, up to 32 characters |
crypto | boolean | Default true: buyers may pay in crypto when it's on for the account |
routing | object | Default { "choice": "smart" }. For one provider: { "choice": "fixed", "provider": "stripe", "fallback": true } |
collect | object | What the page asks buyers for besides their email, as on a checkout session |
curl https://pay.railbed.io/v1/checkouts \
-H "Authorization: Bearer $RAILBED_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Ceramic mug",
"description": "Hand-thrown, 350 ml.",
"amount": "18.00",
"currency": "USD",
"success_url": "https://mugs.example/thanks"
}'const checkout = await fetch('https://pay.railbed.io/v1/checkouts', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.RAILBED_SECRET_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Ceramic mug',
amount: '18.00',
currency: 'USD',
success_url: 'https://mugs.example/thanks',
}),
}).then((r) => r.json());
// checkout.slug goes in <railbed-button checkout="…">; checkout.url is the page.checkout = requests.post(
"https://pay.railbed.io/v1/checkouts",
headers={"Authorization": f"Bearer {os.environ['RAILBED_SECRET_KEY']}"},
json={
"name": "Ceramic mug",
"amount": "18.00",
"currency": "USD",
"success_url": "https://mugs.example/thanks",
},
timeout=15,
).json(){
"id": "chk_Mg7tR2vX9kQp4WnZc8Lb",
"object": "checkout",
"kind": "page",
"slug": "mug4k7tq2z",
"url": "https://pay.railbed.io/c/mug4k7tq2z",
"livemode": false,
"active": true,
"name": "Ceramic mug",
"description": "Hand-thrown, 350 ml.",
"amount": "18.00",
"currency": "USD",
"success_url": "https://mugs.example/thanks",
"theme": "light",
"button_label": null,
"crypto": true,
"routing": {
"choice": "smart",
"provider": null,
"fallback": true
},
"collect": null,
"options": null,
"plans": [],
"created": 1790380525,
"updated": 1790380525
}Put it on your site with the slug:
<script src="https://pay.railbed.io/embed.js" async></script>
<railbed-button checkout="mug4k7tq2z"></railbed-button>The checkout follows the dashboard editor's rules, and an error's field names the parameter you sent. This endpoint ignores Idempotency-Key: after a timeout, list your checkouts before creating another.
| Error | Cause |
|---|---|
400 invalid_kind | kind is something other than page |
400 missing_name, 400 too_long | name is empty, or a text field is over its limit |
400 invalid_description, 400 invalid_button_label | That field isn't a string |
400 invalid_amount | amount isn't a decimal string from "1.00" to "100000.00" |
400 invalid_currency | currency isn't one of the five |
400 invalid_url | success_url isn't a full address, has a username or password, or isn't https:// in Live mode |
400 invalid_theme, 400 invalid_value | theme isn't light or dark, or crypto isn't a boolean |
400 invalid_routing | routing names no choice, or a provider that can't take card payments |
400 invalid_collect | collect asks for something it can't. field names the part |
409 no_payout_wallet | Live mode, and the account has no payout wallet yet |
409 commerce_paused | The account has paused taking payments |
403 integration_disabled | Checkouts, or the API, are turned off for the account |
403 merchant_read_only | The account is suspended or archived |
Retrieve a checkout
GET/v1/checkouts/:id
Returns one of your checkouts in the key's mode, including one deleted in the dashboard (active: false). Another account's, or one in the other mode, is 404 not_found.
curl https://pay.railbed.io/v1/checkouts/chk_Mg7tR2vX9kQp4WnZc8Lb \
-H "Authorization: Bearer $RAILBED_SECRET_KEY"List checkouts
GET/v1/checkouts
Returns your active checkouts of every kind in the key's mode, newest first.
| Parameter | Type | Description |
|---|---|---|
limit | integer | 1–100. Default 20 |
starting_after | string | A checkout id from the previous page's next_cursor |
kind | string | Only page, pricing_table or widget |
curl https://pay.railbed.io/v1/checkouts \
-H "Authorization: Bearer $RAILBED_SECRET_KEY"{
"data": [
{
"id": "chk_Mg7tR2vX9kQp4WnZc8Lb",
"object": "checkout",
"kind": "page",
"slug": "mug4k7tq2z",
"url": "https://pay.railbed.io/c/mug4k7tq2z",
"livemode": false,
"active": true,
"name": "Ceramic mug",
"description": "Hand-thrown, 350 ml.",
"amount": "18.00",
"currency": "USD",
"success_url": "https://mugs.example/thanks",
"theme": "light",
"button_label": null,
"crypto": true,
"routing": {
"choice": "smart",
"provider": null,
"fallback": true
},
"collect": null,
"options": null,
"plans": [],
"created": 1790380525,
"updated": 1790380525
}
],
"has_more": false,
"next_cursor": null
}Changing or deleting a checkout happens in the dashboard. A checkout whose price changes there keeps its slug, so buttons already on your site show the new price.
Access
Retrieving and listing need the payments:read scope, which Read only keys have. Creating needs checkouts:write, which Full access keys and agents with full access have.