Payments
Razorpay
| Where | razorpay package, src/integrations/payments, WhatsApp adapter |
| Auth | RAZORPAY_KEY_ID, secret, webhook secret. Setting the key id makes the other two mandatory at boot |
| Webhooks | WhatsApp payment webhook is @PublicRoute and reads Stripe or Razorpay signatures |
| Scope | Wallet payment intents and WhatsApp checkout |
Wallet debit on order.confirmed is an internal ledger movement (deductToken). It is not itself a Razorpay charge. See Wallet.
Stripe
| Where | automation/whatsapp-agent/payments/adapters/stripe.adapter.ts |
| Auth | Secret read from agent configuration. No STRIPE_ block in the first 250 lines of .env.example |
| Scope | Checkout Sessions for WhatsApp |
Idempotency
Payment event tables exist (PaymentEvent, PaymentIntent). Whether webhook handlers dedupe on a provider event id was not line-read. Do not assume they do.
Failure
A failed Razorpay call on a webhook follows that controller. The order token debit failure mode is the outbox retry, which is a different path.