Integration checklist
What a finished integration looks like. Every line is something an integration has shipped without, and paid for.
Keys
- [ ] The key lives on the server, in a secret store, never in a repository or a browser.
- [ ] Each server has its own key, with only the scopes it needs.
- [ ] Somebody owns rotation: the key has a lifetime, or a date in a calendar.
- [ ] The base URL and the key are both configuration, so going live is a config change.
Charges
- [ ] Every
POST /v1/chargesandPOST /v1/pos/chargescarries anIdempotency-Keyderived from your order or sale id, and retries reuse it. - [ ]
processingis treated as "unknown", never as failed. - [ ] Orders are fulfilled on
charge.succeeded(or a poll returningsucceeded), never on a201from create. - [ ]
503and429are retried with the same key and a backoff;4xxis never retried unchanged. - [ ]
PamoPay-Request-Idis logged on every call.
Webhooks
- [ ] The handler verifies
PamoPay-Signatureover the raw body and checkstwithin five minutes. - [ ] It deduplicates on
id(ev_…) and tolerates out-of-order and repeated events. - [ ] It answers
2xxwithin ten seconds and does the work afterwards. - [ ] A catch-up job reads
GET /v1/events?type=charge.succeededafter any outage.
Money
- [ ] Reconciliation uses
net_minoragainst the bank andamount_minoragainst the order book. - [ ] Code shared between
/v1/chargesand/v1/pos/chargesreads bothfee_minorandmdr_minor. - [ ] Bills:
control_numberstored raw,control_number_printedon the slip; reconciliation keys oncustomer_refanddata.bill.id.
Sandbox
- [ ] The sandbox run covers all five trigger numbers, especially
…004and…005. - [ ] A retry was tested: the same key twice returns the same
id; a different amount under it is409. - [ ] A read-only key was tried against
POST /v1/chargesand gotFORBIDDEN_SCOPE, so the scope check is known to work.