RailbedDocs

Hosted checkout

Create a checkout session for each order on your server, send the buyer to Railbed's hosted page, and bring them back to your store once they've paid.

How it works

Your server creates a checkout session for the order and redirects the buyer to its url. Railbed's page asks for the buyer's email, shows the card providers that can take this payment in their country (the recommended one first), and opens the chosen provider in a new tab. The checkout tab waits there while the buyer pays, then sends them to your success_url.

  1. Order placed. Your server saves the order, then calls POST /v1/checkout_sessions.
  2. Redirect. Your server sends the buyer to the session's url.
  3. Payment. The buyer pays on the provider's page, in its own tab.
  4. Return. The Railbed tab sees the payment confirmed and sends the buyer to your success_url.
  5. Fulfilment. Your server fulfils the order from the payment.paid webhook or GET /v1/payments/:id, never from the return alone.

Create the session

Create one session per order attempt, with an Idempotency-Key saved alongside the order before you call. A retry after a timeout then returns the same session instead of creating a second one.

// POST /checkout on your server, after saving the order
app.post('/checkout', async (req, res) => {
  const order = await orders.create({
    userId: req.user.id,
    sku: 'pro-monthly',
    price: '49.00',
    currency: 'USD',
  });

  const response = 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_${order.id}`,
    },
    body: JSON.stringify({
      amount: order.price,
      currency: order.currency,
      description: 'Pro Membership · monthly',
      reference: `order_${order.id}`,
      customer_email: req.user.email,
      metadata: { user_id: String(req.user.id) },
      success_url:
        `https://yourstore.com/orders/${order.id}/thanks?payment={PAYMENT_ID}`,
      cancel_url: `https://yourstore.com/cart`,
    }),
  });
  if (!response.ok) {
    return res.status(502).send(
      'Checkout is unavailable. Try again in a moment.',
    );
  }
  const session = await response.json();

  await orders.update(order.id, { paymentId: session.id });
  res.redirect(303, session.url);
});

Return URLs

FieldWhen the buyer sees it
success_urlOnce the payment is confirmed, the Railbed checkout tab sends the buyer here. {PAYMENT_ID} and {REFERENCE} in the address are replaced with the payment's id and your reference
cancel_urlA link back to your store, named after your business, while the buyer is paying and after a decline or an expiry

Both are optional, must be full https:// addresses in Live mode (Test also accepts http://), up to 1,000 characters, and can't contain a username or password. Without a success_url, the buyer sees Railbed's own confirmation.

What the buyer sees

  • The order. Your business name and logo, the description and the price, in the currency you set.
  • Their email. Prefilled when you send customer_email. Providers use it for their receipt.
  • Card providers. Only those that serve the buyer's country, take the currency and accept the amount, the recommended one first. The buyer pays on the provider's page.
  • Waiting. The checkout tab says to finish paying in the provider's tab and updates by itself. If the browser blocks the new tab, the provider opens in the same tab instead.
  • The result. Paid, being reviewed (held), declined or expired, each with a clear next step.

A session can be paid for 24 hours. After that it's expired; create a new one if the buyer comes back.

When there's no provider

Providers have minimum amounts and regional limits. When none can take a payment, the checkout says so and asks the buyer to try later. You can check in advance by starting the session through the API: POST /v1/checkout_sessions/:id/start answers 409 no_providers. Orders of a few dollars are the most likely to hit provider minimums.

Updated · This page as Markdown