Quickstart

Build a complete sandbox flow in one pass: authenticate, discover your organisation, create a booking, create a payment link, take a test payment, and verify the resulting transaction.

What you will do

  1. Create a sandbox account and generate API keys
  2. Exchange your public and private keys for a bearer token
  3. Fetch your organisation ID
  4. Create a booking
  5. Create a payment link for that booking
  6. Complete a sandbox payment with a test card
  7. Verify the transaction reached COMPLETE

Before you begin

  • Create a sandbox account at register.felloh.com
  • Generate a sandbox public key and private key from the Felloh dashboard
  • Export them as environment variables:

Environment Variables

export FELLOH_PUBLIC_KEY='your-sandbox-public-key'
export FELLOH_PRIVATE_KEY='your-sandbox-private-key'

If you are testing locally, keep the Testing page open for sandbox cards and go-live checks.

Full docs: Authentication, API Keys, and Testing.


1. Authenticate to the sandbox API

Call POST /token with your key pair. The response contains a short-lived bearer token you will use for the rest of the quickstart.

Create a Bearer Token

POST
/token
const baseUrl = 'https://sandbox.felloh.com'

const response = await fetch(`${baseUrl}/token`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    public_key: process.env.FELLOH_PUBLIC_KEY,
    private_key: process.env.FELLOH_PRIVATE_KEY,
  }),
})

if (!response.ok) {
  throw new Error(`Authentication failed: ${response.status}`)
}

const json = await response.json()
const token = json.data.token

console.log('Bearer token:', token)

Example Response

{
  "data": {
    "type": "BEARER",
    "token": "eyJhbGciOi..."
  },
  "errors": [],
  "meta": {
    "code": 200,
    "reason": "OK"
  }
}

Full docs: Authentication.


2. Fetch your organisation ID

Most API calls require an organisation ID. Fetch the organisations available to the authenticated user, then use the one you want to work with.

List Organisations

GET
/user/organisations
const response = await fetch('https://sandbox.felloh.com/user/organisations', {
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${token}`,
  },
})

if (!response.ok) {
  throw new Error(`Failed to fetch organisations: ${response.status}`)
}

const json = await response.json()
const organisationId = json.data[0].id

console.log('Organisation ID:', organisationId)

Example Response

{
  "data": [
    {
      "id": "X00001",
      "name": "Felloh Travel Sandbox"
    }
  ]
}

Full docs: Organisations.


3. Create a booking

Every Felloh payment flow starts with a booking. This is the core difference from generic payment platforms: the payment is linked to business context from the beginning.

Create a Booking

PUT
/agent/bookings
const bookingReference = `QS-${Date.now()}`

const response = await fetch('https://sandbox.felloh.com/agent/bookings', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${token}`,
  },
  body: JSON.stringify({
    organisation: organisationId,
    booking_reference: bookingReference,
    customer_name: 'Alex Example',
    email: 'alex@example.com',
    departure_date: '2026-08-15',
    return_date: '2026-08-22',
    gross_amount: 100000,
    currency: 'GBX',
  }),
})

if (!response.ok) {
  throw new Error(`Failed to create booking: ${response.status}`)
}

const json = await response.json()
const bookingId = json.data.id

console.log('Booking ID:', bookingId)
console.log('Booking reference:', bookingReference)

Example Response

{
  "data": {
    "id": "226009ab-ffe9-4c80-922b-982e8e7849f8"
  }
}

Full docs: Bookings.


For the quickest first integration, use a payment link. It gives you a hosted payment page without needing frontend SDK work yet.

Create a Payment Link

PUT
/agent/payment-links
const response = await fetch('https://sandbox.felloh.com/agent/payment-links', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${token}`,
  },
  body: JSON.stringify({
    organisation: organisationId,
    booking_id: bookingId,
    customer_name: 'Alex Example',
    email: 'alex@example.com',
    amount: 25000,
    currency: 'GBX',
    type: 'UNKNOWN',
    description: 'Quickstart deposit',
    card_enabled: true,
    open_banking_enabled: true,
  }),
})

if (!response.ok) {
  throw new Error(`Failed to create payment link: ${response.status}`)
}

const json = await response.json()
const paymentLinkId = json.data.id

console.log('Payment link ID:', paymentLinkId)

Example Response

{
  "data": {
    "id": "b5e1bd24-7379-4d27-b4d8-07120fefc25c"
  }
}

Full docs: Payment Links.


5. Complete a sandbox payment

Open the hosted payment page for the link you just created and complete a test payment.

Use a successful sandbox card from Testing, for example:

  • Card number: 4242 4242 4242 4242
  • Expiry date: any future date
  • CVC: any 3 digits
  • Cardholder name: any value

Once the payment is submitted, wait a few seconds for the resulting transaction to be created.

If you are building an embedded checkout instead of a hosted payment link flow, move next to the Ecommerce and JavaScript SDK docs after finishing this quickstart.

Full docs: Testing, Payment Links, Ecommerce, and JavaScript SDK.


6. Verify the transaction

The fastest verification path is to search transactions using the booking reference you created above.

Search Transactions

POST
/agent/transactions
const response = await fetch('https://sandbox.felloh.com/agent/transactions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${token}`,
  },
  body: JSON.stringify({
    organisation: organisationId,
    keyword: bookingReference,
    statuses: ['COMPLETE'],
    take: 10,
    skip: 0,
  }),
})

if (!response.ok) {
  throw new Error(`Failed to search transactions: ${response.status}`)
}

const json = await response.json()
const transaction = json.data[0]

console.log('Transaction status:', transaction?.status)
console.log('Transaction ID:', transaction?.id)
console.log('Amount:', transaction?.amount)

You now have a working end-to-end sandbox flow:

  • authentication works
  • your organisation context is correct
  • bookings can be created
  • payment links can be created
  • sandbox payments become transactions

Full docs: Transactions, Errors, and Pagination.


7. Add a webhook before going live

Polling is fine for a quickstart. Production integrations should use webhooks so your system updates automatically when payments and refunds change state.

Recommended next step:

  1. Expose a local endpoint with ngrok http 4242
  2. Register the webhook in the Felloh dashboard
  3. Subscribe to the events you need
  4. Verify the X-Signature header on every request

The full implementation details are in Webhooks.

Full docs: Webhooks and Integration Security Guide.


Next steps