[{"data":1,"prerenderedAt":1310},["ShallowReactive",2],{"navigation_docs":3,"-packages-fluent-js-webhooks":465,"-packages-fluent-js-webhooks-surround":1305},[4,8,62,115,450],{"title":5,"path":6,"stem":7},"Introduction","\u002Fintroduction","0.introduction",{"title":9,"path":10,"stem":11,"children":12,"page":61},"Guides","\u002Fguides","1.guides",[13,17,21,25,29,33,37,41,45,49,53,57],{"title":14,"path":15,"stem":16},"Quickstart","\u002Fguides\u002Fquickstart","1.guides\u002F1.quickstart",{"title":18,"path":19,"stem":20},"Payouts & Settlement","\u002Fguides\u002Fpayouts","1.guides\u002F10.payouts",{"title":22,"path":23,"stem":24},"Customer Emails","\u002Fguides\u002Fcustomer-emails","1.guides\u002F11.customer-emails",{"title":26,"path":27,"stem":28},"Build your own integration","\u002Fguides\u002Fbuild-your-own-integration","1.guides\u002F2.build-your-own-integration",{"title":30,"path":31,"stem":32},"Selling Workflow","\u002Fguides\u002Fselling-workflow","1.guides\u002F2.selling-workflow",{"title":34,"path":35,"stem":36},"Vatly SDKs","\u002Fguides\u002Fsdks","1.guides\u002F3.sdks",{"title":38,"path":39,"stem":40},"Authentication","\u002Fguides\u002Fauthentication","1.guides\u002F4.authentication",{"title":42,"path":43,"stem":44},"Pagination","\u002Fguides\u002Fpagination","1.guides\u002F5.pagination",{"title":46,"path":47,"stem":48},"Errors","\u002Fguides\u002Ferrors","1.guides\u002F6.errors",{"title":50,"path":51,"stem":52},"Webhooks","\u002Fguides\u002Fwebhooks","1.guides\u002F7.webhooks",{"title":54,"path":55,"stem":56},"Idempotency","\u002Fguides\u002Fidempotency","1.guides\u002F8.idempotency",{"title":58,"path":59,"stem":60},"Testing","\u002Fguides\u002Ftesting","1.guides\u002F9.testing",false,{"title":63,"path":64,"stem":65,"children":66,"page":61},"Api Reference","\u002Fapi-reference","2.api-reference",[67,71,75,79,83,87,91,95,99,103,107,111],{"title":68,"path":69,"stem":70},"Customers","\u002Fapi-reference\u002Fcustomers","2.api-reference\u002F1.customers",{"title":72,"path":73,"stem":74},"Webhook Endpoints","\u002Fapi-reference\u002Fwebhook-endpoints","2.api-reference\u002F10.webhook-endpoints",{"title":76,"path":77,"stem":78},"Test helpers","\u002Fapi-reference\u002Ftest-helpers","2.api-reference\u002F11.test-helpers",{"title":80,"path":81,"stem":82},"Checkouts","\u002Fapi-reference\u002Fcheckouts","2.api-reference\u002F2.checkouts",{"title":84,"path":85,"stem":86},"One-off Products","\u002Fapi-reference\u002Fone-off-products","2.api-reference\u002F3.one-off-products",{"title":88,"path":89,"stem":90},"Subscriptions","\u002Fapi-reference\u002Fsubscriptions","2.api-reference\u002F4.subscriptions",{"title":92,"path":93,"stem":94},"Subscription Plans","\u002Fapi-reference\u002Fsubscription-plans","2.api-reference\u002F5.subscription-plans",{"title":96,"path":97,"stem":98},"Orders","\u002Fapi-reference\u002Forders","2.api-reference\u002F6.orders",{"title":100,"path":101,"stem":102},"Order Refunds","\u002Fapi-reference\u002Frefunds","2.api-reference\u002F7.refunds",{"title":104,"path":105,"stem":106},"Refunds","\u002Fapi-reference\u002Fglobal-refunds","2.api-reference\u002F8.global-refunds",{"title":108,"path":109,"stem":110},"Chargebacks","\u002Fapi-reference\u002Fchargebacks","2.api-reference\u002F9.chargebacks",{"title":112,"path":113,"stem":114},"Webhook Events","\u002Fapi-reference\u002Fwebhook-events","2.api-reference\u002F99.webhook-events",{"title":116,"path":117,"stem":118,"children":119},"Packages","\u002Fpackages","3.packages",[120,122,164,210,244,283,318,366,408],{"title":116,"path":117,"stem":121},"3.packages\u002Findex",{"title":123,"path":124,"stem":125,"children":126,"page":61},"PHP SDK","\u002Fpackages\u002Fphp","3.packages\u002F1.php",[127,131,134,137,140,144,147,151,154,157,160],{"title":128,"path":129,"stem":130},"Getting started","\u002Fpackages\u002Fphp\u002Freadme","3.packages\u002F1.php\u002F00.readme",{"title":68,"path":132,"stem":133},"\u002Fpackages\u002Fphp\u002Fcustomers","3.packages\u002F1.php\u002F02.customers",{"title":80,"path":135,"stem":136},"\u002Fpackages\u002Fphp\u002Fcheckouts","3.packages\u002F1.php\u002F03.checkouts",{"title":88,"path":138,"stem":139},"\u002Fpackages\u002Fphp\u002Fsubscriptions","3.packages\u002F1.php\u002F04.subscriptions",{"title":141,"path":142,"stem":143},"Subscription plans","\u002Fpackages\u002Fphp\u002Fsubscriptionplans","3.packages\u002F1.php\u002F05.subscriptionplans",{"title":96,"path":145,"stem":146},"\u002Fpackages\u002Fphp\u002Forders","3.packages\u002F1.php\u002F06.orders",{"title":148,"path":149,"stem":150},"One-off products","\u002Fpackages\u002Fphp\u002Foneoffproducts","3.packages\u002F1.php\u002F07.oneoffproducts",{"title":104,"path":152,"stem":153},"\u002Fpackages\u002Fphp\u002Frefunds","3.packages\u002F1.php\u002F08.refunds",{"title":108,"path":155,"stem":156},"\u002Fpackages\u002Fphp\u002Fchargebacks","3.packages\u002F1.php\u002F09.chargebacks",{"title":50,"path":158,"stem":159},"\u002Fpackages\u002Fphp\u002Fwebhooks","3.packages\u002F1.php\u002F10.webhooks",{"title":161,"path":162,"stem":163},"Webhook URLs","\u002Fpackages\u002Fphp\u002Fwebhookendpoints","3.packages\u002F1.php\u002F11.webhookendpoints",{"title":165,"path":166,"stem":167,"children":168,"page":61},"PHP Fluent","\u002Fpackages\u002Ffluent-php","3.packages\u002F2.fluent-php",[169,172,176,180,183,186,189,192,196,199,203,207],{"title":128,"path":170,"stem":171},"\u002Fpackages\u002Ffluent-php\u002Freadme","3.packages\u002F2.fluent-php\u002F00.readme",{"title":173,"path":174,"stem":175},"Configuration","\u002Fpackages\u002Ffluent-php\u002Fconfiguration","3.packages\u002F2.fluent-php\u002F01.configuration",{"title":177,"path":178,"stem":179},"Core concepts","\u002Fpackages\u002Ffluent-php\u002Fcoreconcepts","3.packages\u002F2.fluent-php\u002F02.coreconcepts",{"title":68,"path":181,"stem":182},"\u002Fpackages\u002Ffluent-php\u002Fcustomers","3.packages\u002F2.fluent-php\u002F03.customers",{"title":80,"path":184,"stem":185},"\u002Fpackages\u002Ffluent-php\u002Fcheckouts","3.packages\u002F2.fluent-php\u002F04.checkouts",{"title":88,"path":187,"stem":188},"\u002Fpackages\u002Ffluent-php\u002Fsubscriptions","3.packages\u002F2.fluent-php\u002F05.subscriptions",{"title":96,"path":190,"stem":191},"\u002Fpackages\u002Ffluent-php\u002Forders","3.packages\u002F2.fluent-php\u002F06.orders",{"title":193,"path":194,"stem":195},"Customer portal","\u002Fpackages\u002Ffluent-php\u002Fcustomerportal","3.packages\u002F2.fluent-php\u002F07.customerportal",{"title":50,"path":197,"stem":198},"\u002Fpackages\u002Ffluent-php\u002Fwebhooks","3.packages\u002F2.fluent-php\u002F08.webhooks",{"title":200,"path":201,"stem":202},"Webhook event flow","\u002Fpackages\u002Ffluent-php\u002Fwebhook-flow","3.packages\u002F2.fluent-php\u002F09.webhook-flow",{"title":204,"path":205,"stem":206},"Existing tables","\u002Fpackages\u002Ffluent-php\u002Fhost-owns-its-tables","3.packages\u002F2.fluent-php\u002F10.host-owns-its-tables",{"title":58,"path":208,"stem":209},"\u002Fpackages\u002Ffluent-php\u002Ftesting","3.packages\u002F2.fluent-php\u002F11.testing",{"title":211,"path":212,"stem":213,"children":214,"page":61},"Laravel","\u002Fpackages\u002Flaravel","3.packages\u002F3.laravel",[215,218,221,224,227,230,233,236,240],{"title":128,"path":216,"stem":217},"\u002Fpackages\u002Flaravel\u002Freadme","3.packages\u002F3.laravel\u002F00.readme",{"title":173,"path":219,"stem":220},"\u002Fpackages\u002Flaravel\u002Fconfiguration","3.packages\u002F3.laravel\u002F01.configuration",{"title":68,"path":222,"stem":223},"\u002Fpackages\u002Flaravel\u002Fcustomers","3.packages\u002F3.laravel\u002F02.customers",{"title":80,"path":225,"stem":226},"\u002Fpackages\u002Flaravel\u002Fcheckouts","3.packages\u002F3.laravel\u002F03.checkouts",{"title":88,"path":228,"stem":229},"\u002Fpackages\u002Flaravel\u002Fsubscriptions","3.packages\u002F3.laravel\u002F04.subscriptions",{"title":96,"path":231,"stem":232},"\u002Fpackages\u002Flaravel\u002Forders","3.packages\u002F3.laravel\u002F05.orders",{"title":50,"path":234,"stem":235},"\u002Fpackages\u002Flaravel\u002Fwebhooks","3.packages\u002F3.laravel\u002F06.webhooks",{"title":237,"path":238,"stem":239},"Comparison","\u002Fpackages\u002Flaravel\u002Fcomparison","3.packages\u002F3.laravel\u002F07.comparison",{"title":241,"path":242,"stem":243},"Migrating from Cashier","\u002Fpackages\u002Flaravel\u002Fmigrating-to-vatly","3.packages\u002F3.laravel\u002F08.migrating-to-vatly",{"title":245,"path":246,"stem":247,"children":248,"page":61},"JavaScript SDK","\u002Fpackages\u002Fjavascript","3.packages\u002F4.javascript",[249,252,255,258,261,264,267,270,273,276,279],{"title":128,"path":250,"stem":251},"\u002Fpackages\u002Fjavascript\u002Freadme","3.packages\u002F4.javascript\u002F00.readme",{"title":68,"path":253,"stem":254},"\u002Fpackages\u002Fjavascript\u002Fcustomers","3.packages\u002F4.javascript\u002F02.customers",{"title":80,"path":256,"stem":257},"\u002Fpackages\u002Fjavascript\u002Fcheckouts","3.packages\u002F4.javascript\u002F03.checkouts",{"title":88,"path":259,"stem":260},"\u002Fpackages\u002Fjavascript\u002Fsubscriptions","3.packages\u002F4.javascript\u002F04.subscriptions",{"title":141,"path":262,"stem":263},"\u002Fpackages\u002Fjavascript\u002Fsubscriptionplans","3.packages\u002F4.javascript\u002F05.subscriptionplans",{"title":96,"path":265,"stem":266},"\u002Fpackages\u002Fjavascript\u002Forders","3.packages\u002F4.javascript\u002F06.orders",{"title":148,"path":268,"stem":269},"\u002Fpackages\u002Fjavascript\u002Foneoffproducts","3.packages\u002F4.javascript\u002F07.oneoffproducts",{"title":104,"path":271,"stem":272},"\u002Fpackages\u002Fjavascript\u002Frefunds","3.packages\u002F4.javascript\u002F08.refunds",{"title":108,"path":274,"stem":275},"\u002Fpackages\u002Fjavascript\u002Fchargebacks","3.packages\u002F4.javascript\u002F09.chargebacks",{"title":50,"path":277,"stem":278},"\u002Fpackages\u002Fjavascript\u002Fwebhooks","3.packages\u002F4.javascript\u002F10.webhooks",{"title":280,"path":281,"stem":282},"API reference","\u002Fpackages\u002Fjavascript\u002Fapi","3.packages\u002F4.javascript\u002F12.api",{"title":284,"path":285,"stem":286,"children":287,"page":61},"JavaScript Fluent","\u002Fpackages\u002Ffluent-js","3.packages\u002F5.fluent-js",[288,291,294,297,300,303,306,309,312,315],{"title":128,"path":289,"stem":290},"\u002Fpackages\u002Ffluent-js\u002Freadme","3.packages\u002F5.fluent-js\u002F00.readme",{"title":173,"path":292,"stem":293},"\u002Fpackages\u002Ffluent-js\u002Fconfiguration","3.packages\u002F5.fluent-js\u002F01.configuration",{"title":177,"path":295,"stem":296},"\u002Fpackages\u002Ffluent-js\u002Fcoreconcepts","3.packages\u002F5.fluent-js\u002F02.coreconcepts",{"title":68,"path":298,"stem":299},"\u002Fpackages\u002Ffluent-js\u002Fcustomers","3.packages\u002F5.fluent-js\u002F03.customers",{"title":80,"path":301,"stem":302},"\u002Fpackages\u002Ffluent-js\u002Fcheckouts","3.packages\u002F5.fluent-js\u002F04.checkouts",{"title":88,"path":304,"stem":305},"\u002Fpackages\u002Ffluent-js\u002Fsubscriptions","3.packages\u002F5.fluent-js\u002F05.subscriptions",{"title":96,"path":307,"stem":308},"\u002Fpackages\u002Ffluent-js\u002Forders","3.packages\u002F5.fluent-js\u002F06.orders",{"title":193,"path":310,"stem":311},"\u002Fpackages\u002Ffluent-js\u002Fcustomerportal","3.packages\u002F5.fluent-js\u002F07.customerportal",{"title":50,"path":313,"stem":314},"\u002Fpackages\u002Ffluent-js\u002Fwebhooks","3.packages\u002F5.fluent-js\u002F08.webhooks",{"title":58,"path":316,"stem":317},"\u002Fpackages\u002Ffluent-js\u002Ftesting","3.packages\u002F5.fluent-js\u002F11.testing",{"title":319,"path":320,"stem":321,"children":322,"page":61},"Python SDK","\u002Fpackages\u002Fpython","3.packages\u002F6.python",[323,326,329,332,335,338,341,344,347,350,353,356,359,362],{"title":128,"path":324,"stem":325},"\u002Fpackages\u002Fpython\u002Freadme","3.packages\u002F6.python\u002F00.readme",{"title":173,"path":327,"stem":328},"\u002Fpackages\u002Fpython\u002Fconfiguration","3.packages\u002F6.python\u002F01.configuration",{"title":68,"path":330,"stem":331},"\u002Fpackages\u002Fpython\u002Fcustomers","3.packages\u002F6.python\u002F02.customers",{"title":80,"path":333,"stem":334},"\u002Fpackages\u002Fpython\u002Fcheckouts","3.packages\u002F6.python\u002F03.checkouts",{"title":88,"path":336,"stem":337},"\u002Fpackages\u002Fpython\u002Fsubscriptions","3.packages\u002F6.python\u002F04.subscriptions",{"title":141,"path":339,"stem":340},"\u002Fpackages\u002Fpython\u002Fsubscriptionplans","3.packages\u002F6.python\u002F05.subscriptionplans",{"title":96,"path":342,"stem":343},"\u002Fpackages\u002Fpython\u002Forders","3.packages\u002F6.python\u002F06.orders",{"title":148,"path":345,"stem":346},"\u002Fpackages\u002Fpython\u002Foneoffproducts","3.packages\u002F6.python\u002F07.oneoffproducts",{"title":104,"path":348,"stem":349},"\u002Fpackages\u002Fpython\u002Frefunds","3.packages\u002F6.python\u002F08.refunds",{"title":108,"path":351,"stem":352},"\u002Fpackages\u002Fpython\u002Fchargebacks","3.packages\u002F6.python\u002F09.chargebacks",{"title":50,"path":354,"stem":355},"\u002Fpackages\u002Fpython\u002Fwebhooks","3.packages\u002F6.python\u002F10.webhooks",{"title":161,"path":357,"stem":358},"\u002Fpackages\u002Fpython\u002Fwebhookendpoints","3.packages\u002F6.python\u002F11.webhookendpoints",{"title":280,"path":360,"stem":361},"\u002Fpackages\u002Fpython\u002Fapi","3.packages\u002F6.python\u002F12.api",{"title":363,"path":364,"stem":365},"Development","\u002Fpackages\u002Fpython\u002Fdevelopment","3.packages\u002F6.python\u002F13.development",{"title":367,"path":368,"stem":369,"children":370,"page":61},"Python Fluent","\u002Fpackages\u002Ffluent-python","3.packages\u002F7.fluent-python",[371,374,377,380,383,386,389,392,395,398,401,405],{"title":128,"path":372,"stem":373},"\u002Fpackages\u002Ffluent-python\u002Freadme","3.packages\u002F7.fluent-python\u002F00.readme",{"title":173,"path":375,"stem":376},"\u002Fpackages\u002Ffluent-python\u002Fconfiguration","3.packages\u002F7.fluent-python\u002F01.configuration",{"title":177,"path":378,"stem":379},"\u002Fpackages\u002Ffluent-python\u002Fcoreconcepts","3.packages\u002F7.fluent-python\u002F02.coreconcepts",{"title":68,"path":381,"stem":382},"\u002Fpackages\u002Ffluent-python\u002Fcustomers","3.packages\u002F7.fluent-python\u002F03.customers",{"title":80,"path":384,"stem":385},"\u002Fpackages\u002Ffluent-python\u002Fcheckouts","3.packages\u002F7.fluent-python\u002F04.checkouts",{"title":88,"path":387,"stem":388},"\u002Fpackages\u002Ffluent-python\u002Fsubscriptions","3.packages\u002F7.fluent-python\u002F05.subscriptions",{"title":96,"path":390,"stem":391},"\u002Fpackages\u002Ffluent-python\u002Forders","3.packages\u002F7.fluent-python\u002F06.orders",{"title":193,"path":393,"stem":394},"\u002Fpackages\u002Ffluent-python\u002Fcustomerportal","3.packages\u002F7.fluent-python\u002F07.customerportal",{"title":50,"path":396,"stem":397},"\u002Fpackages\u002Ffluent-python\u002Fwebhooks","3.packages\u002F7.fluent-python\u002F08.webhooks",{"title":58,"path":399,"stem":400},"\u002Fpackages\u002Ffluent-python\u002Ftesting","3.packages\u002F7.fluent-python\u002F11.testing",{"title":402,"path":403,"stem":404},"Porting","\u002Fpackages\u002Ffluent-python\u002Fporting","3.packages\u002F7.fluent-python\u002F12.porting",{"title":363,"path":406,"stem":407},"\u002Fpackages\u002Ffluent-python\u002Fdevelopment","3.packages\u002F7.fluent-python\u002F13.development",{"title":409,"path":410,"stem":411,"children":412,"page":61},"Django","\u002Fpackages\u002Fdjango","3.packages\u002F8.django",[413,416,420,423,427,431,434,437,440,444,447],{"title":128,"path":414,"stem":415},"\u002Fpackages\u002Fdjango\u002Freadme","3.packages\u002F8.django\u002F00.readme",{"title":417,"path":418,"stem":419},"Installation","\u002Fpackages\u002Fdjango\u002Finstallation","3.packages\u002F8.django\u002F01.installation",{"title":173,"path":421,"stem":422},"\u002Fpackages\u002Fdjango\u002Fconfiguration","3.packages\u002F8.django\u002F02.configuration",{"title":424,"path":425,"stem":426},"Billable models","\u002Fpackages\u002Fdjango\u002Fbillablemodels","3.packages\u002F8.django\u002F03.billablemodels",{"title":428,"path":429,"stem":430},"Checkout","\u002Fpackages\u002Fdjango\u002Fcheckout","3.packages\u002F8.django\u002F04.checkout",{"title":88,"path":432,"stem":433},"\u002Fpackages\u002Fdjango\u002Fbilling","3.packages\u002F8.django\u002F05.billing",{"title":193,"path":435,"stem":436},"\u002Fpackages\u002Fdjango\u002Fcustomerportal","3.packages\u002F8.django\u002F06.customerportal",{"title":50,"path":438,"stem":439},"\u002Fpackages\u002Fdjango\u002Fwebhooks","3.packages\u002F8.django\u002F07.webhooks",{"title":441,"path":442,"stem":443},"Admin","\u002Fpackages\u002Fdjango\u002Fadmin","3.packages\u002F8.django\u002F08.admin",{"title":58,"path":445,"stem":446},"\u002Fpackages\u002Fdjango\u002Ftesting","3.packages\u002F8.django\u002F09.testing",{"title":363,"path":448,"stem":449},"\u002Fpackages\u002Fdjango\u002Fdevelopment","3.packages\u002F8.django\u002F10.development",{"title":451,"path":452,"stem":453,"children":454},"Integrations","\u002Fintegrations","4.integrations",[455,457,461],{"title":451,"path":452,"stem":456},"4.integrations\u002Findex",{"title":458,"path":459,"stem":460},"Lovable payments with Vatly","\u002Fintegrations\u002Flovable","4.integrations\u002F1.lovable",{"title":462,"path":463,"stem":464},"Bolt payments with Vatly","\u002Fintegrations\u002Fbolt","4.integrations\u002F2.bolt",{"id":466,"title":50,"body":467,"description":1298,"extension":1299,"links":1300,"meta":1301,"navigation":1302,"path":313,"seo":1303,"stem":314,"__hash__":1304},"docs\u002F3.packages\u002F5.fluent-js\u002F08.webhooks.md",{"type":468,"value":469,"toc":1293},"minimark",[470,483,868,887,897,902,913,937,947,954,958,1101,1108,1115,1119,1240,1259,1269,1289],[471,472,473,474,478,479,482],"p",{},"Record payments and subscription changes from signed webhooks, not checkout\nredirects. Pass a configured ",[475,476,477],"code",{},"Vatly"," to this Fetch handler, or export the returned\nfunction as a Next.js Route Handler's ",[475,480,481],{},"POST",":",[484,485,490],"pre",{"className":486,"code":487,"language":488,"meta":489,"style":489},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { VatlyInvalidSignatureError } from '@getvatly\u002Fsdk';\nimport { Vatly } from '@getvatly\u002Ffluent';\n\nexport function webhookRoute(vatly: Vatly) {\n  return async function POST(request: Request): Promise\u003CResponse> {\n    try {\n      const processed = await vatly.webhookProcessor().handleRequest(request);\n      return new Response(null, { status: processed ? 201 : 200 });\n    } catch (error) {\n      if (error instanceof VatlyInvalidSignatureError) {\n        return new Response('Invalid signature', { status: 400 });\n      }\n      \u002F\u002F Failed storage\u002Freactions must be retried; do not acknowledge success.\n      return new Response('Webhook processing failed', { status: 500 });\n    }\n  };\n}\n","ts","",[475,491,492,528,551,558,590,631,639,680,725,746,765,802,808,815,850,856,862],{"__ignoreMap":489},[493,494,497,501,505,509,512,515,518,522,525],"span",{"class":495,"line":496},"line",1,[493,498,500],{"class":499},"s7zQu","import",[493,502,504],{"class":503},"sMK4o"," {",[493,506,508],{"class":507},"sTEyZ"," VatlyInvalidSignatureError",[493,510,511],{"class":503}," }",[493,513,514],{"class":499}," from",[493,516,517],{"class":503}," '",[493,519,521],{"class":520},"sfazB","@getvatly\u002Fsdk",[493,523,524],{"class":503},"'",[493,526,527],{"class":503},";\n",[493,529,531,533,535,538,540,542,544,547,549],{"class":495,"line":530},2,[493,532,500],{"class":499},[493,534,504],{"class":503},[493,536,537],{"class":507}," Vatly",[493,539,511],{"class":503},[493,541,514],{"class":499},[493,543,517],{"class":503},[493,545,546],{"class":520},"@getvatly\u002Ffluent",[493,548,524],{"class":503},[493,550,527],{"class":503},[493,552,554],{"class":495,"line":553},3,[493,555,557],{"emptyLinePlaceholder":556},true,"\n",[493,559,561,564,568,572,575,579,581,584,587],{"class":495,"line":560},4,[493,562,563],{"class":499},"export",[493,565,567],{"class":566},"spNyl"," function",[493,569,571],{"class":570},"s2Zo4"," webhookRoute",[493,573,574],{"class":503},"(",[493,576,578],{"class":577},"sHdIc","vatly",[493,580,482],{"class":503},[493,582,537],{"class":583},"sBMFI",[493,585,586],{"class":503},")",[493,588,589],{"class":503}," {\n",[493,591,593,596,599,601,604,606,609,611,614,617,620,623,626,629],{"class":495,"line":592},5,[493,594,595],{"class":499},"  return",[493,597,598],{"class":566}," async",[493,600,567],{"class":566},[493,602,603],{"class":570}," POST",[493,605,574],{"class":503},[493,607,608],{"class":577},"request",[493,610,482],{"class":503},[493,612,613],{"class":583}," Request",[493,615,616],{"class":503},"):",[493,618,619],{"class":583}," Promise",[493,621,622],{"class":503},"\u003C",[493,624,625],{"class":583},"Response",[493,627,628],{"class":503},">",[493,630,589],{"class":503},[493,632,634,637],{"class":495,"line":633},6,[493,635,636],{"class":499},"    try",[493,638,589],{"class":503},[493,640,642,645,648,651,654,657,660,663,667,669,672,674,676,678],{"class":495,"line":641},7,[493,643,644],{"class":566},"      const",[493,646,647],{"class":507}," processed",[493,649,650],{"class":503}," =",[493,652,653],{"class":499}," await",[493,655,656],{"class":507}," vatly",[493,658,659],{"class":503},".",[493,661,662],{"class":570},"webhookProcessor",[493,664,666],{"class":665},"swJcz","()",[493,668,659],{"class":503},[493,670,671],{"class":570},"handleRequest",[493,673,574],{"class":665},[493,675,608],{"class":507},[493,677,586],{"class":665},[493,679,527],{"class":503},[493,681,683,686,689,692,694,697,699,702,704,706,709,713,716,719,721,723],{"class":495,"line":682},8,[493,684,685],{"class":499},"      return",[493,687,688],{"class":503}," new",[493,690,691],{"class":570}," Response",[493,693,574],{"class":665},[493,695,696],{"class":503},"null,",[493,698,504],{"class":503},[493,700,701],{"class":665}," status",[493,703,482],{"class":503},[493,705,647],{"class":507},[493,707,708],{"class":503}," ?",[493,710,712],{"class":711},"sbssI"," 201",[493,714,715],{"class":503}," :",[493,717,718],{"class":711}," 200",[493,720,511],{"class":503},[493,722,586],{"class":665},[493,724,527],{"class":503},[493,726,728,731,734,737,740,743],{"class":495,"line":727},9,[493,729,730],{"class":503},"    }",[493,732,733],{"class":499}," catch",[493,735,736],{"class":665}," (",[493,738,739],{"class":507},"error",[493,741,742],{"class":665},") ",[493,744,745],{"class":503},"{\n",[493,747,749,752,754,756,759,761,763],{"class":495,"line":748},10,[493,750,751],{"class":499},"      if",[493,753,736],{"class":665},[493,755,739],{"class":507},[493,757,758],{"class":503}," instanceof",[493,760,508],{"class":583},[493,762,742],{"class":665},[493,764,745],{"class":503},[493,766,768,771,773,775,777,779,782,784,787,789,791,793,796,798,800],{"class":495,"line":767},11,[493,769,770],{"class":499},"        return",[493,772,688],{"class":503},[493,774,691],{"class":570},[493,776,574],{"class":665},[493,778,524],{"class":503},[493,780,781],{"class":520},"Invalid signature",[493,783,524],{"class":503},[493,785,786],{"class":503},",",[493,788,504],{"class":503},[493,790,701],{"class":665},[493,792,482],{"class":503},[493,794,795],{"class":711}," 400",[493,797,511],{"class":503},[493,799,586],{"class":665},[493,801,527],{"class":503},[493,803,805],{"class":495,"line":804},12,[493,806,807],{"class":503},"      }\n",[493,809,811],{"class":495,"line":810},13,[493,812,814],{"class":813},"sHwdD","      \u002F\u002F Failed storage\u002Freactions must be retried; do not acknowledge success.\n",[493,816,818,820,822,824,826,828,831,833,835,837,839,841,844,846,848],{"class":495,"line":817},14,[493,819,685],{"class":499},[493,821,688],{"class":503},[493,823,691],{"class":570},[493,825,574],{"class":665},[493,827,524],{"class":503},[493,829,830],{"class":520},"Webhook processing failed",[493,832,524],{"class":503},[493,834,786],{"class":503},[493,836,504],{"class":503},[493,838,701],{"class":665},[493,840,482],{"class":503},[493,842,843],{"class":711}," 500",[493,845,511],{"class":503},[493,847,586],{"class":665},[493,849,527],{"class":503},[493,851,853],{"class":495,"line":852},15,[493,854,855],{"class":503},"    }\n",[493,857,859],{"class":495,"line":858},16,[493,860,861],{"class":503},"  };\n",[493,863,865],{"class":495,"line":864},17,[493,866,867],{"class":503},"}\n",[471,869,870,871,874,875,878,879,883,884,659],{},"Set ",[475,872,873],{},"webhookSecret",", ",[475,876,877],{},"webhookCalls",", and the repositories you want updated in\n",[880,881,882],"a",{"href":292},"configuration",". This route needs no browser session; signatures\nauthenticate deliveries. Pass the original unread request, not reserialized JSON.\nFor raw bytes, use ",[475,885,886],{},"processor.handle(rawBody, signatureHeader)",[471,888,889,890,893,894,896],{},"The SDK checks ",[475,891,892],{},"Vatly-Signature"," HMAC and timestamp before touching storage.\nKeep timestamp checks enabled. To rotate secrets, set ",[475,895,873],{}," to an array\nof accepted secrets.",[898,899,901],"h2",{"id":900},"idempotency-and-one-transaction","Idempotency and one transaction",[471,903,904,905,908,909,482],{},"Implement ",[475,906,907],{},"WebhookCalls.process(event, work)"," in one transaction shared by all\n",[880,910,912],{"href":911},"\u002Fpackages\u002Ffluent-js\u002Fcoreconcepts#webhook-storage","storage drivers",[914,915,916,924,927,934],"ol",{},[917,918,919,920,923],"li",{},"Lock or claim the signed ",[475,921,922],{},"event.id",". If already committed, return false.",[917,925,926],{},"Retain the verified envelope, including unknown events.",[917,928,929,930,933],{},"Await ",[475,931,932],{},"work()"," to run reactions and dispatch.",[917,935,936],{},"Mark the ID processed and commit resource changes, bindings, audit, and outbox\ntogether. Return true. Roll back everything on failure.",[471,938,939,940,942,943,946],{},"Never commit the deduplication row before the work; a failure would lose the retry.\nUse signed ",[475,941,922],{},", not the unsigned ",[475,944,945],{},"Vatly-Event-Id"," header. Scope keys and rows\nby tenant, storefront, and mode. Timestamp checks alone do not deduplicate.",[471,948,949,950,953],{},"Write to an outbox in ",[475,951,952],{},"events.dispatch",". Send email and make network calls from a\nworker after commit. Deliveries can arrive out of order; reconcile conflicting\nsnapshots with the API.",[898,955,957],{"id":956},"what-fluent-persists","What Fluent persists",[959,960,961,974],"table",{},[962,963,964],"thead",{},[965,966,967,971],"tr",{},[968,969,970],"th",{},"Event",[968,972,973],{},"Built-in action when the repository is wired",[975,976,977,991,1004,1017,1028,1044,1054,1074,1090],"tbody",{},[965,978,979,985],{},[980,981,982],"td",{},[475,983,984],{},"subscription.started",[980,986,987,988,659],{},"Create or update a local subscription; a new saved row emits ",[475,989,990],{},"local.subscription_created",[965,992,993,1001],{},[980,994,995,874,998],{},[475,996,997],{},"subscription.updated",[475,999,1000],{},"subscription.billing_updated",[980,1002,1003],{},"Update plan, name, quantity, status, and non-null mandate on an existing row; otherwise skip.",[965,1005,1006,1011],{},[980,1007,1008],{},[475,1009,1010],{},"subscription.resumed",[980,1012,1013,1014,659],{},"Update an existing row and clear ",[475,1015,1016],{},"endsAt",[965,1018,1019,1022],{},[980,1020,1021],{},"Cancellation events and grace-period completion",[980,1023,1024,1025,1027],{},"Update an existing row's ",[475,1026,1016],{}," and cancellation reason.",[965,1029,1030,1038],{},[980,1031,1032,874,1035],{},[475,1033,1034],{},"order.paid",[475,1036,1037],{},"order.payment_failed",[980,1039,1040,1041,659],{},"Create or update an order using the signed status; a newly stored paid order emits ",[475,1042,1043],{},"local.order_created",[965,1045,1046,1051],{},[980,1047,1048],{},[475,1049,1050],{},"order.canceled",[980,1052,1053],{},"Update status and cancellation reason on an existing order; otherwise skip.",[965,1055,1056,1067],{},[980,1057,1058,874,1061,874,1064],{},[475,1059,1060],{},"refund.completed",[475,1062,1063],{},"refund.failed",[475,1065,1066],{},"refund.canceled",[980,1068,1069,1070,1073],{},"Upsert a refund if ",[475,1071,1072],{},"refunds"," is wired.",[965,1075,1076,1084],{},[980,1077,1078,874,1081],{},[475,1079,1080],{},"order.chargeback_received",[475,1082,1083],{},"order.chargeback_reversed",[980,1085,1086,1087,1073],{},"Upsert a chargeback if ",[475,1088,1089],{},"chargebacks",[965,1091,1092,1098],{},[980,1093,1094,1095],{},"Scheduled subscription updates, catalogue, checkout, ",[475,1096,1097],{},"webhook.setup",[980,1099,1100],{},"Dispatch only; no built-in resource write.",[471,1102,1103,1104,1107],{},"Reactions use the signed snapshot without an API GET. Missing repositories skip\nwrites, not dispatch. Null billing-event mandates leave the local mandate unchanged;\nsubscription ",[475,1105,1106],{},"sync()"," reconciles removal.",[471,1109,1110,1111,659],{},"Before using subscription state to grant or revoke access, read the\n",[880,1112,1114],{"href":1113},"\u002Fpackages\u002Ffluent-js\u002Fsubscriptions#grace-period-limitation-in-this-alpha","grace-period limitation in this alpha",[898,1116,1118],{"id":1117},"application-events-and-extensions","Application events and extensions",[484,1120,1122],{"className":486,"code":1121,"language":488,"meta":489,"style":489},"import type { DomainEvent, EventDispatcher } from '@getvatly\u002Ffluent';\n\nexport function billingEvents(\n  enqueueInCurrentTransaction: (event: DomainEvent) => Promise\u003Cvoid>,\n): EventDispatcher {\n  return { dispatch: event => enqueueInCurrentTransaction(event) };\n}\n",[475,1123,1124,1153,1157,1169,1200,1208,1236],{"__ignoreMap":489},[493,1125,1126,1128,1131,1133,1136,1138,1141,1143,1145,1147,1149,1151],{"class":495,"line":496},[493,1127,500],{"class":499},[493,1129,1130],{"class":499}," type",[493,1132,504],{"class":503},[493,1134,1135],{"class":507}," DomainEvent",[493,1137,786],{"class":503},[493,1139,1140],{"class":507}," EventDispatcher",[493,1142,511],{"class":503},[493,1144,514],{"class":499},[493,1146,517],{"class":503},[493,1148,546],{"class":520},[493,1150,524],{"class":503},[493,1152,527],{"class":503},[493,1154,1155],{"class":495,"line":530},[493,1156,557],{"emptyLinePlaceholder":556},[493,1158,1159,1161,1163,1166],{"class":495,"line":553},[493,1160,563],{"class":499},[493,1162,567],{"class":566},[493,1164,1165],{"class":570}," billingEvents",[493,1167,1168],{"class":503},"(\n",[493,1170,1171,1174,1176,1178,1181,1183,1185,1187,1190,1192,1194,1197],{"class":495,"line":560},[493,1172,1173],{"class":570},"  enqueueInCurrentTransaction",[493,1175,482],{"class":503},[493,1177,736],{"class":503},[493,1179,1180],{"class":577},"event",[493,1182,482],{"class":503},[493,1184,1135],{"class":583},[493,1186,586],{"class":503},[493,1188,1189],{"class":566}," =>",[493,1191,619],{"class":583},[493,1193,622],{"class":503},[493,1195,1196],{"class":583},"void",[493,1198,1199],{"class":503},">,\n",[493,1201,1202,1204,1206],{"class":495,"line":592},[493,1203,616],{"class":503},[493,1205,1140],{"class":583},[493,1207,589],{"class":503},[493,1209,1210,1212,1214,1217,1219,1222,1224,1227,1229,1231,1233],{"class":495,"line":633},[493,1211,595],{"class":499},[493,1213,504],{"class":503},[493,1215,1216],{"class":570}," dispatch",[493,1218,482],{"class":503},[493,1220,1221],{"class":577}," event",[493,1223,1189],{"class":566},[493,1225,1226],{"class":570}," enqueueInCurrentTransaction",[493,1228,574],{"class":665},[493,1230,1180],{"class":507},[493,1232,742],{"class":665},[493,1234,1235],{"class":503},"};\n",[493,1237,1238],{"class":495,"line":641},[493,1239,867],{"class":503},[471,1241,1242,1243,1246,1247,1250,1251,1254,1255,1258],{},"Check ",[475,1244,1245],{},"event.known"," before switching on ",[475,1248,1249],{},"eventName",". The union includes SDK\ndeliveries and the two local-created events above. Unknown signed events have\n",[475,1252,1253],{},"known: false"," and ",[475,1256,1257],{},"object: unknown","; retain and dispatch them without built-in\nwrites. Types do not validate resource fields at runtime.",[471,1260,1261,1264,1265,1268],{},[475,1262,1263],{},"additionalWebhookReactions"," takes ",[475,1266,1267],{},"{ supports(event), handle(event) }"," objects.\nThey run after built-ins and before dispatch, in the same transaction. Throw to\nroll back and allow retry.",[471,1270,1271,1272,1277,1278,1282,1283,1288],{},"For event fields, see ",[880,1273,112],{"href":1274,"rel":1275},"https:\u002F\u002Fdocs.vatly.com\u002Fapi-reference\u002Fwebhook-events",[1276],"nofollow",".\nRegister endpoints using ",[880,1279,72],{"href":1280,"rel":1281},"https:\u002F\u002Fdocs.vatly.com\u002Fapi-reference\u002Fwebhook-endpoints",[1276],";\nthe ",[880,1284,1287],{"href":1285,"rel":1286},"https:\u002F\u002Fdocs.vatly.com\u002Fguides\u002Fwebhooks",[1276],"webhooks guide"," describes delivery and signatures.",[1290,1291,1292],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":489,"searchDepth":530,"depth":530,"links":1294},[1295,1296,1297],{"id":900,"depth":530,"text":901},{"id":956,"depth":530,"text":957},{"id":1117,"depth":530,"text":1118},"Record payments and subscription changes from signed webhooks, not checkout redirects.","md",null,{},{"title":50},{"title":50,"description":1298},"cpeHALQNvy6UnZOzYVfqeDnIrQhNkrEvjyApu5xgGfc",[1306,1308],{"title":193,"path":310,"stem":311,"description":1307,"children":-1},"Send a signed-in customer to their invoices and subscription controls.",{"title":58,"path":316,"stem":317,"description":1309,"children":-1},"Test API calls without a network by injecting the SDK's fetch.",1794594930601]