# n8n

> Install the official Railbed node in n8n to start workflows from signed payment events, create checkout sessions, look up payments, orders and customers, and mark orders fulfilled. Works in workflows and as a tool for n8n's AI agents.

Source: https://railbed.com/docs/guides/n8n/ · Updated: 2026-10-12 · Railbed by MediaGlobe developer docs

For AI assistants: the index of every docs page, with the rules for an integration, is https://railbed.com/docs/llms.txt

> [!NOTE]
> The Railbed node isn't available to install yet. Until it is, connect n8n with its own HTTP Request and Webhook nodes, as [Without the node](#without-the-node) shows. This page will say when the node is ready.

## What you get

The Railbed package for [n8n](https://n8n.io) adds two nodes and one credential:

- **Railbed Trigger** starts a workflow when a payment starts, is paid, needs your review or closes unpaid. It subscribes itself when you publish the workflow and checks every event's signature before anything runs.
- **Railbed** creates checkout sessions and reads or updates your records. n8n's AI Agent can also use it as a tool.
- **Railbed API** is the credential both nodes use: one secret key.

| Resource | Operations |
|---|---|
| Checkout session | Create (returns the link to send the buyer), Get, Start (for a checkout page you build yourself) |
| Payment | Get, Get Many (filter by status, reference or date), Simulate (Test mode only) |
| Order | Get, Get Many, Update Fulfillment, Record Cancellation or Refund |
| Customer | Get, Get Many (or find one by email) |
| Webhook endpoint | Create, Get, Get Many, Delete |

Build and test everything in **Test mode** first (turn it on in the business block at the top of the sidebar). Test payments move no money, and Test and Live each have their own keys, endpoints and records.

## Install the node

The package is `@railbed/n8n-nodes-railbed`.

**Self-hosted n8n.** An owner or admin of the n8n instance installs it once:

1. In n8n, open **Settings → Community Nodes** and choose **Install**.
2. Enter `@railbed/n8n-nodes-railbed`, confirm that you understand the risks of installing code from a public source, and choose **Install**.
3. Search the nodes panel for "Railbed". Everyone on the instance can now use it.

If your n8n is managed with configuration rather than the Settings page, follow n8n's guide to [installing community nodes](https://docs.n8n.io/integrations/community-nodes/installation/).

**n8n Cloud.** n8n Cloud only offers community nodes that n8n has reviewed and verified. Railbed's node has been submitted for that review and isn't verified yet, so for now it works on self-hosted n8n only. Once it's verified, an owner or admin will find it by searching the nodes panel for "Railbed" and choosing **Install**, with no settings to change.

## Connect your Railbed account

1. In Railbed, open [Developers](https://app.railbed.io/developers) in the mode you're building in and choose **Create key**. Name it after the workflow or the n8n instance, such as "n8n: fulfilment". Keep **Full access** if the workflow uses the trigger, creates checkout sessions or updates orders; a **Read only** key is enough for workflows that only look things up. The key is shown once, so copy it now.
2. In n8n, add a **Railbed** or **Railbed Trigger** node and, under **Credential to connect with**, choose **Create new credential**.
3. Paste the key into **Secret Key** and leave **Base URL** as it is. Save: n8n checks the key by reading one payment.

A key starting `rb_test_` works only with Test data and one starting `rb_live_` only with Live data, so make one credential for each mode and name them so you can tell them apart, such as "Railbed (Test)". Your key is stored encrypted in n8n's credentials, not in the workflow, and anyone who can use the credential in your n8n can act with it.

## The Railbed Trigger

1. Add the **Railbed Trigger** node and choose its credential (a **Full access** key: subscribing adds a webhook endpoint).
2. Under **Events**, choose what starts the workflow. **Payment Paid** is the one to fulfil orders from.
3. Choose **Listen for test event** (n8n's **Execute step**). n8n adds a temporary endpoint for its test address. In Railbed, open [Developers](https://app.railbed.io/developers), find the endpoint whose description starts with "n8n:" and choose **Send test event**, or [simulate a Test payment](#simulate-a-test-payment). The event appears in n8n. In Live mode, **Send test event** sends only a ping, which the trigger acknowledges without running the workflow, so test with a Test credential.
4. Build the rest of the workflow, then publish it (in older versions of n8n, turn it on). n8n adds the workflow's own endpoint, described as "n8n:" and the workflow's name.

Unpublishing the workflow (or turning it off) removes its endpoint. If you change the events, or n8n's address changes, the trigger replaces its endpoint the next time the workflow is published. If you revoke the key the credential uses, Railbed removes the endpoints that key added: put a new key in the credential and publish the workflow again.

| Event | What it means |
|---|---|
| Payment Paid | The money arrived and passed every check. Fulfil orders on this event only |
| Payment Held | Money arrived but failed a check, so it waits for your decision in [Payments](https://app.railbed.io/payments). Don't fulfil yet ([held payments](https://railbed.com/docs/user-guide/held-payments.md)) |
| Payment Started | The buyer entered their email and was given a way to pay. Useful for abandoned-checkout follow-ups |
| Payment Updated | A paid payment's settlement details were filled in later |
| Payment Expired | Nobody paid in time. Money that arrives later still settles and sends Payment Paid or Payment Held |
| Payment Canceled | You canceled a payment link before anyone started paying |
| Payment Failed | A Test payment ended in a simulated failure |

Each event comes out of the trigger as Railbed sent it: `type`, `id` (`evt_…`), `livemode`, and `data` with the `payment`, its `order` and the `customer` ([every field](https://railbed.com/docs/webhooks/events.md)). In expressions that looks like `{{ $json.data.payment.amount }}` or `{{ $json.data.order.displayNumber }}`. The trigger adds `sample`, which is `true` for the made-up payment that **Send test event** sends. That payment and its order (`ord_sample`) aren't in your account, so put an **If** node on `{{ $json.sample }}` being false before any step that looks them up or fulfils anything, as the [example workflows](#examples) do.

Railbed may deliver an event more than once, and **Resend** in the delivery log sends the same event again. To act on each event only once, add n8n's **Remove Duplicates** node right after the trigger, choose **Remove Items Processed in Previous Executions**, and set **Value to Dedupe On** to `{{ $json.id }}`.

Under **Options**, **Include Current Payment** reads the payment from the API as well and adds it as `currentPayment`. Events can arrive out of order; the API's answer is always the payment as it is now.

> [!IMPORTANT]
> The trigger tells Railbed the event was received as soon as its signature checks out, before the rest of the workflow runs. A step that fails later shows in n8n's **Executions**, not in Railbed's delivery log, and Railbed won't send the event again. Set an error workflow in the workflow's settings if a failed step must reach you.

### n8n's address

Railbed sends Live events only to a public `https://` address, and its servers can't reach `localhost` on your computer. If n8n runs on your own machine, give it a public address, for example through a tunnel, and set n8n's `N8N_WEBHOOK_URL` setting to it (`WEBHOOK_URL` in versions before 2.35). n8n Cloud and most hosted n8n already have one.

Each mode allows 10 webhook endpoints. Every published workflow with a Railbed Trigger holds one, and so does a trigger while it listens for a test event.

## Example workflows

### Add each paid payment to a sheet and tell the team

1. **Railbed Trigger** with **Payment Paid**.
2. **Google Sheets → Append Row**, with columns mapped like these:

| Column | Expression |
|---|---|
| Paid at | `{{ DateTime.fromMillis($json.data.payment.paidAt).toISO() }}` |
| Order | `{{ $json.data.order.displayNumber }}` |
| Customer | `{{ $json.data.payment.customerEmail }}` |
| Amount | `{{ $json.data.payment.amount }}` |
| Currency | `{{ $json.data.payment.currency }}` |
| Received | `{{ $json.data.payment.merchantReceived }}` |
| Payment | `{{ $json.data.payment.id }}` |

3. **Slack → Send Message**, such as `Paid: {{ $json.data.order.summary }}, {{ $json.data.payment.amount }} {{ $json.data.payment.currency }}`.

`amount` is the price you set, and `merchantReceived` is what reached your payout wallet after fees, in dollars, once it's reported (it can be empty at first and arrive with Payment Updated). Keep amounts in their own currency; don't add USD and EUR together.

### Fulfil the order, then mark it fulfilled

1. **Railbed Trigger** with **Payment Paid**.
2. Your shipping, licence or delivery step. When it must happen only once, put **Remove Duplicates** on the event's `id` before it (see [the trigger](#the-railbed-trigger)), and check in your own system for the payment's id, which also covers a workflow you rebuilt.
3. **Railbed → Order → Update Fulfillment**, with **Order ID** `{{ $('Railbed Trigger').item.json.data.order.id }}` and **Fulfillment** set to **Fulfilled**. The order's timeline in Railbed records it.

If your store refunds or cancels the order itself, **Order → Record Cancellation or Refund** notes it on the order's timeline. It moves no money: Railbed can't send money back to a buyer.

### Create a checkout session and email the link

1. Your trigger, such as a form submission or a new deal in your CRM. If it's n8n's **Webhook** node, set its **Authentication** (such as **Header Auth**) so only your CRM can call it: anyone with the address could otherwise create checkout links in your name. Check that the fields you need arrived (an **If** node) before creating anything.
2. **Railbed → Checkout Session → Create**, with **Amount** (decimal text, such as `49.00`; a number with more than two decimals is refused, not rounded), **Currency** and **Description**. Under **Additional Fields**, add **Customer Email**, a **Reference** (your own order id) and an **Idempotency Key** that is unique to this order, such as the form entry's id: if n8n runs the step again, you get the same session back instead of a second one.
3. **Gmail → Send** (or any email node) to the buyer with the session's `url`.

When the buyer pays, a workflow with the Railbed Trigger receives Payment Paid with your reference in `data.payment.reference`. Sessions stay open for 24 hours; every field is in [Create a checkout session](https://railbed.com/docs/api/checkout-sessions.md#create-a-checkout-session).

### Let an AI agent look things up

Connect the **Railbed** node to an **AI Agent** node's **Tool** input, choose the resource and operation, and let the model fill in fields with **Let the model define this parameter**. Good fits are questions like "has my store's order 1042 been paid?" (**Order → Get Many** filtered by **Store Order ID**) or "what did nathan@example.com buy?" (**Customer → Get Many** filtered by email).

Give agent tools a **Read only** key unless the agent needs to create sessions or update orders, and give each tool node one operation, so the agent can do only what you chose. Fulfil orders from the Railbed Trigger and a paid payment, not from what an agent says happened.

## Test mode first

With a Test credential you can run a whole payment without a card:

1. **Checkout Session → Create** with a Test amount.
2. **Checkout Session → Start** with the session's id and a **Customer Email** under **Additional Fields**.
3. **Payment → Simulate** with the same id and an **Outcome**: **Paid**, **Underpaid** (the payment is held for your decision), **Declined** (it stays open for another try) or **Failed**.

Your Test trigger receives the same events a real payment would send. Use a new session for each scenario; a finished payment keeps its outcome. When it all works, make a Live key, a second credential, and switch the workflow's nodes to it.

## Without the node

If you can't install community nodes, n8n's built-in nodes still work with Railbed:

- **Call the API** with the **HTTP Request** node. Use a **Header Auth** credential with the name `Authorization` and the value `Bearer` followed by a space and your secret key. Requests and responses are in the [API reference](https://railbed.com/docs/api.md), such as `POST https://pay.railbed.io/v1/checkout_sessions`.
- **Receive events** with the **Webhook** node: add its production address as an endpoint in [Developers](https://app.railbed.io/developers), turn on the node's **Raw Body** option, and check the `Railbed-Signature` header in a **Code** node exactly as [Verify signatures](https://railbed.com/docs/webhooks/signatures.md) describes before any other step. The signature covers the exact bytes Railbed sent, so check the raw body, never JSON that n8n parsed and wrote out again.

The node does both for you, so prefer it when you can.

## Troubleshooting

| Symptom | Likely cause |
|---|---|
| The credential test fails | The key was revoked or copied with a space, or it's for the other mode. Create a new key in [Developers](https://app.railbed.io/developers) |
| Publishing says Railbed can't send events to this n8n address | n8n's address is `localhost` or `http://`. Set `N8N_WEBHOOK_URL` to a public `https://` address ([n8n's address](#n8n-address)) |
| Listening for a test event never receives anything | n8n's address isn't reachable from the internet, or you sent the test event from another endpoint. Check the endpoint's delivery log in Developers |
| `insufficient_scope` | The key is **Read only**. The trigger, creating sessions and updating orders need a **Full access** key |
| `too_many` | This mode already has 10 webhook endpoints. Remove ones you no longer use in Developers |
| Deliveries fail with "The signature does not match" | Someone rolled the endpoint's secret in Developers, and the old secret stopped working after 24 hours. Unpublish the workflow and publish it again, which subscribes with a new secret. Within those 24 hours, restarting n8n or publishing again replaces the endpoint by itself |
| `not_found` for a record you can see in Railbed | The credential is for the other mode: a Test key can't see Live records, and a Live key can't see Test ones |
| A lookup fails after **Send test event** | The event's payment is a sample (`sample` is `true`) and isn't in your account. Skip it with an **If** node on `{{ $json.sample }}` |
| An endpoint called "n8n: …" stays in Developers after you switched keys | The trigger subscribed again in the new key's mode. Remove the old one in Developers |
| A step should carry on when Railbed refuses a request | Set the node's **On Error** to continue. The failed item then has `error`, `code` (Railbed's error code, such as `not_found`), `httpCode` and `description`, so an **If** node can branch on `code` |
| The AI Agent doesn't offer Railbed as a tool | Check that the instance is on a recent version of n8n. Some self-hosted versions offer community nodes as tools only when `N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE` is `true` |

- [Event types](https://railbed.com/docs/webhooks/events.md): Every event, what it means and the full payload
- [Fulfil orders safely](https://railbed.com/docs/guides/fulfilment.md): Deliver each order once, only for money that arrived
- [Webhook endpoints](https://railbed.com/docs/api/webhook-endpoints.md): How the trigger subscribes, and how to do the same from code
