Simpaisa Architectural Review
Version: 1.0.0
Date: 2026-04-01
Reviewer: CDO
Scope: Full technology stack, all products, all platforms
Classification: Internal — Architecture & Engineering Leadership
Table of Contents
- Executive Summary
- Company & Product Overview
- Technology Stack
- Product Architecture: Pay-Ins
- Product Architecture: Pay-Outs (Disbursements)
- Product Architecture: Remittances
- Product Architecture: Cards
- Infrastructure Architecture (AWS)
- Data Architecture
- Integration Architecture
- Security Architecture
- API Architecture
- Web Platform (simpaisa.com)
- Developer Experience & Documentation
- Operational Architecture
- Cross-Cutting Concerns
- Risk Register
- Maturity Assessment
- Target Architecture & Preferred Stack
- Strategic Recommendations
- Appendix: Source Documents
1. Executive Summary
Simpaisa is a payment gateway and facilitator operating primarily in Pakistan with expansion into Bangladesh, Nepal, and Iraq. The platform processes 270M+ transactions worth $1B+ across three core product lines: Pay-Ins (merchant payment collection), Pay-Outs (disbursements), and Remittances (cross-border transfers), plus a Cards product (Visa/Mastercard acquiring).
What's Working
- Payment channel coverage is best-in-class for Pakistan. Integration with 5 digital wallets (Easypaisa, JazzCash, HBL Konnect, Alfa, JSBL Zindagi), 3 telcos for direct carrier billing (Telenor, Zong, Ufone), IBFT via 1Link/RAAST, and Visa/Mastercard.
- AWS infrastructure is architecturally sound. Multi-AZ deployment, WAF at the edge, ALB, NAT Gateway, Auto Scaling Groups, RDS, ElastiCache — the foundational patterns are correct for a payment platform.
- Pay-Outs and Remittances have proper cryptographic auth. RSA 2048-bit signing with PKCS#8 and SHA-256, plus mTLS for Cards.
- 98% client retention rate and 150+ merchant integrations demonstrate product-market fit.
- New AEO website (Astro-based) is a significant improvement in web architecture — SSG, proper schema markup, structured data, MDX content.
What Needs Attention
- API architecture is fragmented. Three different auth mechanisms, three different URL patterns, three different error formats, 7 different base URLs. Merchants integrating multiple products build three different clients.
- No idempotency on payment initiation. The most critical gap for a payment platform — duplicate payments are possible on retry.
- Internal implementation details leak into merchant-facing docs. Database table names, scheduler intervals, cache implementation — all visible to external parties.
- Security inconsistency. Pay-Ins uses JSESSIONID cookies (session-based auth inappropriate for APIs) while Pay-Outs/Remittances use RSA signing. Pay-Ins has no request signing at all.
- No webhook signature verification. Merchants cannot verify webhook authenticity — spoofing is possible.
- Corporate website (simpaisa.com) has an SEO score of 2/10. No robots.txt, no sitemap, no meta descriptions, no canonical URLs. The company is nearly invisible to search engines.
- Exposed credentials in source control. Surge deployment token hardcoded in
deploy.sh.
Overall Maturity Rating
| Domain |
Rating |
Notes |
| Payment Channel Coverage |
8/10 |
Best-in-class for Pakistan |
| Infrastructure (AWS) |
7/10 |
Sound foundations, needs observability |
| Security |
4/10 |
Inconsistent across products, critical gaps |
| API Design & Consistency |
3/10 |
Fragmented, non-standard, underdocumented |
| Developer Experience |
3/10 |
Missing schemas, sandbox gaps, no SDKs |
| Observability & Operations |
3/10 |
CloudWatch only, no distributed tracing |
| Corporate Web Presence |
2/10 |
SEO/AEO nearly non-existent |
| Documentation |
4/10 |
GitBook improved over SA docs, still major gaps |
2. Company & Product Overview
Company Profile
| Attribute |
Value |
| Founded |
2016 |
| HQ |
Karachi, Pakistan |
| Markets |
Pakistan (primary), Bangladesh, Nepal, Iraq |
| Transactions processed |
270M+ |
| Transaction value |
$1B+ |
| Client retention |
98% |
| Merchants |
150+ |
Product Portfolio
| Product |
Function |
Channels |
Markets |
| Pay-Ins |
Merchant payment collection |
Easypaisa, JazzCash, HBL Konnect, Alfa, JSBL Zindagi, Telenor DCB, Zong DCB, Ufone DCB, IBFT, Cards |
PK, BD, NP, IQ |
| Pay-Outs |
Disbursements / payouts |
1Link, bKash, BRAC, Faysal, PayMob, Prime, Agrani, AamarPay |
PK, BD |
| Remittances |
Cross-border transfers |
Same payout channels + FX conversion |
PK, BD, NP |
| Cards |
Card acquiring |
Visa, Mastercard |
PK |
Use Cases Served
- Gaming: Micro-payments via carrier billing (DCB) for in-app purchases, eSports
- Ecommerce: Full checkout with wallet, bank, and card options
- Freelance: Disbursements to freelancers via wallets and bank transfers
- Streaming: Content monetisation via DCB and wallets
- Ride-hailing: Real-time driver payouts (e.g., InDrive case study)
Payment Channel Reach
| Channel |
Type |
Users (millions) |
Fee |
Settlement |
| JazzCash |
Mobile wallet |
40 |
1.2-1.5% |
T+1 |
| Easypaisa |
Mobile wallet |
30 |
1.8% |
T+1 |
| Telenor DCB |
Carrier billing |
50 |
2.0% |
T+2 |
| Zong DCB |
Carrier billing |
45 |
2.0% |
T+2 |
| Ufone DCB |
Carrier billing |
30 |
2.0% |
T+2 |
| IBFT |
Bank transfer |
60 |
0.5% + PKR 10 |
T+1 |
| Cards |
Visa/MC |
25 |
2.5% |
T+3 |
Total addressable reach: 100M+ Pakistanis (accounting for overlap across channels).
3. Technology Stack
Backend
| Layer |
Technology |
Notes |
| Application framework |
Spring Boot (Java) |
Core payment processing services |
| Message queue |
Apache Kafka |
Async event processing between services |
| Cache |
Redis (AWS ElastiCache) |
Transaction caching, session state, rate limiting |
| Primary database |
MySQL (AWS RDS) |
Transaction records, merchant config, credentials |
| Search / logging |
OpenSearch |
API logs, transaction tracing |
| Scheduler |
Spring-based scheduler |
5-minute interval for disbursement processing |
Infrastructure (AWS)
| Component |
AWS Service |
Configuration |
| Compute |
EC2 instances |
Multi-AZ with Auto Scaling Groups |
| Load balancer |
ALB (Application Load Balancer) |
Public subnets, SSL termination |
| WAF |
AWS WAF |
Edge protection at Internet Gateway |
| Networking |
VPC with public/private subnets |
NAT Gateway for outbound from private subnets |
| Database |
RDS (MySQL) |
Shared across services, private subnet |
| Cache |
ElastiCache (Redis) |
Shared, private subnet |
| Secrets |
AWS Parameter Store |
Configuration and credential management |
| Monitoring |
CloudWatch |
Metrics and basic alerting |
| Security scanning |
GuardDuty |
Threat detection |
Frontend / Web
| Platform |
Technology |
Status |
| Corporate site (simpaisa.com) |
Unknown CMS/framework |
Live, SEO score 2/10 |
| New AEO site (simpaisa-beta) |
Astro 6.1 + Preact + MDX |
Beta on Surge, SSG |
| API documentation |
GitBook |
Live at simpaisa.gitbook.io |
| Future target |
OpenAPI 3.1 + Redocly/Swagger UI |
Planned |
| Area |
Tool |
Notes |
| Issue tracking |
Beads (bd) |
For AEO project |
| Deployment (AEO) |
Surge.sh |
Beta hosting |
| API spec linting |
Spectral (planned) |
Not yet implemented |
| Contract testing |
Schemathesis/Dredd (planned) |
Not yet implemented |
| SDK generation |
openapi-generator (planned) |
Not yet implemented |
4. Product Architecture: Pay-Ins
Overview
Pay-Ins handles merchant payment collection from consumers. It is the most complex product, supporting two payment models across five wallet operators and three telcos.
Payment Models
- Single Charge — One-time payment with OTP or async wallet approval
- Recurring Payments (Tokenisation) — Merchant charges users automatically at predefined intervals using stored tokens
Transaction Types
| Type Code |
Name |
Description |
| 0 |
Single charge |
One-time payment |
| 1 |
Initial charge (subscription) |
First payment that creates a token for recurring |
| 8 |
Recurring charge |
Subsequent automated charge using stored token |
| 9 |
Subscription charge |
Regular interval charge for ongoing services |
Supported Operators
| Operator |
Code |
Single Charge |
Recurring |
Notes |
| Easypaisa |
100007 |
Yes |
Yes |
Requires storeId from easypaisa_credentials |
| JazzCash |
100008 |
Yes |
Yes |
|
| HBL Konnect |
100014 |
Yes |
No |
Single charge only |
| Alfa |
100012 |
Yes |
No |
Single charge only |
| JSBL Zindagi |
100015 |
Yes |
No |
Single charge only |
Flow Architecture
Single Charge — Synchronous Flow
Merchant → POST /v2/wallets/transaction/initiate
↓
Validate merchantId + operatorId
↓
Log transaction (status=0, PENDING)
↓
[OTP allowed?] ──YES──→ Send OTP via SMS
│ ↓
NO Merchant submits OTP via Verify API
↓ ↓
Call operator API directly Validate OTP (check threshold)
↓ ↓
[Success?] ←───────────────────┘
│
YES → Cache transaction, update status=1 (SUCCESS)
→ Log in api_logs table
→ Post to merchant webhook URL
│
NO → Fetch error from external_response table
→ Return error to merchant
Single Charge — Asynchronous Flow
Same as synchronous except:
- After initiate, returns "transaction pending" immediately
- Operator processes asynchronously
- Inquiry API polls for final status
- Final result posted to merchant via webhook
Recurring Payment Flow
1. First Transaction (Initial Charge):
Validate inputs → Log transaction → Call operator API
↓ (Success)
Generate payment token at Simpaisa
↓
Store in operator_token table (Simpaisa token + operator token)
↓
[Subscription-based?] → Calculate next renewal date
↓ → Store in recursion + payment_logs tables
Post success to merchant
2. Subsequent Charges:
Retrieve stored token from operator_token table
↓
Call Direct Charge API using stored token (no OTP needed)
↓
Update transaction status → Log in payment_logs
↓
[Subscription?] → Update recursion table with next renewal
↓
Post result to merchant
Key Architectural Observations
| Observation |
Severity |
Details |
| JSESSIONID authentication |
CRITICAL |
Session-based auth is inappropriate for stateless APIs. Only product without cryptographic signing |
| No request signing |
CRITICAL |
Pay-Ins has no signature verification — requests can be forged |
| 30-minute OTP expiry |
HIGH |
Industry standard is 5 minutes for payment OTPs |
| Internal table names in docs |
HIGH |
merchant_details, product_configuration, transaction, api_logs, easypaisa_credentials, operator_token, recursion, payment_logs, wallet_transaction_threshold, product_webhook, external_response all exposed |
| Numeric transaction types |
MEDIUM |
0, 1, 8, 9 instead of named enums |
| Numeric status codes |
MEDIUM |
status=0 (pending), status=1 (success) instead of named states |
| merchantId in request body |
MEDIUM |
Should be in URL path per REST conventions |
5. Product Architecture: Pay-Outs (Disbursements)
Overview
Pay-Outs handles outbound payments from merchants to beneficiaries — payroll, refunds, prize payouts, driver earnings, etc.
API Endpoints (SA Doc)
| Endpoint |
Method |
Purpose |
/merchants/{merchantId}/disbursements/initiate |
POST |
Create a new disbursement |
/merchants/{merchantId}/disbursements |
GET |
List disbursements |
/merchants/{merchantId}/disbursements/fetch-account |
POST |
Fetch account details (should be GET) |
/merchants/{merchantId}/disbursements/balance-data |
POST |
Get merchant balance (should be GET) |
/merchants/{merchantId}/disbursements/banks |
GET |
List available banks |
/merchants/{merchantId}/disbursements/reasons |
GET |
List failure reasons |
/merchants/{merchantId}/disbursements/register-customer |
POST |
Register a beneficiary |
Transaction State Machine
PUBLISHED (new)
↓
IN_REVIEW → DISBURSED (success, terminal)
↓
ON_HOLD (insufficient balance)
↓ (after top-up)
PUBLISHED → IN_REVIEW → DISBURSED
↓
STUCK (channel issues) → REJECTED (terminal, after max retries)
→ DISBURSED (after manual intervention)
↓
REJECTED (terminal)
6 states: Published, In Review, On Hold, Stuck, Disbursed, Rejected
Processing Architecture
- Disbursements are not processed in real time
- A Spring-based scheduler runs every 5 minutes to pick up pending disbursements
- This creates an implicit SLA of ~10 minutes from initiation to processing
- The scheduler interval is exposed in merchant-facing documentation (violation of contract-over-implementation principle)
Payout Channel Adapters
The Remittance SA doc reveals 8 payout provider adapters with inconsistent interfaces:
| Provider |
Versioned |
Endpoints |
Extras |
| 1Link |
Yes |
status, titleFetch, fundTransfer |
Standard |
| AamarPay |
Yes |
token, status, fundTransfer |
Has /token |
| Agrani |
No |
status, titleFetch, fundTransfer |
Standard |
| bKash |
No |
status, titleFetch, fundTransfer |
Standard |
| BRAC |
No |
status, titleFetch, fundTransfer, balance |
Has /balance |
| Faysal |
No |
status, titleFetch, fundTransfer, fundTransfer-b2c |
Has B2C variant |
| Prime |
No |
token, status, titleFetch, fundTransferNPSB, fundTransferBEFTN |
Split by network |
| PayMob |
No |
status, fundTransfer |
No titleFetch |
Key issue: No consistent adapter interface. Some require token auth, some have balance endpoints, some split transfer types by network. This increases the surface area for bugs when adding new providers.
Authentication
- RSA 2048-bit signing with PKCS#8, SHA-256
- Mutual TLS (2-way SSL)
- Request body wrapped in
"request": { ... } object
- Response body wrapped in
"response": { ... } object
6. Product Architecture: Remittances
Overview
Remittances handles cross-border money transfers. It adds FX rate management and multi-country compliance (AML) on top of the payout infrastructure.
API Endpoints (SA Doc)
| Endpoint |
Method |
Purpose |
/{merchantId}/initiate |
POST |
Quick remittance |
/{merchantId}/remit-initiate |
POST |
Full remittance (duplicate of initiate?) |
/{merchantId}/getFxRate |
POST |
Get FX rate (should be GET) |
/{merchantId}/confirmQuotation |
POST |
Lock FX rate quote |
/{merchantId}/fetch |
POST |
Search remittances (should be GET or POST /search) |
/{merchantId}/inquire |
POST |
Check remittance status (should be GET) |
/{merchantId}/fetch-account |
POST |
Get beneficiary info (should be GET) |
/{merchantId}/balance-data |
POST |
Get balance (should be GET) |
/{merchantId}/banks/list |
GET |
List banks |
/{merchantId}/reasons/list |
GET |
List failure reasons |
/{merchantId}/register-customer |
POST |
Register beneficiary |
Transaction State Machine
PUBLISHED (new, enum=1)
↓
IN_PROCESS (enum=2) → REMITTED (success, terminal, enum=5)
↓
IN_REVIEW (enum=3) → REMITTED
↓
ON_HOLD (enum=4) → REMITTED (after resolution)
↓
AML_REVIEW (enum=8) → REMITTED (after clearance)
→ REJECTED (terminal, enum=6)
↓
STUCK (enum=7) → REMITTED (after intervention)
→ REJECTED
↓
REJECTED (terminal, enum=6) → REVERSED (enum=9, balance restored)
9 states: Published, In Process, In Review, On Hold, Remitted, Rejected, Stuck, AML Review, Reversed
Webhook Coverage Gap
Only 4 of 9 states trigger webhooks:
- On Hold ✓
- Remitted ✓
- Rejected ✓
- Reversed ✓
States that are silent (no webhook — merchant must poll):
- Published, In Process, In Review, Stuck, AML Review
This is a significant operational gap. A merchant has no way to know a transaction is stuck in AML review unless they actively poll.
FX Rate Architecture
The flow is:
getFxRate → confirmQuotation → initiate
Undocumented:
- Quote validity window (how long before expiry?)
- Behaviour on expired quote
- Decimal precision for rates vs amounts
- Rate lock timing (on getFxRate or confirmQuotation?)
- What happens if steps are skipped or reordered
Authentication
- Same RSA signing as Pay-Outs
- Header:
mode: remitance (typo — missing 't', but may be baked into the protocol)
- Uses
commerceplex.com domain instead of simpaisa.com (trust/brand concern)
7. Product Architecture: Cards
Overview
Card acquiring for Visa and Mastercard. The most security-hardened product with AES encryption, mTLS, and PCI DSS compliance.
API Surface (from GitBook)
7 referenced APIs: Payments, Inquiry, Capture, Void, Finalize, Refunds, Postbacks, plus Response Codes.
Security Layers
| Layer |
Technology |
| Card data encryption |
AES (symmetric encryption) |
| Transport security |
Mutual TLS (2-way SSL) |
| Request signing |
RSA 2048-bit |
| Compliance |
PCI DSS |
Architectural Observations
- Most secure product in the portfolio
- Documentation is incomplete — the overview references 7 APIs but full endpoint schemas are sparse
- Webhook timeout of 40 minutes mentioned (unusually long)
8. Infrastructure Architecture (AWS)
Network Topology
Internet
↓
AWS WAF (edge protection)
↓
Internet Gateway
↓
┌─────────────────────── VPC ───────────────────────┐
│ │
│ ┌─── AZ-1 ───┐ ┌─── AZ-2 ───┐ │
│ │ Public │ │ Public │ │
│ │ subnet │ │ subnet │ │
│ └─────────────┘ └─────────────┘ │
│ ↓ ↓ │
│ ┌────────── ALB ──────────────┐ │
│ └─────────────────────────────┘ │
│ ↓ ↓ │
│ NAT Gateway │
│ ↓ ↓ │
│ ┌─── AZ-1 ───┐ ┌─── AZ-2 ───┐ │
│ │ Private │ │ Private │ │
│ │ EC2 (ASG) │ │ EC2 (ASG) │ │ ← GuardDuty
│ └─────────────┘ └─────────────┘ │ ← Parameter Store
│ ↓ ↓ │ ← CloudWatch
│ ┌─── AZ-1 ───┐ ┌─── AZ-2 ───┐ │
│ │ Private │ │ Private │ │
│ │ RDS │ ←shared→│ ElastiCache│ │
│ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────┘
What's Right
| Pattern |
Assessment |
| Multi-AZ deployment |
Correct — HA for payment processing |
| WAF at the edge |
Correct — blocks common attacks before they hit the ALB |
| Private subnets for compute |
Correct — EC2 instances not directly internet-accessible |
| Private subnets for data |
Correct — RDS and ElastiCache isolated |
| NAT Gateway for outbound |
Correct — private instances can reach payment channels |
| ALB (not NLB) |
Correct for HTTP/HTTPS API traffic |
| Auto Scaling Groups |
Correct — handles traffic spikes |
| GuardDuty |
Correct — threat detection baseline |
| Parameter Store |
Correct — secrets not in code (mostly — see deploy.sh issue) |
What's Missing or Concerning
| Gap |
Severity |
Details |
| No API Gateway |
HIGH |
No AWS API Gateway or Kong/Tyk. Rate limiting, auth, throttling must be implemented per-service instead of centrally |
| Single RDS instance (shared) |
HIGH |
All products appear to share one MySQL RDS. No per-service database isolation. A schema migration in Pay-Ins could affect Pay-Outs |
| No disaster recovery documentation |
HIGH |
Multi-AZ is not multi-region. No documented RPO/RTO targets for a payment platform |
| No distributed tracing |
HIGH |
CloudWatch only. No Jaeger, X-Ray, or OpenTelemetry. Cannot trace a transaction across services |
| No CDN for API docs/website |
MEDIUM |
GitBook and corporate site served without CloudFront |
| ElastiCache single cluster |
MEDIUM |
Appears to be one shared Redis cluster. Cache poisoning in one product affects all |
| No blue/green or canary deployment |
MEDIUM |
Auto Scaling Groups suggest rolling deployments. No documented zero-downtime deployment strategy |
| No IaC documented |
MEDIUM |
No evidence of Terraform, CloudFormation, or CDK. Infrastructure may be manually provisioned |
9. Data Architecture
Database Schema (Pay-Ins — from ERD)
The Pay-Ins ERD reveals 15 tables:
| Table |
Purpose |
Key Fields |
product_configuration |
Merchant-operator mappings, fee config |
merchantId, operatorId, product_productId |
product |
Product definitions |
productId, amount, description |
webhook |
Webhook endpoint config |
merchantId, platform, callbackUrl |
merchant_detail |
Merchant profiles |
merchantId, contact, email, phone |
currency |
Supported currencies |
currencyCode, currencyName |
transaction |
Core transaction records |
AC, amount, msisdn, status, operatorId, merchantId |
transaction_refund |
Refund records |
transactionId, amount, status |
operator |
Payment operators |
operatorId, operatorName, status |
operator_credentials |
Operator API credentials |
operatorId, credentialId, key |
operator_redirect_urls |
Redirect URLs per operator |
operatorId, merchantId |
postback |
Postback delivery records |
merchantId, transactionId, status |
api_logs |
API request/response logs |
transactionId, requestBody, responseBody |
refund_requests |
Refund request tracking |
transactionId, amount, status |
refund_transaction_status |
Refund state tracking |
transaction_id, refund_id, status |
external_response |
Error code mapping (3rd party → internal) |
responseCode, responseMessage |
Data Architecture Concerns
| Concern |
Severity |
Details |
| Shared database |
CRITICAL |
All products appear to use a single MySQL instance. No service-level database isolation |
| No documented retention policy |
HIGH |
Transaction records, API logs, PII — no documented retention periods or automated cleanup |
| PII in plain text |
HIGH |
MSISDN, account numbers, names stored. No documentation of encryption at rest or column-level encryption |
| Credential storage |
HIGH |
operator_credentials and easypaisa_credentials tables store third-party API keys. Encryption method not documented |
| No read replicas documented |
MEDIUM |
For a platform processing 270M+ transactions, read replicas are expected for reporting/analytics |
| Numeric status codes |
MEDIUM |
status=0 (pending), status=1 (success) instead of named enums. Brittle — adding a new status risks collisions |
10. Integration Architecture
Payment Channel Integrations
┌─── Easypaisa API
├─── JazzCash API
Merchant → Simpaisa API → ├─── HBL Konnect API (Pay-Ins)
├─── Alfa API
├─── JSBL Zindagi API
├─── Telenor DCB API
├─── Zong DCB API
└─── Ufone DCB API
┌─── 1Link (IBFT/RAAST)
├─── bKash API
Merchant → Simpaisa API → ├─── BRAC Bank API (Pay-Outs / Remittances)
├─── Faysal Bank API
├─── PayMob API
├─── Prime Bank API
├─── Agrani Bank API
└─── AamarPay API
Integration Patterns
| Pattern |
Used By |
Description |
| Synchronous REST |
Pay-Ins (sync flow), Pay-Outs inquiry |
Real-time request/response |
| Asynchronous with webhook |
Pay-Ins (async flow) |
Initiate returns pending, result via webhook |
| Scheduled batch |
Pay-Outs (disbursements) |
5-minute scheduler picks up pending transactions |
| Token-based recurring |
Pay-Ins (tokenisation) |
Stored token enables Direct Charge API without OTP |
| FX quote-lock-execute |
Remittances |
getFxRate → confirmQuotation → initiate |
Message Queue (Kafka)
Kafka is mentioned in the SA docs as part of the architecture but its specific usage is not documented:
- Likely used for inter-service communication
- Likely used for webhook delivery queue
- Likely used for transaction event sourcing
- No Kafka architecture documentation found — topic naming, partitioning, consumer groups, retention
11. Security Architecture
Authentication Mechanisms (Current State)
| Product |
Mechanism |
Strength |
Issues |
| Pay-Ins |
Custom headers + JSESSIONID cookie |
Weak |
No signing, session-based, forgeable |
| Pay-Outs |
RSA 2048-bit signing + mTLS |
Strong |
Well-documented |
| Remittances |
RSA signing + custom headers |
Strong |
Header typo (remitance) |
| Cards |
RSA signing + mTLS + AES encryption |
Strongest |
PCI DSS compliant |
Security Assessment
| Area |
Rating |
Details |
| Transport security (TLS) |
6/10 |
mTLS for Pay-Outs/Cards, but TLS version requirements not documented for Pay-Ins |
| Authentication |
4/10 |
Two products have proper signing, one uses session cookies |
| Authorisation |
5/10 |
merchantId validation exists but IDOR testing is not documented |
| Webhook security |
2/10 |
No signature verification — merchants cannot verify webhook authenticity |
| Credential management |
6/10 |
Parameter Store used, but Surge token in deploy.sh, credential tables in plain docs |
| Data protection (PII) |
3/10 |
No documented PII masking in logs or responses, no retention policy |
| Input validation |
4/10 |
No field-level validation rules documented, no regex patterns |
| Rate limiting |
2/10 |
Mentioned in architecture but zero documentation of actual limits |
| OTP security |
4/10 |
30-minute expiry is 6x industry standard (5 min), max attempts undocumented |
| Secret rotation |
2/10 |
No key rotation process documented |
Critical Security Findings
- Pay-Ins has no request signing. Any party knowing the merchantId and operatorId can forge requests.
- Webhook payloads are unsigned. Attackers can send fake webhooks to merchant callback URLs.
- 30-minute OTP window. A stolen OTP is valid for 30 minutes — should be 5 minutes maximum.
- Surge token in source control.
deploy.sh contains SURGE_TOKEN="28be224226e172996d603d3bd48c0735". Must be rotated immediately.
- No documented rate limiting. APIs are vulnerable to brute-force and denial-of-service without documented or evidenced rate limits.
- Database table names in merchant docs. Aids targeted SQL injection attempts.
12. API Architecture
Current State Summary
The API architecture has been audited in three documents:
- SA Docs Audit: 25 findings (6 Critical, 8 High, 7 Medium, 4 Low)
- GitBook Docs Audit: 28 findings (5 Critical, 10 High, 9 Medium, 4 Low)
- Open Banking UK Gap Analysis: 15-dimension comparison
API Fragmentation Matrix
| Dimension |
Pay-Ins |
Pay-Outs |
Remittances |
Cards |
| Base URL |
wallets.simpaisa.com (+ 4 others) |
disb.simpaisa.com |
remit.commerceplex.com |
payment.simpaisa.com |
| Auth |
JSESSIONID + custom headers |
RSA + mTLS |
RSA + headers |
RSA + mTLS + AES |
| URL pattern |
/v2/wallets/transaction/{action} |
/merchants/{id}/disbursements/{action} |
/{id}/{action} |
Unknown |
| merchantId |
In request body |
In URL path |
In URL path |
Unknown |
| Request wrapping |
Flat JSON |
{"request": {...}} |
{"request": {...}} |
Unknown |
| Response wrapping |
Flat JSON |
{"response": {...}} |
{"response": {...}} |
Unknown |
| Error format |
{"status":"0006","message":"..."} |
{"response":{"status":"0054","message":"..."}} |
{"response":{"status":"0000","message":"..."}} |
Unknown |
| Error code range |
0001-0095 |
0044-0119 |
Own range |
Own range |
| Idempotency |
Request-Id on verify only |
None |
None |
Unknown |
| Versioning |
/v2/ in URL + version:3.0 header |
None |
version:3.0 header |
Unknown |
| Status codes |
Likely 200 for everything |
200 documented |
Not documented |
Not documented |
| Pagination |
Not applicable |
Not documented |
Not documented |
Not documented |
This is the single biggest architectural debt. A merchant integrating Pay-Ins + Pay-Outs builds two completely different API clients with different auth, different error parsing, different URL construction, and different response unwrapping.
Target State (from API-STANDARDS.md)
The API Standards document defines the target architecture:
- Single domain: api.simpaisa.com
- Unified URL pattern: /v{version}/{product}/{merchantId}/{resource}
- RSA-SHA256 signing for all products
- Single error schema across all products
- Idempotency on all state-changing endpoints
- Proper HTTP status codes
- OpenAPI 3.1 as source of truth
Gap to Target
| Standard |
Current Compliance |
Effort |
| Single base URL |
0% (7 URLs) |
HIGH — infrastructure routing change |
| Unified URL pattern |
0% (3 patterns) |
HIGH — breaking change, parallel run |
| Unified auth |
33% (Pay-Outs + Remittances) |
HIGH — Pay-Ins rebuild |
| Standard error schema |
0% |
MEDIUM — response wrapper change |
| Idempotency |
10% (Pay-Ins verify only) |
MEDIUM — server-side implementation |
| HTTP status codes |
~0% (200 for everything) |
MEDIUM — response code changes |
| OpenAPI specs |
0% |
MEDIUM — documentation effort |
| Pagination |
0% |
LOW — additive change |
| Rate limiting |
0% documented |
MEDIUM — implementation + docs |
| Webhook signatures |
0% |
MEDIUM — implementation + docs |
Current Corporate Site
Tech stack: Next.js 15.4.8, React 18, Tailwind CSS 3.4.1, Strapi CMS backend
Repository: simpaisa1/sp-website (Bitbucket, project SW, 251MB)
Deployment: Jenkins CI/CD → AWS (4 environments: DEV, QA, UAT, PROD)
| Metric |
Score |
Code Evidence (verified 2026-04-02) |
| SEO health |
2/10 |
|
| AEO readiness |
1/10 |
|
| Pages discovered |
27 routes (25 static + 2 dynamic) |
Previously reported as 20+ |
| Broken pages |
/solutions returns 404 |
No app/solutions/page.js exists |
| robots.txt |
Missing |
No /public/robots.txt, no /app/robots.js |
| sitemap.xml |
Missing |
No /public/sitemap.xml, no /app/sitemap.js |
| Meta descriptions |
None on any page |
Root layout is "use client" — Next.js metadata API unusable |
| Canonical URLs |
None |
Zero matches for "canonical" in entire codebase |
| Open Graph tags |
Partial |
Only on blogs/[slug] and newsrooms/[slug] (with wrong type: "website" instead of "article") |
| JSON-LD schema |
Organisation only |
app/layout.js:86-97 — single schema with name, url, logo |
| H1 tags |
Missing on product page |
components/TwoCol/TwoCol.js:136 renders as <h3>. Case study page has 6× <h1> |
| H2 tag misuse |
Stats as H2 |
components/VerticalSlider/VerticalSlider.js:210 — <h2>{item.price}</h2> |
| Alt text |
73+ images affected |
10× alt="", 63× alt="img", 1+ missing entirely (worse than initially reported) |
| llms.txt |
Missing |
No /public/llms.txt |
| Client-side rendering |
CRITICAL |
app/layout.js:1 is "use client" — entire site CSR, crawlers see empty HTML |
| CSP |
Non-functional |
Missing default-src, script-src, style-src, img-src (next.config.mjs:29-36) |
| Contact form security |
No protection |
No CSRF, no rate limiting, no CAPTCHA, client-only validation |
| Bundle size |
Inflated |
Monaco Editor (~2MB), 9 font weights, duplicate carousel libraries |
| Favicon |
Missing |
No favicon files in /app/ or /public/ |
| Custom 404 |
Missing |
No app/not-found.js |
| Security: 4/10 |
Performance: 5/10 |
Accessibility: 3/10 |
Full technical audit: See API/Website-Technical-Audit.md (created 2026-04-02)
SEO audit with code evidence: See AEO/SEO-AEO-AUDIT-REPORT.md (addendum added 2026-04-02)
New AEO Site (Astro-based)
A replacement site is being developed:
| Attribute |
Details |
| Framework |
Astro 6.1 (SSG — Static Site Generation) |
| Components |
Preact for interactive elements |
| Content |
MDX for payment method pages |
| Schema markup |
Per-page JSON-LD (FAQPage, HowTo, Product, BlogPosting) |
| SEO |
Meta descriptions, canonical URLs, Open Graph, robots.txt, sitemap.xml |
| AEO |
llms.txt, CitationBlock component, FAQ component |
| Data |
payment-methods.json with structured fee/settlement data |
| Hosting |
Surge.sh (beta), target production TBD |
| Testing |
Vitest + Playwright (configured, not yet extensive) |
Assessment: The new Astro site is architecturally well-designed for SEO/AEO. It fixes every critical issue found in the corporate site audit. The key risk is deployment — it's currently on Surge.sh beta and needs a production hosting strategy (likely CloudFront + S3 or Vercel).
Content Architecture (AEO Site)
src/
├── pages/
│ ├── index.astro (homepage)
│ ├── company.astro (about)
│ ├── payments/
│ │ ├── index.astro (payment methods listing)
│ │ ├── compare.astro (comparison tool)
│ │ └── [id].astro (dynamic: per-method pages)
│ └── developers/
│ ├── docs.astro (API documentation entry)
│ └── changelog.astro (API changelog)
├── content/
│ ├── payments/ (MDX: per-method content)
│ │ ├── easypaisa.mdx
│ │ ├── jazzcash.mdx
│ │ ├── ibft.mdx
│ │ ├── cards.mdx
│ │ └── dcb-*.mdx (3 telco pages)
│ └── resources/
│ ├── changelog.mdx
│ └── glossary.mdx
├── components/
│ ├── CitationBlock.astro (AEO: structured citations)
│ ├── ComparisonTool.tsx (Preact: interactive comparison)
│ ├── FAQ.astro (structured FAQ with schema)
│ └── SchemaHead.astro (JSON-LD injection)
├── data/
│ └── payment-methods.json (structured product data)
└── layouts/
└── ContentPage.astro (global layout with SEO)
Planned Content (TODOs)
| Priority |
Item |
Status |
| P2 |
Competitor comparison pages (/payments/simpaisa-vs-jazzcash) |
Deferred |
| P3 |
Merchant rating/review system (AggregateRating schema) |
Deferred |
| P3 |
Blog + ongoing content programme |
Deferred |
| P3 |
Video content + social distribution |
Deferred |
| P4 |
ASO for Simpaisa mobile apps |
Deferred |
14. Developer Experience & Documentation
| Platform |
Content |
Quality |
| Internal SA Docs (.docx) |
Architecture, database schema, scheduler design |
Mixed — useful for engineering, leaked to merchants |
| GitBook (simpaisa.gitbook.io) |
Merchant-facing API docs |
Improved over SA docs, still 28 findings |
| New AEO site |
Payment method guides, developer docs entry point |
Good quality, not yet live |
Developer Experience Gaps
| Gap |
Impact |
Priority |
| No OpenAPI specs |
Merchants cannot auto-generate clients, cannot validate requests |
P1 |
| No SDKs |
Every merchant writes from scratch — Java, Python, Node.js, PHP, C# |
P1 |
| No Postman collection |
Merchants cannot quickly test endpoints |
P2 |
| Sandbox has no test scenarios |
No magic values for deterministic testing (success/failure/timeout) |
P1 |
| No interactive API explorer |
No Swagger UI or equivalent |
P2 |
| Auth code samples in 1 language only |
Need 5+ languages (Java, Python, Node.js, PHP, C#) |
P2 |
| No API changelog |
Merchants don't know when things change |
P2 |
| No status page |
No programmatic way to check if channels are operational |
P2 |
15. Operational Architecture
Monitoring & Observability
| Layer |
Current |
Target |
| Infrastructure metrics |
CloudWatch |
CloudWatch + Grafana dashboards |
| Application metrics |
CloudWatch (basic) |
Prometheus + Grafana |
| Logging |
OpenSearch (API logs) |
Structured logging → OpenSearch with correlation IDs |
| Distributed tracing |
None |
OpenTelemetry → Jaeger or AWS X-Ray |
| Alerting |
CloudWatch Alarms |
PagerDuty/OpsGenie with escalation policies |
| Status page |
None |
status.simpaisa.com with per-channel status |
| SLA monitoring |
None |
Track P95/P99 latency per endpoint per channel |
Incident Response
No incident response documentation found. For a payment platform, this should include:
- Runbook for common failure modes (channel down, database failover, Redis failure)
- Escalation matrix
- Communication templates for merchant notification
- Post-incident review process
- RPO/RTO targets per service
Deployment
| Attribute |
Current |
Concern |
| Strategy |
Rolling (ASG) |
No blue/green or canary documented |
| Rollback |
Unknown |
No documented rollback procedure |
| Database migrations |
Unknown |
No migration strategy documented |
| Feature flags |
Unknown |
No feature flag system documented |
| CI/CD pipeline |
Unknown |
No pipeline documentation found |
16. Cross-Cutting Concerns
Consistency Issues Across Products
| Concern |
Details |
Impact |
| Authentication |
3 different mechanisms |
Merchant confusion, security inconsistency |
| Error formats |
3 different structures |
Every merchant writes 3 error parsers |
| URL patterns |
3 different conventions |
3 different HTTP client configurations |
| Base URLs |
7 different domains/subdomains |
Firewall whitelisting complexity |
| Request wrapping |
Flat JSON vs {"request": {...}} |
Inconsistent serialisation logic |
| Status checking |
/inquire vs /verify vs implicit |
Inconsistent mental model |
| Bank listing |
/banks vs /banks/list |
Naming confusion |
| Naming |
camelCase in URLs (getFxRate, titleFetch) |
Violates REST conventions (kebab-case) |
Technical Debt Inventory
| Debt |
Origin |
Cost of Not Fixing |
| JSESSIONID auth in Pay-Ins |
Legacy design |
Security vulnerability, can't scale stateless |
| POST for GET operations |
Convenience over correctness |
Responses not cacheable, CDN bypass |
| 200 for all HTTP responses |
Legacy pattern |
Standard clients can't detect errors |
| Numeric status/type codes |
Database-driven design |
Brittle, unclear, error-prone |
| Internal details in docs |
No doc separation discipline |
Security risk, coupling |
| Shared database |
Monolithic origin |
Schema changes affect all products |
| No idempotency |
Not implemented |
Duplicate payments on retry |
| No webhook signing |
Not implemented |
Webhook spoofing possible |
| 7 base URLs |
Organic growth |
Merchant friction, brand confusion |
commerceplex.com domain |
Legacy/acquisition |
Trust erosion |
17. Risk Register
Critical Risks
| # |
Risk |
Likelihood |
Impact |
Mitigation |
| R1 |
Duplicate payments from missing idempotency |
HIGH |
CRITICAL |
Implement idempotency keys on all payment POST endpoints |
| R2 |
Forged Pay-Ins requests (no signing) |
MEDIUM |
CRITICAL |
Add RSA signing to Pay-Ins |
| R3 |
Webhook spoofing (no signature) |
MEDIUM |
HIGH |
Implement HMAC-SHA256 webhook signing |
| R4 |
OTP brute force (30-min window + no max attempts documented) |
MEDIUM |
HIGH |
Reduce to 5 minutes, enforce 3-attempt lockout |
| R5 |
Shared database failure cascading across all products |
LOW |
CRITICAL |
Database-per-service or at minimum read replicas |
| R6 |
No disaster recovery plan |
LOW |
CRITICAL |
Document RPO/RTO, implement multi-region failover |
| R7 |
Exposed credentials in source control |
HAS OCCURRED |
HIGH |
Rotate Surge token, use env vars, scan for secrets |
High Risks
| # |
Risk |
Likelihood |
Impact |
Mitigation |
| R8 |
Merchant churn from API fragmentation |
MEDIUM |
HIGH |
API standardisation programme |
| R9 |
Support overload from undocumented APIs |
HIGH |
MEDIUM |
OpenAPI specs, SDKs, sandbox test scenarios |
| R10 |
Regulatory compliance gap (no PII/retention docs) |
MEDIUM |
HIGH |
Document data retention, PII masking, GDPR-equivalent |
| R11 |
Search engine invisibility (SEO 2/10) |
ONGOING |
MEDIUM |
Deploy new AEO site |
| R12 |
No distributed tracing for incident debugging |
HIGH |
MEDIUM |
Implement OpenTelemetry |
18. Maturity Assessment
Capability Maturity Model
| Capability |
Level 1 (Ad Hoc) |
Level 2 (Managed) |
Level 3 (Defined) |
Level 4 (Measured) |
Level 5 (Optimised) |
| Payment processing |
|
|
● |
|
|
| Channel integration |
|
|
|
● |
|
| API design |
● |
|
|
|
|
| Security |
|
● |
|
|
|
| Documentation |
|
● |
|
|
|
| Observability |
● |
|
|
|
|
| DevOps/CI-CD |
● |
|
|
|
|
| Developer experience |
● |
|
|
|
|
| Web presence (SEO/AEO) |
● |
|
|
|
|
| Incident management |
● |
|
|
|
|
| Data governance |
● |
|
|
|
|
| Testing/QA |
|
● |
|
|
|
Summary
Simpaisa's core payment processing and channel integration capabilities are mature — the company has product-market fit, strong channel partnerships, and handles real money at scale. But the surrounding architecture (APIs, security, docs, observability, DevOps) is at Level 1-2, which creates operational risk and slows growth.
The gap between "can process payments reliably" and "is a well-architected payment platform" is where the work needs to happen.
19. Target Architecture & Preferred Stack
This section defines the target technology stack that Simpaisa should migrate towards. It replaces legacy components with modern, high-performance alternatives aligned with the company's strategic direction.
19.1 Target Stack Overview
| Layer |
Current |
Target |
Rationale |
| API Gateway |
None (per-service) |
KrakenD |
Ultra-high-performance, declarative config, OpenAPI-native. Handles auth, rate limiting, aggregation, CORS at the edge. Eliminates per-service reimplementation of cross-cutting concerns |
| API Documentation |
GitBook (manual) |
Stoplight (design) + Scalar (portal) |
Stoplight for OpenAPI design, linting (Spectral), and governance. Scalar for beautiful, interactive API reference docs. Replaces hand-written GitBook |
| Workflow Orchestration |
Spring scheduler (5-min cron) |
Temporal |
Durable workflow execution for payment processing, disbursement scheduling, retry logic, FX quote lifecycle. Eliminates fragile cron-based processing. Built-in saga pattern for multi-step payment flows |
| Serverless Workflows |
None |
Serverless Workflow (serverlessworkflow.io) |
CNCF standard for defining workflow DSL. Complements Temporal for lightweight, event-driven flows (webhook delivery, notification chains) |
| Primary Database |
MySQL (shared RDS) |
SurrealDB |
Multi-model (document + graph + relational), real-time subscriptions, built-in auth, per-table permissions. Enables per-service data isolation without per-service database ops overhead. Native support for time-series transaction data |
| Search |
OpenSearch (logs only) |
Meilisearch |
Typo-tolerant, instant search for merchant dashboards, transaction lookup, bank/channel search. Sub-50ms responses. Replaces OpenSearch for user-facing search (keep OpenSearch for log aggregation) |
| Cache / Message Queue |
Redis + Kafka |
NSQ (messaging) + Redis (cache) |
NSQ for real-time message delivery — webhook fanout, event streaming, inter-service communication. Simpler operations than Kafka (no ZooKeeper, no partition management). Keep Redis for caching and rate limiting |
| Analytics / Product |
CloudWatch only |
PostHog |
Product analytics, session replay, feature flags, A/B testing, funnels. Replaces the "no observability" gap for product and merchant behaviour tracking. Self-hostable for PII compliance |
| Observability |
CloudWatch |
OpenTelemetry → backends |
Vendor-neutral telemetry collection. Traces, metrics, logs unified. Feeds into Grafana (metrics), Jaeger (traces), and existing CloudWatch (infrastructure) |
| Identity / Access |
Custom (merchantId + RSA) |
ControlPlane.com |
Centralised identity, policy, and access management across all services and merchant tenants. Fine-grained RBAC/ABAC. Service mesh identity. Replaces per-service auth implementation |
| Reverse Proxy / TLS |
ALB |
Caddy (per-service) + ALB (edge) |
Automatic HTTPS, HTTP/3, reverse proxy with zero-config TLS cert management. Use at the service level behind ALB for mTLS termination, internal routing, and local dev parity |
| Compute (New Services) |
EC2 (Spring Boot / Java) |
Unikraft unikernels on Cloudflare / EC2 |
Ultra-lightweight, single-purpose VMs for new microservices. Sub-millisecond cold start. Dramatically reduced attack surface (no OS, no shell, no unnecessary packages). Ideal for payment processing where security and performance are paramount |
| Edge / CDN |
None (direct ALB) |
Cloudflare |
CDN, DDoS protection, Workers for edge logic, R2 for static assets, DNS. Replaces AWS WAF + CloudFront with a unified edge platform. Workers enable edge-side rate limiting and request validation |
| AI / Automation |
None |
Claude (API) + Claude Code |
AI-powered code review, documentation generation, incident analysis, merchant support automation. Claude Code for engineering productivity |
19.2 Programming Languages
| Language |
Use Case |
Current |
Migration Path |
| Go |
Core payment services, API gateway plugins, high-throughput processing |
Java (Spring Boot) |
New services in Go. KrakenD plugins in Go. Migrate critical-path services from Spring Boot |
| Python |
Data pipelines, ML/analytics, scripting, PostHog integrations |
None documented |
New capability — analytics, reporting, reconciliation scripts |
| Rust |
Security-critical modules, cryptographic operations, Unikraft services |
None |
Signature verification, encryption modules, performance-critical paths |
| TypeScript |
Web platforms, Cloudflare Workers, merchant dashboard, SDKs |
None (Java everywhere) |
Merchant-facing web apps, Cloudflare Workers edge logic, generated TypeScript SDKs |
| Astro |
Corporate website, developer portal, documentation site |
Already adopted (AEO project) |
Continue — deploy to production on Cloudflare Pages |
| Platform |
Technology |
Hosting |
| Corporate site (simpaisa.com) |
Astro (SSG) |
Cloudflare Pages |
| Merchant dashboard |
TypeScript + React/Preact |
Cloudflare Pages + Workers |
| Developer portal (API docs) |
Scalar (from OpenAPI specs) |
Cloudflare Pages |
| API design / governance |
Stoplight |
SaaS |
| Status page |
Self-hosted or Cloudflare Workers |
Cloudflare |
19.4 Mobile
| Platform |
Status |
Technology |
| App Store (iOS) |
Planned / existing (ASO audit pending) |
Native or React Native |
| Play Store (Android) |
Planned / existing (ASO audit pending) |
Native or React Native |
| Merchant mobile app |
Feature-gated rollout via PostHog |
— |
19.5 Target Architecture Diagram
┌─────────────────────────────────────────┐
│ Cloudflare Edge │
│ CDN · WAF · DDoS · Workers · Pages │
│ Rate limiting · Request validation │
└──────────────┬──────────────────────────┘
│
┌──────────────▼──────────────────────────┐
│ KrakenD API Gateway │
│ Auth · Rate limit · Aggregation │
│ OpenAPI validation · Request routing │
│ ControlPlane.com identity integration │
└──┬───────┬────────┬────────┬────────────┘
│ │ │ │
┌────────▼┐ ┌───▼────┐ ┌─▼──────┐ ┌▼──────────┐
│ Pay-Ins │ │Pay-Outs│ │Remit │ │ Cards │
│ (Go) │ │ (Go) │ │ (Go) │ │ (Go/Rust) │
│ + Caddy │ │+ Caddy │ │+ Caddy │ │ + Caddy │
└────┬─────┘ └───┬────┘ └──┬─────┘ └──┬────────┘
│ │ │ │
┌─────────▼───────────▼─────────▼───────────▼──────┐
│ Temporal │
│ Payment workflows · Disbursement scheduling │
│ FX quote lifecycle · Retry/saga orchestration │
│ Webhook delivery workflows │
└──────────────────────┬─────────────────────────────┘
│
┌──────────┬────────────────┼──────────────┬──────────────┐
│ │ │ │ │
┌───▼────┐ ┌──▼──────┐ ┌─────▼──────┐ ┌─────▼────┐ ┌──────▼────┐
│SurrealDB│ │ Redis │ │ NSQ │ │Meilisearch│ │ PostHog │
│ (data) │ │ (cache) │ │ (messages) │ │ (search) │ │(analytics)│
└────────┘ └─────────┘ └────────────┘ └──────────┘ └───────────┘
│
┌───────────▼──────────────────────┐
│ OpenTelemetry Collector │
│ Traces → Jaeger │
│ Metrics → Grafana │
│ Logs → OpenSearch │
└──────────────────────────────────┘
External Channels:
Easypaisa · JazzCash · HBL Konnect · Alfa · JSBL Zindagi
Telenor DCB · Zong DCB · Ufone DCB · 1Link · RAAST
bKash · BRAC · Faysal · PayMob · Prime · Agrani · AamarPay
Visa · Mastercard
Developer Tooling:
Claude Code → engineering productivity
Stoplight → API design & governance
Scalar → interactive API docs
Cloudflare Pages → static site hosting
PostHog → feature flags & A/B testing
19.6 Migration Strategy: Current → Target
The migration is not a big-bang rewrite. It follows a strangler fig pattern:
| Phase |
Components |
Approach |
| Immediate (no migration needed) |
Cloudflare (edge), PostHog (analytics), OpenTelemetry (observability), Stoplight + Scalar (docs), Claude Code (tooling) |
Additive — deploy alongside existing stack |
| Gateway first |
KrakenD |
Deploy in front of existing Spring Boot services. Route all traffic through KrakenD. Implement auth, rate limiting, error standardisation at the gateway without changing backends |
| New services in Go |
Any new microservice or feature |
Write in Go, deploy behind KrakenD. Existing Spring Boot services continue running |
| Temporal for workflows |
Disbursement scheduler, webhook delivery, FX quote lifecycle |
Replace Spring cron scheduler with Temporal workflows. Biggest operational improvement |
| NSQ for messaging |
Inter-service events, webhook fanout |
Replace Kafka for simpler operational model. Run alongside during migration |
| SurrealDB for new services |
New services get SurrealDB. MySQL stays for existing services |
Per-service databases. No forced migration of existing data |
| Meilisearch for search |
Merchant-facing search (transactions, banks, channels) |
Deploy alongside OpenSearch. OpenSearch remains for log aggregation |
| Unikraft for critical paths |
Signature verification, encryption, high-security payment processing |
Deploy Rust-based unikernels for security-critical functions |
| ControlPlane.com |
Centralised identity and policy |
Gradual: start with new services, then migrate existing auth |
| Caddy |
Per-service reverse proxy |
Deploy alongside services for mTLS, HTTP/3, cert management |
20. Strategic Recommendations
Phase 1: Secure the Foundation (Weeks 1-4)
Goal: Eliminate critical security and reliability risks.
| # |
Action |
Addresses |
Effort |
| 1 |
Implement idempotency keys on all payment POST endpoints |
R1 |
M |
| 2 |
Add RSA signing to Pay-Ins (eliminate JSESSIONID) |
R2 |
L |
| 3 |
Implement HMAC-SHA256 webhook signing |
R3 |
M |
| 4 |
Reduce OTP expiry to 5 minutes, document max attempts |
R4 |
S |
| 5 |
Rotate exposed Surge token, scan all repos for secrets |
R7 |
S |
| 6 |
Define standard error response schema |
API fragmentation |
M |
| 7 |
Document HTTP status codes for every endpoint |
API fragmentation |
S |
| 8 |
Separate internal architecture docs from merchant docs |
Security |
M |
Phase 2: Standardise the APIs (Weeks 5-10)
Goal: Create a consistent, well-documented API platform.
| # |
Action |
Addresses |
Effort |
| 9 |
Write OpenAPI 3.1 specs for all 4 products |
Documentation |
L |
| 10 |
Implement Spectral linting in CI |
Quality gates |
M |
| 11 |
Standardise URL patterns (with parallel-run migration) |
Fragmentation |
XL |
| 12 |
Add pagination to all list endpoints |
Missing feature |
M |
| 13 |
Document rate limits, implement rate limit headers |
Missing feature |
M |
| 14 |
Document FX rate quote validity and lifecycle |
Underspecified |
S |
| 15 |
Document transaction state machines with webhook mapping |
Underspecified |
M |
| 16 |
Define versioning strategy and deprecation policy |
Undefined |
S |
Phase 3: Developer Experience (Weeks 11-14)
Goal: Make merchant integration fast and self-service.
| # |
Action |
Addresses |
Effort |
| 17 |
Generate SDKs from OpenAPI specs (Java, Python, Node.js, PHP, C#) |
No SDKs |
M |
| 18 |
Build sandbox test scenarios with magic values |
No test scenarios |
M |
| 19 |
Deploy Swagger UI / Redocly developer portal |
No API explorer |
M |
| 20 |
Create Postman collections from OpenAPI specs |
No quick testing |
S |
| 21 |
Deploy new AEO site to production (CloudFront + S3 or Vercel) |
SEO 2/10 |
M |
| 22 |
Implement status page (status.simpaisa.com) |
No status visibility |
M |
Phase 4: Operational Excellence (Weeks 15-20)
Goal: Build the operational infrastructure for a payment platform at scale.
| # |
Action |
Addresses |
Effort |
| 23 |
Implement distributed tracing (OpenTelemetry) |
No tracing |
L |
| 24 |
Add x-request-id correlation across all services and webhooks |
No correlation |
M |
| 25 |
Document incident response runbooks |
No IR process |
M |
| 26 |
Define RPO/RTO and implement DR plan |
No DR |
L |
| 27 |
Implement API Gateway (rate limiting, auth, throttling) |
No central gateway |
L |
| 28 |
Document PII handling, data retention, masking |
No data governance |
M |
| 29 |
Consolidate base URLs to api.simpaisa.com |
7 URLs |
L |
| 30 |
Migrate Remittances domain from commerceplex.com |
Brand/trust |
M |
Phase 5: Scale & Mature (Ongoing)
| # |
Action |
Addresses |
Effort |
| 31 |
Database-per-service migration (or at minimum read replicas) |
Shared DB risk |
XL |
| 32 |
Normalise payout provider adapter interfaces |
Internal inconsistency |
L |
| 33 |
Implement blue/green or canary deployment strategy |
Deployment risk |
L |
| 34 |
Infrastructure as Code (Terraform/CDK) |
Manual infrastructure |
L |
| 35 |
Contract testing (Schemathesis) against OpenAPI specs |
Spec drift |
M |
| 36 |
Reconciliation API for merchants |
Missing feature |
L |
| 37 |
Batch/bulk disbursement endpoint |
Missing feature |
L |
| 38 |
Apply API standards audit to Bangladesh, Nepal, Iraq APIs |
Regional consistency |
L |
Appendix: Source Documents
This review was compiled from the following source materials:
Audit Reports
| Document |
Date |
Findings |
| API-Best-Practices-Audit.md (SA Docs) |
2026-03-31 |
25 findings (6C, 8H, 7M, 4L) |
| GitBook-API-Audit.md |
2026-04-01 |
28 findings (5C, 10H, 9M, 4L) |
| OpenBanking-Comparison-Audit.md |
2026-04-01 |
15-dimension gap analysis |
| SEO-AEO-AUDIT-REPORT.md |
2026-03-31 |
SEO 2/10, AEO 1/10 |
Technical Specifications
| Document |
Type |
Product |
| PayIn PK Technical Specs.pdf |
Internal SA doc |
Pay-Ins |
| Disbursement SA v1.0 - Draft.docx |
Internal SA doc |
Pay-Outs |
| Remittance SA v1.0 - Draft.docx |
Internal SA doc |
Remittances |
| GitBook (simpaisa.gitbook.io) |
External docs |
All products |
Architecture Artifacts
| Artifact |
Source |
Content |
| AWS Architecture Diagram |
PayIn PK Technical Specs.pdf |
VPC, ALB, EC2, RDS, ElastiCache |
| Pay-Ins ERD |
PayIn PK Technical Specs.pdf |
15 database tables |
| Sync Flow Diagram |
PayIn PK Technical Specs.pdf |
Transaction processing flowchart |
| Async Flow Diagram |
PayIn PK Technical Specs.pdf |
Async processing flowchart |
| Recurring Flow Diagram |
PayIn PK Technical Specs.pdf |
Tokenisation flowchart |
Standards Documents
| Document |
Date |
Status |
| API-STANDARDS.md |
2026-04-01 |
Active — defines target API architecture |
| Artifact |
Source |
Content |
| AEO site source code |
/Work/AEO/ |
Astro 6.1 + Preact + MDX |
| payment-methods.json |
/Work/AEO/src/data/ |
7 payment channels with fees, settlement, reach |
| TODOS.md |
/Work/AEO/ |
Planned content roadmap |
Not Available for This Review
| Source |
Status |
Impact |
| Confluence spaces |
No API access configured |
Could not search company knowledge base |
| Jira tickets |
No API access configured |
Could not assess backlog or incident history |
| Git repositories |
Not in scope |
Could not review application source code |
| Disbursement SA v1.0 - Draft.docx |
Binary format, not fully readable |
Partial information from other docs |
| Remittance SA v1.0 - Draft.docx |
Binary format, not fully readable |
Partial information from other docs |
| Bangladesh/Nepal/Iraq API docs |
Not assessed |
Regional consistency unknown |
This document should be updated quarterly as architectural changes are implemented. Next review: 2026-07-01.