Sign In Get Started โ†’
Documentation

ScayPay API Reference

The ScayPay API provides three core capabilities for moving money: collect it from customers (Payment), send it out to recipients (Disbursement), and move it from one party to another in one atomic operation (Transfer).

Base URL
https://api.scaypay.com/v1
Currency
TZS only
Min Payment
TZS 500
Max / Transaction
TZS 10,000,000

Core Concepts

๐Ÿ’ณ
Payment
Collect money from customers via mobile money, card, or QR. Funds flow into your balance.
๐Ÿ’ธ
Disbursement
Send money from your balance to a mobile wallet or bank account. Cashout for payroll, suppliers, or refunds.
๐Ÿ”„
Transfer
Collect from sender and immediately disburse to a pre-configured destination. No balance held.

Authentication

All requests require your API key in the Authorization header:

HTTP
Authorization: Bearer sk_live_your_api_key_here

Get your live API key from your ScayPay Dashboard after application approval. Use sk_test_ prefix for sandbox testing. Keep your key secret โ€” never expose it in client-side code.

Fee Structure

ScayPay charges transparent, per-transaction fees with no monthly minimums.

๐Ÿ’ฐ ScayPay Fee Schedule

๐Ÿ’ณ Payment (Collection) โ€” any methodTZS 250 flat per transaction
๐Ÿ’ธ Disbursement โ€” up to TZS 1,000,000TZS 2,500 flat
๐Ÿ’ธ Disbursement โ€” above TZS 1,000,0000.5% of transaction amount
๐Ÿ”„ Transfer โ€” up to TZS 1,000,000TZS 2,500 flat
๐Ÿ”„ Transfer โ€” above TZS 1,000,0000.5% of transaction amount

Fee Examples

OperationAmountFeeYou Receive / Pay
Payment collectionTZS 50,000TZS 250TZS 49,750 net
Payment collectionTZS 500,000TZS 250TZS 499,750 net
DisbursementTZS 200,000TZS 2,500TZS 202,500 deducted
DisbursementTZS 1,500,000TZS 7,500 (0.5%)TZS 1,507,500 deducted
TransferTZS 800,000TZS 2,500Sender pays TZS 800,000
TransferTZS 2,000,000TZS 10,000 (0.5%)Sender pays TZS 2,000,000

Fees are deducted from your collected balance for payments, and added on top of the amount for disbursements and transfers. All fees are in TZS.

Quick Start

cURL
curl -X POST https://api.scaypay.com/v1/payments/collect \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-znz-001" \
  -d '{
    "payment_type": "mobile",
    "amount": 50000,
    "currency": "TZS",
    "phone": "+255758243132",
    "customer": { "name": "Amani Juma", "email": "amani@example.co.tz" },
    "reference": "ORD-ZNZ-001",
    "webhook_url": "https://yourapp.co.tz/webhooks/scaypay"
  }'

Payment โ€” Mobile Money

POST/v1/payments/collect

Customer receives a push notification on their phone and enters their PIN to authorize. Supported: M-Pesa (Vodacom TZ), Airtel Money, Mixx By Yas (Mixx by Yas), Halotel.

FieldTypeDescription
payment_typestringRequiredMust be "mobile"
amountintegerRequiredAmount in TZS. Min: 500 ยท Max: 10,000,000
currencystringRequiredMust be "TZS"
phonestringRequiredE.164 format e.g. +255758243132
customer.namestringRequiredCustomer full name
customer.emailstringRequiredCustomer email address
referencestringRequiredYour order/reference ID (max 30 chars)
webhook_urlstringOptionalHTTPS URL for status updates
descriptionstringOptionalShown to customer (max 100 chars)
JSON Response
{ "id":"pay_9f3a2bc7", "status":"pending", "amount":{"value":50000,"currency":"TZS"},
  "phone":"+255758243132", "network":"Vodacom TZ",
  "fee": {"value":250,"currency":"TZS"},
  "expires_at":"2026-05-05T18:00:00Z" }

Payment โ€” Card (Hosted Checkout)

POST/v1/payments/collect with "payment_type": "card"

For card payments, ScayPay returns a checkout_url โ€” you must redirect your customer there to complete payment on the secure hosted checkout page. Supported: Visa, Mastercard, local debit cards.

cURL
curl -X POST https://api.scaypay.com/v1/payments/collect \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_type": "card",
    "amount": 150000,
    "currency": "TZS",
    "phone": "+255758243132",
    "customer": {
      "name": "Amani Juma", "email": "amani@example.co.tz",
      "address": "Chikai House, M/kwerekwe",
      "city": "Zanzibar", "state": "ZNZ",
      "postcode": "71000", "country": "TZ"
    },
    "redirect_url": "https://yourapp.co.tz/payment/success",
    "cancel_url":   "https://yourapp.co.tz/payment/cancel",
    "reference": "ORD-ZNZ-002",
    "webhook_url": "https://yourapp.co.tz/webhooks/scaypay"
  }'
JSON Response
{ "id":"pay_2e0bcc5f", "status":"pending",
  "checkout_url": "https://checkout.scaypay.com/pay/W0SzdUSHQm",
  "payment_type": "card",
  "amount":{"value":150000,"currency":"TZS"},
  "fee":{"value":250,"currency":"TZS"},
  "expires_at":"2026-05-05T18:00:00Z" }

Important: After receiving the response, immediately redirect your customer to checkout_url. The payment expires if not completed within 4 hours. After payment, the customer is redirected to your redirect_url (success) or cancel_url (cancelled).

PHP โ€” Redirect to Checkout
<?php
$response = json_decode($apiResponse, true);
if ($response['status'] === 'success' && isset($response['data']['checkout_url'])) {
    header('Location: ' . $response['data']['checkout_url']);
    exit;
}

Payment โ€” Dynamic QR

POST/v1/payments/collect with "payment_type": "dynamic-qr"

Returns a QR code string for the customer to scan with their mobile money app. Ideal for in-person and POS payments. Only amount and currency are required.

JSON Response
{ "id":"pay_6a490816", "status":"pending",
  "payment_qr_code": "000201010212041552...",
  "checkout_url": "https://checkout.scaypay.com/qr/Ax7kM2",
  "amount":{"value":25000,"currency":"TZS"},
  "fee":{"value":250,"currency":"TZS"} }

Check Status & List Payments

GET/v1/payments/{id} โ€” get a single payment by ID

GET/v1/payments โ€” list payments with optional filters:

Query ParamDescription
statusFilter: pending, completed, failed
fromStart date: YYYY-MM-DD
toEnd date: YYYY-MM-DD
limitResults per page (max 100, default 20)
pagePage number (default 1)

Payment status values: pending ยท completed ยท failed ยท voided ยท expired

Account Balance

GET/v1/payments/balance

JSON Response
{ "available":{"currency":"TZS","value":1500000}, "balance":{"currency":"TZS","value":1500000} }

Disbursement โ€” Mobile Money Cashout

Disbursements send money out from your ScayPay balance to a recipient. The total (amount + fee) is deducted immediately. If the payout fails, funds are automatically returned.

POST/v1/disbursements/send

Fee: TZS 2,500 flat (โ‰ค 1M) ยท 0.5% (> 1M)

Example: sending TZS 800,000 โ†’ fee TZS 2,500 ยท total deducted TZS 802,500
FieldDescription
amountRequiredTZS amount to send. Min: 5,000
channelRequired"mobile" for mobile money
recipient_phoneRequiredRecipient phone (+255XXXXXXXXX). Network auto-detected.
recipient_nameRequiredRecipient full name
narrationOptionalPayment reason (shown on statement)
webhook_urlOptionalHTTPS URL for status notifications
metadataOptionalKey-value object (returned in webhook)
cURL
curl -X POST https://api.scaypay.com/v1/disbursements/send \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: payout-may2025-emp001" \
  -d '{
    "amount": 250000,
    "channel": "mobile",
    "recipient_phone": "+255758243132",
    "recipient_name": "Amani Juma",
    "narration": "Salary May 2026",
    "webhook_url": "https://yourapp.co.tz/webhooks/scaypay"
  }'
JSON Response
{ "id":"dib_667c9279", "status":"pending",
  "amount":{"value":250000,"currency":"TZS"},
  "fee":{"value":2500,"currency":"TZS"},
  "total_deducted":{"value":252500,"currency":"TZS"},
  "recipient":{"name":"Amani Juma","phone":"+255758243132"},
  "network":"Vodacom TZ" }

Disbursement โ€” Bank Transfer

POST/v1/disbursements/send with "channel": "bank"

FieldDescription
amountRequiredTZS amount. Min: 5,000
channelRequiredMust be "bank"
recipient_bankRequiredBank code from the list below
recipient_accountRequiredBank account number
recipient_nameRequiredAccount holder name
narrationOptionalPayment reference
cURL
-d '{ "amount":500000, "channel":"bank",
     "recipient_bank":"NMB", "recipient_account":"21000012345678",
     "recipient_name":"Fatuma Hassan", "narration":"Invoice INV-2026-ZNZ-001" }'

All Supported Bank Codes (Tanzania)

Use the Code value as the recipient_bank field for bank disbursements and transfer profiles.

Absa Bank Tanzania ABSA
Access Bank Tanzania ACCESS
Akiba Commercial Bank AKIBA
Amana Bank AMANA
Azania Bank AZANIA
Bank of Baroda Tanzania BARODA
Bank of Africa Tanzania BOA
Citibank Tanzania CITI
CRDB Bank CRDB
Diamond Trust Bank Tanzania DTB
Ecobank Tanzania ECOBANK
Equity Bank Tanzania EQUITY
Exim Bank Tanzania EXIM
First National Bank Tanzania FNB
Habib African Bank HABIB
I&M Bank Tanzania IMBANK
KCB Bank Tanzania KCB
National Bank of Commerce NBC
NCBA Bank Tanzania NCBA
NMB Bank NMB
People's Bank of Zanzibar PBZ
Standard Chartered Tanzania SCB
Stanbic Bank Tanzania STANBIC
Tanzania Commercial Bank TCB
TIB Development Bank TIB
United Bank for Africa Tanzania UBA
Uchumi Commercial Bank UCHUMI
Bank of Tanzania (Gov only) BOT

Calculate Disbursement Fee

GET/v1/disbursements/fee?amount=500000

Always calculate the fee before sending to ensure sufficient balance.

JSON Response
{ "amount":500000, "fee_amount":2500, "total_amount":502500, "currency":"TZS",
  "fee_breakdown": "Flat rate TZS 2,500 (amount โ‰ค 1,000,000)" }

Transfer โ€” How It Works

A Transfer collects money from a sender and immediately disburses it to a pre-configured destination โ€” all in one API call. No funds are held in your balance. โš ๏ธ A Transfer Profile must exist before initiating any transfer.

1๏ธโƒฃ
Create Profile
Define payout destination (phone or bank)
2๏ธโƒฃ
Initiate Transfer
Reference the profile + specify sender + amount
3๏ธโƒฃ
Auto Disburse
Funds collected from sender โ†’ sent to destination instantly

Transfer โ€” Payout Profiles

POST/v1/transfers/profiles โ€” create a destination profile (required before transfers)

cURL โ€” Mobile Profile
-d '{ "name":"Zanzibar Store", "channel":"mobile",
     "recipient_name":"Fatuma Hassan", "recipient_phone":"+255710578275" }'
cURL โ€” Bank Profile
-d '{ "name":"Company Bank", "channel":"bank",
     "recipient_name":"Fatuma Hassan", "recipient_bank":"NMB",
     "recipient_account":"21000012345678" }'
JSON Response
{ "profile_id":"tpf_8a3b2c1d", "name":"Zanzibar Store",
  "channel":"mobile", "recipient":{"name":"Fatuma Hassan","phone":"+255710578275"} }

GET/v1/transfers/profiles โ€” list all profiles.

Initiate a Transfer

POST/v1/transfers/initiate

Fee: TZS 2,500 flat (โ‰ค 1M) ยท 0.5% (> 1M)

Fee is added to the sender's collection amount
FieldDescription
profile_idRequiredID from a Transfer Profile
amountRequiredTZS amount. Min 5,000 ยท Max 10,000,000
sender_phoneRequiredPhone to collect from
sender_nameRequiredSender's full name
referenceRequiredYour reference ID (max 30 chars)
cURL
curl -X POST https://api.scaypay.com/v1/transfers/initiate \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Idempotency-Key: txf-znz-001" \
  -d '{ "profile_id":"tpf_8a3b2c1d", "amount":150000,
        "sender_phone":"+255758243132", "sender_name":"Amani Juma",
        "reference":"TXF-ZNZ-001" }'

Transfer status flow: collecting โ†’ disbursing โ†’ completed ยท or failed

Webhook Events

ScayPay sends HTTP POST to your webhook_url for every status change. Respond with HTTP 200 within 30 seconds.

EventDescription
payment.completedPayment collected successfully
payment.failedPayment failed or rejected by customer
payment.expiredPayment expired (4-hour window)
disbursement.completedCashout delivered to recipient
disbursement.failedCashout failed โ€” balance restored
disbursement.reversedCashout reversed after completion
transfer.completedCollected + disbursed successfully
transfer.failedFailed at collection or disbursement
daily_limit.warning80% of daily collection limit reached

Webhook Payload

JSON
{ "id":"evt_a1b2c3d4", "type":"payment.completed", "api_version":"2026-01",
  "created_at":"2026-05-05T14:32:18Z",
  "data":{ "id":"pay_9f3a2bc7", "status":"completed",
    "amount":{"value":50000,"currency":"TZS"},
    "fee":{"value":250,"currency":"TZS"},
    "net":{"value":49750,"currency":"TZS"},
    "reference":"ORD-ZNZ-001", "phone":"+255758243132" } }

Verify Webhook Signature

Each webhook includes X-ScayPay-Signature. Verify in production to prevent spoofing.

PHP
<?php
$payload   = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_SCAYPAY_TIMESTAMP'];
$signature = $_SERVER['HTTP_X_SCAYPAY_SIGNATURE'];
$secret    = 'your_webhook_signing_secret';

if (abs(time() - (int)$timestamp) > 300) { http_response_code(400); exit; } // replay protection

$expected = hash_hmac('sha256', $timestamp . '.' . $payload, $secret);
if (!hash_equals($expected, $signature)) { http_response_code(401); exit; }

$event = json_decode($payload, true);
http_response_code(200); echo 'OK';

Error Codes

HTTPerror_codeDescription
400validation_errorInvalid or missing field
401unauthorizedInvalid or missing API key
403insufficient_scopeKey lacks required permission
404not_foundResource doesn't exist
422idempotency_conflictKey reused with different body
429rate_limit_exceeded60 req/min exceeded
500payment_failedUpstream failure (retry with backoff)

Rate Limits & Tier Limits

60 requests/minute. Response headers: X-Ratelimit-Limit, X-Ratelimit-Remaining, X-Ratelimit-Reset.

PlanAccess FeeMax Daily CollectionMax / Transaction
StudentTZS 1,000,000TZS 1,000,000
BasicTZS 10,000,000TZS 10,000,000
BusinessTZS 100,000,000TZS 10,000,000
EnterpriseTZS 500,000,000TZS 10,000,000

Idempotency

Include Idempotency-Key on all POST requests to prevent duplicates on retry. Keys must be โ‰ค 30 chars, valid for 24 hours.

HTTP Header
Idempotency-Key: order-znz-001-attempt-1

Need Help?

๐Ÿ“ง support@scaypay.com  ยท  ๐Ÿ“ž +255 710 578 275  ยท  ๐Ÿ’ฌ +255 758 243 132 (WhatsApp)
Chikai House, M/kwerekwe, Zanzibar, Tanzania