Skip to content
Demo environment. M-Pesa and DMVIC are simulated; no real money or certificates move. Sandbox details
FlexySure

Payments

5 endpoints · base URL https://flexysure.intrepidprojects.co.ke/api/v1

Collect premiums with an M-Pesa STK push, follow the prompt to its result, and read receipts and client balances. The STK callback lands on Flexysure's Daraja webhook, which raises the receipt, allocates it to the debit note and activates the policy (and queues the DMVIC certificate) once the first instalment is paid; a premium-finance loan ref collects an instalment for Flexysure Finance instead. Subscribe to the payment.received and policy.activated webhooks rather than polling where you can. Amounts are sent in whole shillings (amount) and returned in shillings plus cents (amount_minor).

MethodPathSummaryScope
POST /api/v1/payment/stk/push Send an M-Pesa STK push pay
GET /api/v1/payment/stk/{uuid} Get STK push status Flexysure only pay
GET /api/v1/receipts List receipts Flexysure only pay
GET /api/v1/receipts/{number} Get a receipt Flexysure only pay
GET /api/v1/clients/{client_no}/balance Get a client's balance Flexysure only pay
POST /api/v1/payment/stk/push

Send an M-Pesa STK push

Sends a "Lipa na M-Pesa" prompt to the customer's phone. account may be a debit note number, a policy number, a risk note number or a premium-finance loan ref (IPF-…). A policy resolves to its oldest unpaid debit note. If the policy has a signed premium-finance loan waiting for its deposit, the prompt is for the deposit (purpose ipf_deposit) and paying it hands the loan to Flexysure Finance. An active (or in-arrears) loan ref is an instalment repayment to Flexysure Finance (purpose ipf_repayment): when the customer pays, the money is booked in Flexysure Finance's books against the loan (fees, then interest, then principal of the oldest unpaid instalment), never as a brokerage receipt, and the loan's repaid and arrears update. To clear a loan early, use POST /ipf/loans/{uuid}/early-settlement (purpose ipf_settlement). The amount may not exceed what is outstanding on that account. Daraja takes whole shillings, so cents are rounded up.

Scope
pay
Authentication
Bearer token
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Required: send an Idempotency-Key; a retry with the same key replays the first response.

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope pay)
Idempotency-KeyRequired. A unique value (a UUID) per write. Replays within 24 hours return the stored response with Idempotent-Replayed: true; the same key with a different body is rejected (idempotency_key_reused).

Body fields

FieldTypeRequiredDescription
account string Yes Debit note number, policy number, risk note number or IPF loan ref. Example: DN-000123
amount number Yes Amount in shillings, at least 1 and at most the outstanding balance. Example: 30175
phone string Yes Safaricom number: 07XXXXXXXX or 2547XXXXXXXX (01… and 2541… also accepted). Example: 0712345678

Example

Request cURL
curl -X POST 'https://flexysure.intrepidprojects.co.ke/api/v1/payment/stk/push' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json' \
  -H 'Idempotency-Key: 3917f09c-c992-4f40-a44f-0fe777689102' \
  -H 'Content-Type: application/json' \
  -d '{
    "account": "DN-000123",
    "amount": 30175,
    "phone": "0712345678"
}'
Request body (JSON)
Request body JSON
{
    "account": "DN-000123",
    "amount": 30175,
    "phone": "0712345678"
}
Response JSON
{
    "merchant_request_id": "29115-34620561-1",
    "checkout_request_id": "ws_CO_14102026101500123",
    "stk_request_uuid": "9b2f0f5e-6d0b-4c1e-9d55-2b8f3c1a7e10",
    "status": "pending",
    "status_label": "Waiting for customer",
    "purpose": "premium",
    "account": "DN-000123",
    "phone": "0712 345 678",
    "amount": 30175,
    "amount_minor": 3017500,
    "result_code": null,
    "result_desc": null,
    "mpesa_receipt": null,
    "receipt_number": null,
    "debit_note": "DN-000123",
    "ipf_loan_ref": null,
    "created_at": "2026-10-14T10:15:00+03:00",
    "updated_at": "2026-10-14T10:15:00+03:00",
    "customer_message": "We sent an M-Pesa prompt to 0712 345 678. The customer enters their PIN to pay."
}

Responses

StatusMeaning
200 Prompt sent: Insurance Cloud fields plus stk_request_uuid to poll
404 account_not_found: no debit note, policy, risk note or loan with that reference in your organisation
422 amount_exceeds_balance (with outstanding), nothing_outstanding, financed_by_lender, loan_not_payable (loan not running: pending, closed or cancelled), payment_refused or validation_failed. No money moved.

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/payment/stk/{uuid} Flexysure only

Get STK push status

pending until the customer answers the prompt, then paid (with mpesa_receipt and the Flexysure receipt_number) or failed (with Daraja's result_code and result_desc, for example 1032 cancelled by the customer).

Scope
pay
Authentication
Bearer token
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Safe to repeat (read only).

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope pay or read)

Parameters

NameInTypeRequiredDescription
uuid path string Yes stk_request_uuid from the push response.

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/payment/stk/{uuid}' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json'
Response JSON
{
    "data": {
        "merchant_request_id": "29115-34620561-1",
        "checkout_request_id": "ws_CO_14102026101500123",
        "stk_request_uuid": "9b2f0f5e-6d0b-4c1e-9d55-2b8f3c1a7e10",
        "status": "paid",
        "status_label": "Paid",
        "purpose": "premium",
        "account": "DN-000123",
        "phone": "0712 345 678",
        "amount": 30175,
        "amount_minor": 3017500,
        "result_code": 0,
        "result_desc": "The service request is processed successfully.",
        "mpesa_receipt": "SKD1A2B3C4",
        "receipt_number": "RCT-000412",
        "debit_note": "DN-000123",
        "ipf_loan_ref": null,
        "created_at": "2026-10-14T10:15:00+03:00",
        "updated_at": "2026-10-14T10:15:00+03:00",
        "customer_message": "We sent an M-Pesa prompt to 0712 345 678. The customer enters their PIN to pay."
    }
}

Responses

StatusMeaning
200 The STK request
404 Unknown or not visible to this token

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/receipts Flexysure only

List receipts

Money received by the organisation, newest first, with what each receipt paid. Cursor paginated (limit, cursor); page/per_page also accepted. Agent-scoped clients see receipts for their own clients and policies.

Scope
pay
Authentication
Bearer token
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Safe to repeat (read only).

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope pay or read)

Parameters

NameInTypeRequiredDescription
channel query string No How the money came in. One of: mpesa_stk, mpesa_c2b, bank, cash, cheque, refund
from query string No Received on or after this date (YYYY-MM-DD). Example: 2026-10-01
to query string No Received on or before this date. Example: 2026-10-31
client_no query string No Only this client's receipts.
policy query string No Policy uuid, policy number or risk note: receipts allocated to its debit notes.
limit query integer No Page size, 1–100 (default 25).
cursor query string No Opaque cursor from links.next.

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/receipts' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json'
Response JSON
{
    "data": [
        {
            "number": "RCT-000412",
            "channel": "mpesa_stk",
            "reference": "SKD1A2B3C4",
            "amount": 30175,
            "amount_minor": 3017500,
            "allocated": 30175,
            "allocated_minor": 3017500,
            "unallocated": 0,
            "unallocated_minor": 0,
            "payer_phone": "254712345678",
            "received_at": "2026-10-14T10:16:02+03:00",
            "status": "allocated",
            "client": {
                "client_no": "C000231",
                "name": "Wanjiru Kamau"
            },
            "allocations": [
                {
                    "debit_note": "DN-000123",
                    "policy_no": "POL/2026/000123",
                    "policy_uuid": "5d0c…",
                    "amount": 30175,
                    "amount_minor": 3017500,
                    "allocated_at": "2026-10-14T10:16:02+03:00"
                }
            ]
        }
    ],
    "meta": {
        "limit": 25,
        "has_more": false,
        "count": 1
    },
    "links": {
        "next": null
    }
}

Responses

StatusMeaning
200 A page of receipts

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/receipts/{number} Flexysure only

Get a receipt

Scope
pay
Authentication
Bearer token
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Safe to repeat (read only).

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope pay or read)

Parameters

NameInTypeRequiredDescription
number path string Yes Receipt number. Example: RCT-000412

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/receipts/RCT-000412' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json'
Response JSON
{
    "data": {
        "number": "RCT-000412",
        "channel": "mpesa_stk",
        "reference": "SKD1A2B3C4",
        "amount": 30175,
        "amount_minor": 3017500,
        "allocated": 30175,
        "allocated_minor": 3017500,
        "unallocated": 0,
        "unallocated_minor": 0,
        "payer_phone": "254712345678",
        "received_at": "2026-10-14T10:16:02+03:00",
        "status": "allocated",
        "client": {
            "client_no": "C000231",
            "name": "Wanjiru Kamau"
        },
        "allocations": [
            {
                "debit_note": "DN-000123",
                "policy_no": "POL/2026/000123",
                "policy_uuid": "5d0c…",
                "amount": 30175,
                "amount_minor": 3017500,
                "allocated_at": "2026-10-14T10:16:02+03:00"
            }
        ]
    }
}

Responses

StatusMeaning
200 The receipt with its allocations
404 Unknown receipt

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/clients/{client_no}/balance Flexysure only

Get a client's balance

Open debit notes, credits (unallocated receipts and credit notes not yet refunded) and premium-finance balances. due is what the client owes the organisation; debit notes Flexysure Finance is paying are listed with payable_by: lender and left out of due. ipf_outstanding is owed to Flexysure Finance (paybill and account in repay_to).

Scope
pay
Authentication
Bearer token
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Safe to repeat (read only).

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope pay or read)

Parameters

NameInTypeRequiredDescription
client_no path string Yes Client number. Example: C000231

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/clients/C000231/balance' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json'
Response JSON
{
    "data": {
        "client": {
            "client_no": "C000231",
            "name": "Wanjiru Kamau"
        },
        "currency": "KES",
        "due": 30175,
        "due_minor": 3017500,
        "credits": 0,
        "credits_minor": 0,
        "net_due": 30175,
        "net_due_minor": 3017500,
        "ipf_outstanding": 46500,
        "ipf_outstanding_minor": 4650000,
        "open_debit_notes": [
            {
                "number": "DN-000123",
                "kind": "Premium",
                "policy_no": "POL/2026/000123",
                "policy_uuid": "5d0c…",
                "due_on": "2026-10-14",
                "amount": 30175,
                "amount_minor": 3017500,
                "paid": 0,
                "paid_minor": 0,
                "outstanding": 30175,
                "outstanding_minor": 3017500,
                "payable_by": "client"
            }
        ],
        "unallocated_receipts": [],
        "credit_notes": [],
        "ipf_loans": [
            {
                "uuid": "1f7e…",
                "loan_ref": "IPF-000017",
                "status": "active",
                "policy_no": "POL/2026/000099",
                "outstanding": 46500,
                "outstanding_minor": 4650000,
                "arrears": 0,
                "arrears_minor": 0,
                "arrears_days": 0,
                "repay_to": {
                    "paybill": "700100",
                    "account": "IPF-000017"
                }
            }
        ],
        "as_of": "2026-10-14T10:20:00+03:00"
    }
}

Responses

StatusMeaning
200 Balance
404 Unknown client

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.