| 1 | Every webhook’s signature is verified on the raw body before it is used, and an invalid one answers 4xx and is logged | Code review against Verify the signature; send a request with a wrong signature |
| 2 | The handler answers 2xx within 15 seconds and does its work after acknowledging | Measure the handler under load |
| 3 | Events are deduplicated on eventId: a second delivery changes nothing | Deliver the same body twice to your endpoint |
| 4 | A step that arrives before the one it follows creates the record, and the earlier step fills it in without moving it back | Deliver investor.transaction.processed before investor.minting.completed, and investor.payout.completed before investor.payout.initiated |
| 5 | Amounts are parsed as integers in base units with their decimals, never as floating point | Code review against Amounts |
| 6 | Cash amounts and token amounts are kept apart, and joined only through the fund’s price | Code review |
| 7 | Deposits are joined to issuances on tokenIssuanceId, and a deposit with tokenIssuanceId null is shown as received, not issued | Reconcile a sandbox subscription end to end |
| 8 | A redemption is joined to its transfer on txHash, and its steps on the redemption id | Reconcile a sandbox redemption end to end |
| 9 | An unknown eventType, processType, paymentMethod or other value is stored as informational and does not fail the handler | Code review against Versioning |
| 10 | After an outage, GET /webhook-events is paged back to the start of the outage and the missing events applied | Rehearse it: stop your endpoint, run a sandbox subscription, start it, recover |
| 11 | A scheduled reconciliation reads GET /deposits, GET /transactions and GET /assets, and flags what the webhooks did not explain | Run it against sandbox |
| 12 | The bearer token is cached and refreshed, not requested per call | Log review |
| 13 | The client secret and the signing secret live only in your backend’s secret store, never in logs or frontend code | Secret scan |
| 14 | Every non-2xx response is logged with its error, message and statusCode, and every webhook with its eventId and svix-id | Log review |