Zivo Invoice. Track expenses. See your money.
Menu

Zivo Developers · ZivoPay API

Create invoices, hosted checkout links, and M-Pesa payments from your app.

Use ZivoPay like a payment gateway: create an invoice, redirect customers to a hosted checkout page, trigger STK, and receive payment callbacks.

Gateway-style checkout Redirect to ZivoPay checkout, then update your platform from status checks, callbacks, and webhook events.

Quick start

  1. Log in to Zivo and open Settings.
  2. Open ZivoPay API and generate a dedicated API key.
  3. Save the key securely. It is shown only once.
  4. Create an invoice with customer details, line items, and your own external_id.
  5. Store the returned invoice_number, external_id, status, and checkout URL.
  6. Redirect your customer to checkout.url or invoice.public_url when you want the hosted checkout page.
  7. Optionally send the hosted invoice link over WhatsApp or trigger M-Pesa STK push.
  8. Check invoice status from your own system, or process callback events when configured.
Use ZivoPay API for payment workflows. For direct WhatsApp messaging and reply webhooks, use Zivo WhatsApp API.

ZivoPay API answers

Quick answers for teams connecting orders, service calls, bookings, or balances to ZivoPay invoice and M-Pesa collection workflows.

What can the ZivoPay API do?

The ZivoPay API lets an external system use an activated business wallet, collect and pay out through M-Pesa, create invoices, redirect customers to hosted checkout, and check transaction or payment status.

Can I create invoices from my own system?

Yes. Send customer details and line items to the invoice endpoint. Zivo returns an invoice number, balance, status, checkout URL, and public payment URL.

Can I use ZivoPay like a payment gateway checkout?

Yes. Create the invoice, store the returned invoice number and checkout URL, redirect the customer to that URL, then update your local order or invoice from the status endpoint or callback.

Can ZivoPay send the payment link on WhatsApp?

Yes. After creating an invoice, call the send endpoint to deliver the hosted payment link through the connected Zivo WhatsApp workspace.

Can I trigger M-Pesa STK push?

Yes. Use the STK endpoint to request payment for the invoice balance or a partial amount.

Which API key should I use?

Use the dedicated ZivoPay API key generated in Settings > ZivoPay API. Existing shared Zivo API keys remain supported for older integrations.

Authentication

Every request needs your Zivo partnerID and ZivoPay API key. Send the key as a Bearer token or as an apikey field.

Field Required Description
partnerID Yes Your Zivo business ID, shown in Settings > ZivoPay API.
apikey Yes Your generated ZivoPay API key, such as zivopay_live_xxxxx. You may also send it as a Bearer token.
workspace_id No Use this when a business has more than one Zivo workspace. If omitted, Zivo uses the default workspace.
Authorization: Bearer zivopay_live_xxxxx
Content-Type: application/json

{
  "partnerID": "1376"
}

Business wallet

After a Zivo administrator activates your wallet, your business can collect into and pay out from the shared ZivoPay paybill. Use your wallet code as the paybill account reference for direct customer payments.

All wallet requests use the same partnerID and API key authentication. Every deposit or withdrawal request must also include a unique Idempotency-Key header so retries cannot create duplicate transactions.

View wallet and recent transactions

GET https://zivo.co.ke/api/zivo/zivopay/wallet
curl "https://zivo.co.ke/api/zivo/zivopay/wallet?partnerID=1376" \
  -H "Authorization: Bearer zivopay_live_xxx"
GET https://zivo.co.ke/api/zivo/zivopay/wallet/transactions

Returns the wallet's latest deposits, payouts, statuses, and M-Pesa references.

Request an M-Pesa deposit

POST https://zivo.co.ke/api/zivo/zivopay/wallet/deposits
curl -X POST "https://zivo.co.ke/api/zivo/zivopay/wallet/deposits" \
  -H "Authorization: Bearer zivopay_live_xxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: deposit-order-10045" \
  -d '{"partnerID":"1376","phone":"254712345678","amount":2500}'

Send a B2C payout

POST https://zivo.co.ke/api/zivo/zivopay/wallet/withdrawals

A payout is accepted only when both the business ledger and the shared paybill have sufficient available funds, and the configured wallet limits allow it.

curl -X POST "https://zivo.co.ke/api/zivo/zivopay/wallet/withdrawals" \
  -H "Authorization: Bearer zivopay_live_xxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: payout-order-10045" \
  -d '{"partnerID":"1376","phone":"254712345678","amount":1000,"note":"Supplier payout"}'

Create invoice

POST https://zivo.co.ke/api/zivo/zivopay/invoices

Create a hosted ZivoPay invoice with a public payment URL and line items.

curl -X POST "https://zivo.co.ke/api/zivo/zivopay/invoices" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer zivopay_live_xxx" \
  -d '{
    "partnerID": "1376",
    "workspace_id": 12,
    "customer_name": "Solomon",
    "phone": "254742097330",
    "external_id": "ORDER-10045",
    "items": [
      { "description": "Starlink wall mount stand", "quantity": 1, "unit_price": 12500 }
    ],
    "notes": "Delivery after payment confirmation",
    "success_url": "https://spacekits.co.ke/checkout/success",
    "cancel_url": "https://spacekits.co.ke/cart",
    "failed_url": "https://spacekits.co.ke/checkout/failed",
    "callback_url": "https://spacekits.co.ke/api/zivopay/callback"
  }'

Response

{
  "ok": true,
  "invoice": {
    "invoice_number": "ZV-12-260715-AB123",
    "external_id": "ORDER-10045",
    "amount": 12500,
    "paid_amount": 0,
    "balance": 12500,
    "status": "pending",
    "public_url": "https://zivo.co.ke/zivopay/checkout/...",
    "checkout_url": "https://zivo.co.ke/zivopay/checkout/..."
  },
  "checkout": {
    "url": "https://zivo.co.ke/zivopay/checkout/...",
    "status_url": "https://zivo.co.ke/zchat/chat-pay/invoices/.../poll",
    "success_url": "https://spacekits.co.ke/checkout/success",
    "cancel_url": "https://spacekits.co.ke/cart",
    "failed_url": "https://spacekits.co.ke/checkout/failed",
    "callback_url": "https://spacekits.co.ke/api/zivopay/callback",
    "callback_secret": "shown-once-for-signature-checks"
  }
}

Request fields

Field Required Description
customer_name Yes Name shown on the invoice and in payment context.
phone Yes Customer phone in international format, such as 2547....
items Yes One or more invoice lines. Each item needs description and unit_price; quantity defaults to 1.
external_id No Your own order, booking, job, or account reference.
success_url No Where ZivoPay redirects the customer after the invoice becomes paid.
cancel_url No Where the customer returns if they cancel from the hosted checkout page.
failed_url No Where ZivoPay can redirect after a failed, expired, or cancelled payment attempt.
callback_url No Your server endpoint for ZivoPay payment events. ZivoPay sends a JSON POST with X-ZivoPay-Signature. Store the returned callback_secret to verify it.

Hosted checkout

GET https://zivo.co.ke/zivopay/checkout/{invoice}/{token}

Redirect your customer to checkout.url. They see a ZivoPay checkout page, trigger M-Pesa STK, and ZivoPay updates the invoice when payment is confirmed.

window.location.href = checkout.url;

After success, ZivoPay appends zivopay_invoice, zivopay_status, and zivopay_external_id to your success_url.

Recommended local integration

  1. Create the ZivoPay invoice from your local order, subscription invoice, booking, or job.
  2. Save invoice_number, external_id, checkout.url, invoice.public_url, status, and callback_secret.
  3. Redirect the customer to the checkout URL instead of building your own M-Pesa form.
  4. When the customer returns, call GET /invoices/{invoice} and update your local invoice status.
  5. If callback_url is configured, verify X-ZivoPay-Signature and process the callback idempotently.
Use external_id for reconciliation. For example, FAMA can send FAMA-BILLING-INVOICE-3 so a callback or status sync updates the exact local billing invoice.

Create checkout session

POST https://zivo.co.ke/api/zivo/zivopay/checkout

This is the gateway-style alias for creating an invoice and hosted checkout in one call. It accepts the same fields as POST /invoices.

curl -X POST "https://zivo.co.ke/api/zivo/zivopay/checkout" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer zivopay_live_xxx" \
  -d '{
    "partnerID": "1376",
    "customer_name": "Solomon",
    "phone": "254742097330",
    "external_id": "ORDER-10045",
    "items": [
      { "description": "Starlink wall mount stand", "quantity": 1, "unit_price": 12500 }
    ],
    "success_url": "https://spacekits.co.ke/checkout/success",
    "cancel_url": "https://spacekits.co.ke/cart",
    "failed_url": "https://spacekits.co.ke/checkout/failed",
    "callback_url": "https://spacekits.co.ke/api/zivopay/callback"
  }'

List invoices

GET https://zivo.co.ke/api/zivo/zivopay/invoices

Return recent invoices for a workspace. Filter by status, search text, and limit.

curl "https://zivo.co.ke/api/zivo/zivopay/invoices?partnerID=1376&workspace_id=12&status=paid&limit=25" \
  -H "Authorization: Bearer zivopay_live_xxx"

Trigger STK push

POST https://zivo.co.ke/api/zivo/zivopay/invoices/{invoice}/stk-push

Start an M-Pesa STK push for the invoice balance or a partial amount.

curl -X POST "https://zivo.co.ke/api/zivo/zivopay/invoices/ZV-12-260715-AB123/stk-push" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer zivopay_live_xxx" \
  -d '{
    "partnerID": "1376",
    "amount": 12500,
    "phone": "254742097330"
  }'

Invoice status

GET https://zivo.co.ke/api/zivo/zivopay/invoices/{invoice}

Return invoice status, balance, public URL, line items, timestamps, and payment progress.

curl "https://zivo.co.ke/api/zivo/zivopay/invoices/ZV-12-260715-AB123?partnerID=1376" \
  -H "Authorization: Bearer zivopay_live_xxx"
{
  "ok": true,
  "invoice": {
    "invoice_number": "ZV-12-260715-AB123",
    "amount": 12500,
    "paid_amount": 12500,
    "balance": 0,
    "status": "paid",
    "public_url": "https://zivo.co.ke/zchat/pay/..."
  }
}

Payment status

GET https://zivo.co.ke/api/zivo/zivopay/payments/{payment}

Look up a recorded payment by payment ID or M-Pesa receipt number.

curl "https://zivo.co.ke/api/zivo/zivopay/payments/RG123ABC?partnerID=1376" \
  -H "Authorization: Bearer zivopay_live_xxx"

Webhook events

GET https://zivo.co.ke/api/zivo/zivopay/webhook-events

Inspect recent M-Pesa/ZivoPay webhook processing events for reconciliation and support.

curl "https://zivo.co.ke/api/zivo/zivopay/webhook-events?partnerID=1376&workspace_id=12&status=failed" \
  -H "Authorization: Bearer zivopay_live_xxx"

Gateway callbacks

If you pass callback_url when creating an invoice, ZivoPay sends a JSON POST when payment is confirmed or an STK attempt fails, expires, or is cancelled.

{
  "event": "payment.confirmed",
  "gateway": "zivopay",
  "checkout_session_id": "uuid",
  "invoice": {
    "invoice_number": "ZV-12-260715-AB123",
    "external_id": "ORDER-10045",
    "status": "paid",
    "amount": 12500,
    "paid_amount": 12500,
    "balance": 0,
    "checkout_url": "https://zivo.co.ke/zivopay/checkout/..."
  },
  "payment": {
    "receipt": "RG123ABC",
    "amount": 12500,
    "status": "confirmed"
  }
}

Verify the X-ZivoPay-Signature HMAC header using the callback_secret returned when the checkout was created, then confirm final status with GET https://zivo.co.ke/api/zivo/zivopay/invoices/{invoice}.

API activity

GET https://zivo.co.ke/api/zivo/zivopay/api-events

Review recent API calls with request IDs, HTTP status, endpoint, source IP, and error message.

curl "https://zivo.co.ke/api/zivo/zivopay/api-events?partnerID=1376&workspace_id=12&limit=50" \
  -H "Authorization: Bearer zivopay_live_xxx"

Errors

ZivoPay returns JSON errors with an HTTP status code and a readable message.

Status Meaning What to check
401 Invalid credentials Confirm partnerID and the ZivoPay API key from Settings > ZivoPay API.
422 Validation failed Check required fields such as customer name, phone, and invoice items.
423 Billing paused The Zivo tenant may be suspended or cancelled until billing is resolved.