payloadcms / payload

Payload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a headless CMS or for building powerful applications.
https://payloadcms.com
MIT License
23.12k stars 1.44k forks source link

plugin-stripe: deleteFromStripe hook crashes application #4493

Open chrisulloa opened 12 months ago

chrisulloa commented 12 months ago

When I delete a product from Stripe, the following error crashes my application:

[17:31:22] INFO (payload): - Deleting Payload document with ID: '64fdfd696f7457b9e210f2ce'...
[17:31:22] INFO (payload): - ✅ Successfully deleted Payload document with ID: '64fdfd696f7457b9e210f2ce'.
POST /stripe/webhooks 200 17 - 5.742 ms
[17:31:22] INFO (payload): Document with ID: '64fdfd696f7457b9e210f2ce' in collection: 'products' has been deleted, deleting from Stripe...
[17:31:22] INFO (payload): - Deleting Stripe document with ID: 'prod_id'..
/Users/folder/api/node_modules/@payloadcms/plugin-stripe/dist/hooks/deleteFromStripe.js:33
            op = body.call(thisArg, _);
                      ^
APIError: Failed to delete Stripe document with ID: 'prod_id': No such product: 'prod_id'
    at /Users/folder/api/node_modules/@payloadcms/plugin-stripe/src/hooks/deleteFromStripe.ts:53:15
    at step (/Users/folder/api/node_modules/@payloadcms/plugin-stripe/dist/hooks/deleteFromStripe.js:33:23)
    at Object.throw (/Users/folder/api/node_modules/@payloadcms/plugin-stripe/dist/hooks/deleteFromStripe.js:14:53)
    at rejected (/Users/folder/api/node_modules/@payloadcms/plugin-stripe/dist/hooks/deleteFromStripe.js:6:65)
    at processTicksAndRejections (node:internal/process/task_queues:95:5) {
  status: 500,
  data: null,
  isPublic: false,
  isOperational: true
}

After some investigation it appears that the afterDelete deleteFromStripe collection hook errors out here after a 404 response from Stripe https://github.com/payloadcms/plugin-stripe/blob/main/src/hooks/deleteFromStripe.ts#L37

Looking at the webhook events after I delete a product in Stripe -> product.deleted (deletes product in payload) -> deleteFromStripe collection hook attempts to delete product already deleted in Stripe

stripe.retrieve throws an error caused by 404 rather than returning null. expected behavior is for the else block to be called and the afterDelete hook to terminate without error.

Stripe 10.2.0 @payloadcms/plugin-stripe 0.0.14 payload 1.6.32

jacobsfletch commented 8 months ago

Hey @chrisulloa thank you for the detailed report on this 👍 I'll look further into this as soon as possible.

jacobsfletch commented 8 months ago

This plugin is now being maintained in the Packages Directory of the Payload Monorepo. This repo will soon be archived and all open issues will be closed. This issue, however, will be transferred over. Please refer to this open discussion for more details.

jacobsfletch commented 1 month ago

Circling back on this, this should now be possible through the context property on hooks: https://payloadcms.com/docs/hooks/context. Should be able to simply thread some key through context which indicates to subsequent hooks that the event was initiated by Stripe, in order to ultimately skip the follow-up deletion that is made.