

Write the workflow
nelkap/workflows/refund-order.ts
- It emails a manager a link to a review page in your app.
- It waits on the key
refund_<orderId>. The call ends, and the run stays paused until an event arrives with that key. - When the event arrives,
step.waitreturns its payload: the manager’s review. - If the manager declined, the customer gets an email with the manager’s note. Otherwise, the payment is refunded, and the customer gets an email saying it’s done.
lib with your own. Here, refundPayment passes an idempotency key to your payment provider, so a refund is never made twice, even if a crash cuts the step off before it’s saved.
Start a run for each request
Register the workflow:nelkap/index.ts
Send the manager’s answer
Your review page posts the manager’s decision to a route of your app. The route emits it as an event, with the key the run waits on:app/api/refunds/review/route.ts
refund_ord_42 goes on right away. The key is built from the order, so the route doesn’t need to know the run’s ID.
An event only wakes the runs already waiting on its key. That’s why the workflow asks for the review in the step just before the wait: the run is waiting long before the manager can answer.
See it run
While the manager thinks it over, the run shows as waiting in your project’s runs. If the customer withdraws the request, cancel the run from its page. A run can wait up to a year.Ideas to extend it
- Remind the manager: start a second workflow that sleeps a day, then emails them if the refund is still pending.
- Listen for
refund.reviewedin another workflow, for example to keep a record of every decision.