Available for automation projects

COD RTO Reduction System

Five coordinated n8n workflows that measurably lower Cash-on-Delivery return-to-origin rates for a Bangladesh-based e-commerce retailer.

n8n PostgreSQL Telegram
Courier handing a package to a customer at the door

The problem

In Cash-on-Delivery markets, a meaningful share of orders never get delivered. The courier tries, the customer isn't there, isn't reachable, or simply declines at the door. Every one of those returns costs the shop shipping both ways with zero revenue. Fraud-scoring tools that just flag risky orders don't fix this on their own. They don't change customer behavior.

The approach

The system is built around one idea: intent-based friction beats a fraud score. Asking a risky customer to confirm by SMS, or to put down a small advance payment, changes their behavior before the parcel ever ships. The fraud score's job is narrower: decide who gets asked, not whether to block them outright.

  1. Scorer/Router normalizes the order, checks the shop's own blacklist (the only hard block), calls a fraud-scoring API as a router input only, and routes to auto-ship, SMS-confirm, advance-payment, or human review.
  2. Payment Callback verifies the gateway's signature before trusting anything in the payload, then marks the advance payment received. Shipped feature-flagged off until the real gateway was confirmed.
  3. Review lets a human approve or reject the orders the router couldn't confidently place. A reject scopes a blacklist entry to that specific client, never a blanket ban.
  4. Proof Loop records what actually happened to each order, then sends a weekly plain-English digest of the RTO trend, built before the router that depends on it.
  5. Error Handler catches errors from every workflow above and pushes a Telegram alert with the workflow, node, and error message.

Architecture

flowchart LR
    A[Order Intake Webhook] --> N[Normalize Order + Phone Match]
    N --> C[(Check Blacklist and Order History)]
    C --> BL{Blacklisted}
    BL -- yes --> BLOCK[Hard Block, No API Call]
    BL -- no --> FS[FraudShield Risk Check]
    FS --> RS[Compute Risk Score]
    RS --> ROUTE{Risk Band}
    ROUTE -- low --> APPROVE[Auto Approve, Ship]
    ROUTE -- medium --> SMS[SMS Auto Confirm]
    ROUTE -- high --> PAY[Advance Payment Link - feature flagged]
    ROUTE -- review --> TG[Telegram Review Request]
    TG --> HUMAN[Ops Approves or Rejects]
    PAY --> IPN[Payment Gateway Webhook]
    IPN --> VERIFY{Signature Valid}
    VERIFY -- yes --> PAID[Mark Advance Paid]
    VERIFY -- no --> REJECT[Reject - fails closed]
    COURIER[Courier Status Webhook] --> OUTCOME[(Upsert Final Outcome)]
    OUTCOME --> DIGEST[Weekly ROI Digest to Telegram]
                    

Engineering decisions

Idempotency everywhere

Every write is an upsert keyed on order ID. A duplicated webhook call never double-charges, double-texts, or double-counts a delivery outcome.

Fails closed, never fake

The payment callback's signature verification always rejects until a real gateway is wired in. It never pretends to validate something it can't.

No veto power for third parties

A timeout, error, or missing data on the fraud-scoring API routes to human review, never to auto-approval and never to an auto-block.

Tested before a real credential existed

Every workflow was validated and traced node by node, then exercised end to end with simulated data. A real runtime bug was caught this way before anything touched production.

Orchestration

n8n Workflow SDK

Data

PostgreSQL

Messaging

Telegram Bot API

Want something like this built for your business?