supabase / stripe-sync-engine

Sync your Stripe account to you Postgres database.
https://supabase.com
Apache License 2.0
496 stars 49 forks source link

Unhandled webhook event on charge.refund.updated #114

Open yinghaochan opened 2 months ago

yinghaochan commented 2 months ago

Bug report

Looks like it's not on the list of webhooks in the README.md

Logs from docker

Error: Unhandled webhook event
    at /app/dist/routes/webhooks.js:262:44
    at step (/app/dist/routes/webhooks.js:33:23)
    at Object.next (/app/dist/routes/webhooks.js:14:53)
    at /app/dist/routes/webhooks.js:8:71
    at new Promise (<anonymous>)
    at __awaiter (/app/dist/routes/webhooks.js:4:12)
    at Object.handler (/app/dist/routes/webhooks.js:61:61)
    at preHandlerCallback (/app/node_modules/fastify/lib/handleRequest.js:137:37)
    at validationCompleted (/app/node_modules/fastify/lib/handleRequest.js:121:5)
    at preValidationCallback (/app/node_modules/fastify/lib/handleRequest.js:98:5)
{
    "level": "error",
    "time": "2024-08-28T12:46:04.707Z",
    "pid": 13,
    "hostname": "supabase-stripe-sync-engine-778859f98-7lnvx",
    "reqId": "req-7",
    "req": {
        "method": "POST",
        "url": "/webhooks",
        "hostname": "yhc-dev-kfwzw.ondigitalocean.app",
        "remoteAddress": "10.244.3.189",
        "remotePort": 40750
    },
    "res": { "statusCode": 500 },
    "err": {
        "type": "Error",
        "message": "Unhandled webhook event",
        "stack": "Error: Unhandled webhook event\n    at /app/dist/routes/webhooks.js:262:44\n    at step (/app/dist/routes/webhooks.js:33:23)\n    at Object.next (/app/dist/routes/webhooks.js:14:53)\n    at /app/dist/routes/webhooks.js:8:71\n    at new Promise (<anonymous>)\n    at __awaiter (/app/dist/routes/webhooks.js:4:12)\n    at Object.handler (/app/dist/routes/webhooks.js:61:61)\n    at preHandlerCallback (/app/node_modules/fastify/lib/handleRequest.js:137:37)\n    at validationCompleted (/app/node_modules/fastify/lib/handleRequest.js:121:5)\n    at preValidationCallback (/app/node_modules/fastify/lib/handleRequest.js:98:5)"
    },
    "msg": "Unhandled webhook event"
}

Logs from Stripe

Response body

{
  "statusCode": 500,
  "error": "Internal Server Error",
  "message": "Unhandled webhook event"
}

Request body

{
  "id": "evt_1PsbAsDZJ8Qwumi2PPwVK8gq",
  "object": "event",
  "api_version": "2024-06-20",
  "created": 1724810394,
  "data": {
    "object": {
      "id": "pyr_1PsbAmDZJ8Qwumi2synMmGaf",
      "object": "refund",
      "amount": 103,
      "balance_transaction": "txn_1PsbAmDZJ8Qwumi2hcRVlXqn",
      "charge": "py_3Psb7zDZJ8Qwumi20vvVEtQW",
      "created": 1724810388,
      "currency": "sgd",
      "destination_details": {
        "paynow": {},
        "type": "paynow"
      },
      "metadata": {},
      "payment_intent": "pi_3Psb7zDZJ8Qwumi20lg8AyBS",
      "reason": "duplicate",
      "receipt_number": null,
      "source_transfer_reversal": null,
      "status": "succeeded",
      "transfer_reversal": null
    },
    "previous_attributes": {}
  },
  "livemode": false,
  "pending_webhooks": 1,
  "request": {
    "id": null,
    "idempotency_key": null
  },
  "type": "charge.refund.updated"
}
yinghaochan commented 2 months ago

this might be because the list of webhooks in the readme wasn't complete, and I thought it tried to be exhaustive.

13 would be great to have!

kevcodez commented 2 months ago

The stripe-sync-engine does not support refunds yet, PRs are welcome though - should be fairly straight forward to add if you look at any of the supported events

The auto webhook creation won't help with unsupported events

yinghaochan commented 2 months ago

@kevcodez yeah I realized that after looking a bit closer. My bad.

The full list from stripe can be gotten by pasting this into your browser console:

window.location = "https://docs.stripe.com/api/events/types" ; [...document.body.getElementsByClassName("⚙ rs12 as1a7 as17e as17d as158 as1a8 as11s ⚙oaj2dp")].map(x => x.innerText)

I'm fixing the webhook enabled_events to match the readme list now. looks like payment_intent.partially_refunded doesn't exist. Perhaps a typo? https://docs.stripe.com/api/events/types#event_types-payment_intent.partially_funded

after changing partially_refunded to partially_funded this update seems to work: (postman export)

curl --location 'https://api.stripe.com//v1/webhook_endpoints/we_ENDPOINT_ID_HERE' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: BEARER TOKEN HERE' \
--data-urlencode 'enabled_events%5B%5D=charge.captured' \
--data-urlencode 'enabled_events%5B%5D=charge.expired' \
--data-urlencode 'enabled_events%5B%5D=charge.failed' \
--data-urlencode 'enabled_events%5B%5D=charge.pending' \
--data-urlencode 'enabled_events%5B%5D=charge.refunded' \
--data-urlencode 'enabled_events%5B%5D=charge.succeeded' \
--data-urlencode 'enabled_events%5B%5D=charge.updated' \
--data-urlencode 'enabled_events%5B%5D=charge.dispute.closed' \
--data-urlencode 'enabled_events%5B%5D=charge.dispute.created' \
--data-urlencode 'enabled_events%5B%5D=charge.dispute.funds_reinstated' \
--data-urlencode 'enabled_events%5B%5D=charge.dispute.funds_withdrawn' \
--data-urlencode 'enabled_events%5B%5D=charge.dispute.updated' \
--data-urlencode 'enabled_events%5B%5D=credit_note.created' \
--data-urlencode 'enabled_events%5B%5D=credit_note.updated' \
--data-urlencode 'enabled_events%5B%5D=credit_note.voided' \
--data-urlencode 'enabled_events%5B%5D=customer.created' \
--data-urlencode 'enabled_events%5B%5D=customer.deleted' \
--data-urlencode 'enabled_events%5B%5D=customer.subscription.created' \
--data-urlencode 'enabled_events%5B%5D=customer.subscription.deleted' \
--data-urlencode 'enabled_events%5B%5D=customer.subscription.paused' \
--data-urlencode 'enabled_events%5B%5D=customer.subscription.pending_update_applied' \
--data-urlencode 'enabled_events%5B%5D=customer.subscription.pending_update_expired' \
--data-urlencode 'enabled_events%5B%5D=customer.subscription.resumed' \
--data-urlencode 'enabled_events%5B%5D=customer.subscription.trial_will_end' \
--data-urlencode 'enabled_events%5B%5D=customer.subscription.updated' \
--data-urlencode 'enabled_events%5B%5D=customer.tax_id.created' \
--data-urlencode 'enabled_events%5B%5D=customer.tax_id.deleted' \
--data-urlencode 'enabled_events%5B%5D=customer.tax_id.updated' \
--data-urlencode 'enabled_events%5B%5D=customer.updated' \
--data-urlencode 'enabled_events%5B%5D=invoice.created' \
--data-urlencode 'enabled_events%5B%5D=invoice.deleted' \
--data-urlencode 'enabled_events%5B%5D=invoice.finalized' \
--data-urlencode 'enabled_events%5B%5D=invoice.finalization_failed' \
--data-urlencode 'enabled_events%5B%5D=invoice.marked_uncollectible' \
--data-urlencode 'enabled_events%5B%5D=invoice.paid' \
--data-urlencode 'enabled_events%5B%5D=invoice.payment_action_required' \
--data-urlencode 'enabled_events%5B%5D=invoice.payment_failed' \
--data-urlencode 'enabled_events%5B%5D=invoice.payment_succeeded' \
--data-urlencode 'enabled_events%5B%5D=invoice.sent' \
--data-urlencode 'enabled_events%5B%5D=invoice.upcoming' \
--data-urlencode 'enabled_events%5B%5D=invoice.updated' \
--data-urlencode 'enabled_events%5B%5D=invoice.voided' \
--data-urlencode 'enabled_events%5B%5D=payment_intent.amount_capturable_updated' \
--data-urlencode 'enabled_events%5B%5D=payment_intent.canceled' \
--data-urlencode 'enabled_events%5B%5D=payment_intent.created' \
--data-urlencode 'enabled_events%5B%5D=payment_intent.partially_funded' \
--data-urlencode 'enabled_events%5B%5D=payment_intent.payment_failed' \
--data-urlencode 'enabled_events%5B%5D=payment_intent.processing' \
--data-urlencode 'enabled_events%5B%5D=payment_intent.requires_action' \
--data-urlencode 'enabled_events%5B%5D=payment_intent.succeeded' \
--data-urlencode 'enabled_events%5B%5D=payment_method.attached' \
--data-urlencode 'enabled_events%5B%5D=payment_method.automatically_updated' \
--data-urlencode 'enabled_events%5B%5D=payment_method.detached' \
--data-urlencode 'enabled_events%5B%5D=payment_method.updated' \
--data-urlencode 'enabled_events%5B%5D=plan.created' \
--data-urlencode 'enabled_events%5B%5D=plan.deleted' \
--data-urlencode 'enabled_events%5B%5D=plan.updated' \
--data-urlencode 'enabled_events%5B%5D=price.created' \
--data-urlencode 'enabled_events%5B%5D=price.deleted' \
--data-urlencode 'enabled_events%5B%5D=price.updated' \
--data-urlencode 'enabled_events%5B%5D=product.created' \
--data-urlencode 'enabled_events%5B%5D=product.deleted' \
--data-urlencode 'enabled_events%5B%5D=product.updated' \
--data-urlencode 'enabled_events%5B%5D=setup_intent.canceled' \
--data-urlencode 'enabled_events%5B%5D=setup_intent.created' \
--data-urlencode 'enabled_events%5B%5D=setup_intent.requires_action' \
--data-urlencode 'enabled_events%5B%5D=setup_intent.setup_failed' \
--data-urlencode 'enabled_events%5B%5D=setup_intent.succeeded' \
--data-urlencode 'enabled_events%5B%5D=subscription_schedule.aborted' \
--data-urlencode 'enabled_events%5B%5D=subscription_schedule.canceled' \
--data-urlencode 'enabled_events%5B%5D=subscription_schedule.completed' \
--data-urlencode 'enabled_events%5B%5D=subscription_schedule.created' \
--data-urlencode 'enabled_events%5B%5D=subscription_schedule.expiring' \
--data-urlencode 'enabled_events%5B%5D=subscription_schedule.released' \
--data-urlencode 'enabled_events%5B%5D=subscription_schedule.updated'