Implement Timeout Refund Workflow
Company: DoorDash
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates skills in deterministic workflow design, idempotency and retry-safety for external payment integrations, state-transition correctness, and unit testing for edge cases such as timeouts and duplicate execution.
Constraints
- `status` is one of `PENDING`, `COMPLETED`, `CANCELED`, or `REFUNDED`.
- `0 <= created_at <= now <= 10^12`.
- `1 <= timeout_minutes <= 10^9`.
- `0 <= refunded_cents <= amount_cents <= 10^12`.
- `0 <= runs <= 1000`.
- `payment_results` contains booleans; values are consumed only when a refund call is actually attempted.
Examples
Input: ({'order_id': 'o1', 'created_at': 100, 'status': 'PENDING', 'amount_cents': 2500, 'refunded_cents': 0}, 119, 20, [True], 1)
Expected Output: {'order': {'order_id': 'o1', 'created_at': 100, 'status': 'PENDING', 'amount_cents': 2500, 'refunded_cents': 0}, 'events': [], 'refund_calls': []}
Explanation: The order is pending, but only 19 minutes have passed, which is less than the 20 minute timeout. The workflow routes directly to end.
Input: ({'order_id': 'o2', 'created_at': 100, 'status': 'PENDING', 'amount_cents': 3000, 'refunded_cents': 0}, 130, 30, [True], 1)
Expected Output: {'order': {'order_id': 'o2', 'created_at': 100, 'status': 'REFUNDED', 'amount_cents': 3000, 'refunded_cents': 3000}, 'events': [['REFUND_ISSUED', 'o2', 3000, 'refund:o2:full']], 'refund_calls': [['o2', 3000, 'refund:o2:full', 'SUCCESS']]}
Explanation: This is the boundary case: exactly 30 minutes have passed, so the order has timed out. The refund succeeds and one refund event is emitted.
Input: ({'order_id': 'o3', 'created_at': 0, 'status': 'COMPLETED', 'amount_cents': 4500, 'refunded_cents': 0}, 1000, 30, [True], 1)
Expected Output: {'order': {'order_id': 'o3', 'created_at': 0, 'status': 'COMPLETED', 'amount_cents': 4500, 'refunded_cents': 0}, 'events': [], 'refund_calls': []}
Explanation: Even though the order is older than the timeout, it is already COMPLETED, not PENDING, so no refund is attempted.
Input: ({'order_id': 'o4', 'created_at': 0, 'status': 'PENDING', 'amount_cents': 2000, 'refunded_cents': 0}, 60, 30, [False, True], 2)
Expected Output: {'order': {'order_id': 'o4', 'created_at': 0, 'status': 'REFUNDED', 'amount_cents': 2000, 'refunded_cents': 2000}, 'events': [['REFUND_ISSUED', 'o4', 2000, 'refund:o4:full']], 'refund_calls': [['o4', 2000, 'refund:o4:full', 'RETRYABLE_FAILURE'], ['o4', 2000, 'refund:o4:full', 'SUCCESS']]}
Explanation: The first run attempts the refund but receives a retryable failure, so the order remains PENDING. The second run retries with the same idempotency key and succeeds.
Input: ({'order_id': 'o5', 'created_at': 0, 'status': 'PENDING', 'amount_cents': 999, 'refunded_cents': 0}, 60, 30, [True, True], 2)
Expected Output: {'order': {'order_id': 'o5', 'created_at': 0, 'status': 'REFUNDED', 'amount_cents': 999, 'refunded_cents': 999}, 'events': [['REFUND_ISSUED', 'o5', 999, 'refund:o5:full']], 'refund_calls': [['o5', 999, 'refund:o5:full', 'SUCCESS']]}
Explanation: The first run succeeds. The second run is a duplicate execution, but the order is already REFUNDED, so no second payment call is made.
Hints
- Represent each workflow node as a small function that returns the next node id, then loop until the end node stops execution.
- Before calling the payment client, check persisted order state and emitted refund events. The idempotency key should be stable and derived only from the order and refund type.