Repository navigation
PAY-003A: harden Stripe webhook event processing - #140
Merged
Merged
Conversation
✅ Deploy Preview for luminous-fox-7c393f ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Outcome
Stripe webhook source now fails closed when a payment event has a conflicting owner, incomplete money evidence, the wrong Stripe mode, an unsafe state transition, or an ambiguous local record. Exact event replay is idempotent, supported missing targets retry, unmatched refunds/disputes become durable review items, and accepted provider objects receive a server-only atomic binding so two records cannot claim the same Stripe object concurrently.
Source was merged as main commit 87bd121. It is not deployed Firebase behavior.
Tracks #101. Parent tracker: #106. #102 remains a separate follow-up for discount, tax, and shipping-adjustment policy.
Security invariant and failure behavior
Scope
Excluded: checkout creators, discount/tax/shipping adjustments, command idempotency, inventory/capacity, reconciliation workers, Firestore Rules, provider configuration, secrets, production data, and every public asset.
Test evidence
Node 20.20.2 on exact source head fd89a8d:
No test contacts Stripe, Firebase production, or real member/payment data.
Schema, compatibility, and rollback
The stripeEvents inbox remains additive. The new stripeObjectBindings collection stores only provider object type/ID and the server-side target path/type. It is denied to browsers by the repository's default-deny Rules posture. No backfill is required: existing record fields are checked before a new binding is claimed, and ambiguous legacy data fails closed for repair.
Rollback is the four source commits. Existing binding documents are inert if the code is rolled back and must not be deleted without a separate reviewed migration.
Known residual work remains on #106: append-oriented canonical audit/dispute storage, TTL provider proof, reconciliation/reprocessing, checkout persistence/idempotency, inventory/capacity, and provider rehearsal.
Officer impact
No current officer steps change. Commerce and payment operations are still NOT AVAILABLE YET, and review-ledger tooling remains future work.
Officer documentation
None — this is an internal source-only payment safety boundary and does not make an officer procedure available. Existing officer guides already say commerce is unavailable; changing them now would falsely describe undeployed behavior.
Deployment evidence