Remittance network · Colombia → Venezuela

From a legacy Web Forms app to an owned remittance platform

We replaced the ASP.NET system of a network that takes pesos in Colombia and pays out bolívares in Venezuela. The new platform has 8 roles, mandatory MFA and every money movement inside Postgres functions.

A Pago Móvil transfer end to end: the shop fills in the form and confirms, checks the day's list, and the operator opens the ID in the payout queue. Invented data.
In short

We replaced the ASP.NET Web Forms system of a money-transfer network running from Colombia to Venezuela. The new platform covers all 8 roles in the operation, from the shop that takes the cash to the operator who pays out in bolívares, with MFA mandatory for everyone and every money movement inside database functions. The first commit is dated 14 September 2026; by the end of October the platform was running with the network's real users.

Client
Remittance network · Colombia → Venezuela
Sector
Remittances and exchange houses
Where
Colombia → Venezuela
Year
2026
Deliverables
  • Web platform with 8 roles
  • TOTP MFA and invite-only access
  • Money moved in Postgres functions
  • Migration from SQL Server
  • Reports with XLSX and CSV export
8roles, all with mandatory MFA
132automated tests, all passing
6 weeksfrom first commit to real users
The context

A Web Forms system moving real money

The network works with two exchange houses and a set of shops in Colombia that take cash in pesos. A shop creates a transfer to a bank account or to Pago Móvil, and sells phone top-ups and TV plans against a prepaid peso balance. In Venezuela, operators pay out from the exchange house's bolívar accounts and attach the bank's proof of payment.

All of this ran on an ASP.NET Web Forms application over SQL Server. In September 2026 we received the app and a backup of its database. We wrote the new core from scratch and used the old system as a reference for business rules and as a data source.

Design and build

Money only moves inside the database

Every money operation is a SECURITY DEFINER function in Postgres (Supabase, sa-east-1 region), and the browser never writes a balance. Behind it sit a double-entry ledger, an audit schema that only accepts inserts, idempotency keys so a double click can't create two transfers, and step-up codes bound to each request's hash. The schema lives in 73 migrations and the app calls about 100 distinct functions.

The interface is Next.js 16.4 with React 19.2 and TypeScript, on Vercel, with 66 pages and 22 API routes. Access is by invitation only, with authenticator-app MFA (TOTP), a 30-minute idle timeout, an 8-hour session cap and one session per user. Payment proofs land in a private quarantine bucket, go through an isolated scanner and are rejected if their SHA-256 already exists. The old system's data moved from SQL Server to Postgres through an ETL written for the project.

  1. 01

    The shop creates the transfer

    It looks up sender and recipient by ID number, picks bank or Pago Móvil, and sees live how much comes off its balance and how many bolívares the recipient gets. Pago Móvil applies the rate × 1.01. A 6-digit code confirms it, and the shop gets a receipt with an operational ID.

  2. 02

    The operator pays out in Venezuela

    The queue refreshes every 10 seconds and splits the work by exchange house. Opening an ID reserves it for that operator, who picks the source account, uploads the proof and sees the 0.3% interbank commission before paying.

  3. 03

    8 roles, 38 actions

    Shop, payouts, admin, distributor, senior distributor, purchasing, super seller and seller. The 38 permissioned actions come from the role, and an admin can allow or block one action for one person without changing their role.

  4. 04

    132 automated tests

    Vitest runs 132 unit and component tests, all passing. Another 11 Playwright files with axe-core walk through the full flows and check accessibility, and GitHub Actions runs the CI.

Outcomes

Six weeks from first commit to operation

Between 14 September and 29 October 2026 there were 71 commits, with client reviews on 6, 8 and 13 October. By the end of October the platform was running with the network's real users, on an invite-only URL.

We don't yet have volume or payout-time figures we can publish. The client is confidential, so the screenshots use invented data and two fictional exchange houses, Andina and Orinoco.

  • ASP.NET Web Forms system replaced by an owned platform
  • 8 roles and 38 permissioned actions, MFA mandatory for everyone
  • 73 migrations and about 100 database functions
  • 132 automated tests, all passing
Frequently asked questions

The questions we hear often

Why move money in database functions?

Because one Postgres function checks the balance, writes the double-entry posting and records the audit row in the same transaction. If anything fails, nothing is left half-done, and no browser can write a balance.

Can the data from the old exchange-house software be migrated?

Yes. The project's ETL reads the SQL Server .bak backup and loads it into Postgres. Legacy balances become the starting point, and every later movement is posted by the new functions.

Is MFA mandatory for every user?

Yes, across all 8 roles. A user joins by invitation, sets a password, enrols an authenticator app with a QR code or manual key, and from then on every sign-in asks for the 6-digit code. That code is never sent over WhatsApp.

Talk to Slash

Let's put it in production

Tell us your challenge. We reply within 24 business hours with an honest first read: if we can help, we'll say how; if not, we'll say who can.

I reply personally. No endless forms, no canned replies.

Message Esteban