[{"data":1,"prerenderedAt":525},["ShallowReactive",2],{"navigation_docs":3,"-guides-sandbox":132,"-guides-sandbox-surround":520},[4,30,47,128],{"title":5,"path":6,"stem":7,"children":8,"page":29},"Getting Started","\u002Fgetting-started","1.getting-started",[9,13,17,21,25],{"title":10,"path":11,"stem":12},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction",{"title":14,"path":15,"stem":16},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F2.quickstart",{"title":18,"path":19,"stem":20},"Authentication","\u002Fgetting-started\u002Fauthentication","1.getting-started\u002F3.authentication",{"title":22,"path":23,"stem":24},"Self-Hosting","\u002Fgetting-started\u002Fself-hosting","1.getting-started\u002F4.self-hosting",{"title":26,"path":27,"stem":28},"Build an Integration","\u002Fgetting-started\u002Fbuild-an-integration","1.getting-started\u002F5.build-an-integration",false,{"title":31,"path":32,"stem":33,"children":34,"page":29},"Sdks","\u002Fsdks","2.sdks",[35,39,43],{"title":36,"path":37,"stem":38},"TypeScript SDK","\u002Fsdks\u002Ftypescript","2.sdks\u002F1.typescript",{"title":40,"path":41,"stem":42},"Python SDK","\u002Fsdks\u002Fpython","2.sdks\u002F2.python",{"title":44,"path":45,"stem":46},"PHP SDK","\u002Fsdks\u002Fphp","2.sdks\u002F3.php",{"title":48,"path":49,"stem":50,"children":51,"page":29},"Guides","\u002Fguides","3.guides",[52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124],{"title":53,"path":54,"stem":55},"Customers","\u002Fguides\u002Fcustomers","3.guides\u002F1.customers",{"title":57,"path":58,"stem":59},"Usage-Based Billing","\u002Fguides\u002Fusage-billing","3.guides\u002F10.usage-billing",{"title":61,"path":62,"stem":63},"Wallets","\u002Fguides\u002Fwallets","3.guides\u002F11.wallets",{"title":65,"path":66,"stem":67},"Coupons, Add-ons and Credit Notes","\u002Fguides\u002Fcoupons-add-ons-credit-notes","3.guides\u002F12.coupons-add-ons-credit-notes",{"title":69,"path":70,"stem":71},"Taxes","\u002Fguides\u002Ftaxes","3.guides\u002F13.taxes",{"title":73,"path":74,"stem":75},"Customer Portal","\u002Fguides\u002Fcustomer-portal","3.guides\u002F14.customer-portal",{"title":77,"path":78,"stem":79},"Ledger","\u002Fguides\u002Fledger","3.guides\u002F15.ledger",{"title":81,"path":82,"stem":83},"Plan Limits and Access","\u002Fguides\u002Fplan-limits-and-access","3.guides\u002F16.plan-limits-and-access",{"title":85,"path":86,"stem":87},"Currencies and Exchange Rates","\u002Fguides\u002Fcurrencies","3.guides\u002F17.currencies",{"title":89,"path":90,"stem":91},"Charge a Customer","\u002Fguides\u002Fcharge-a-customer","3.guides\u002F18.charge-a-customer",{"title":93,"path":94,"stem":95},"One-time Products & Partial Payments","\u002Fguides\u002Fone-time-products-and-partial-payments","3.guides\u002F19.one-time-products-and-partial-payments",{"title":97,"path":98,"stem":99},"Plans & Pricing","\u002Fguides\u002Fplans-and-pricing","3.guides\u002F2.plans-and-pricing",{"title":101,"path":102,"stem":103},"Subscriptions","\u002Fguides\u002Fsubscriptions","3.guides\u002F3.subscriptions",{"title":105,"path":106,"stem":107},"Invoices & Payments","\u002Fguides\u002Finvoices-and-payments","3.guides\u002F4.invoices-and-payments",{"title":109,"path":110,"stem":111},"Payment Providers","\u002Fguides\u002Fpayment-providers","3.guides\u002F5.payment-providers",{"title":113,"path":114,"stem":115},"Analytics","\u002Fguides\u002Fanalytics","3.guides\u002F6.analytics",{"title":117,"path":118,"stem":119},"Webhooks","\u002Fguides\u002Fwebhooks","3.guides\u002F7.webhooks",{"title":121,"path":122,"stem":123},"Sandbox","\u002Fguides\u002Fsandbox","3.guides\u002F8.sandbox",{"title":125,"path":126,"stem":127},"Money Movement","\u002Fguides\u002Fmoney-movement","3.guides\u002F9.money-movement",{"title":129,"path":130,"stem":131},"API Reference","\u002Fapi-reference","4.api-reference",{"id":133,"title":121,"body":134,"description":513,"extension":514,"links":515,"meta":516,"navigation":517,"path":122,"seo":518,"stem":123,"__hash__":519},"docs\u002F3.guides\u002F8.sandbox.md",{"type":135,"value":136,"toc":506},"minimark",[137,141,146,158,161,243,246,260,267,271,283,286,290,370,380,384,418,421,425,428,454,457,490,496,499,502],[138,139,140],"p",{},"A sandbox is a separate deployment of PimaBill that runs the same code as live but connects only to the payment providers' test accounts. Nothing you do there moves real money, and nothing there appears in live.",[142,143,145],"h2",{"id":144},"switching-between-live-and-sandbox","Switching between live and sandbox",[138,147,148,149,152,153,157],{},"The dashboard has a ",[150,151,121],"strong",{}," switch at the foot of the sidebar, next to Documentation. Turn it on to see the same organisation's sandbox: its own customers, plans, payments and ",[154,155,156],"code",{},"sk_test_"," API keys. Turn it off to return to live. You sign in once, on live; the first switch opens your account and organisation in the sandbox, with the same role. Data never moves between the two.",[138,159,160],{},"Your code talks to each environment's API directly, with that environment's key:",[162,163,164,178],"table",{},[165,166,167],"thead",{},[168,169,170,173,176],"tr",{},[171,172],"th",{},[171,174,175],{},"Live",[171,177,121],{},[179,180,181,197,213,228],"tbody",{},[168,182,183,187,192],{},[184,185,186],"td",{},"API base URL",[184,188,189],{},[154,190,191],{},"https:\u002F\u002Fapi.pimabill.com\u002Fapi",[184,193,194],{},[154,195,196],{},"https:\u002F\u002Fsandbox.pimabill.com\u002Fapi",[168,198,199,202,207],{},[184,200,201],{},"Dashboard",[184,203,204],{},[154,205,206],{},"https:\u002F\u002Fapp.pimabill.com",[184,208,209,210,212],{},"The same, with the ",[150,211,121],{}," switch on",[168,214,215,218,223],{},[184,216,217],{},"Provider webhooks",[184,219,220],{},[154,221,222],{},"https:\u002F\u002Fapi.pimabill.com\u002Fwebhooks\u002F{provider}",[184,224,225],{},[154,226,227],{},"https:\u002F\u002Fsandbox.pimabill.com\u002Fwebhooks\u002F{provider}",[168,229,230,233,238],{},[184,231,232],{},"Key",[184,234,235],{},[154,236,237],{},"sk_live_...",[184,239,240],{},[154,241,242],{},"sk_test_...",[138,244,245],{},"These are the hosted cloud's addresses; a self-hosted deployment has its own.",[138,247,248,249,252,253,255,256,259],{},"Everything you create has a ",[150,250,251],{},"different ID in each environment",", because they are separate databases. Your own references don't change: plan and add-on ",[154,254,154],{},"s and customer ",[154,257,258],{},"externalId","s are whatever you set, so use the same ones in both and look records up by them. Store PimaBill IDs per environment, if at all.",[138,261,262,263,266],{},"Your webhook URL and signing secret are also per environment. Point the sandbox at your staging app and live at your production app (see ",[264,265,117],"a",{"href":118},").",[142,268,270],{"id":269},"managed-payments-in-the-sandbox","Managed payments in the sandbox",[138,272,273,274,278,279,282],{},"If your organisation is approved for ",[264,275,277],{"href":276},"\u002Fguides\u002Fmoney-movement#managed-payments","managed payments"," on live, it's approved in the sandbox too. The first time you open managed payments there (or the Providers page, or ",[150,280,281],{},"Charge a customer","), the sandbox account is set up from your live one, with the same business, contact and payout details, and is ready at once: no second application and no review. It takes test payments through the providers' test accounts.",[138,284,285],{},"If you apply in the sandbox before you're approved on live, the sandbox account is approved at the same moment as the live one.",[142,287,289],{"id":288},"how-to-tell-them-apart","How to tell them apart",[162,291,292,302],{},[165,293,294],{},[168,295,296,298,300],{},[171,297],{},[171,299,175],{},[171,301,121],{},[179,303,304,317,327,342,359],{},[168,305,306,309,313],{},[184,307,308],{},"API keys",[184,310,311],{},[154,312,237],{},[184,314,315],{},[154,316,242],{},[168,318,319,321,324],{},[184,320,201],{},[184,322,323],{},"No banner",[184,325,326],{},"A \"Sandbox: test money only\" banner on every page",[168,328,329,332,335],{},[184,330,331],{},"Emails",[184,333,334],{},"Sent to customers",[184,336,337,338,341],{},"Subjects start with ",[154,339,340],{},"[Sandbox]",", and they go only to people with a login or an invitation to an organisation; emails to test customers are logged, not sent",[168,343,344,349,354],{},[184,345,346],{},[154,347,348],{},"GET \u002Fhealth",[184,350,351],{},[154,352,353],{},"\"environment\": \"live\"",[184,355,356],{},[154,357,358],{},"\"environment\": \"sandbox\"",[168,360,361,364,367],{},[184,362,363],{},"Cloud plan",[184,365,366],{},"Free or Growth, with their limits",[184,368,369],{},"None: no plan limits and nothing to pay",[138,371,372,373,376,377,379],{},"Keys work only where they were issued. A ",[154,374,375],{},"sk_live_"," key sent to the sandbox, or a ",[154,378,156],{}," key sent to live, is refused with a message saying which environment it belongs to.",[142,381,383],{"id":382},"getting-started","Getting started",[385,386,387,394,404,415],"ol",{},[388,389,390,391,393],"li",{},"Sign in to the dashboard and turn on ",[150,392,121],{},".",[388,395,396,397,399,400,403],{},"Copy your ",[154,398,156],{}," key from ",[150,401,402],{},"Settings → API keys"," and point your client at the sandbox API.",[388,405,406,407,410,411,414],{},"Connect payment providers with their ",[150,408,409],{},"test"," credentials: for example a Flutterwave test secret key (",[154,412,413],{},"FLWSECK_TEST-...","), PayPal sandbox credentials, or Yo! Payments sandbox details.",[388,416,417],{},"Take payments using each provider's published test cards and numbers, and check that your webhooks receive the events.",[138,419,420],{},"When you are ready, repeat the setup on live with live credentials. Nothing is copied from the sandbox.",[142,422,424],{"id":423},"running-your-own-sandbox","Running your own sandbox",[138,426,427],{},"A self-hosted deployment becomes a sandbox with one setting:",[429,430,435],"pre",{"className":431,"code":432,"language":433,"meta":434,"style":434},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","SANDBOX_MODE=true\n","bash","",[154,436,437],{"__ignoreMap":434},[438,439,442,446,450],"span",{"class":440,"line":441},"line",1,[438,443,445],{"class":444},"sTEyZ","SANDBOX_MODE",[438,447,449],{"class":448},"sMK4o","=",[438,451,453],{"class":452},"sfazB","true\n",[138,455,456],{},"Run it as its own deployment, with its own databases and secrets, next to your live one. To give the live dashboard its Sandbox switch, set on the live deployment:",[429,458,460],{"className":431,"code":459,"language":433,"meta":434,"style":434},"SANDBOX_BACKEND_URL=https:\u002F\u002Fsandbox.example.com   # the sandbox API, as the dashboard container reaches it\nSANDBOX_LINK_SECRET=...                           # 32+ characters, the same on both deployments\n",[154,461,462,476],{"__ignoreMap":434},[438,463,464,467,469,472],{"class":440,"line":441},[438,465,466],{"class":444},"SANDBOX_BACKEND_URL",[438,468,449],{"class":448},[438,470,471],{"class":452},"https:\u002F\u002Fsandbox.example.com",[438,473,475],{"class":474},"sHwdD","   # the sandbox API, as the dashboard container reaches it\n",[438,477,479,482,484,487],{"class":440,"line":478},2,[438,480,481],{"class":444},"SANDBOX_LINK_SECRET",[438,483,449],{"class":448},[438,485,486],{"class":452},"...",[438,488,489],{"class":474},"                           # 32+ characters, the same on both deployments\n",[138,491,492,493,495],{},"and the same ",[154,494,481],{}," on the sandbox. Live then signs a two-minute link for the signed-in person, and the sandbox opens the same account with the same ids.",[138,497,498],{},"Managed payments can serve both: create a separate sandbox deployment there and route it only to provider connections marked as sandbox.",[138,500,501],{},"Sandbox data may be cleared from time to time.",[503,504,505],"style",{},"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 .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 .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}",{"title":434,"searchDepth":478,"depth":478,"links":507},[508,509,510,511,512],{"id":144,"depth":478,"text":145},{"id":269,"depth":478,"text":270},{"id":288,"depth":478,"text":289},{"id":382,"depth":478,"text":383},{"id":423,"depth":478,"text":424},"Test your integration with test money before going live.","md",null,{},true,{"title":121,"description":513},"24RT0nx2dA9tjtqU-iDH-c-Xdq0cO4kOgqYEdqgAsvc",[521,523],{"title":117,"path":118,"stem":119,"description":522,"children":-1},"Set up real-time webhook notifications for billing events.",{"title":125,"path":126,"stem":127,"description":524,"children":-1},"Collect one-time payments, send payouts, move money between wallets, and use managed payments when you have no provider account.",1793401245830]