# Quickstart

> Take your first payment in Test mode in about ten minutes. Create a secret key, create a checkout session, pay it as a buyer, and confirm it from your server.

Source: https://railbed.io/docs/quickstart/ · Updated: 2026-09-26 · Railbed by DeepWork developer docs

## Before you start

You need a Railbed account ([sign up](https://app.railbed.io/signup) takes a minute) and a terminal. Everything below runs in **Test mode**: no card is charged and no money moves. The same code works in Live mode with a live key.

## 1. Create a secret key

In the dashboard, switch to **Test** mode, open [Developers](https://app.railbed.io/developers) and choose **Create key**. Name it after the server that will use it, for example "Store backend". The key starts with `rb_test_` and is shown once: copy it into your server's environment.

Your server's environment:

```bash
export RAILBED_SECRET_KEY="rb_test_…"
```

> [!IMPORTANT]
> A secret key can create checkouts and read your payments. Keep it on your server. Never put it in a web page, a mobile app or a repository. If one leaks, revoke it in Developers and create another.

## 2. Create a checkout session

A checkout session is one payment for one order: a fixed amount, a currency, and your order's reference. Send an `Idempotency-Key` so a retried request can never create a second payment.

cURL:

```bash
curl https://pay.railbed.io/v1/checkout_sessions \
  -H "Authorization: Bearer $RAILBED_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order_1042" \
  -d '{
    "amount": "49.00",
    "currency": "USD",
    "description": "Pro Membership",
    "reference": "order_1042",
    "customer_email": "buyer@example.com",
    "success_url": "https://yourstore.com/thanks?order={REFERENCE}"
  }'
```

Node.js:

```js
const res = await fetch('https://pay.railbed.io/v1/checkout_sessions', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.RAILBED_SECRET_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': 'order_1042',
  },
  body: JSON.stringify({
    amount: '49.00',
    currency: 'USD',
    description: 'Pro Membership',
    reference: 'order_1042',
    customer_email: 'buyer@example.com',
    success_url: 'https://yourstore.com/thanks?order={REFERENCE}',
  }),
});
const session = await res.json();
console.log(session.url);
```

Python:

```python
import os, requests

session = requests.post(
    "https://pay.railbed.io/v1/checkout_sessions",
    headers={
        "Authorization": f"Bearer {os.environ['RAILBED_SECRET_KEY']}",
        "Idempotency-Key": "order_1042",
    },
    json={
        "amount": "49.00",
        "currency": "USD",
        "description": "Pro Membership",
        "reference": "order_1042",
        "customer_email": "buyer@example.com",
        "success_url": "https://yourstore.com/thanks?order={REFERENCE}",
    },
    timeout=15,
).json()
print(session["url"])
```

PHP:

```php
<?php
$ch = curl_init('https://pay.railbed.io/v1/checkout_sessions');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . getenv('RAILBED_SECRET_KEY'),
    'Content-Type: application/json',
    'Idempotency-Key: order_1042',
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'amount' => '49.00',
    'currency' => 'USD',
    'description' => 'Pro Membership',
    'reference' => 'order_1042',
    'customer_email' => 'buyer@example.com',
    'success_url' => 'https://yourstore.com/thanks?order={REFERENCE}',
  ]),
]);
$session = json_decode(curl_exec($ch), true);
echo $session['url'];
```

The response is the new session. Save its `id` (`pay_…`) with your order.

Response · response 201 Created:

```json
{
  "id": "pay_7AAiYH0Ykt11ED4hmfiN",
  "object": "checkout_session",
  "url": "https://pay.railbed.io/p/pay_7AAiYH0Ykt11ED4hmfiN",
  "status": "open",
  "livemode": false,
  "amount": "49.00",
  "currency": "USD",
  "description": "Pro Membership",
  "reference": "order_1042",
  "customer_email": "buyer@example.com",
  "created": 1790380525,
  "expires_at": 1790466925,
  "started_at": null,
  "metadata": null
}
```

## 3. Pay as a buyer

Open the session's `url` in a browser. Continue with the email, pick a card provider and choose **Pay**. In Test mode the provider's page is replaced by Railbed's test provider, where **Simulate successful payment** stands in for entering a card. The checkout tab then shows the payment as paid and takes the buyer to your `success_url`, with `{REFERENCE}` filled in.

## 4. Confirm the payment from your server

The redirect is for the buyer's comfort, not proof of payment. Confirm it from your server, with the same key:

cURL:

```bash
curl https://pay.railbed.io/v1/payments/pay_7AAiYH0Ykt11ED4hmfiN \
  -H "Authorization: Bearer $RAILBED_SECRET_KEY"
```

Node.js:

```js
const res = await fetch(`https://pay.railbed.io/v1/payments/${paymentId}`, {
  headers: { Authorization: `Bearer ${process.env.RAILBED_SECRET_KEY}` },
});
const payment = await res.json();
if (payment.status === 'paid') fulfil(payment.reference);
```

Python:

```python
payment = requests.get(
    f"https://pay.railbed.io/v1/payments/{payment_id}",
    headers={"Authorization": f"Bearer {os.environ['RAILBED_SECRET_KEY']}"},
    timeout=15,
).json()
if payment["status"] == "paid":
    fulfil(payment["reference"])
```

PHP:

```php
<?php
$ch = curl_init('https://pay.railbed.io/v1/payments/' . rawurlencode($paymentId));
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('RAILBED_SECRET_KEY')],
]);
$payment = json_decode(curl_exec($ch), true);
if ($payment['status'] === 'paid') fulfil($payment['reference']);
```

Response (trimmed) · response 200 OK:

```json
{
  "id": "pay_7AAiYH0Ykt11ED4hmfiN",
  "object": "payment",
  "status": "paid",
  "livemode": false,
  "amount": "49.00",
  "currency": "USD",
  "reference": "order_1042",
  "paid_at": 1790381342,
  "provider": "stripe",
  "settlement": {
    "coin": "polygon_usdc",
    "value_coin": "47.53",
    "merchant_received": "44.915850",
    "txid_in": "0x0c65…582e",
    "txid_out": "0x8202…356f",
    "payout_wallet": "0xF977814e90dA44bFA03b6295A0616a897441aceC"
  }
}
```

Check that `status` is `paid` and that the id, amount, currency and reference match the order you saved, then fulfil it once.

## 5. Get told instead of asking

Polling works, but webhooks tell you the moment something happens. In [Developers](https://app.railbed.io/developers), choose **Add endpoint** and enter your server's `https://` address (while you build on your own computer, [use a tunnel](https://railbed.io/docs/testing.md#receive-webhooks-on-your-own-computer)). Copy the signing secret, then choose **Send test event** to see exactly what your server receives. [Webhooks](https://railbed.io/docs/webhooks.md) covers the events and [verifying signatures](https://railbed.io/docs/webhooks/signatures.md).

## Next

- [Fulfil orders safely](https://railbed.io/docs/guides/fulfilment.md): The checks that make fulfilment correct even with retries, late payments and reviews.
- [Your own checkout](https://railbed.io/docs/guides/custom-checkout.md): Show card providers in your own screen instead of redirecting.
- [Testing](https://railbed.io/docs/testing.md): Simulate underpayments and declines, and send sample events.
- [Going live](https://railbed.io/docs/testing.md#going-live): The short checklist before real payments.
