stripe-sync-engine icon indicating copy to clipboard operation
stripe-sync-engine copied to clipboard

Unhandled webhook event on charge.refund.updated

Open yinghaochan opened this issue 1 year ago • 3 comments

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 avatar Aug 28 '24 13:08 yinghaochan

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!

yinghaochan avatar Aug 28 '24 13:08 yinghaochan

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

kevcodez avatar Aug 28 '24 13:08 kevcodez

@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'

yinghaochan avatar Aug 28 '24 14:08 yinghaochan

Event is supported with https://github.com/supabase/stripe-sync-engine/pull/147

though it's recommended to listen to refunds.* events instead

kevcodez avatar Jun 02 '25 04:06 kevcodez