01
Understand the provider/server boundary
A browser can start checkout, but it should not be the authority that grants paid access. The payment provider, your server-side webhook handler, and your application database each have different responsibilities.
- The provider records payment events and their status
- The server verifies trusted events and maps them to the right account or order
- The database records the state your app needs, with a traceable event or transaction ID
- The UI displays server-backed status and handles pending or unknown states
- No client-supplied price, plan, user ID, or “paid” flag is treated as proof
02
Signature verification and secret handling
- Webhook signatures are checked using the provider’s documented server-side method
- The raw request body is preserved when the provider requires it for verification
- Webhook secrets and private payment keys remain server-side
- Invalid signatures are rejected and do not change entitlements
- Logs contain event IDs and safe diagnostics, not card data or secret values
- Provider dashboard endpoints, signing secrets, and test/live mode are checked separately
03
Duplicate events and idempotency
Providers retry events, and networks can deliver the same event more than once. A correct handler can safely receive an event again without double-crediting, double-shipping, or corrupting access.
- Store a provider event ID or another provider-supported idempotency key
- Make the state change safe to repeat
- Handle two deliveries arriving close together
- Do not use a browser refresh as a payment confirmation mechanism
- Return the correct response so the provider knows whether delivery succeeded
- Test duplicate delivery against a test account and inspect the resulting records
04
Retries, refunds, cancellations, and delayed events
- A timeout or temporary failure can be retried without creating a second entitlement
- A payment pending state is distinct from paid and failed
- Cancellations and subscription period changes update access at the intended time
- Refunds and chargebacks have an owner-approved access policy
- Delayed or out-of-order events cannot move a record to an older unsafe state
- Support can find the provider transaction, account, current state, and last event
05
Test mode, keys, and entitlement changes
- Test products, test keys, and test webhook endpoints cannot grant production access
- Live and test provider dashboards are clearly separated
- The displayed price, currency, interval, and product ID match provider configuration
- Entitlements are granted and revoked on a trusted server path
- Changing a plan does not accidentally remove or extend access incorrectly
- A user cannot edit their own paid status through a public request
06
What payment tests can and cannot prove
A code review can identify a signature check or idempotency table. It cannot prove that the provider is sending the expected event, that the dashboard secret matches, or that production monitoring will catch a failure.
- Code evidence: handler path, signature check, event storage, state transition, and error handling
- Application tests: success, invalid signature, duplicate, retry, refund, cancellation, and delayed event cases
- Provider evidence: test-mode delivery, endpoint status, event payload, signing configuration, and dashboard logs
- Production evidence: safe monitoring, alert ownership, and a support or reconciliation process
- Never label payment security proven without both provider-side and application-side tests
07
Copy-paste payment audit prompt
Prompt 61
Audit without changing payment logic
Copy-paste prompt
Audit this app’s payment webhook flow without changing files, sending live payments, or printing secret values. Trace the provider/server boundary and report evidence for signature verification, raw-body handling if required, event identity, duplicate delivery, idempotency, retries, timeouts, refunds, cancellations, delayed or out-of-order events, test/live mode separation, secret handling, and entitlement changes. Separate code evidence, application tests actually run, provider-dashboard checks not available here, and production monitoring unknowns. Do not claim payment security, correctness, or production readiness without provider-side and application-side evidence. Use READY, BLOCKED, UNKNOWN, or NOT APPLICABLE.
Use a test account and provider test mode for hands-on checks. Do not paste keys or sensitive payment data into the prompt.