System Overview
The Konekte Voucher System is a full-lifecycle digital voucher infrastructure designed for the Haitian market. It supports multiple entry points (Partner API, Stripe, NGO bulk, in-app), a multi-merchant redemption network with real-time float management, and a double-entry financial ledger with automated settlement and contribution-based capital recovery.
System Architecture
High-level architecture showing entry points, core processing engine, and distribution network.
- Partner API (REST + API Key)
- Stripe Checkout (public buyers)
- NGO Bulk Purchase (dashboard)
- In-App Purchase (wallet users)
- Voucher Lifecycle Manager
- Treasury Ledger (double-entry)
- Fee Engine (contribution-recovery-aware)
- FX Pricing Engine (real-time)
- Idempotency Guard
- SMS Delivery (Twilio)
- Webhook Dispatcher (HMAC)
- Merchant Registry (multi-location)
- Float Management (real-time alerts)
- MSF Configuration (per-merchant)
- Department-based routing
- Denomination validation
API Reference
All endpoints use POST method with JSON body. Authentication via X-API-Key header.
| Endpoint | Purpose | Idempotent |
|---|---|---|
| /api/partnerIssueVoucher | Issue new voucher with SMS PIN delivery | Yes (external_reference_id) |
| /api/partnerGetVoucher | Lookup voucher by external reference | N/A (read) |
| /api/partnerGetBalance | Current balance / credit utilization | N/A (read) |
| /api/partnerGetSummary | Aggregated issuance & redemption metrics | N/A (read) |
| /api/partnerGetTransactions | Paginated transaction history | N/A (read) |
policy object. Partner API only supports policy.type = "MERCHANT". Requests without a policy are rejected with ERR_INVALID_POLICY. Legacy merchant_id field is accepted as fallback but deprecated.// MERCHANT — locked to specific merchant (Partner API)
{ "type": "MERCHANT", "merchant_code": "M-001" }
// CATEGORY — restricted to merchant categories (Admin/NGO/In-App)
{ "type": "CATEGORY", "category_codes": ["food", "pharmacy"] }
// ANY — redeemable at any merchant (Admin/NGO with confirmation)
{ "type": "ANY" }POST /api/partnerIssueVoucher
X-API-Key: pk_live_xxxxxxxxxx
{
"external_reference_id": "DING-TXN-20260425-001",
"amount_htg": 500,
"recipient_phone": "+50912345678",
"recipient_name": "Jean Pierre",
"policy": {
"type": "MERCHANT",
"merchant_code": "M-001"
}
}{
"voucher_code": "VI-A1B2C3D4",
"external_reference_id": "DING-TXN-20260425-001",
"amount_htg": 500,
"currency": "HTG",
"status": "ISSUED",
"expires_at": "2026-10-22T14:30:00Z",
"policy": {
"type": "MERCHANT",
"merchant_code": "M-001",
"merchant_id": "abc123"
},
"merchant_name": "MegaMart",
"_request_id": "req_..."
}Error Codes
ERR_UNAUTHORIZED — Invalid/missing API keyERR_INVALID_POLICY — Missing/invalid policy objectERR_MERCHANT_REQUIRED — merchant_code missingERR_INVALID_MERCHANT — Merchant not found/inactiveERR_MERCHANT_MISMATCH — Redemption at wrong merchantERR_CATEGORY_MISMATCH — Category not matchingERR_INVALID_CATEGORY — Invalid category codeERR_INSUFFICIENT_CUSTODIAL — Balance too lowERR_CREDIT_LIMIT_EXCEEDED — Over credit limitERR_INVALID_AMOUNT — No voucher for amountERR_RATE_LIMIT_EXCEEDED — Rate limit exceededERR_PARTNER_INACTIVE — Account suspendedDeprecated Fields
eligibility_type → use policy.typeeligibility_value → use policy.merchant_code / policy.category_codesmerchant_id (request) → use policy.merchant_codeLegacy fields are retained on existing records but not used for validation.
Voucher Issuance Flow
Complete issuance pipeline from API request to SMS delivery and webhook notification.
Voucher = Amount + Recipient + Policy
Every voucher is defined by three immutable properties: the denomination (amount), the intended recipient, and the redemption policy. The policy is attached at issuance and never modified thereafter.
Policy attached (immutable). Treasury lock created. SMS PIN delivered.
Assignment only (NGO bulk). No policy change. Narrows, never broadens.
Policy validation enforced. Merchant match required for MERCHANT type.
Merchant credited. MSF deducted. Lock released.
- POST /api/partnerIssueVoucher
- X-API-Key header
- external_reference_id (idempotency)
- 1. Authenticate API key (SHA-256 hash match)
- 2. Validate partner status & balance/credit
- 3. Check contribution recovery → calculate fee split
- 4. Create VoucherInstance + PIN (hashed)
- 5. Create VoucherTreasuryLock (liability)
- 6. Create VoucherFeeSnapshot (fee audit)
- 7. Create VoucherLedgerEntry (ISSUANCE_DEBIT)
- 8. Send PIN via SMS (Twilio)
- 9. Dispatch webhook (voucher_issued)
- Receives PIN via SMS
- Can check status online
- voucher_issued event
- HMAC signature verified
external_reference_id is submitted twice, the system returns the original voucher data without creating a duplicate. Safe for network retries.Voucher Redemption Flow
End-to-end redemption process from recipient presentation to merchant settlement.
- Presents serial number + PIN at merchant
- Verifies voucher via Konekte system
- Provides cash/goods to recipient
- 1. Validate PIN (hash comparison)
- 2. Check voucher status = ISSUED & not expired
- 3. Create VoucherRedemption (PENDING → COMPLETED)
- 4. Release VoucherTreasuryLock (LOCKED → RELEASED)
- 5. Deduct merchant float_balance
- 6. Record allocation ledger entry
- 7. Calculate & record MSF (merchant service fee)
- 8. Dispatch webhook (voucher_redeemed)
- voucher_redeemed event
- Real-time settlement tracking
Settlement & Fee Recovery
Weekly settlement cycle with contribution-based capital recovery.
- System aggregates deferred receivables
- Calculates: principal + fees (contribution recovery applied at issuance)
- Generates settlement snapshot
- Receives settlement statement
- Remits net amount to Konekte
- PARTNER_SETTLEMENT_INFLOW recorded
- current_receivable decreased
- Fee snapshots marked SETTLED
- Revenue recognized (platform + partner shares)
Contribution Recovery Mechanism
When a partner has an active PartnerContribution (capital investment), the system redirects issuance fees to the partner until the contributed amount is fully recovered. Fees are charged normally — the split is adjusted so the partner receives a larger share until recovery is complete, then transitions to the standard revenue share model.
Fees are redirected to partner (contribution_recovery_htg) until capital is recovered
Auto-transitions to standard revenue share (e.g., 20%)
Every recovery is recorded as a CONTRIBUTION_RECOVERY ledger entry
Merchant Float Model
Merchants receive float through two distinct channels, tracked via campaign_tag for reporting:
One-time seed capital to activate a new merchant. Treated as working capital deployment, not operational expense.
Promotional float top-ups. Treated as true operational expense for P&L reporting.
Data Schemas
Core entity schemas powering the voucher system. Click each to expand field details.
Security Model
API Authentication
SHA-256 hashed API keys. Plaintext shown once at generation, never stored. Prefix-based identification for key management.
PIN Security
Voucher PINs are hashed before storage using HMAC-SHA256. Verification via hash comparison only. Plaintext delivered once via SMS.
Webhook Signatures
All webhook payloads are signed with HMAC-SHA256 using a per-partner secret. Recipients must verify the X-Webhook-Signature header.
Idempotency
Every write operation uses a unique reference_id enforced at the database level (unique constraint). Prevents double-issuance under any failure condition.
Optimistic Locking
All balance mutations use version counters. Concurrent writes are detected and safely retried, preventing race conditions.
Immutable Ledger
Financial ledger entries are append-only. No updates or deletes. Every entry includes balance_before and balance_after snapshots for audit.
Monitoring & Alerts
Konekte — Digital Infrastructure for Haiti
This document is confidential and intended for authorized integration partners only.
Contact: info@konekte.org