[{"data":1,"prerenderedAt":649},["ShallowReactive",2],{"navigation_docs":3,"-guides-payments-setup":119,"-guides-payments-setup-surround":644},[4,25],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"/getting-started","1.getting-started",[10,15,20],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","/getting-started/introduction","1.getting-started/2.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Installation","/getting-started/installation","1.getting-started/3.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Project Structure","/getting-started/project-structure","1.getting-started/4.project-structure","i-lucide-folder-tree",{"title":26,"icon":6,"path":27,"stem":28,"children":29,"page":6},"Guides","/guides","2. guides",[30,34,49,74],{"title":31,"path":32,"stem":33,"icon":24},"Repositories","/guides/respositories","2. guides/3. respositories",{"title":35,"icon":6,"path":36,"stem":37,"children":38,"page":6},"Authentication","/guides/authentication","2. guides/4. authentication",[39,44],{"title":40,"path":41,"stem":42,"icon":43},"Authentication Setup","/guides/authentication/setup","2. guides/4. authentication/5. setup","i-lucide-lock-keyhole",{"title":45,"path":46,"stem":47,"icon":48},"JWT Configuration","/guides/authentication/jwt-configuration","2. guides/4. authentication/6. jwt-configuration","i-lucide-key",{"title":50,"icon":6,"path":51,"stem":52,"children":53,"page":6},"Charcoles Swagger","/guides/swagger","2. guides/5. swagger",[54,59,64,69],{"title":55,"path":56,"stem":57,"icon":58},"Introduction to Charcole Swagger Documentation","/guides/swagger/introduction","2. guides/5. swagger/6. introduction","i-lucide-book-open",{"title":60,"path":61,"stem":62,"icon":63},"Adding Swagger to Existing Charcole Projects","/guides/swagger/swagger-migration","2. guides/5. swagger/7. swagger-migration","i-lucide-arrow-up-circle",{"title":65,"path":66,"stem":67,"icon":68},"Swagger for Non-Charcole Projects","/guides/swagger/non-charcole-users","2. guides/5. swagger/8. non-charcole-users","i-lucide-package-plus",{"title":70,"path":71,"stem":72,"icon":73},"Swagger Examples","/guides/swagger/swagger-examples","2. guides/5. swagger/9. swagger-examples","i-lucide-code-2",{"title":75,"icon":76,"path":77,"stem":78,"children":79,"page":6},"Charcoles Payments","i-heroicons-credit-card","/guides/payments","2. guides/6. payments",[80,84,89,94,99,104,109,114],{"title":81,"path":82,"stem":83,"icon":76},"Payments","/guides/payments/introduction","2. guides/6. payments/1. introduction",{"title":85,"path":86,"stem":87,"icon":88},"Setup","/guides/payments/setup","2. guides/6. payments/2. setup","i-heroicons-wrench-screwdriver",{"title":90,"path":91,"stem":92,"icon":93},"Providers","/guides/payments/providers","2. guides/6. payments/3. providers","i-heroicons-building-library",{"title":95,"path":96,"stem":97,"icon":98},"API Endpoints","/guides/payments/endpoints","2. guides/6. payments/4. endpoints","i-heroicons-arrows-right-left",{"title":100,"path":101,"stem":102,"icon":103},"Webhooks","/guides/payments/webhooks","2. guides/6. payments/5. webhooks","i-heroicons-bolt",{"title":105,"path":106,"stem":107,"icon":108},"Environment Variables","/guides/payments/environment-variables","2. guides/6. payments/6. environment-variables","i-heroicons-key",{"title":110,"path":111,"stem":112,"icon":113},"Using Without Charcole","/guides/payments/non-charcole-users","2. guides/6. payments/7. non-charcole-users","i-heroicons-puzzle-piece",{"title":115,"path":116,"stem":117,"icon":118},"Examples","/guides/payments/payments-examples","2. guides/6. payments/8. payments-examples","i-heroicons-code-bracket",{"id":120,"title":85,"body":121,"description":629,"extension":630,"links":631,"meta":632,"navigation":633,"path":86,"seo":634,"stem":87,"__hash__":643},"docs/2. guides/6. payments/2. setup.md",{"type":122,"value":123,"toc":622},"minimark",[124,129,133,136,159,167,170,178,184,187,191,194,210,225,442,449,451,455,480,482,486,489,504,507,570,581,584,587,589,593,618],[125,126,128],"h2",{"id":127},"setup-with-charcole-cli","Setup with Charcole CLI",[130,131,132],"p",{},"If you're creating a new Charcole project, payments are the easiest to set up.",[130,134,135],{},"Run the create command:",[137,138,143],"pre",{"className":139,"code":140,"language":141,"meta":142,"style":142},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npx create-charcole@latest\n","bash","",[144,145,146],"code",{"__ignoreMap":142},[147,148,151,155],"span",{"class":149,"line":150},"line",1,[147,152,154],{"class":153},"sBMFI","npx",[147,156,158],{"class":157},"sfazB"," create-charcole@latest\n",[130,160,161,162,166],{},"When the CLI asks \"Include payments module?\", select ",[163,164,165],"strong",{},"Yes",".",[130,168,169],{},"Then choose your provider:",[137,171,176],{"className":172,"code":174,"language":175},[173],"language-text","? Choose a payment provider\n❯ Stripe\n  LemonSqueezy\n","text",[144,177,174],{"__ignoreMap":142},[130,179,180,181,166],{},"The CLI generates everything: env vars, controllers, webhooks, and adapter switching logic. All you need to do is add credentials to ",[144,182,183],{},".env",[185,186],"hr",{},[125,188,190],{"id":189},"setup-in-existing-charcole-project","Setup in Existing Charcole Project",[130,192,193],{},"If you already have a Charcole project and want to add payments later:",[137,195,197],{"className":139,"code":196,"language":141,"meta":142,"style":142},"npm install @charcoles/payments\n",[144,198,199],{"__ignoreMap":142},[147,200,201,204,207],{"class":149,"line":150},[147,202,203],{"class":153},"npm",[147,205,206],{"class":157}," install",[147,208,209],{"class":157}," @charcoles/payments\n",[130,211,212,213,216,217,220,221,224],{},"Then in your main ",[144,214,215],{},"app.js"," file, add the raw body middleware ",[163,218,219],{},"before"," ",[144,222,223],{},"express.json()",":",[137,226,230],{"className":227,"code":228,"language":229,"meta":142,"style":142},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import express from 'express'\nimport { setupPayments } from '@charcoles/payments'\n\nconst app = express()\n\n// ⚠️ Must come BEFORE express.json()\napp.use('/payments/webhook', express.raw({ type: 'application/json' }))\n\napp.use(express.json())\n// ... rest of your middleware\n\nsetupPayments(app)\n\napp.listen(3000)\n","js",[144,231,232,255,279,286,306,311,318,373,378,398,404,409,418,423],{"__ignoreMap":142},[147,233,234,238,242,245,249,252],{"class":149,"line":150},[147,235,237],{"class":236},"s7zQu","import",[147,239,241],{"class":240},"sTEyZ"," express ",[147,243,244],{"class":236},"from",[147,246,248],{"class":247},"sMK4o"," '",[147,250,251],{"class":157},"express",[147,253,254],{"class":247},"'\n",[147,256,258,260,263,266,269,272,274,277],{"class":149,"line":257},2,[147,259,237],{"class":236},[147,261,262],{"class":247}," {",[147,264,265],{"class":240}," setupPayments",[147,267,268],{"class":247}," }",[147,270,271],{"class":236}," from",[147,273,248],{"class":247},[147,275,276],{"class":157},"@charcoles/payments",[147,278,254],{"class":247},[147,280,282],{"class":149,"line":281},3,[147,283,285],{"emptyLinePlaceholder":284},true,"\n",[147,287,289,293,296,299,303],{"class":149,"line":288},4,[147,290,292],{"class":291},"spNyl","const",[147,294,295],{"class":240}," app ",[147,297,298],{"class":247},"=",[147,300,302],{"class":301},"s2Zo4"," express",[147,304,305],{"class":240},"()\n",[147,307,309],{"class":149,"line":308},5,[147,310,285],{"emptyLinePlaceholder":284},[147,312,314],{"class":149,"line":313},6,[147,315,317],{"class":316},"sHwdD","// ⚠️ Must come BEFORE express.json()\n",[147,319,321,324,326,329,332,335,338,340,343,345,347,350,352,355,359,361,363,366,368,370],{"class":149,"line":320},7,[147,322,323],{"class":240},"app",[147,325,166],{"class":247},[147,327,328],{"class":301},"use",[147,330,331],{"class":240},"(",[147,333,334],{"class":247},"'",[147,336,337],{"class":157},"/payments/webhook",[147,339,334],{"class":247},[147,341,342],{"class":247},",",[147,344,302],{"class":240},[147,346,166],{"class":247},[147,348,349],{"class":301},"raw",[147,351,331],{"class":240},[147,353,354],{"class":247},"{",[147,356,358],{"class":357},"swJcz"," type",[147,360,224],{"class":247},[147,362,248],{"class":247},[147,364,365],{"class":157},"application/json",[147,367,334],{"class":247},[147,369,268],{"class":247},[147,371,372],{"class":240},"))\n",[147,374,376],{"class":149,"line":375},8,[147,377,285],{"emptyLinePlaceholder":284},[147,379,381,383,385,387,390,392,395],{"class":149,"line":380},9,[147,382,323],{"class":240},[147,384,166],{"class":247},[147,386,328],{"class":301},[147,388,389],{"class":240},"(express",[147,391,166],{"class":247},[147,393,394],{"class":301},"json",[147,396,397],{"class":240},"())\n",[147,399,401],{"class":149,"line":400},10,[147,402,403],{"class":316},"// ... rest of your middleware\n",[147,405,407],{"class":149,"line":406},11,[147,408,285],{"emptyLinePlaceholder":284},[147,410,412,415],{"class":149,"line":411},12,[147,413,414],{"class":301},"setupPayments",[147,416,417],{"class":240},"(app)\n",[147,419,421],{"class":149,"line":420},13,[147,422,285],{"emptyLinePlaceholder":284},[147,424,426,428,430,433,435,439],{"class":149,"line":425},14,[147,427,323],{"class":240},[147,429,166],{"class":247},[147,431,432],{"class":301},"listen",[147,434,331],{"class":240},[147,436,438],{"class":437},"sbssI","3000",[147,440,441],{"class":240},")\n",[130,443,444,445,448],{},"Then configure environment variables (see ",[446,447,105],"a",{"href":106},").",[185,450],{},[125,452,454],{"id":453},"the-critical-raw-body-middleware","The Critical Raw Body Middleware",[456,457,459,474,477],"callout",{"type":458},"warning",[130,460,461,462,465,466,220,468,220,470,473],{},"The webhook route requires the raw request body before Express parses it. Register ",[144,463,464],{},"express.raw()"," on ",[144,467,337],{},[163,469,219],{},[144,471,472],{},"app.use(express.json())",". Reversing the order will silently break webhook signature verification.",[130,475,476],{},"Webhook signature verification needs the exact raw bytes from the provider (Stripe or LemonSqueezy). If Express parses the body into JSON first, the raw bytes are gone, and signature verification fails. Providers will consider unsigned webhooks a security breach and reject them.",[130,478,479],{},"This is the #1 setup mistake. If your webhooks aren't firing, check this first.",[185,481],{},[125,483,485],{"id":484},"verify-it-works","Verify It Works",[130,487,488],{},"Start your server:",[137,490,492],{"className":139,"code":491,"language":141,"meta":142,"style":142},"npm run dev\n",[144,493,494],{"__ignoreMap":142},[147,495,496,498,501],{"class":149,"line":150},[147,497,203],{"class":153},[147,499,500],{"class":157}," run",[147,502,503],{"class":157}," dev\n",[130,505,506],{},"Check that the endpoints respond. Using a JWT token for your app:",[137,508,510],{"className":139,"code":509,"language":141,"meta":142,"style":142},"curl -X POST http://localhost:3000/payments/create-intent \\\n  -H \"Authorization: Bearer your-jwt-token\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\": 1000, \"currency\": \"usd\"}'\n",[144,511,512,529,545,558],{"__ignoreMap":142},[147,513,514,517,520,523,526],{"class":149,"line":150},[147,515,516],{"class":153},"curl",[147,518,519],{"class":157}," -X",[147,521,522],{"class":157}," POST",[147,524,525],{"class":157}," http://localhost:3000/payments/create-intent",[147,527,528],{"class":240}," \\\n",[147,530,531,534,537,540,543],{"class":149,"line":257},[147,532,533],{"class":157},"  -H",[147,535,536],{"class":247}," \"",[147,538,539],{"class":157},"Authorization: Bearer your-jwt-token",[147,541,542],{"class":247},"\"",[147,544,528],{"class":240},[147,546,547,549,551,554,556],{"class":149,"line":281},[147,548,533],{"class":157},[147,550,536],{"class":247},[147,552,553],{"class":157},"Content-Type: application/json",[147,555,542],{"class":247},[147,557,528],{"class":240},[147,559,560,563,565,568],{"class":149,"line":288},[147,561,562],{"class":157},"  -d",[147,564,248],{"class":247},[147,566,567],{"class":157},"{\"amount\": 1000, \"currency\": \"usd\"}",[147,569,254],{"class":247},[130,571,572,573,576,577,580],{},"You should get back a response with either a ",[144,574,575],{},"clientSecret"," (Stripe) or ",[144,578,579],{},"checkoutUrl"," (LemonSqueezy).",[130,582,583],{},"If you get a 404, check that the module initialized correctly.",[130,585,586],{},"If you get a 401, the JWT verification failed — this is expected if you haven't authenticated properly. That's not a setup issue.",[185,588],{},[125,590,592],{"id":591},"what-comes-next","What Comes Next",[594,595,596,604,611],"ul",{},[597,598,599,603],"li",{},[163,600,601],{},[446,602,90],{"href":91}," — Get your API keys and configure your provider",[597,605,606,610],{},[163,607,608],{},[446,609,105],{"href":106}," — Reference all required env vars",[597,612,613,617],{},[163,614,615],{},[446,616,95],{"href":96}," — Learn the 4 payment endpoints",[619,620,621],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .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 .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 .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 .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 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}",{"title":142,"searchDepth":257,"depth":257,"links":623},[624,625,626,627,628],{"id":127,"depth":257,"text":128},{"id":189,"depth":257,"text":190},{"id":453,"depth":257,"text":454},{"id":484,"depth":257,"text":485},{"id":591,"depth":257,"text":592},"Get the payments module running in your project with either the Charcole CLI or manual setup.","md",null,{},{"icon":88},{"title":635,"description":636,"keywords":637},"Setup Payments in Charcole","Configure payment processing with Stripe or LemonSqueezy in your Charcole project.",[638,639,640,641,642],"setup","configuration","payment setup","stripe setup","lemonsqueezy setup","gBVd8MbUFvTIbvejDT6ChVIyqzjvstSyZZ6G9dGiK7c",[645,647],{"title":81,"path":82,"stem":83,"description":646,"icon":76,"children":-1},"Add payment processing to your application with Stripe or LemonSqueezy. Choose the provider that fits your region and business model.",{"title":90,"path":91,"stem":92,"description":648,"icon":93,"children":-1},"Configure your payment provider credentials for Stripe or LemonSqueezy.",1777986765799]