Skip to content

Challenge 16: Receivables Financing — The R$ 500B Market That Moves Brazil

🇧🇷 Crédito sobre Vendas Futuras
🇬🇧 Receivables Financing


Receivables Financing allows merchants to receive today the value of credit card sales that would only be paid in 30, 60 or 90 days. It moves over R$ 500 billion per year and is the main revenue source for Stone, PagSeguro and Mercado Pago.

Switch: TypeScript vs Go

What is Receivables Financing?

ConceptDescription
D+30Standard payment receipt period (30 days)
MDRAcquirer fee (1.5-3% per transaction)
SpreadBank margin on anticipation (2-8% p.a.)
IOFTax: 0.38% + 0.0041% per day
CETAnnualized Total Effective Cost
FIDCCredit Rights Investment Fund

The Math

typescript
// Anticipation of R$ 10,000 in 30 days
const futureValue = 10000;
const days = 30;
const annualRate = 0.18; // 18% p.a. (CDI + spread)
const iof = 0.0038 + (0.000041 * days);
const fixedFee = 10;

const dailyRate = Math.pow(1 + annualRate, 1/365) - 1;
const discount = futureValue * (Math.pow(1 + dailyRate, days) - 1);
const iofAmount = futureValue * iof;
const netAmount = futureValue - discount - iofAmount - fixedFee;

// Net Amount: R$ 9,795.33
// CET: 18.00% p.a.

Complete Flow

Architecture

Pricing Engine

typescript
export class PricingEngine {
  public async calculateQuote(merchantId: string, receivables: Receivable[]) {
    const cdiRate = await this.marketData.getCDIRate();
    const riskPremium = this.calculateRiskPremium(merchant);
    const spread = this.calculateSpread(merchant);
    const totalRate = cdiRate + spread + riskPremium;

    let grossAmount = 0, discountAmount = 0, iofAmount = 0;

    for (const r of receivables) {
      const days = r.daysUntilPayment();
      const dailyRate = Math.pow(1 + totalRate, 1/365) - 1;
      const discount = r.netAmount * (Math.pow(1 + dailyRate, days) - 1);
      const iof = r.netAmount * (0.0038 + 0.000041 * days);

      grossAmount += r.netAmount;
      discountAmount += discount;
      iofAmount += iof;
    }

    return {
      grossAmount, discountAmount, iofAmount,
      netAmount: grossAmount - discountAmount - iofAmount - 10,
      effectiveRate: this.calculateCET(grossAmount, grossAmount - discountAmount - iofAmount, avgDays),
    };
  }
}

Risk Engine

typescript
export class RiskEngine {
  public async evaluate(input: RiskEvaluationInput) {
    const creditData = await this.creditBureau.query({ document: merchant.document });
    const history = await this.historyRepo.findByMerchant(input.merchantId, { months: 12 });
    const fraudCheck = await this.fraudService.evaluateAnticipation({ ... });

    const finalScore = Math.round(
      creditData.score * 0.35 +
      this.calculateHistoryScore(history) * 0.30 +
      this.calculateBehaviorScore(merchant, input) * 0.20 +
      fraudCheck.score * 0.15
    );

    return {
      approved: finalScore >= 500 && input.totalAmount <= limits.maxAmount,
      score: finalScore,
      riskLevel: finalScore >= 800 ? 'LOW' : finalScore >= 650 ? 'MEDIUM' : 'HIGH',
    };
  }
}

Comparison: TypeScript vs Go

AspectTypeScriptGo
MathNumber (ok)shopspring/decimal
BatchWorker threadsGoroutines
1M receivables~14 minutes~80 seconds
Quote P99180-1200ms45-280ms
Memory~2GB~100MB

Real Cases

  • Stone (Go) — Leader, R$ 100B+/year, P99 < 200ms
  • PagSeguro (Go + Java) — 40M customers, auto-anticipation
  • Mercado Pago (Go) — Largest in Latam, dynamic pricing
  • Creditas (Go) — SME niche, own FIDC

How to test

bash
# TypeScript
pnpm --filter @banking/anticipation dev

# Go
cd packages/backend/anticipation-go
go run .

# Simulate quote
curl -X POST http://localhost:3010/anticipation/quote \
  -H "Content-Type: application/json" \
  -d '{"receivableIds":["uuid1","uuid2"]}'

Lessons learned

  1. R$ 500B+/year — Largest credit market in Brazil
  2. Precise math is critical — Cents matter at scale
  3. shopspring/decimal — Never native float for money in Go
  4. Batch processing — 50M+ receivables/day in large acquirers
  5. Multi-layer risk engine — Credit + history + behavior + fraud
  6. Funding sources — Own capital, FIDCs, wholesale banks
  7. Chargeback is the biggest risk — Merchant can disappear
  8. CET must be disclosed — BACEN requirement
  9. Go processes 1M in 80s — vs 14min in TypeScript
  10. Stone, PagSeguro and Mercado Pago — All use Go in core