Skip to content

case study · Upcard · 2026 · in pre-production

Payment orchestrator

Backend and payment site

Collections platform an institutional client's borrowers use to pay online via PSE and Bre-B. Certified by the payment processor and deployed; in pre-production testing before cutover.

  • NestJS
  • Next.js
  • PostgreSQL
  • Redis/Valkey
  • Docker
precedence rules to resolve the payer's return
5
payment rails
PSE · Bre-B

Problem

An institutional client needed its borrowers to pay hundreds of thousands of active obligations online, via PSE and Bre-B. The contract with the previous provider had an end date, so the replacement had a fixed date and no way back: on cutover day, the new site had to collect correctly from the very first payment.

That set three requirements: never lose a payment even if something fails halfway, never block a legitimate payer, and pass the payment processor's certification within the deadline.

Architecture

The orchestrator is a NestJS backend with a Next.js payment site in front of it. The source of truth for a payment's state is the processor's signed notice, not whatever the payer's browser happens to see.

  1. Obligation lookup
  2. Payment start
  3. Processor checkout
  4. Payer return
  5. Reconciliation webhook
  6. Client notification
Payment flow: obligation lookup, payment start, processor checkout, payer return, reconciliation webhook and client notification.

Besides the online flow, a worker delivers the daily payment report to the external reconciliation system.

Decisions

The payer's return is resolved with rules, not assumptions

When the payer comes back from checkout, the state may not be settled yet. The return use case applies five precedence rules to decide what to show and what to query, without marking as paid anything the processor has not confirmed.

Every webhook is verified before it touches a payment

Webhook reconciliation checks the notice's signature and freshness, using constant-time comparison so response timing leaks nothing. A stale or badly signed notice changes nothing.

Personal data stays where it belongs

The backend has PII guards and a read-only operations console, with CSV and XLSX exports that contain no personal data. Support can investigate a payment without seeing more than it needs.

Results

  • Certified by the payment processor, checked item by item against its checklist, two weeks after the integration model was confirmed.
  • Deployed to its environment, with a code security audit and TLS 1.2 or higher verified on the published domain.
  • It is now in pre-production testing, waiting for the final production cutover.

Shall we build something reliable?

I reply in English or Spanish.

Email me on Gmail