[{"data":1,"prerenderedAt":1053},["ShallowReactive",2],{"navigation_docs":3,"-packages-django-configuration":465,"-packages-django-configuration-surround":1048},[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":467,"body":468,"description":1041,"extension":1042,"links":1043,"meta":1044,"navigation":1045,"path":421,"seo":1046,"stem":422,"__hash__":1047},"docs\u002F3.packages\u002F8.django\u002F02.configuration.md","Configure billing",{"type":469,"value":470,"toc":1038},"minimark",[471,489,773,776,901,906,909,1021,1024,1034],[472,473,474,475,479,480,483,484,488],"p",{},"Keep keys on the server. ",[476,477,478],"code",{},"test_"," and ",[476,481,482],{},"live_"," select mode on the same API host.\nAdd these values to your project's settings after ",[485,486,487],"a",{"href":418},"installation",".",[490,491,496],"pre",{"className":492,"code":493,"language":494,"meta":495,"style":495},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import os\n\nVATLY_API_KEY = os.environ[\"VATLY_API_KEY\"]\nVATLY_WEBHOOK_SECRET = os.environ[\"VATLY_WEBHOOK_SECRET\"]\nVATLY_SCOPE = \"my-tenant\u002Fmy-storefront\"\nVATLY_REDIRECT_URL_SUCCESS = \"https:\u002F\u002Fapp.example.com\u002Fbilling\u002Fsuccess\"\nVATLY_REDIRECT_URL_CANCELED = \"https:\u002F\u002Fapp.example.com\u002Fbilling\u002Fcanceled\"\nVATLY_PORTAL_REDIRECT_URL = \"https:\u002F\u002Fapp.example.com\u002Faccount\u002Fbilling\"\nVATLY_CHECKOUTS = {\n    \"book\": {\"products\": [{\"id\": \"one_off_product_example\", \"quantity\": 1}]},\n    \"pro\": {\"products\": [{\"id\": \"subscription_plan_example\", \"quantity\": 1}]},\n}\n","python","",[476,497,498,511,518,552,577,594,609,624,639,650,714,767],{"__ignoreMap":495},[499,500,503,507],"span",{"class":501,"line":502},"line",1,[499,504,506],{"class":505},"s7zQu","import",[499,508,510],{"class":509},"sTEyZ"," os\n",[499,512,514],{"class":501,"line":513},2,[499,515,517],{"emptyLinePlaceholder":516},true,"\n",[499,519,521,524,528,531,533,537,540,543,547,549],{"class":501,"line":520},3,[499,522,523],{"class":509},"VATLY_API_KEY ",[499,525,527],{"class":526},"sMK4o","=",[499,529,530],{"class":509}," os",[499,532,488],{"class":526},[499,534,536],{"class":535},"swJcz","environ",[499,538,539],{"class":526},"[",[499,541,542],{"class":526},"\"",[499,544,546],{"class":545},"sfazB","VATLY_API_KEY",[499,548,542],{"class":526},[499,550,551],{"class":526},"]\n",[499,553,555,558,560,562,564,566,568,570,573,575],{"class":501,"line":554},4,[499,556,557],{"class":509},"VATLY_WEBHOOK_SECRET ",[499,559,527],{"class":526},[499,561,530],{"class":509},[499,563,488],{"class":526},[499,565,536],{"class":535},[499,567,539],{"class":526},[499,569,542],{"class":526},[499,571,572],{"class":545},"VATLY_WEBHOOK_SECRET",[499,574,542],{"class":526},[499,576,551],{"class":526},[499,578,580,583,585,588,591],{"class":501,"line":579},5,[499,581,582],{"class":509},"VATLY_SCOPE ",[499,584,527],{"class":526},[499,586,587],{"class":526}," \"",[499,589,590],{"class":545},"my-tenant\u002Fmy-storefront",[499,592,593],{"class":526},"\"\n",[499,595,597,600,602,604,607],{"class":501,"line":596},6,[499,598,599],{"class":509},"VATLY_REDIRECT_URL_SUCCESS ",[499,601,527],{"class":526},[499,603,587],{"class":526},[499,605,606],{"class":545},"https:\u002F\u002Fapp.example.com\u002Fbilling\u002Fsuccess",[499,608,593],{"class":526},[499,610,612,615,617,619,622],{"class":501,"line":611},7,[499,613,614],{"class":509},"VATLY_REDIRECT_URL_CANCELED ",[499,616,527],{"class":526},[499,618,587],{"class":526},[499,620,621],{"class":545},"https:\u002F\u002Fapp.example.com\u002Fbilling\u002Fcanceled",[499,623,593],{"class":526},[499,625,627,630,632,634,637],{"class":501,"line":626},8,[499,628,629],{"class":509},"VATLY_PORTAL_REDIRECT_URL ",[499,631,527],{"class":526},[499,633,587],{"class":526},[499,635,636],{"class":545},"https:\u002F\u002Fapp.example.com\u002Faccount\u002Fbilling",[499,638,593],{"class":526},[499,640,642,645,647],{"class":501,"line":641},9,[499,643,644],{"class":509},"VATLY_CHECKOUTS ",[499,646,527],{"class":526},[499,648,649],{"class":526}," {\n",[499,651,653,656,659,661,664,667,669,672,674,676,679,681,684,686,688,690,693,695,698,700,703,705,707,711],{"class":501,"line":652},10,[499,654,655],{"class":526},"    \"",[499,657,658],{"class":545},"book",[499,660,542],{"class":526},[499,662,663],{"class":526},":",[499,665,666],{"class":526}," {",[499,668,542],{"class":526},[499,670,671],{"class":545},"products",[499,673,542],{"class":526},[499,675,663],{"class":526},[499,677,678],{"class":526}," [{",[499,680,542],{"class":526},[499,682,683],{"class":545},"id",[499,685,542],{"class":526},[499,687,663],{"class":526},[499,689,587],{"class":526},[499,691,692],{"class":545},"one_off_product_example",[499,694,542],{"class":526},[499,696,697],{"class":526},",",[499,699,587],{"class":526},[499,701,702],{"class":545},"quantity",[499,704,542],{"class":526},[499,706,663],{"class":526},[499,708,710],{"class":709},"sbssI"," 1",[499,712,713],{"class":526},"}]},\n",[499,715,717,719,722,724,726,728,730,732,734,736,738,740,742,744,746,748,751,753,755,757,759,761,763,765],{"class":501,"line":716},11,[499,718,655],{"class":526},[499,720,721],{"class":545},"pro",[499,723,542],{"class":526},[499,725,663],{"class":526},[499,727,666],{"class":526},[499,729,542],{"class":526},[499,731,671],{"class":545},[499,733,542],{"class":526},[499,735,663],{"class":526},[499,737,678],{"class":526},[499,739,542],{"class":526},[499,741,683],{"class":545},[499,743,542],{"class":526},[499,745,663],{"class":526},[499,747,587],{"class":526},[499,749,750],{"class":545},"subscription_plan_example",[499,752,542],{"class":526},[499,754,697],{"class":526},[499,756,587],{"class":526},[499,758,702],{"class":545},[499,760,542],{"class":526},[499,762,663],{"class":526},[499,764,710],{"class":709},[499,766,713],{"class":526},[499,768,770],{"class":501,"line":769},12,[499,771,772],{"class":526},"}\n",[472,774,775],{},"Replace catalog IDs with your own. Offers are an allowlist, not buyer-provided\npayloads. Products, quantity and redirect destinations stay under server control.",[777,778,779,795],"table",{},[780,781,782],"thead",{},[783,784,785,789,792],"tr",{},[786,787,788],"th",{},"Setting",[786,790,791],{},"Required?",[786,793,794],{},"Meaning",[796,797,798,811,823,835,852,865,877,889],"tbody",{},[783,799,800,805,808],{},[801,802,803],"td",{},[476,804,546],{},[801,806,807],{},"Yes",[801,809,810],{},"May fall back to the environment",[783,812,813,818,820],{},[801,814,815],{},[476,816,817],{},"VATLY_SCOPE",[801,819,807],{},[801,821,822],{},"Stable tenant\u002Fstorefront identity, up to 200 characters",[783,824,825,829,832],{},[801,826,827],{},[476,828,572],{},[801,830,831],{},"For webhooks",[801,833,834],{},"Secret string or rotation sequence",[783,836,837,846,849],{},[801,838,839,842,843],{},[476,840,841],{},"VATLY_REDIRECT_URL_SUCCESS",", ",[476,844,845],{},"VATLY_REDIRECT_URL_CANCELED",[801,847,848],{},"For checkout",[801,850,851],{},"HTTPS return destinations",[783,853,854,859,862],{},[801,855,856],{},[476,857,858],{},"VATLY_PORTAL_REDIRECT_URL",[801,860,861],{},"No",[801,863,864],{},"Optional return link in the portal",[783,866,867,872,874],{},[801,868,869],{},[476,870,871],{},"VATLY_CHECKOUTS",[801,873,848],{},[801,875,876],{},"Offer slug → products; optional locale, metadata, billingAddress",[783,878,879,884,886],{},[801,880,881],{},[476,882,883],{},"VATLY_BILLABLE_RESOLVER",[801,885,861],{},[801,887,888],{},"Dotted callable taking request; defaults to request.user",[783,890,891,896,898],{},[801,892,893],{},[476,894,895],{},"VATLY_SCOPE_RESOLVER",[801,897,861],{},[801,899,900],{},"Dotted callable taking request; chooses a trusted scope",[902,903,905],"h2",{"id":904},"bill-an-organization-instead-of-the-user","Bill an organization instead of the user",[472,907,908],{},"A billable resolver must verify membership before returning a saved team\u002Fmodel.\nFor the default user case, the equivalent resolver is:",[490,910,912],{"className":492,"code":911,"language":494,"meta":495,"style":495},"from django.core.exceptions import PermissionDenied\n\n\ndef example(request):\n    if not request.user.is_authenticated:\n        raise PermissionDenied(\"Login required\")\n    return request.user\n",[476,913,914,937,941,945,965,989,1009],{"__ignoreMap":495},[499,915,916,919,922,924,927,929,932,934],{"class":501,"line":502},[499,917,918],{"class":505},"from",[499,920,921],{"class":509}," django",[499,923,488],{"class":526},[499,925,926],{"class":509},"core",[499,928,488],{"class":526},[499,930,931],{"class":509},"exceptions ",[499,933,506],{"class":505},[499,935,936],{"class":509}," PermissionDenied\n",[499,938,939],{"class":501,"line":513},[499,940,517],{"emptyLinePlaceholder":516},[499,942,943],{"class":501,"line":520},[499,944,517],{"emptyLinePlaceholder":516},[499,946,947,951,955,958,962],{"class":501,"line":554},[499,948,950],{"class":949},"spNyl","def",[499,952,954],{"class":953},"s2Zo4"," example",[499,956,957],{"class":526},"(",[499,959,961],{"class":960},"sHdIc","request",[499,963,964],{"class":526},"):\n",[499,966,967,970,973,976,978,981,983,986],{"class":501,"line":579},[499,968,969],{"class":505},"    if",[499,971,972],{"class":526}," not",[499,974,975],{"class":509}," request",[499,977,488],{"class":526},[499,979,980],{"class":535},"user",[499,982,488],{"class":526},[499,984,985],{"class":535},"is_authenticated",[499,987,988],{"class":526},":\n",[499,990,991,994,997,999,1001,1004,1006],{"class":501,"line":596},[499,992,993],{"class":505},"        raise",[499,995,996],{"class":953}," PermissionDenied",[499,998,957],{"class":526},[499,1000,542],{"class":526},[499,1002,1003],{"class":545},"Login required",[499,1005,542],{"class":526},[499,1007,1008],{"class":526},")\n",[499,1010,1011,1014,1016,1018],{"class":501,"line":611},[499,1012,1013],{"class":505},"    return",[499,1015,975],{"class":509},[499,1017,488],{"class":526},[499,1019,1020],{"class":535},"user\n",[472,1022,1023],{},"Put your resolver in an importable module and set its dotted path in settings.\nNever trust a query-string tenant\u002Fcustomer ID as authorization. The facade uses\none API key\u002Fsecret configuration per deployment; scope resolvers alone do not\nswitch credentials. For a multi-credential registry, compose ORMDriver and Fluent\nexplicitly. Webhook routing must also select trusted credentials and scope.",[472,1025,1026,1028,1029],{},[485,1027,424],{"href":425}," · ",[485,1030,280],{"href":1031,"rel":1032},"https:\u002F\u002Fdocs.vatly.com\u002Fapi-reference",[1033],"nofollow",[1035,1036,1037],"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 .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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);}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}",{"title":495,"searchDepth":513,"depth":513,"links":1039},[1040],{"id":904,"depth":513,"text":905},"Keep keys on the server.","md",null,{},{"title":173},{"title":467,"description":1041},"kb28tGIg-0hKTGDqD3UaHvg-x4FWuWxV_5vObMvv8Ck",[1049,1051],{"title":417,"path":418,"stem":419,"description":1050,"children":-1},"Start with a normal Django project, including its auth, sessions, messages and CSRF configuration.",{"title":424,"path":425,"stem":426,"description":1052,"children":-1},"A billable is the saved user, team or company your application has authorized to buy.",1794594933874]