← All case studies

Business applications · Fintech / APAC · RedDot Payment

Payment CRM & gateway (RedDot Payment)

Sevendyne built a remote PHP and Android team for RedDot Payment (PayU-group APAC), then that team worked with their product and gateway leads to design and ship the CodeIgniter CRM — EMI plans, payment channels, payment forms, and companion Android for merchant operations in Singapore and Indonesia.

Technical one-pager for prospects: Open brief → Print to PDF

3-minute CTO brief

We staffed a dedicated PayU-group pod for RedDot Payment and embedded them with client engineering — daily standups, shared PR reviews, and pairing on tenant boundaries. They needed one CRM that could serve Singapore and Indonesia tenants without cross-leaking merchant data — while EMI plans, wallet channels, and QR flows kept shipping on live traffic. The team isolated tenants at the DB boundary, wrapped each payment provider behind adapters, and staged schema changes with feature flags.

  • Complexity: Multi-tenant CRM, money movement, mobile QR
  • Constraint: Zero-downtime migrations on production APAC
  • Stack: CodeIgniter · Android · adapter-per-channel

Multi-tenant fintech · EMI · payment adapters

Architecture — tenant-safe payments CRM

Multi-tenant payments architecture

Every request carries tenant_id resolved at the edge. CRM entities, ledger views, and reconciliation exports are scoped queries — no shared tables without tenant prefix. Mobile Android clients use the same REST contracts with device-bound credentials.

EMI & channel design

AreaDesign choiceRationale
EMI schedulesState machine per plan (draft→active→delinquent→closed)Operators see auditable transitions; cron jobs idempotent per installment.
Payment channelsAdapter interface per providerNew wallet/QR provider = new adapter, not forked CRM.
Schema changesShadow columns + dual-write windowLive merchants never see broken reconciliation during deploy.
Android appThin client, server-side validationQR payloads validated server-side; app handles offline queue only.

Code shape (representative)

// Channel adapter contract — each provider implements
interface PaymentChannelAdapter {
  public function initiate(PaymentIntent $intent): ChannelResponse;
  public function capture(string $providerRef): CaptureResult;
  public function reconcile(ReconBatch $batch): ReconSummary;
}

// Tenant guard on every CRM query
$merchant = MerchantModel::forTenant($tenantId)->find($id);

Production outcomes

  • Daily online payments for consumers and merchants in Singapore & Indonesia.
  • Unified CRM for wallet, merchant, and logistics channels on PayU-group infra.
  • Staged rollout — backward compatible APIs through migration windows.

Download technical brief (PDF) Schedule a technical review