Payment retries · Dunning sequences · KYC pipelines · Billing automation
Payment workflows that never lose a transaction.
A duplicate charge costs you a customer. Orch8 is a Rust-based durable workflow engine with crash recovery, memoized step outputs, and per-provider rate limiting — so payment retries, dunning sequences, and KYC pipelines run exactly as designed, even through crashes and deploys.
The problem
Payment infrastructure is your biggest liability.
Your Stripe integration is 200 lines. The retry logic, dunning state machine, idempotency layer, and crash recovery code around it is 20,000 lines of fragile custom infrastructure.
Duplicate charges after crashes
Your payment service crashes after charging a card but before recording the result. Without memoization, the retry charges the customer again. Chargebacks, refunds, and lost trust follow.
Manual dunning sequences
Failed payment? Someone wrote a cron job that retries once, then gives up. There is no escalation, no payment method switching, no grace period logic. Involuntary churn climbs silently.
KYC/AML pipeline fragility
Identity verification, sanctions screening, document review, and manual approval are stitched together with queues and hope. One service goes down and the whole pipeline stalls with no recovery path.
No rate limiting on payment provider APIs
Stripe, Adyen, and Plaid all enforce per-second limits. A burst of subscription renewals at midnight exhausts your quota and fails legitimate charges at the worst possible moment.
Compliance audit trails missing
Regulators ask who approved what, when, and why. Your payment decisions are scattered across application logs, database tables, and Slack threads. Reconstructing the trail takes days.
3-6 months building billing infrastructure
Retry logic, state machines, idempotency layers, dead letter queues, monitoring dashboards. Your team spends half the year building plumbing instead of the product your customers pay for.
Use cases
Every payment workflow. One engine.
Orch8 is a general-purpose durable workflow engine. These are the fintech and payments workloads teams reach for it most.
Payment retry & dunning
Retry failed charges with escalating intervals and method switching
Charge fails? Wait 3 days and retry. Still failing? Try the backup payment method. Send a soft reminder after 7 days. Downgrade the account after 30 days. All durable, all configurable, all crash-safe. No involuntary churn from lost retries.
Subscription lifecycle
Trial to paid to renewal to cancellation — with grace periods
Manage the full subscription lifecycle: trial start, conversion reminder, first charge, recurring renewal, failed payment dunning, cancellation with grace period, and win-back sequences. Each transition is a durable step that survives restarts.
KYC/AML compliance
Identity verification pipelines that never lose state
Chain identity verification, sanctions screening, document review, and manual approval into a single durable pipeline. If the sanctions API is down, the step retries with backoff. If a human reviewer is needed, the pipeline waits. Full audit trail for every decision.
Invoice processing
Receive, extract, validate, approve, pay — end to end
Receive an invoice via webhook or email. Extract line items with an LLM. Validate against purchase orders. Route to the right approver based on amount thresholds. Execute payment on approval. Reconcile with the general ledger. Crash-safe across every step.
Refund & chargeback handling
Detect, investigate, decide, process, notify — automatically
Chargeback received? Pull transaction details, check fraud signals, route to the right team based on dispute reason. If auto-resolvable, process the refund and notify the customer. If manual review is needed, pause and wait for a human signal. Every step is auditable.
Payout orchestration
Calculate, approve, batch, submit, reconcile
Calculate payouts for merchants or creators. Route large amounts through human approval gates. Batch transactions to minimize fees. Submit to banking rails with per-provider rate limits. Reconcile settlements against expected amounts. Resume from any step after failures.
How it works
Three steps to a crash-safe payment pipeline
Define your payment retry flow as JSON
Describe the steps, delays, conditions, and retry logic in a JSON sequence definition. No SDK required. No new programming model. Your handlers are plain HTTP endpoints in any language.
{
"id": "payment_dunning",
"blocks": [
{
"type": "step",
"handler": "charge_payment_method",
"retry": { "max_attempts": 2, "backoff": "5s" },
"rate_limit_key": "stripe:charges",
"rate_limit": { "max": 95, "window_seconds": 1 }
},
{
"type": "router",
"routes": [
{
"condition": "{{outputs.charge_payment_method.status == 'succeeded'}}",
"blocks": [
{ "type": "step", "handler": "activate_subscription" }
]
},
{
"default": true,
"blocks": [
{
"type": "step",
"handler": "wait",
"delay": { "days": 3 }
},
{
"type": "step",
"handler": "retry_with_backup_method"
},
{
"type": "step",
"handler": "wait",
"delay": { "days": 7 }
},
{
"type": "step",
"handler": "send_payment_reminder"
},
{
"type": "step",
"handler": "wait",
"delay": { "days": 30 }
},
{
"type": "step",
"handler": "downgrade_account"
}
]
}
]
}
]
}Deploy workers in any language
Workers are plain HTTP handlers. Orch8 calls them via a pull-based REST API. Write them in TypeScript with the Stripe SDK, Python, Go, Ruby -- anything that can respond to a POST request.
// TypeScript worker — charge a payment method via Stripe
app.post('/workers/charge_payment_method', async (req, res) => {
const { context } = req.body;
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
const charge = await stripe.paymentIntents.create({
amount: context.data.amount_cents,
currency: context.data.currency,
customer: context.data.stripe_customer_id,
payment_method: context.data.payment_method_id,
confirm: true,
idempotency_key: context.data.idempotency_key,
});
// Output is memoized — if engine crashes after this,
// the charge result is preserved, never re-charged
res.json({
status: charge.status,
charge_id: charge.id,
amount: charge.amount,
});
});Create instances from your billing events
Start a dunning sequence from a failed charge webhook, a subscription renewal event, or a manual trigger. Orch8 schedules and tracks execution from start to finish. Idempotency keys prevent duplicate pipeline creation.
POST /sequences/payment_dunning/instances
{
"context": {
"data": {
"stripe_customer_id": "cus_R8x2kLm9nPq4vT",
"payment_method_id": "pm_1Nq2xY2eZvKYlo2C",
"amount_cents": 9900,
"currency": "usd",
"subscription_id": "sub_8kT3mW",
"idempotency_key": "charge-sub_8kT3mW-2026-04"
}
},
"idempotency_key": "dunning-sub_8kT3mW-2026-04"
}Why Orch8 for fintech
Memoized outputs prevent duplicate charges.
When a step completes, its output is persisted before the next step begins. If the engine crashes and recovers, it returns the cached result instead of re-executing. Your charge_payment_method handler runs exactly once — even across crashes, deploys, and restarts. No duplicate charges. No customer escalations.
- ✓Output memoization — charge result is saved before moving to the next step
- ✓Snapshot recovery — resume from last checkpoint, no event replay
- ✓Idempotency keys — prevent duplicate pipeline creation from the same invoice
- ✓Per-provider rate limits — respect Stripe, Adyen, and Plaid quotas per API
- ✓Signals — pause, cancel, or resume dunning sequences via REST API
- ✓Full audit trail — every step, output, and retry persisted in PostgreSQL
Payment retry sequence — simplified
{
"id": "invoice_retry",
"blocks": [
{
"type": "step",
"handler": "charge_payment_method",
"retry": { "max_attempts": 2, "backoff": "3s" },
"rate_limit_key": "stripe:charges",
"rate_limit": { "max": 95, "window_seconds": 1 }
},
{
"type": "step",
"handler": "wait",
"delay": { "days": 3 }
},
{
"type": "step",
"handler": "retry_with_backup_method"
},
{
"type": "step",
"handler": "wait",
"delay": { "days": 7 }
},
{
"type": "step",
"handler": "send_payment_reminder"
},
{
"type": "step",
"handler": "wait",
"delay": { "days": 30 }
},
{
"type": "step",
"handler": "downgrade_account"
}
]
}What happens on crash
What you don't build
6 problems you never have to solve
Every fintech team that handles payments eventually builds all of these. With Orch8, none of them are your problem.
Payment deduplication logic
No tracking whether a charge was already processed before the crash. Orch8 memoizes step outputs — retries return the cached charge result, never re-charge.
Dunning state machine
No custom code tracking which retry attempt the customer is on, which payment method to try next, or when to downgrade. Define the flow as JSON. Orch8 manages the state.
Payment provider rate limiter
No Redis-backed counters per provider. Set a rate_limit_key and a limit on any step. Orch8 tracks usage with a sliding window and defers overages automatically.
Retry backoff scheduler
No exponential backoff implementation, no dead letter queue wiring, no cron-based retry jobs. Each step configures its own retry behavior and delay inline.
Compliance audit logging
No separate logging pipeline for regulatory compliance. Every step execution, output, retry, and signal is persisted in PostgreSQL. Query it directly for audit reports.
Subscription state tracker
No hand-rolled state machine for trial, active, past_due, canceled, and grace_period states. Define lifecycle transitions as sequence steps. Orch8 tracks position across restarts.
Your payment infrastructure shouldn't be your biggest risk.
Tell us what you're building. We'll reach out within 24 hours to walk you through a working example for your payment workflow — dunning sequences, subscription lifecycle, KYC pipelines, or payout orchestration.
No credit card required. Self-host free with no feature gates.