Payment boundary
Separate checkout, payment truth and product entitlement
The browser is a participant, not the authority. Consequential state should come from authenticated provider events and reconciled server records.
Collection scope
Minimize where payment account data enters your systems.
- Define
- Hosted page, redirect or approved component
- Risk
- Custom form unexpectedly expands sensitive scope
- Evidence
- Documented data flow and provider responsibility
Product and price
Create the payable object from server-authoritative configuration.
- Define
- Currency, amount, tax mode and product ID
- Risk
- Client submits trusted amount
- Evidence
- Tampered-price negative test
Payment state
Authenticate events and process repeated delivery safely.
- Define
- Signature, event ID, ordering and terminal states
- Risk
- Forged or duplicate webhook grants access
- Evidence
- Replay, delay and signature tests
Entitlement
Translate payment state into bounded product access.
- Define
- Start, renewal, grace, cancellation and refund
- Risk
- Access exists only as a success-page flag
- Evidence
- Direct request and lifecycle tests
Reconciliation
Find disagreement between provider, application and customer experience.
- Define
- Daily checks, support reference and owner
- Risk
- Missing event silently changes revenue or access
- Evidence
- Mismatch report and correction runbook
Operating principle
Design for duplicate, delayed and missing events
Payment providers deliver through networks and asynchronous events. A user closing a tab does not cancel a payment, and a timeout does not prove failure.
Store provider identifiers, authenticate callbacks and make handlers idempotent. Reconcile provider state with internal orders and entitlements so an event-delivery gap does not become permanent state.
- Keep prices server-authoritative
- Authenticate webhooks
- Use idempotency for writes
- Reconcile provider and application state
Applied example
Failure example: access granted by return URL
After checkout, the success page reads a query parameter and marks the account paid. A user opens the URL directly without completing payment.
- The browser controlled the success signal
- No authenticated provider event was required
- Entitlement and payment state were conflated
- Direct navigation bypassed the commercial boundary
Plain answers
Questions to resolve before shipping
Does using a payment provider remove PCI obligations?+
It can reduce scope depending on the architecture, but it does not automatically remove merchant responsibilities. Confirm the actual arrangement with qualified guidance.
Should webhooks be processed immediately?+
Acknowledge within provider expectations, persist safely and move slow work to reliable processing while preserving idempotency.
How should refunds affect access?+
Define the product policy explicitly and implement it as an auditable state transition rather than an improvised support action.