GODAMRI
Systems & Architecture•Jan 2025•12 min read

Architecting an Omnichannel Retail Ecosystem: Serialized Inventory, Accurate Online ERP Sync, and Automated Sinarmas Warranty Issuance

How we built a hybrid distributed core monolith across 8 codebases to eliminate ghost inventory on IDR 20M–80M cameras, gatekeep physical serial numbers at retail counters via Accurate Online ERP, and automate Sinarmas warranty policy issuance.

Verified Benchmark
Inventory Accuracy: 100%Sub-60s In-Store Pickup · Zero Phantom Stock

Selling high-ticket professional electronics—such as flagship mirrorless cameras (IDR 20M–80M), cine lenses, and enterprise drones—exposes every weak seam in standard e-commerce architecture.

When inventory is shared across nationwide retail brick-and-mortar stores, e-commerce web storefronts, mobile apps, and authorized partner microsites, the classic distributed system challenge becomes acute: how do you prevent double-selling a serialized, high-value asset without creating crippling distributed lock contention across physical counter checkout lanes?

Here is the architectural breakdown of how we designed, deployed, and scaled an omnichannel retail ecosystem spanning 8 decoupled codebases, connecting physical retail POS terminals to Accurate Online (AOL) ERP, and orchestrating automated warranty policy registration with PT Asuransi Sinarmas via API.


1. High-Level Ecosystem Topology

The platform is architected as a Hybrid Distributed Core Monolith complemented by dedicated operational microservices:

text
source
[ Client & Operational Interfaces ]
  ├── Web Client & Mobile App (Customer Checkout)
  ├── React 17 Retail POS SPA (Store Staff & Cashier Desk)
  ├── Multi-Tenant Partner Portal (Subdomain Brand Microsites)
  └── Backoffice AdminLTE Hub (Warehouse & Fulfillment)
            │
            ▼
[ Core Engines & Gateways ]
  ├── Core Monolith (Catalog, Cart State Machine, Auctions, Crons)
  ├── O2O Bridge Middleware (Sanctum Auth, Accurate ERP OAuth2 Adapter)
  ├── Payment Microservice & Settlement Router (Midtrans / BCA Direct)
  └── Media Transcoding CDN (WebP Variants & SHA Deduplication)
            │
            ▼
[ External Enterprise Ecosystem ]
  ├── Accurate Online (AOL) ERP (Fiscal Ledgers & Serial Stock)
  ├── Asuransi Sinarmas API (Automated Extended Warranty & Drone Policies)
  └── Payment Gateways & Banking APIs (Idempotent Webhooks)

Architectural Separation of Concerns

  1. Core Platform (Laravel 8.x): Serves as the central catalog, shopping cart finite-state machine, secondhand auction engine, and primary event dispatcher.
  2. O2O Bridge Middleware (Laravel Sanctum): Operates as an isolated, resilient gateway to Accurate Online ERP, shielding physical store checkout counters from third-party API latency.
  3. Retail POS Application (React 17, MUI v5): Runs in physical retail branches across Indonesia, driving barcode/QR scanning, serialized hardware verification, and customer Down Payments (DP).
  4. Payment Driver & Reverse Proxy (CodeIgniter 3 + Lumen): Handles multi-gateway aggregation, HMAC-SHA256 signature verification, and conflict-free manual bank transfer reconciliation.

2. The Hardware Serial Number (SN) Gatekeeper & BOPIS Flow

The highest risk in camera retail is "ghost fulfillment"—a customer orders online for in-store pickup (Buy Online Pick up In Store - BOPIS), but by the time they arrive, store staff has already handed that specific camera box to a walk-in retail customer.

To solve this, we enforced an immutable physical verification gatekeeper: an order cannot transition to COMPLETED until a physical barcode scanner reads a valid Serial Number directly from the retail store's designated Accurate Online warehouse database.

text
source
CUSTOMER (Web/App)         STORE CASHIER (React POS)      O2O BRIDGE        ACCURATE ERP
    │                                  │                      │                  │
    ├── 1. Checkout (BOPIS) ───────────┼──────────────────────┼──────────────────┤
    │   Select Target Branch Store     │                      │                  │
    ├── 2. Payment Confirmed (PAID) ───┼──────────────────────┼──────────────────┤
    │   Receives Pickup QR Code        │                      │                  │
    │                                  │                      │                  │
    ├── 3. Customer Arrives at Store ─►│                      │                  │
    │   Presents QR Code               ├── 4. Scan QR ───────►│                  │
    │                                  │   Fetch Order Items  │                  │
    │                                  │                      │                  │
    │                                  ├── 5. Physical Scan ─►│                  │
    │                                  │   Read Box Barcode SN│                  │
    │                                  │                      ├── 6. Verify SN ─►│
    │                                  │                      │   In Branch WH?  │
    │                                  │                      │◄─ 7. Validated ──┤
    │                                  │◄─ 8. Unlock Handover─┤                  │
    │                                  │                      │                  │
    │                                  ├── 9. Complete Pick ─►├── 10. Post SO ──►│
    │◄── 11. Handover Camera & Invoice ┤                      │   Deduct Stock   │

Zero-Overselling Implementation

  1. Atomic Soft Reservation: When an online customer enters checkout, inventory quota is temporarily locked in Redis with a 30-minute expiration window.
  2. Branch Warehouse DB Isolation: Accurate Online maintains separate database contexts per physical branch. The O2O bridge dynamically switches tenant database tokens based on the store officer's location.
  3. Hardware SN Verification API: Before the cashier's UI enables the "Complete Pickup" action, the backend invokes AccurateApiController@fetchSerialNumber. If the scanned serial number is not physically allocated to that branch warehouse in the ERP, the transaction is rejected on the spot.

3. Event-Driven Warranty Policy Issuance (Asuransi Sinarmas API)

Camera equipment frequently suffers accidental physical damage or liquid spills during fieldwork. The ecosystem provides integrated electronic device protection (Extended Warranty & Drone Protection) underwritten by PT Asuransi Sinarmas.

Previously, warranty registration required tedious manual paperwork. We engineered an event-driven policy issuance pipeline that integrates with the Sinarmas API to generate legal, verifiable electronic insurance certificates within seconds of payment settlement:

text
source
[ Event: OnCartPaid ]
         │
         ├── 1. Deduct Promotional Quotas & Update Sold Counters
         ├── 2. Asynchronous ERP Sales Order Sync
         └── 3. Dispatch Job: InformProtection
                     │
                     ▼
             Evaluate Category & SKU Blacklist
             (Filter out ineligible batteries, cables, or accessories)
                     │
                     ▼
             Fetch Sinarmas Auth Token (Dynamic 4-Day Cache)
                     │
                     ▼
             POST /dataservice/createtoken.php
             Payload: Customer NIK, Invoice ID, Camera SKU, Scanned Serial Number
                     │
                     ▼
             Receive Policy Token & Electronic Certificate Number
                     │
                     ▼
             Render Official Policy Certificate (DomPDF)
             Includes cryptographic signature & verification QR Code

Fault-Tolerant Policy Issuance Design

External insurance APIs can experience periodic maintenance or connectivity drops. Rather than blocking payment completion:

  • If the Sinarmas token service times out, the purchase is committed to warranty_insurance_purchases with a STATUS_PENDING flag.
  • A resilient scheduled worker (warranty:check-pending) scans pending records every 5 minutes with exponential backoff.
  • Backoffice administrators have an idempotent Regenerate Polis action with complete audit trails (warranty_insurance_rest_history).

4. Resilience & The Transactional Outbox Pattern

A primary architectural decision was: How do we coordinate state between our relational database (MySQL) and the external Accurate Online ERP?

Using distributed two-phase commits (2PC) over public HTTP endpoints is an anti-pattern that destroys availability. If Accurate Online experiences a 3-second network spike, tying up incoming web checkout threads would rapidly exhaust PHP-FPM worker pools.

Instead, we adopted an Asynchronous Outbox & Retry Queue Pattern:

plain
source
// Storing the outbox payload inside the local ACID transaction
DB::beginTransaction();
try {
    $cart->status = Cart::STATUS_PAID;
    $cart->save();

    // Push ERP synchronization payload to the persistent outbox table
    ApiCallQueue::create([
        'endpoint'    => '/api/sales-order/save.do',
        'payload'     => json_encode($salesOrderPayload),
        'status'      => 'PENDING',
        'retry_count' => 0,
        'max_retries' => 5,
    ]);

    DB::commit();
} catch (\Exception $e) {
    DB::rollBack();
    throw $e;
}

Outbox Worker & Dead-Letter Recovery

  • A background cron worker (erp:fetch-accurate-responses) executes every 5 minutes, picking up pending payloads in batches.
  • When Accurate Online returns a rate-limit (429) or server error (500), the payload is transitioned to an error table (o2o_accurate_fails) with incremented retry hits.
  • A single-click "Reset Hits" control in the operational backoffice allows finance and inventory managers to re-queue failed synchronization requests deterministically once network connectivity is restored.

5. Decoupled Payment Microservice & Reconciliation

Handling multi-million rupiah transactions requires zero payment drop tolerance. We decoupled the payment ingestion layer into a specialized payment driver service:

Algorithmic 3-Digit Unique Transfer Codes

For customers utilizing manual bank transfers, accounting departments often struggle with manual verification. We engineered an algorithmic 3-digit unique payment code generator:

  • When a customer selects manual bank transfer, the payment engine queries all active transactions in STATUS_PAYMENT_PENDING.
  • It calculates an integer offset (1 <= N <= 999) that is provably unique among all unresolved invoices.
  • When bank mutation webhooks arrive from corporate banking APIs, the system matches the exact amount down to the single rupiah, triggering automatic order settlement without human intervention.

Reverse Proxy & Webhook Verification

Payment callbacks from Midtrans and direct banking partners pass through a dedicated reverse proxy (toko-router):

  • Incoming HTTP payloads are validated against cryptographic HMAC-SHA256 signatures.
  • Requests and upstream responses are written into an immutable audit ledger (log database).
  • Idempotent callback locking ensures that duplicated webhook deliveries from payment gateways never trigger duplicate order fulfillments or duplicate policy registrations.

6. Key Operational Results

text
source
METRIC                            BEFORE SYSTEM ARCHITECTURE       AFTER SYSTEM ARCHITECTURE
────────────────────────────────────────────────────────────────────────────────────────────
In-Store BOPIS Handover Time      12 – 25 minutes (manual calls)   < 60 seconds (QR scan)
Inventory Shrinkage (Flagships)   Frequent phantom allocations     Zero discrepancies (100% serialized)
Sinarmas Warranty Issuance        Manual paper filing (2-3 days)   Instant automated PDF policy
ERP Synchronization Latency       End-of-day batch manual CSV      Near real-time outbox queues
Payment Reconciliation Speed      Manual bank mutation checks      Sub-second automated matching

By enforcing strict system boundaries, treating physical serial numbers as first-class constraints, and decoupling critical financial integrations through event-driven outbox patterns, we transformed a fragmented retail operation into an enterprise-grade omnichannel engine.