Getting Started

Build an Integration

Connect your app or platform to PimaBill from start to finish, covering environments, catalogue, customers, selling, webhooks and going live.

This page covers the whole job of connecting an app (a school, an ISP, a SaaS product) to PimaBill. Each step links to the guide with the details. If you're an AI agent doing the integration, follow the steps in order and keep the rules for agents at the end.

1. Two environments, two keys

The hosted cloud runs two separate copies of PimaBill. They share no data.

LiveSandbox
API base URLhttps://api.pimabill.com/apihttps://sandbox.pimabill.com/api
Dashboardhttps://app.pimabill.comThe same, with the Sandbox switch (foot of the sidebar) on
API keysk_live_...sk_test_...
MoneyRealTest only
  • Get each key from Settings → API keys in the dashboard: with Sandbox off for the live key, and on for the test key. A key only works in the environment that issued it.
  • Configure your app per environment, for example PIMABILL_API_URL and PIMABILL_API_KEY. Never hard-code either.
  • Send the key as Authorization: Bearer sk_.... Give each system the narrowest scopes it needs.

Build and test everything in the sandbox first, then repeat the same setup in live. See Sandbox.

2. Refer to things by your own codes, not IDs

Every record has a different ID in each environment. Your own identifiers don't change, so make your app depend on them:

RecordYour identifierLook it up with
Plancode, e.g. diploma-monthlyGET /api/plans?code=diploma-monthly
Add-on (one-time product)code, e.g. cert-bundle-3mGET /api/add-ons?code=cert-bundle-3m
CustomerexternalId: your user's IDGET /api/customers?externalId=usr_123

If you store PimaBill IDs, for example the customer ID on your user record, store them per environment.

3. Set up your catalogue

Decide, for each thing you sell, whether it renews:

  • It's billed again every period (a monthly fee, a yearly licence): create a plan with a price in each currency. See Plans & Pricing.
  • It's bought once (a course, a bundle, a setup fee, a "3-month package" paid up front): create an add-on. It never renews; your app decides how long access lasts. See One-time products & partial payments.

Create the catalogue with a script that you can run against either environment and that is safe to run twice. If the code exists, update it; otherwise, create it.

4. Create customers

Create a PimaBill customer when your user first needs to pay, with your user's ID as externalId:

curl -X POST "$PIMABILL_API_URL/customers" \
  -H "Authorization: Bearer $PIMABILL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "externalId": "usr_123", "name": "Amina N.", "email": "amina@example.com", "country": "UG", "currency": "UGX" }'

A second create with the same externalId is refused with 409. Look the customer up with ?externalId= instead. See Customers.

5. Take payments

You're sellingCallGuide
A planPOST /api/subscriptions, then POST /api/invoices/{id}/checkout for the first invoiceSubscriptions
A one-time productPOST /api/invoices with items: [{ "addOnCode": "...", "quantity": 1 }] and checkout: {}One-time products
A custom amountPOST /api/invoices with your own items and checkout: {}Charge a customer
A deposit or instalmentscheckout.amount, or amount on /checkout and /mark-paidPaying in parts
Cash or a bank transfer you receivedPOST /api/invoices/{id}/mark-paidInvoices & Payments

Each checkout returns a checkoutUrl. Redirect the customer to it, or send it by WhatsApp, SMS or email. Set callbackUrl to the page they come back to. That page should say "we're confirming your payment", not "paid": the webhook is what confirms it.

Payment providers. Checkouts use your own connected providers first, in priority order. If none can take the payment, they use managed payments (the provider named managed). With managed payments, PimaBill collects for you and pays out to your mobile money, bank or PayPal. You don't need a provider account to start. See Payment Providers and Managed payments.

6. Listen to webhooks

Your app learns about payments from webhooks, not from the redirect.

  1. Register your endpoint in each environment, with that environment's key:
    curl -X PATCH "$PIMABILL_API_URL/tenants/me" \
      -H "Authorization: Bearer $PIMABILL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "webhookUrl": "https://your-app.example.com/webhooks/pimabill" }'
    
    For example, point live at your production app and the sandbox at your staging app. The key needs the write or tenants:write scope.
  2. Read the signing secret from GET /api/tenants/me (webhookSecret) and store it with your other secrets.
  3. Check X-Webhook-Signature-V2 on every request before trusting it. See Handling webhooks.
  4. Handle each event idempotently. Deliveries are retried, so the same event can arrive more than once. Key your handling on the invoice or payment ID.

The events most apps need:

EventWhat to do
invoice.paidGrant what was bought, or extend access for a renewal
invoice.partially_paidRecord the part payment; apply your deposit policy
payment.failedTell the customer; renewals are retried automatically
subscription.canceledRemove access at the end of what was paid for
subscription.renewedA new period began; its invoice follows

See the full event list.

7. Let customers help themselves

Give customers a link to the hosted portal, where they can see invoices, download PDFs and pay. Your server asks for a short-lived link per customer with POST /api/portal/customers/{externalId}/sessions. Never put an API key in a link. See Customer Portal.

8. Go live

  • Every flow passes in the sandbox: buy, renew, pay in parts, fail and retry, cancel.
  • The catalogue script has run against live, with the same codes.
  • Live has a payment provider: your own, or managed payments approved for your organisation.
  • Your live webhook URL is set, its secret is stored, and signature checks are on.
  • Your app's live config uses https://api.pimabill.com/api and the sk_live_ key.
  • One small real payment has gone through and the invoice.paid webhook was received.

Rules for AI agents

If you're an agent integrating an app with PimaBill:

  • Work in the sandbox (sk_test_, https://sandbox.pimabill.com/api) until the owner says to go live. Never use a live key for tests.
  • Never print, log or commit API keys or the webhook secret. Read them from the app's secret store.
  • Make every setup step safe to repeat. Look up by code or externalId before creating, and update instead of duplicating.
  • Don't create plans for things that are paid once. Use add-ons. Plans renew and charge again.
  • Don't treat the redirect back from checkout as payment. Wait for invoice.paid (or invoice.partially_paid).
  • Ask the owner before anything irreversible in live: voiding invoices, refunds, deleting catalogue items, changing prices customers already pay.
  • The API reference lists every endpoint and field. The OpenAPI document is at https://api.pimabill.com/api/openapi.json.
Copyright © 2026