Migrating from Stripe
A practical guide for travel businesses migrating from Stripe to Felloh. This covers concept mapping, code migration patterns, and a step-by-step migration plan so you can move with confidence.
Felloh is purpose-built for travel payments. While Stripe is a general-purpose payment platform, Felloh's data model centres around bookings — the natural unit of work for travel businesses. This means some Stripe concepts map directly, some map differently, and some don't apply at all.
Concept mapping
This is the most important section. Understand how Stripe concepts translate to Felloh before writing any code.
Direct equivalents
These concepts map cleanly between the two platforms.
| Stripe | Felloh | Notes |
|---|---|---|
Customer | Customer | Nearly identical — name, email, address. Felloh customers are scoped to an organisation. |
Refund | Refund | Similar, but Felloh uses a two-stage process — refunds require separate authorisation. |
Webhook | Webhook | Same concept. Event types differ — see the event mapping below. |
PaymentLink | Payment Link | Similar — both generate a hosted payment page URL. Felloh payment links are tied to a booking. |
Different concepts
These Stripe concepts exist in Felloh but work differently.
| Stripe | Felloh | How it differs |
|---|---|---|
PaymentIntent | Payment Link / Ecommerce / Scheduled Payment | Stripe has one universal object for collecting payment. Felloh splits this into three tools depending on the scenario — see choosing a payment method. |
Charge | Transaction | A Felloh Transaction is the result of a completed payment. It's always linked to a Booking. |
Subscription | Scheduled Payment | Stripe subscriptions are recurring indefinitely. Felloh scheduled payments are one-off future charges — you create one per installment. |
SetupIntent + PaymentMethod | Tokenised Card | In Stripe, you explicitly save a card via SetupIntent. In Felloh, cards are automatically tokenised when a customer pays — you then retrieve tokens with the API to use for future charges. |
Connect (platform payouts) | Disbursements + Beneficiaries | Stripe Connect handles marketplace payouts. Felloh disbursements pay suppliers from trust accounts — a different model built for travel supply chains. |
Radar (fraud detection) | Fraud Shield | Stripe Radar uses ML-based fraud scoring. Felloh Fraud Shield provides configurable rule-based fraud prevention — 3DS rules, card rules, customer rules, device fingerprinting, location checks, and velocity limits. Configure via the Felloh Dashboard. |
Terminal (in-person) | Terminal | Felloh supports in-person payments via terminals. Speak to your account manager to get set up. |
No Felloh equivalent
These Stripe features don't have a Felloh counterpart because they're outside the travel payment domain.
| Stripe feature | What to do |
|---|---|
Product / Price | Felloh doesn't have a product catalog. Your booking system or CRM holds trip/product information. Pass the total as the booking gross_amount. |
Invoice | Not needed — Felloh bookings with payment links serve a similar purpose for travel. Use your own invoicing system if required. |
Subscription (recurring) | Felloh doesn't do recurring billing. Create individual scheduled payments for each installment. |
Tax | Handle tax in your own booking system. |
Identity | Use a separate KYC provider if required. |
The booking model
The most important conceptual shift is that every payment in Felloh is tied to a Booking. In Stripe, you can create a PaymentIntent with no context — just an amount and a customer. In Felloh, you always need a booking first.
Stripe flow:
Customer → PaymentIntent → Charge
(payment exists independently)
Felloh flow:
Customer → Booking → Payment Link / Ecommerce / Scheduled Payment → Transaction
(payment is always linked to a booking)
This means your migration needs to ensure that every payment has a corresponding booking. For most travel businesses, this is already how you think about payments — Felloh just makes it explicit.
If you currently use Stripe metadata to link payments to booking references, Felloh replaces that pattern entirely. The booking reference is a first-class field, not metadata.
Because every payment is tied to a booking, Felloh provides automatic reconciliation out of the box. Every payment — cards, open banking, and bank transfers — is automatically matched to its booking using 3-point verification, from initiation through to settlement in your bank account. This eliminates the manual spreadsheet work your finance team does today to match Stripe's bulk settlement payouts to individual bookings.
Felloh also provides automatic surcharging — when a customer enters their card details, Felloh detects whether it's a consumer, corporate, or international card and applies the correct compliant surcharge in real time. The customer sees the surcharge before confirming payment and can switch payment method if they prefer. This protects your margins on expensive card types without manual fee calculations or compliance guesswork.
Choosing a payment method
In Stripe, you always create a PaymentIntent. In Felloh, you choose based on the scenario:
| Scenario | Stripe | Felloh |
|---|---|---|
| Send customer a link to pay | PaymentLink or PaymentIntent + Checkout | create-payment-link |
| Embed payment in your app | PaymentIntent + Elements | create-ecommerce + Felloh SDK |
| Charge a saved card later | PaymentIntent with off_session | create-scheduled-payment |
| Charge a saved card now | PaymentIntent with confirm: true | create-scheduled-payment with today's date |
Code migration
Authentication
Stripe uses a single secret key. Felloh uses a public/private key pair to generate a bearer token.
Authentication
import Stripe from 'stripe';
const stripe = new Stripe('sk_live_...');
Felloh tokens are valid for a limited time. Cache and refresh them as needed. See the Authentication guide for full details.
Creating a customer
Create a customer
const customer = await stripe.customers.create({
name: 'Sarah Jones',
email: 'sarah@example.com',
address: {
line1: '10 Downing Street',
city: 'London',
postal_code: 'SW1A 2AA',
country: 'GB',
},
});
Creating a booking (new concept)
This has no Stripe equivalent — it's the step you add to your flow.
Create a booking
const response = await axios({
method: 'post',
url: 'https://api.felloh.com/agent/bookings',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
data: {
organisation: 'your-organisation-id',
booking_reference: 'TRIP-2026-001',
gross: 150000, // £1,500.00 in pence
currency: 'GBX',
customer_email: 'sarah@example.com',
customer_name: 'Sarah Jones',
departure_date: '2026-08-15',
return_date: '2026-08-22',
},
});
Collecting a payment
Collect a payment
// Create a PaymentIntent
const paymentIntent = await stripe.paymentIntents.create({
amount: 50000, // £500.00 in pence
currency: 'gbp',
customer: customer.id,
metadata: {
booking_ref: 'TRIP-2026-001', // Stored as metadata
},
});
// Use paymentIntent.client_secret with Stripe Elements on the frontend
Processing a refund
Process a refund
const refund = await stripe.refunds.create({
payment_intent: 'pi_...',
amount: 20000, // £200.00 partial refund
});
// Refund is processed immediately
Felloh's two-stage refund process is intentional — it prevents accidental refunds and supports compliance workflows where a manager must approve refunds. If you want to auto-authorise, call both endpoints sequentially in your code.
Scheduling a future payment
Schedule a future payment
// Save the card via SetupIntent
const setupIntent = await stripe.setupIntents.create({
customer: customer.id,
payment_method_types: ['card'],
});
// Later, charge off-session
const paymentIntent = await stripe.paymentIntents.create({
amount: 100000,
currency: 'gbp',
customer: customer.id,
payment_method: 'pm_...',
off_session: true,
confirm: true,
});
Currency mapping
Stripe uses standard ISO 4217 currency codes in lowercase. Felloh uses minor-unit currency codes.
| Stripe | Felloh | Unit |
|---|---|---|
gbp | GBX | Pence |
usd | USX | Cents |
eur | EUX | Euro cents |
Both platforms use minor units for amounts (pence/cents), so the numeric values are the same — only the currency code changes.
Currency conversion helper
const STRIPE_TO_FELLOH_CURRENCY = {
gbp: 'GBX',
usd: 'USX',
eur: 'EUX',
};
function convertCurrency(stripeCurrency) {
const fellohCurrency = STRIPE_TO_FELLOH_CURRENCY[stripeCurrency.toLowerCase()];
if (!fellohCurrency) {
throw new Error(`Unsupported currency: ${stripeCurrency}`);
}
return fellohCurrency;
}
// Amount values stay the same — both use minor units
// Stripe: { amount: 150000, currency: 'gbp' }
// Felloh: { amount: 150000, currency: 'GBX' }
Webhook event mapping
If you have existing Stripe webhook handlers, map them to Felloh events.
| Stripe event | Felloh event | Notes |
|---|---|---|
payment_intent.succeeded | transaction.completed | Payment was successful |
payment_intent.payment_failed | transaction.failed | Payment failed |
charge.refunded | refund.completed | Refund was processed |
charge.dispute.created | chargeback.created | Customer disputed a charge |
customer.created | No equivalent | Felloh does not emit customer events |
invoice.paid | No equivalent | Felloh does not have invoices |
Migrating a webhook handler
Webhook handler migration
app.post('/webhooks/stripe', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['stripe-signature'];
const event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
switch (event.type) {
case 'payment_intent.succeeded':
handlePaymentSuccess(event.data.object);
break;
case 'payment_intent.payment_failed':
handlePaymentFailure(event.data.object);
break;
case 'charge.refunded':
handleRefund(event.data.object);
break;
}
res.json({ received: true });
});
Stripe uses a custom signature scheme via its SDK. Felloh uses a standard HMAC-SHA256 signature in the x-signature header — you verify it directly without an SDK.
Migration plan
A step-by-step approach to moving from Stripe to Felloh without disrupting live operations.
Phase 1 — Set up and validate
- Create a Felloh account and generate sandbox API keys from the Sandbox Registration Form
- Set up authentication — implement token generation and caching
- Create a test booking and payment link to verify your integration works
- Connect the MCP server (optional) — useful for exploring the API interactively during migration
Phase 2 — Migrate customer and booking data
- Export customers from Stripe — use the Stripe API or Dashboard export
- Create customers in Felloh — map Stripe customer fields to Felloh fields
- Create bookings for any active reservations — this is the new step that doesn't exist in Stripe
- Map your existing booking references to Felloh bookings using the
booking_referencefield
Phase 3 — Migrate payment flows
- Replace PaymentIntent creation with the appropriate Felloh payment method:
- Checkout/PaymentLinks →
create-payment-link - Elements/embedded →
create-ecommerce - Off-session/saved cards →
create-scheduled-payment
- Checkout/PaymentLinks →
- Replace refund logic with Felloh's two-stage process
- Update webhook handlers to use Felloh event types
- Update your frontend if using Stripe Elements — replace with the Felloh SDK
Phase 4 — Test in sandbox
- Run through every payment flow in the Felloh sandbox
- Test edge cases: declined payments, partial refunds, expired tokens
- Verify webhook delivery and handling
- Confirm customer-facing emails and receipts are correct
Phase 5 — Go live
- Switch to production API keys
- Run Stripe and Felloh in parallel for a transition period if needed — new bookings go through Felloh, existing Stripe subscriptions complete naturally
- Monitor the Felloh Dashboard for transaction status
- Decommission Stripe integration once all active payments have settled
You don't need to migrate historical transaction data. Stripe retains your historical records, and Felloh starts fresh with new bookings. Keep your Stripe account active in read-only mode for historical reporting.
Common migration questions
Can I run Stripe and Felloh in parallel? Yes. Route new bookings to Felloh and let existing Stripe payment schedules complete. There's no conflict between the two.
Do I need to re-collect card details? Yes, for new payments. Stripe card tokens are not transferable to Felloh. Customers will enter their card details on their first Felloh payment, and the card is automatically tokenised for future use.
What about PCI compliance? Felloh handles PCI compliance the same way Stripe does — card details are collected via Felloh's hosted payment pages or SDK, never touching your servers.
Can I use the Felloh MCP server during migration? Absolutely. Connect the MCP server to your AI editor and use it to explore the API, create test bookings, and debug your integration interactively.
What if I use Stripe Connect for marketplace payouts? Felloh's equivalent is Disbursements with Beneficiaries. The model is different — designed for paying travel suppliers rather than marketplace sellers — so this part of the migration needs the most planning. Speak to your Felloh account manager for guidance.
