Required reading

Dual-Mode Merchant Engine

One deployable URL. Two gates.

Architecture

Environment (ENVIRONMENT=village|live, with legacy sandbox→village and production for Live telecom) configures infrastructure.

Execution mode (VILLAGE | LIVE) is chosen per request:

  • Classifier: payment proof → Village; client key → Live; both → reject; neither → 402.
  • Gate establishes trust (verify proof or credential).
  • ExecutionContext flows into every side-effect adapter.

Telecom safety (two gates)

  1. May *this request* perform live side effects? (allow_external_side_effects)
  2. Is *this deploy* production with Twilio configured?

Village always records virtual SMS — even on production hosts.

Credentials

Per-client keys (pp_live_…), hash-only storage, revoke/rotate, node scope, idempotency for live calls.

Issue via POST /admin/client-keys with X-Admin-Token.

Response metadata

Every response should say which mode ran (execution.mode, telecom_mode, request_id).

Checklist

  • [ ] Ambiguous headers return 400
  • [ ] Village unpaid returns 402
  • [ ] Production + Village still virtual SMS
  • [ ] Live + sandbox stays virtual
  • [ ] Live + production without Twilio fails explicitly (not fake success)
  • [ ] Idempotent live retries do not double-send

Full template notes: Merchant Template.