# Runbook: Payments Sanity Check (Local Mock) Validate payment create + webhook reconciliation without hitting Moyasar. ## Preconditions - Venv + backend deps installed. - DB migrated. - Run from repo root unless noted. ## Steps 1. Start local mock server on `127.0.0.1:8001` exposing `POST /v1/payments`. 2. Seed data: - `source venv/bin/activate` - `cd backend` - `python3 manage.py migrate` - `python3 manage.py seed_demo` 3. Run API with mock settings: - `DJANGO_DEBUG=1 MOYASAR_SECRET_KEY=sk_test MOYASAR_PUBLISHABLE_KEY=pk_test MOYASAR_BASE_URL=http://127.0.0.1:8001 MOYASAR_WEBHOOK_SECRET=whsec python3 manage.py runserver 8000` 4. Generate JWT in shell (demo user) and store as ``. 5. Create payment: - `POST /api/payments/` with `booking_id`, `provider=moyasar`, `idempotency_key`, valid source. 6. Send paid webhook: - `POST /api/payments/webhook/` with `{"type":"payment_paid","secret_token":"whsec","data":{"id":""}}` 7. Verify `GET /api/payments/` shows status `paid` and `paid_at` set. ## Expected Results - Create payment returns `status=initiated` + provider `external_id` + `redirect_url`. - Webhook returns `{"detail":"Webhook processed"}`. - Payment transitions to `paid` idempotently. ## Edge Checks - Wrong/missing webhook secret -> `401`. - Reused idempotency key -> same payment reused, no duplicate charge. - Unsupported sources rejected by validation. ## Cleanup Stop Django + mock processes.