Giving, paybills and pledges
Where money comes in: the collection accounts members pay to, the ledger of every collection, the review list for payments that could not be matched, pledges, fundraisers, and the paybills and bank accounts behind them.
The api never credits a payment from a callback alone: each M-Pesa payment is verified with Safaricom first, and anything it cannot place waits on the incoming payments list. Payment verification explains why, and How giving works walks the whole flow. Read routes on this page also accept head_office:churches:view and system:churches:view with an X-Church header, except the paybill and bank routes.
Collection accounts
A collection account is what a member types as the M-Pesa account number: TITHE, BUILDING, OFFERING. Each sits on one paybill or one bank account, and its number is unique on that channel. Numbers may not start with a reserved prefix (FR- OP- MP- CLS- CAR- EV- EVS- MERCH- CH- QR-); see Account numbers.
| Route | Permission | Purpose |
|---|---|---|
| GET/v1/collection-accounts | church:collections:view | List accounts (q, status, type, page, page_size) with goal and amount achieved. |
| GET/v1/collection-accounts/stats | church:collections:view | Accounts, active accounts, this month's and this year's collections. |
| GET/v1/collection-accounts/search | church:collections:view | Quick search for pickers. |
| GET/v1/collection-accounts/options | church:collections:view | Paybills, bank accounts and cell groups an account can be tied to. |
| POST/v1/collection-accounts | church:collections:manage | Create an account. |
| GET/v1/collection-accounts/{uuid} | church:collections:view | One account. |
| PUT/v1/collection-accounts/{uuid} | church:collections:manage | Update (PATCH accepted). |
| POST/v1/collection-accounts/{uuid}/status | church:collections:manage | Activate or deactivate (status: active | inactive). |
| PUT/v1/collection-accounts/{uuid}/instructions | church:collections:manage | Set the how-to-pay text members receive by SMS (instruction, send). |
| POST/v1/collection-accounts/{uuid}/send-instructions | church:collections:manage | Text the instructions to a member (member_uuid) or a phone. |
| DELETE/v1/collection-accounts/{uuid} | church:collections:manage | Remove an account. |
Collection account fields
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Shown to members, for example "Building Fund". |
| account | string | Yes | The account number members type. One word, at most 40 characters, stored upper case. |
| paybill_uuid | uuid | No | The paybill payments arrive on. Give this or bank_account_uuid. |
| bank_account_uuid | uuid | No | The bank account payments arrive on. |
| type | string | No | fixed (default) or temporary. |
| status | string | No | active (default) or inactive. |
| tithe_offering | string | No | none (default), tithe or offering, for reports. |
| goal | number | No | A target in KES; progress shows in the app. |
| send_alert | boolean | No | Send the payer a receipt SMS built from message. |
| message | string | No | Receipt text; must contain [amount] when send_alert is on. Also [name] [fname] [total] [balance] [reference] [account] [account_name] and others. |
| pledge_message | string | No | Text sent when a member pledges to the account: [name] [amount] [account]. |
| hide_from_members | boolean | No | Keep it out of the app's giving list. |
| cell_group_uuid | uuid | No | Tie the account to a cell group for cell group giving reports. |
# Paste your token once (it starts with mc_):
export MYCHURCH_TOKEN="mc_your_token_here"
curl -X POST https://uat-api.mychurch.co.ke/v1/collection-accounts \
-H "Authorization: Bearer $MYCHURCH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Building Fund",
"account": "BUILDING",
"paybill_uuid": "3c9a7b21-0000-4000-8000-00000000b001",
"goal": 2500000,
"send_alert": true,
"message": "Dear [fname], we have received KES [amount] for [account_name]. God bless you."
}'The collection ledger
Every credited collection, whatever the channel. Lists are read for a date window (from, to; default the current month).
| Route | Permission | Purpose |
|---|---|---|
| GET/v1/collection-transactions | church:transactions:view | Collections (from, to, account, member, mode, verified, q, page, page_size). |
| GET/v1/collection-transactions/totals | church:transactions:view | Totals for the same filters, by payment mode. |
| GET/v1/collection-transactions/export.csv | church:transactions:export | The same filters as a CSV download. |
| POST/v1/collection-transactions | church:collections:manage | Record a cash, cheque or other collection by hand. |
| GET/v1/collection-transactions/{uuid} | church:transactions:view | One collection. |
# Paste your token once (it starts with mc_):
export MYCHURCH_TOKEN="mc_your_token_here"
curl -X POST https://uat-api.mychurch.co.ke/v1/collection-transactions \
-H "Authorization: Bearer $MYCHURCH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"account_uuid": "8e4d2f10-0000-4000-8000-00000000a201",
"amount": 1500,
"payment_mode": "cash",
"member_uuid": "0b6f4c1e-1111-4a2b-9c3d-000000000001",
"reference": "ENV-0412",
"transaction_time": "2026-11-01"
}'Incoming payments
Payments that reached a paybill or bank account but could not be credited on their own: an account number no collection account matches, a failed verification, a Safaricom outage. Nothing is dropped. Assigning a payment hands it back to the payments worker, which credits it (verifying it first if Safaricom has not confirmed it yet); the api never credits on its own.
| Route | Permission | Purpose |
|---|---|---|
| GET/v1/incoming-payments | church:collections:reconcile | Parked payments (status, q, from, to, page, page_size). |
| GET/v1/incoming-payments/stats | church:collections:reconcile | Counts and amounts by status. |
| GET/v1/incoming-payments/{uuid} | church:collections:reconcile | One payment with the body Safaricom sent. |
| POST/v1/incoming-payments/{uuid}/assign | church:collections:reconcile | Credit it to a collection account on the same channel: account_uuid, optional member_uuid and note. |
| POST/v1/incoming-payments/{uuid}/retry | church:collections:reconcile | Send a stuck or failed payment back for verification. |
| POST/v1/incoming-payments/{uuid}/dismiss | church:collections:reconcile | Close it with a reason. It stays as evidence and can still be assigned later. |
| GET/v1/incoming-payments/bank-unverified | church:collections:reconcile | Bank credits not yet checked against the bank statement. |
| POST/v1/incoming-payments/bank/{uuid}/verify | church:collections:reconcile | Mark a bank credit as seen on the statement. |
Staff may read the review list with system:churches:view; head office users cannot.
Pledges
| Route | Permission | Purpose |
|---|---|---|
| GET/v1/pledges | church:pledges:view | Pledges with amount paid and balance (page, page_size and filters). |
| GET/v1/pledges/totals | church:pledges:view | Pledged, paid and outstanding totals. |
| POST/v1/pledges | church:pledges:create | Record a pledge for a member against a collection account. |
| GET/v1/pledges/{uuid} | church:pledges:view | One pledge. |
| PUT/v1/pledges/{uuid} | church:pledges:edit | Update (PATCH accepted). |
| POST/v1/pledges/{uuid}/pay | church:pledges:edit | Record a payment against the pledge by hand (amount). |
| DELETE/v1/pledges/{uuid} | church:pledges:delete | Remove a pledge. |
| GET/v1/pledges/reminder-days | church:pledges:view | Which days pledge reminder SMS go out. |
| PUT/v1/pledges/reminder-days | church:pledges:edit | Change the reminder days. |
| POST/v1/pledges/remind | church:pledges:edit | Send reminders now. |
Fundraisers
A fundraiser has its own FR- account number, a target and dates, and takes pledges of its own.
| Route | Permission | Purpose |
|---|---|---|
| GET/v1/fundraisers | church:fundraising:view | List fundraisers with raised and pledged amounts. |
| POST/v1/fundraisers | church:fundraising:create | Create one; the FR- account number is issued. |
| GET/v1/fundraisers/{uuid} | church:fundraising:view | One fundraiser. |
| PUT/v1/fundraisers/{uuid} | church:fundraising:edit | Update (PATCH accepted). |
| POST/v1/fundraisers/{uuid}/status | church:fundraising:edit | Open or close it. |
| DELETE/v1/fundraisers/{uuid} | church:fundraising:delete | Remove it. |
| GET/v1/fundraisers/{uuid}/transactions | church:fundraising:view | Contributions received. |
| POST/v1/fundraisers/{uuid}/payments | church:fundraising:edit | Record a cash or cheque contribution. |
| GET/v1/fundraisers/{uuid}/pledges | church:fundraising:view | Pledges to the fundraiser. |
| POST/v1/fundraisers/{uuid}/pledges | church:fundraising:edit | Record a pledge. |
| PUT/v1/fundraising-pledges/{uuid} | church:fundraising:edit | Change a fundraiser pledge (PATCH accepted). |
| DELETE/v1/fundraising-pledges/{uuid} | church:fundraising:edit | Remove a fundraiser pledge. |
Contribution programs
| Route | Permission | Purpose |
|---|---|---|
| GET/v1/contribution-programs | church:programs:view | Programs: an expected amount per member per period (frequency) on one collection account, with how many members are complete. |
| POST/v1/contribution-programs | church:programs:create | Create a program: name, account_uuid, frequency, expected_amount. |
| GET/v1/contribution-programs/{uuid} | church:programs:view | One program. |
| PUT/v1/contribution-programs/{uuid} | church:programs:edit | Update (PATCH accepted). |
| DELETE/v1/contribution-programs/{uuid} | church:programs:delete | Remove a program. |
| GET/v1/contribution-programs/{uuid}/transactions | church:programs:view | Each member's expected and paid amount. |
Paybills and tills
A church's own M-Pesa paybill or till, with its Daraja credentials. Secrets are encrypted at rest and never returned: a paybill shows has_pass_key, has_consumer_secret and a consumer_key_hint instead. Leave a secret blank on update to keep the stored one. Step by step: Paybill and till setup.
| Route | Permission | Purpose |
|---|---|---|
| GET/v1/paybills | church:paybills:manage | The church's paybills and tills. |
| POST/v1/paybills | church:paybills:manage | Add a paybill or till with its Daraja credentials. |
| GET/v1/paybills/{uuid} | church:paybills:manage | One paybill (secrets masked). |
| PUT/v1/paybills/{uuid} | church:paybills:manage | Update (PATCH accepted); blank secrets keep the stored values. |
| POST/v1/paybills/{uuid}/test | church:paybills:manage | Ask Daraja for a token with the stored consumer key and secret. The token is never returned. |
| POST/v1/paybills/{uuid}/register-c2b | church:paybills:manage | Register MyChurch's validation and confirmation URLs for the shortcode with Safaricom. |
| POST/v1/paybills/{uuid}/stk | church:paybills:manage | Turn STK push on or off (allow_stk_push). |
| DELETE/v1/paybills/{uuid} | church:paybills:manage | Remove a paybill no collection account uses. |
Paybill fields
| Field | Type | Required | Description |
|---|---|---|---|
| short_code | string | Yes | The paybill or store number. A short code can belong to one church only (409 otherwise). |
| is_till | boolean | No | A Buy Goods till rather than a paybill. |
| till_number | string | No | The till number members pay to, when is_till. |
| allow_stk_push | boolean | No | Let the app and USSD send payment prompts on this paybill. |
| settlement_account_uuid | uuid | No | The money account the paybill settles into, for the finance ledger. |
| consumer_key | string | No | Daraja app consumer key. |
| consumer_secret | string | No | Daraja app consumer secret. |
| pass_key | string | No | Lipa na M-Pesa Online pass key, for STK push. |
| initiator | string | No | API initiator user name, for Transaction Status verification. |
| initiator_password | string | No | The initiator's password. |
# Paste your token once (it starts with mc_):
export MYCHURCH_TOKEN="mc_your_token_here"
curl -X POST "https://uat-api.mychurch.co.ke/v1/paybills/3c9a7b21-0000-4000-8000-00000000b001/register-c2b" \
-H "Authorization: Bearer $MYCHURCH_TOKEN"{
"success": true,
"data": {
"ok": true,
"code": "0",
"description": "Success",
"validation_url": "https://api.mychurch.co.ke/api/v1/callback",
"confirmation_url": "https://api.mychurch.co.ke/api/v1/confirm"
}
}A refusal is still HTTP 200
data.ok and data.description, so a wrong consumer secret or an unreachable Daraja answers 200 with ok: false. Check ok, not the status code.Bank accounts and KCB
Bank accounts that receive giving (Equity, KCB, Co-operative Bank, NCBA), with the bank's integration credentials where the bank issues them. Bitwise staff can manage these for a church with system:integrations:manage. See Bank integrations.
| Route | Permission | Purpose |
|---|---|---|
| GET/v1/bank-accounts | church:bank_accounts:manage | The church's bank accounts (credentials masked). |
| GET/v1/bank-accounts/currencies | church:bank_accounts:manage | Currencies an account can hold. |
| POST/v1/bank-accounts | church:bank_accounts:manage | Add: name, bank_name, account_number, currency_uuid, opening_balance and the bank's credentials. |
| GET/v1/bank-accounts/{uuid} | church:bank_accounts:manage | One account. |
| PUT/v1/bank-accounts/{uuid} | church:bank_accounts:manage | Update (PATCH accepted); clear_secrets removes stored credentials. |
| DELETE/v1/bank-accounts/{uuid} | church:bank_accounts:manage | Remove an account nothing settles into. |
| GET/v1/kcb-integrations | church:bank_accounts:manage | KCB Buni credentials on file. |
| POST/v1/kcb-integrations | church:bank_accounts:manage | Store KCB Buni credentials: client_id, client_secret, username, password. |
| PUT/v1/kcb-integrations/{uuid} | church:bank_accounts:manage | Update or disable them (PATCH accepted). |
| DELETE/v1/kcb-integrations/{uuid} | church:bank_accounts:manage | Remove them. |
Reconciliation uploads
Upload an M-Pesa organisation portal statement or a bank export. The imports worker matches each credit line by receipt and amount with the ledger and reports rows_matched and rows_unmatched. It credits nothing: a payment missing from the ledger reaches the incoming payments list through the normal verified path.
| Route | Permission | Purpose |
|---|---|---|
| GET/v1/reconciliation-uploads | church:collections:reconcile | Uploaded statements and their match results. |
| POST/v1/reconciliation-uploads | church:collections:reconcile | Upload a statement (multipart: file, source, paybill_uuid or bank_account_uuid, notes). |