Ekaterina Deys1 · Remittances2 · Virtual IBANs3 · Orchestration4 · Payouts5 · Antifraud

Ekaterina Deys

Lead Technical PM · Payments, money movement & partner integrations
katedeys@gmail.com·linkedin.com/in/kate-deys·Open to roles from November 2026·remote or relocation
Case studies redrawn from scratch and generalised: no partner names, internal systems or figures beyond my CV.

I design how money, data and systems move between a product, its partners and its users. These cases show the problem, the architecture I drew, the decisions behind it, and what I would do differently.

Case 1 · Lending fintech · Gulf → Southeast Asia

From a remittance MVP to relatives repaying a credit line from abroad

IdeaCapture migrant remittances that already flow to the families we lend to
CorridorUAE / KSA → Southeast Asia, AED/SAR → USD → local currency
My role0 → MVP → pivot: partners, flows, commercial model, launch path
ModelOur margin plus interbank FX, negotiated with the partner until volume tiers

The market

The Gulf is the largest source of remittances in the world: GCC countries sent out about $161B in 2025, with the UAE and Saudi Arabia at roughly $62B and $58B. For scale, one corridor of the kind we worked on, UAE and Saudi Arabia to the Philippines, officially carries around $4B a year (4.6% and 6.6% of the Philippines' $35.6B in 2025 cash remittances), and the real figure is higher, because transfers are recorded where the remitting institution sits. Even a 1% share of that one corridor is about $40M a year flowing to families who are, or could become, our borrowers.

Sources: GCC-Stat 2025 outward worker remittances; Bangko Sentral ng Pilipinas 2025 cash remittances by source country. The share scenario is illustrative.

The problem

Many of our borrowers' families depend on relatives working in the Gulf. That money already crossed borders every month, but through other apps, so we saw neither the revenue nor the income it proved. The goal was to bring that flow into our product fast, without building a cross-border stack first.

moneydata / statusexternalholds money

How a transfer works

  1. Pay-in. The sender pays the remittance provider in AED or SAR by card, wallet or cash. The provider runs sender KYC.
  2. Identity reuse. The provider shares a KYC ID; we store it and call the provider with it on every next transfer, so the sender is verified once. On our side the relative's kinship is confirmed with a document, kept in the PII vault.
  3. FX and payout. The provider converts AED/SAR → USD → local currency at interbank rate and calls our payment service with an idempotent transfer request.
  4. Booking. The ledger posts the incoming funds; billing books our margin.
  5. Destination. In the MVP the money lands in the recipient's wallet. After the pivot, the credit engine applies it as a repayment to the relative's credit line.
  6. Status back. Final status goes back to the provider; the relative sees it in the app.
  7. Data for lending. Transfer history feeds scoring as an income signal for the recipient's credit decisions (piloted).

One repeat transfer, step by step (after the pivot)

money movementcallresponse / callback

Key decisions

Buy first, build later

A remittance-as-a-service provider gave us licensed pay-in, KYC and FX in the Gulf from day one. An in-house build only makes sense once volume justifies the licences and the margin.

Interbank FX until volume tiers

I negotiated interbank FX with the partner until we reached agreed volumes, so our margin was the only spread the sender paid, and the price stayed competitive with existing apps.

Verify the sender once

Reusing the partner's KYC ID removed repeat verification for every transfer; our own check covered only what we owned: the family link to the borrower.

Pivot to repayments

Paying straight into a relative's credit line tied the flow to our core product: the money now reduces credit risk instead of only sitting in a wallet.

What happened, and what I'd do differently

The scoring pilot launched, then stalled on two constraints: team funding, and the licence question of receiving funds at volume. Next time I would put the licensing path and its volume thresholds into the business case at the discovery stage, and size the team for the in-house phase before the MVP goes live, not after.

Generalised from my work at a lending fintech. Diagram redrawn from scratch; component names are generic.

↑ Back to contents
Case 2 · Lending fintech · Malaysia

Virtual IBANs inside loan origination: bank-transfer repayments that reconcile themselves

ProblemBank-transfer repayments had to be matched to loans by hand
ScopeVIBAN issuance in origination, async bank API, matching, repayment events
ContextRepayments with 2 partners, 3 methods each: cards, bank transfer, cash
Result100% of bank-transfer repayments reconcile automatically

The problem

When customers repay by bank transfer to one shared account, every payment has to be matched to a loan by name or reference, and people get references wrong. The fix is to give each loan its own virtual account number: whatever arrives on it already says whose repayment it is.

moneydata / statusexternalholds money

Issuance and the first repayment, step by step

money movementcallresponse / callback

Key decisions

Issue the VIBAN inside origination

The account number exists before the first repayment is due, so the customer gets payment details together with the loan and no repayment ever arrives without a key.

The account number is the matching key

Matching stops depending on what the customer typed in the reference: the destination itself identifies the loan, which is what makes 100% automatic reconciliation possible.

Design for a slow, asynchronous bank API

Creation is async with callbacks; timeouts trigger a status check by request ID and a retry with the same ID, never a blind second request.

Clean up duplicates explicitly

If a bank glitch ever produced two accounts for one loan, we closed the earlier one and kept the last created, so a loan never has two live repayment addresses.

One account per loan, same lifecycle

The VIBAN is opened with the loan and closed with it. A late transfer to a closed loan bounces back to the sender instead of landing in a suspense account.

Amounts that don't match the schedule

Overpayments wait on a technical account and lower the next payment, or go to partial early repayment if the customer asks. Underpayments wait too, and the app shows how much is missing for the minimum payment and nudges a top-up.

Result

All bank-transfer repayments now reconcile automatically, and the same payment event model feeds the credit engine for cards and cash, so every repayment method lands in one place.

Generalised from my work at a lending fintech. Diagrams redrawn from scratch; component names are generic.

↑ Back to contents
Case 3 · Ride-hailing super-app · 40+ countries

From two external orchestrators to our own payment orchestration

Before2 external orchestrators, plus direct splits between two PSPs in some countries
ScaleFrom 4 to 40+ countries, 2–3 providers per country on average
Savings~$100K/month (~20%) in processing costs from cost-aware routing
Reliability96.4% provider SLA with health monitoring and automatic failover

Why we built our own

ProblemWhat we builtOutcome
Orchestrator fees grew with every new country and every extra transactionDirect connectors to each PSP and routing by provider cost, limits and coverage~$100K/month saved (~20%)
Vendor lock-in: two orchestrators is too few to negotiate or switchOur own layer where the old orchestrators are just two connectors among many; card tokens in our own vaultAdding or switching a provider no longer depends on a vendor
We set the routes, but inside someone else's systemRouting rules in our admin panel: business sets the commercial part, support and product react to dropsRouting changes without a release, by the people who own the outcome
A mix of end-provider errors, mapped somehow by the orchestratorsOne internal transaction state model and our own status and error mapping per providerSoft and hard declines handled consistently; outcomes are auditable
Incidents were reactive: we waited and controlled nothingHealth monitor on queue length, response speed and SLA, with failover and gradual return rules96.4% provider SLA

Target architecture

payment trafficrules / signals / dataexternal

Provider health: failover and gradual return

StateTypical triggerWhat routing does
DegradedSuccess rate 5+ pp below the provider's baseline for ~5 min, p95 response time over 2× normal, or a growing pending queueAlert, keep routing, watch closely
ExcludedTimeouts or errors above 15–20% for 3–5 min, pending queue over its limit, or an SLA breachNo new traffic; soft declines fail over to the next provider
RecoveringHealth checks pass again5% → 25% → 50% → 100% of the normal share, 10–15 min per step; any relapse goes back to Excluded

Values are illustrative and follow common industry practice; production thresholds were tuned per provider and country.

One driver top-up, step by step

money movementcallresponse / callback

How we moved 40+ countries without a big-bang switch

1 · Orchestrators go under our layer

The two external orchestrators were connected to our orchestration as ordinary connectors, so every payment already went through our routing and state model.

2 · Dial traffic over to direct PSPs

Country by country, traffic moved from the orchestrators to direct PSP connectors in steps, with the old path one rule away if something went wrong.

3 · Migrate tokens provider by provider

Cards started on provider tokens; we migrated them over a secure channel, one provider at a time, into our own vault. Going by provider rather than by country matched how the tokens were actually held.

4 · Keep a share on the orchestrators

We agreed with the orchestrators to keep part of the traffic: a live backup route, and an integration that stays working instead of rotting unused.

Key decisions

Rules in our admin, owned by the business

Commercial routing is a business decision, so the business sets it; support and product step in on drops and failures without a release.

Classify declines before retrying

Soft declines can fail over to another provider; hard declines cannot. One internal state model makes that rule the same in every country.

Exclude fast, return slowly

A degraded provider leaves the routing quickly but comes back in steps, so one recovery blip does not hit full traffic.

Own the card vault

Tokens in our vault (PCI DSS Service Provider) mean cards are not tied to the PSP that first saw them, which is what makes routing across providers real.

Generalised from my work at a ride-hailing super-app. Diagrams redrawn from scratch; provider names omitted.

↑ Back to contents
Case 4 · Lending fintech · Malaysia

Money out and money in: async loan payouts and multi-channel repayments on one event bus

PayoutsBuilt from scratch: primary and backup partner, mostly bank transfer via FPX
Repayments2 partners, 3 methods each: cards (one-off and auto-debit), Virtual IBAN transfers, cash by QR
EventsEvery success and failure goes to Kafka: credit engine, DWH and origination listen
ResultManual payout investigations removed entirely

The problem

A lender lives on two money flows: the loan going out and the repayments coming back. Payout partners answer slowly and sometimes not at all; repayments arrive through cards, bank transfers and cash desks, each with its own statuses. If either side loses a status, someone ends up searching for a missing payout or a repayment that never reached the loan.

Architecture

moneyrequests / eventsexternalholds money

A loan payout, step by step

A repayment, step by step

Key decisions

A backup payout partner from day one

Payouts are the moment the customer is waiting for. A second partner turns a partner outage into a slower payout instead of no payout.

Retry on a ladder, then fail over

Status check and retries with growing intervals up to a timeout, always with the same idempotency key, so a slow partner never produces a double payout.

Link every repayment to the contract at the start

The payment knows which loan it belongs to before money moves: a QR per payment for cash, a VIBAN per loan for transfers. Nothing has to be matched afterwards.

Failures are events, not silence

Success and failure both go to Kafka. The credit engine, DWH and origination see the same truth, and the customer hears about a failure from a push, not from support.

Money logic stays in the credit engine

Balances, minimum payment and the full-payoff amount are calculated in one place; the payment service moves money and reports what happened.

Reconcile through the partner API

Statuses are checked against the partner's API rather than files and spreadsheets, so a mismatch shows up the same day.

Generalised from my work at a lending fintech. Diagrams redrawn from scratch; partner names omitted.

↑ Back to contents
Case 5 · Payments and lending · in-house fraud services

Payments as the data source for fraud controls

My roleOwner of the payment data and integration points; consultant on the rules, not the fraud product owner
ScopeCard payment rules, chargebacks, checks at loan issuance, payout protection
SetupIn-house fraud services, no external vendor
What I broughtWhich signals payments can give, and where in the flow a check can stop money

The problem

A fraud team can only stop what it can see in time. Most of the useful signals are born in payments: declines and their reasons, 3DS outcomes, chargebacks, cards reused across accounts, a payout destination that changed an hour before the payout. My job was to make those signals reliable and to give the fraud services a place in the flow where a decision actually changes what happens to the money.

Where fraud checks plug into the money flow

money flow paused for a decisiondecisions / signalsfraud check point

What I worked on

Clean signals from payments

One internal state model and unified decline codes meant fraud rules could rely on "insufficient funds" and "stolen card" meaning the same thing across every provider and country.

3DS as a dial, not a switch

Helping decide when to step a payment up to 3DS: a lever between conversion and fraud losses, rather than "always" or "never".

Chargebacks back into the loop

Chargeback and dispute outcomes returned as events, so a card or account that cost money once is visible to the next check.

A hold point before payouts

A payout can wait for review without breaking the flow: hold is a normal payout state with its own push to the customer, not a stuck transaction.

What this taught me

Most fraud controls fail at the plumbing, not at the model: a rule is only as good as the signal it reads and the point in the flow where it can still stop the money. I'm comfortable on that boundary and would grow into owning the rules and the review operations themselves.

Generalised from my work at a ride-hailing super-app and a lending fintech. I was the payments owner and a consultant to in-house fraud teams, not the owner of the fraud product.

↑ Back to contents