feat(GRO-608): Add Stripe webhook handler for payment events

- Add POST /api/webhooks/stripe endpoint for Stripe event processing
- Handle payment_intent.succeeded: mark invoice as paid, set paymentMethod=card
- Handle payment_intent.payment_failed: record failure reason on invoice
- Handle charge.refunded: mark invoice as void
- Handle charge.dispute.created: log dispute
- Idempotency: skip if stripePaymentIntentId already recorded
- Add stripe_payment_intent_id, stripe_refund_id, payment_failure_reason columns
- Requires STRIPE_WEBHOOK_SECRET env var for signature verification

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Paperclip
2026-04-13 00:09:46 +00:00
parent 4f6a1e8149
commit a7e98c0582
6 changed files with 137 additions and 0 deletions
+16
View File
@@ -40,6 +40,9 @@ importers:
nodemailer:
specifier: ^6.9.16
version: 6.10.1
stripe:
specifier: ^22.0.0
version: 22.0.1(@types/node@22.19.15)
zod:
specifier: ^4.3.6
version: 4.3.6
@@ -4124,6 +4127,15 @@ packages:
strip-literal@3.1.0:
resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==}
stripe@22.0.1:
resolution: {integrity: sha512-Yw764pZ6s8Xu4CtUZdD5uWOkw6gc9xzO9OKylCuj1gMhMDLbyGbDtaPNNSFE4mB6njYSHESYIVbF1iIzUfAl2g==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
strnum@2.2.1:
resolution: {integrity: sha512-BwRvNd5/QoAtyW1na1y1LsJGQNvRlkde6Q/ipqqEaivoMdV+B1OMOTVdwR+N/cwVUcIt9PYyHmV8HyexCZSupg==}
@@ -8774,6 +8786,10 @@ snapshots:
dependencies:
js-tokens: 9.0.1
stripe@22.0.1(@types/node@22.19.15):
optionalDependencies:
'@types/node': 22.19.15
strnum@2.2.1: {}
supports-color@7.2.0: