Back to board

Food delivery: completed order incorrectly timeout + refund after manual rider assign

dinebd__api.business#153

Description

Reported by Yemon (DineBD CEO) via WhatsApp, 10 Jul 2026. Evidence: issues/yemon-inbox/2026-07-10-order-complete-refund-mess/

Client report

It was manually assigned the rider and order was completed. But now showing order time out and refund given. The whole things has gone mess

Can you check rider invoice and rider due amount and see if there are updating accordingly as it should

What to build

Investigate and fix order FD-20249178-353 (Food Delivery, BDT 38.00, ordered 10 Jul 2026 ~4:21 PM).

Observed in admin (business dashboard):

  • Order list shows status DELIVERED but Delivered at: Not Delivered (inconsistent).
  • Refund log entry 202606-0935 created 10 Jul 2026 ~4:55 PM — status Waiting for customer action, refunded BDT 0.00, payment gateway Bkash.

Preliminary analysis (agent, Jul 2026):

  1. Timing matches no-rider timeout (~30 min) — order at 4:21 PM, refund log at 4:55 PM. Rider API NoRiderTimeoutService fires initiateFoodDeliveryRefundForTimeout when delivery stays NO_RIDER_FOUND for ~30 minutes.

  2. initiateFoodDeliveryRefundForTimeout does not guard completed orders (food-delivery.grpc-controller.ts) — it always calls initRefund and forces business order status to TIMEOUT, even if the rider later completed the delivery.

  3. syncStatus gRPC bypasses onUpdate hook (food-delivery.grpc-controller.ts) — rider → business status sync uses direct updateOne({ status }) only. Side effects skipped:

    • deliveredAt never set → admin shows DELIVERED + "Not Delivered"
    • sendOrderStatusChangedEvent never fired → Inngest vendor timeout may not cancel
  4. Manual assign does call cancelNoRiderFoundTimeout (rider-action.service.ts) — so if assign happened before the Redis timer expired, refund should not fire via no-rider path. Need prod logs/timeline for FD-20249178-353 to confirm whether assign completed after timeout or timer cancel failed.

Likely failure modes (verify on prod):

  • No-rider timeout fired → refund + TIMEOUT while/for before rider completion synced
  • Late manual assign after timeout already triggered refund
  • Business order marked DELIVERED via syncStatus but missing deliveredAt; refund row still exists from earlier timeout event
  • Rider invoice / due amount may be wrong if business order ended in TIMEOUT + refund while rider delivery was DELIVERED

Fix (merged)

dinebd__api.business #154

  • Route gRPC syncStatus through syncStatusFromRider() so onUpdate runs (timestamps, Inngest cancel, socket events)
  • Backfill missing status timestamps when rider re-syncs same status
  • Guard initiateFoodDeliveryRefundForTimeout — only allow when status is FINDING_RIDER or NO_RIDER_FOUND

dinebd__api.rider #52

  • Skip no-rider timeout refund when delivery.assignedRider is set
  • Cancel pending Redis timer when assigned rider detected

Acceptance criteria

  • [x] Completed or in-progress deliveries cannot trigger timeout refund (initiateFoodDeliveryRefundForTimeout must check rider delivery + business order status)
  • [x] Rider → business syncStatus sets timestamp fields (deliveredAt, etc.) and cancels scheduled timeouts (use service layer / onUpdate, not raw updateOne)
  • [ ] Order FD-20249178-353 audited on prod: delivery timeline, refund 202606-0935, rider invoice, rider due — corrected if inconsistent
  • [ ] Admin UI shows consistent status + delivered timestamp after deploy
  • [ ] Regression test: manual assign → rider completes → no refund/timeout; deliveredAt populated

Blocked by

None — code fix merged; prod deploy + order audit remaining

Evidence

  • refund-log-fd-20249178-353.png — Refund log: order FD-20249178-353, BDT 38.00, refund 202606-0935, status Waiting for customer action, created 10 Jul 2026 4:55:55 PM
  • order-list-delivered-not-delivered.png — Order list: FD-20249178-353 marked DELIVERED (green) but Delivered at column shows Not Delivered

Related code

  • api/dinebd__api.business/src/api/food-delivery-order/food-delivery.grpc-controller.tssyncStatus, initiateFoodDeliveryRefundForTimeout
  • api/dinebd__api.rider/src/api/delivery/services/no-rider-timeout.service.ts
  • api/dinebd__api.rider/src/api/delivery/rider-action/rider-action.service.tsmanualAssignRiderToDelivery

Related issues

  • dinebd__api.rider #41 (closed) — delivery status sync
  • dinebd__api.rider #43, dinebd__api.business #149 (closed) — timeout after rider accept
Comments (2)
Synced 10 Sept 2026, 05:33

kingRayhan

Fix shipped

Two PRs merged to address the root causes identified in this issue:

Business API — dinebd__api.business #154 (merged)

  1. syncStatussyncStatusFromRider() — rider status sync now goes through the service layer so onUpdate runs:
    • Sets deliveredAt (and other status timestamps)
    • Fires sendOrderStatusChangedEvent (cancels Inngest vendor timeout)
    • Emits socket events
  2. Timestamp backfill — if rider syncs DELIVERED again but deliveredAt is missing, it gets backfilled
  3. Refund guardinitiateFoodDeliveryRefundForTimeout only proceeds when business order status is FINDING_RIDER or NO_RIDER_FOUND; skips completed/in-progress orders

Rider API — dinebd__api.rider #52 (merged)

  1. Assigned-rider guard — Redis no-rider timeout handler skips refund when delivery.assignedRider is set
  2. Timer cleanup — cancels the pending Redis timer when an assigned rider is detected

Acceptance criteria status

  • [x] Completed or in-progress deliveries cannot trigger timeout refund
  • [x] Rider → business syncStatus sets timestamp fields and cancels scheduled timeouts
  • [ ] Order FD-20249178-353 audited on prod (delivery timeline, refund 202606-0935, rider invoice/due) — still needs manual prod check
  • [ ] Admin UI consistent after deploy — verify post-deploy
  • [ ] Regression test on staging/prod — manual assign → rider completes → no refund; deliveredAt populated

Next steps

  • Deploy both APIs to production (Coolify)
  • Audit FD-20249178-353 on prod and correct rider invoice/due if still inconsistent from the earlier bad refund
Details
In Review🔥 HighAPIclosed
Repository
graphland-dev/dinebd__api.business
Issue
#153
Author
kingRayhan
Created
11 Jul 2026, 08:07
Updated
11 Jul 2026, 08:41
bug