[{"data":1,"prerenderedAt":564},["ShallowReactive",2],{"navigation_docs":3,"-getting-started-self-hosting":132,"-getting-started-self-hosting-surround":559},[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":22,"body":134,"description":552,"extension":553,"links":554,"meta":555,"navigation":556,"path":23,"seo":557,"stem":24,"__hash__":558},"docs\u002F1.getting-started\u002F4.self-hosting.md",{"type":135,"value":136,"toc":544},"minimark",[137,141,146,162,166,214,221,330,333,358,372,376,408,414,418,436,440,451,455,534,540],[138,139,140],"p",{},"PimaBill is open source (AGPL-3.0). You can run the whole platform yourself, with no limits on organisations, customers or invoices. Everything below is free.",[142,143,145],"h2",{"id":144},"what-you-need","What you need",[147,148,149,153,156,159],"ul",{},[150,151,152],"li",{},"A Linux server with Docker and Docker Compose (2 GB of memory is enough to start)",[150,154,155],{},"A domain for the API and one for the dashboard, behind a reverse proxy with TLS",[150,157,158],{},"SMTP credentials for emails (invoices, password resets, invitations)",[150,160,161],{},"Your own account with at least one payment provider (Flutterwave, Paystack, Stripe, MTN MoMo, Airtel Money, Yo! Payments, PayPal and more)",[142,163,165],{"id":164},"install","Install",[167,168,173],"pre",{"className":169,"code":170,"language":171,"meta":172,"style":172},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl -O https:\u002F\u002Fraw.githubusercontent.com\u002Fpimabill\u002Fbilling\u002Fmain\u002Fdocker-compose.prod.yml\ncurl -O https:\u002F\u002Fraw.githubusercontent.com\u002Fpimabill\u002Fbilling\u002Fmain\u002F.env.example\ncp .env.example .env\n","bash","",[174,175,176,192,202],"code",{"__ignoreMap":172},[177,178,181,185,189],"span",{"class":179,"line":180},"line",1,[177,182,184],{"class":183},"sBMFI","curl",[177,186,188],{"class":187},"sfazB"," -O",[177,190,191],{"class":187}," https:\u002F\u002Fraw.githubusercontent.com\u002Fpimabill\u002Fbilling\u002Fmain\u002Fdocker-compose.prod.yml\n",[177,193,195,197,199],{"class":179,"line":194},2,[177,196,184],{"class":183},[177,198,188],{"class":187},[177,200,201],{"class":187}," https:\u002F\u002Fraw.githubusercontent.com\u002Fpimabill\u002Fbilling\u002Fmain\u002F.env.example\n",[177,203,205,208,211],{"class":179,"line":204},3,[177,206,207],{"class":183},"cp",[177,209,210],{"class":187}," .env.example",[177,212,213],{"class":187}," .env\n",[138,215,216,217,220],{},"Fill in ",[174,218,219],{},".env",". These are required:",[222,223,224,237],"table",{},[225,226,227],"thead",{},[228,229,230,234],"tr",{},[231,232,233],"th",{},"Setting",[231,235,236],{},"What it is",[238,239,240,259,275,288,308],"tbody",{},[228,241,242,252],{},[243,244,245,248,249],"td",{},[174,246,247],{},"CENTRAL_DB_PASSWORD",", ",[174,250,251],{},"TENANT_DB_PASSWORD",[243,253,254,255,258],{},"Database passwords (",[174,256,257],{},"openssl rand -hex 24",")",[228,260,261,269],{},[243,262,263,248,266],{},[174,264,265],{},"JWT_SECRET",[174,267,268],{},"JWT_REFRESH_SECRET",[243,270,271,272,258],{},"Session signing secrets, different from each other (",[174,273,274],{},"openssl rand -hex 32",[228,276,277,282],{},[243,278,279],{},[174,280,281],{},"ENCRYPTION_KEY",[243,283,284,285,287],{},"Encrypts provider credentials and database URLs (",[174,286,274],{},"); keep a copy: without it they cannot be read",[228,289,290,298],{},[243,291,292,248,295],{},[174,293,294],{},"API_URL",[174,296,297],{},"DASHBOARD_URL",[243,299,300,301,304,305],{},"Your public addresses, e.g. ",[174,302,303],{},"https:\u002F\u002Fapi.example.com"," and ",[174,306,307],{},"https:\u002F\u002Fapp.example.com",[228,309,310,327],{},[243,311,312,248,315,248,318,248,321,248,324],{},[174,313,314],{},"EMAIL_HOST",[174,316,317],{},"EMAIL_PORT",[174,319,320],{},"EMAIL_USER",[174,322,323],{},"EMAIL_PASSWORD",[174,325,326],{},"EMAIL_FROM",[243,328,329],{},"SMTP",[138,331,332],{},"Then start it:",[167,334,336],{"className":169,"code":335,"language":171,"meta":172,"style":172},"docker compose -f docker-compose.prod.yml up -d\n",[174,337,338],{"__ignoreMap":172},[177,339,340,343,346,349,352,355],{"class":179,"line":180},[177,341,342],{"class":183},"docker",[177,344,345],{"class":187}," compose",[177,347,348],{"class":187}," -f",[177,350,351],{"class":187}," docker-compose.prod.yml",[177,353,354],{"class":187}," up",[177,356,357],{"class":187}," -d\n",[138,359,360,361,304,364,367,368,371],{},"The API listens on port 4000 and the dashboard on 4002 (change them with ",[174,362,363],{},"API_PORT",[174,365,366],{},"DASHBOARD_PORT","). Put both behind your reverse proxy; ",[174,369,370],{},"nginx.conf.example"," in the repository is a starting point. Database migrations run on start, and each organisation gets its own database when it signs up.",[142,373,375],{"id":374},"updating","Updating",[167,377,379],{"className":169,"code":378,"language":171,"meta":172,"style":172},"docker compose -f docker-compose.prod.yml pull\ndocker compose -f docker-compose.prod.yml up -d\n",[174,380,381,394],{"__ignoreMap":172},[177,382,383,385,387,389,391],{"class":179,"line":180},[177,384,342],{"class":183},[177,386,345],{"class":187},[177,388,348],{"class":187},[177,390,351],{"class":187},[177,392,393],{"class":187}," pull\n",[177,395,396,398,400,402,404,406],{"class":179,"line":194},[177,397,342],{"class":183},[177,399,345],{"class":187},[177,401,348],{"class":187},[177,403,351],{"class":187},[177,405,354],{"class":187},[177,407,357],{"class":187},[138,409,410,411,413],{},"Back up the two PostgreSQL volumes and your ",[174,412,219],{}," before updating. Releases and what changed are on the GitHub releases page.",[142,415,417],{"id":416},"branding","Branding",[138,419,420,248,423,248,426,248,429,304,432,435],{},[174,421,422],{},"BRAND_NAME",[174,424,425],{},"BRAND_LOGO",[174,427,428],{},"BRAND_TAGLINE",[174,430,431],{},"BRAND_PRIMARY",[174,433,434],{},"BRAND_SUPPORT_EMAIL"," put your own name on emails, invoices and the API reference.",[142,437,439],{"id":438},"a-sandbox","A sandbox",[138,441,442,443,446,447,450],{},"Run a second deployment with ",[174,444,445],{},"SANDBOX_MODE=true"," for testing with providers' test accounts, and give your live dashboard a switch to it. See ",[448,449,121],"a",{"href":122},".",[142,452,454],{"id":453},"what-is-different-from-the-cloud","What is different from the cloud",[222,456,457,469],{},[225,458,459],{},[228,460,461,463,466],{},[231,462],{},[231,464,465],{},"Self-hosted",[231,467,468],{},"Cloud",[238,470,471,482,496,507,523],{},[228,472,473,476,479],{},[243,474,475],{},"Price",[243,477,478],{},"Free",[243,480,481],{},"Free up to 1,000 customers; Growth, with no limits, $15 a month or the same in your currency (UGX 55,000, KES 1,900, NGN 22,000, …); Enterprise on request",[228,483,484,487,490],{},[243,485,486],{},"Limits",[243,488,489],{},"None",[243,491,492,493],{},"Per plan; see ",[448,494,495],{"href":82},"Plan limits and access",[228,497,498,501,504],{},[243,499,500],{},"Payment providers",[243,502,503],{},"Your own accounts",[243,505,506],{},"Your own accounts, plus managed payments",[228,508,509,515,520],{},[243,510,511],{},[512,513,514],"strong",{},"Managed payments",[243,516,517],{},[512,518,519],{},"Not available",[243,521,522],{},"Included: get paid without a payment provider account of your own",[228,524,525,528,531],{},[243,526,527],{},"Servers, updates, backups",[243,529,530],{},"Yours",[243,532,533],{},"Ours",[138,535,536,537,450],{},"Managed payments are a service run by the cloud: it takes payments for you and pays you out, with review and payouts handled by us. A self-hosted deployment always uses its own provider accounts. Connect them in ",[512,538,539],{},"Settings → Payment providers",[541,542,543],"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);}",{"title":172,"searchDepth":194,"depth":194,"links":545},[546,547,548,549,550,551],{"id":144,"depth":194,"text":145},{"id":164,"depth":194,"text":165},{"id":374,"depth":194,"text":375},{"id":416,"depth":194,"text":417},{"id":438,"depth":194,"text":439},{"id":453,"depth":194,"text":454},"Run PimaBill on your own servers with Docker, and what differs from the hosted cloud.","md",null,{},true,{"title":22,"description":552},"ZmI-dB7CWJ0DeNHkqMqWrEL2zV22wl4XQpNpkdlkAV8",[560,562],{"title":18,"path":19,"stem":20,"description":561,"children":-1},"How PimaBill authenticates people signed in to the dashboard and servers calling the API with an API key.",{"title":26,"path":27,"stem":28,"description":563,"children":-1},"Connect your app or platform to PimaBill from start to finish, covering environments, catalogue, customers, selling, webhooks and going live.",1793401244546]