Money + Points 9 Currencies • 1 Point = 1 Shilling • Free Transfers
Architecture REST API v1 • Mobile & Ecosystem Apps • Webhooks

Jayb Developer Documentation

Jayb is a unified wallet, checkout, and cross-border settlement hub for holding real money across 9 currencies (KES, USD, EUR, GBP, CNY, AED, UGX, TZS, RWF) alongside universal loyalty points (1 Point = 1 KES). Partner platforms (such as Kasoko and cargo.ke) and mobile apps can provision multi-currency wallets and merchant subaccounts, collect payments via M-Pesa, Airtel Money, Card, and PesaLink, convert currencies, and settle domestic or international suppliers funded from any currency wallet or direct payment rail.

2. Authentication & Idempotency Headers

Bearer Token or X-Jayb-Api-Key

Authenticate server-to-server requests using either the standard Authorization: Bearer header or the X-Jayb-Api-Key header. For mutating payout and invoice endpoints, include an Idempotency-Key header to safely retry network timeouts without double-charging.

Authorization: Bearer YOUR_JAYB_API_KEY
# or
X-Jayb-Api-Key: YOUR_JAYB_API_KEY
Idempotency-Key: idem_2026_unique_request_uuid

3. Wallets, Multi-Currency FX, Top-Ups & Transfers API

/api/v1/wallets/*

Every wallet endpoint accepts either a RESTful path parameter (/api/v1/wallets/:phone_number/...) or a JSON body parameter (/api/v1/wallets/... with phone_number, merchant_code, or wallet_id).

# 1. Create or Look Up a Wallet (supports multi-currency fiat & loyalty points)
POST https://jayb.page.ke/api/v1/wallets
{
  "phone_number": "+254712345678",
  "full_name": "Amina Hassan",
  "wallet_type": "individual",
  "currencies": ["KES", "USD", "CNY", "AED"]
}

# 2. Fetch Wallet Balances (Points + All Open Currency Sub-Accounts)
GET https://jayb.page.ke/api/v1/wallets/+254712345678/balance

# 3. Fetch Wallet Transactions (Points Ledger + Fiat Ledger)
GET https://jayb.page.ke/api/v1/wallets/+254712345678/transactions?limit=25&offset=0

# 4. Open Any Supported Currency Sub-Account (KES, USD, EUR, GBP, CNY, AED, UGX, TZS, RWF)
POST https://jayb.page.ke/api/v1/wallets/+254712345678/open_currency
{ "currency": "EUR" }

# 5. Upgrade a Points-Only Wallet to Fiat / Current Account via KYC
POST https://jayb.page.ke/api/v1/wallets/+254712345678/upgrade_fiat
{ "id_number": "29481023", "kra_pin": "A009182736Z", "currencies": ["KES", "USD"] }

# 6. Top Up Wallet (channels: "mpesa", "airtel_money", "card", "pesalink")
POST https://jayb.page.ke/api/v1/wallets/+254712345678/top_up
{ "amount": 20000.0, "currency": "KES", "channel": "mpesa" }

# 7. Transfer Money, Pay Business, or Withdraw to Mobile Money / Bank
# - Internal personal P2P ("channel": "jayb"): 0% fee
# - Internal business payment ("channel": "jayb"): follows business fee_bearer ("business", "customer", "split")
# - External mobile/bank withdrawal or payout ("channel": "mpesa" | "airtel_money" | "pesalink"): 1.0% fee
# - funding_source: "wallet:KES", "wallet:USD", "direct:mpesa", "direct:airtel_money", or "direct:pesalink"
POST https://jayb.page.ke/api/v1/wallets/+254712345678/transfer
{
  "recipient": "582910",
  "amount": 4000.0,
  "currency": "KES",
  "funding_source": "wallet:KES",
  "channel": "jayb",
  "note": "Order #1042"
}

# 8. Instant Multi-Currency Wallet Conversion
POST https://jayb.page.ke/api/v1/wallets/+254712345678/convert_currency
{ "from_currency": "KES", "to_currency": "USD", "amount": 12950.0 }

4. Multi-Business, Ecosystem Subaccounts, KYB & Fee Policy

/api/v1/businesses • /api/v1/merchants/*

Individuals can create unlimited separate businesses, and partner marketplaces (such as Kasoko and cargo.ke) can programmatically provision isolated merchant subaccounts, submit KYB verification dossiers, and configure fee bearer rules (business / disabled, customer / mandatory, or split).

# 1. Create a Separate Business Owned by an Individual
POST https://jayb.page.ke/api/v1/businesses
{
  "owner_phone": "+254712345678",
  "business_name": "Kasoko Hardware Depot",
  "business_type": "Wholesale",
  "fee_bearer": "split",
  "fee_percentage": 1.5,
  "currencies": ["KES", "USD", "CNY"]
}

# 2. List All Separate Businesses Managed by an Individual
GET https://jayb.page.ke/api/v1/wallets/+254712345678/businesses

# 3. Update Wallet Fee Bearer Policy ("business", "customer", or "split")
POST https://jayb.page.ke/api/v1/wallets/fee_policy
{ "merchant_code": "582910", "fee_bearer": "customer", "fee_percentage": 1.5 }

# 4. Provision an Ecosystem Merchant Subaccount (or Standalone Client App)
POST https://jayb.page.ke/api/v1/merchants/provision
{
  "name": "Mombasa Auto Spares Ltd",
  "external_reference": "kasoko-acc-441",
  "contact_email": "accounts@mombasaspares.co.ke",
  "contact_phone": "+254722111222"
}

# 5. Submit Merchant KYB Dossier & Check KYB Status
POST https://jayb.page.ke/api/v1/merchants/kyb
{
  "external_reference": "kasoko-acc-441",
  "legal_business_name": "Mombasa Auto Spares Limited",
  "registration_number": "PVT-2024-88219",
  "tax_id": "P051928374K",
  "director_name": "Salim Bakari",
  "director_id_number": "22819201"
}
GET https://jayb.page.ke/api/v1/merchants/kyb_status?external_reference=kasoko-acc-441

# 6. Configure or Query Checkout Fee Coverage Policy for a Subaccount
POST https://jayb.page.ke/api/v1/merchants/fee_policy
{ "external_reference": "kasoko-acc-441", "mode": "split" }
GET https://jayb.page.ke/api/v1/merchants/fee_policy?external_reference=kasoko-acc-441

5. Universal Loyalty Points Ledger API

/api/v1/points/*

Award, reserve (two-phase checkout hold), commit, release, redeem, or refund universal loyalty points (1 Point = 1 KES) across partner apps. All endpoints are idempotent on reference_id + source_app.

# 1. Award Points (explicit points or auto-calculated from event_type & amount_kes)
POST https://jayb.page.ke/api/v1/points/earn
{ "phone_number": "+254712345678", "event_type": "payment_received", "amount_kes": 5000, "reference_id": "ORD-901" }

# 2. Redeem Points Immediately
POST https://jayb.page.ke/api/v1/points/redeem
{ "phone_number": "+254712345678", "points": 250, "purpose": "checkout_discount", "reference_id": "RED-901" }

# 3. Two-Phase Points Reservation (Reserve -> Commit or Release)
POST https://jayb.page.ke/api/v1/points/reserve
{ "phone_number": "+254712345678", "points": 500, "purpose": "cart_hold", "reference_id": "HOLD-402" }

POST https://jayb.page.ke/api/v1/points/commit
{ "reference_id": "HOLD-402", "description": "Order completed" }

POST https://jayb.page.ke/api/v1/points/release
{ "reference_id": "HOLD-402" }

# 4. Refund Redeemed Points
POST https://jayb.page.ke/api/v1/points/refund
{ "phone_number": "+254712345678", "points": 250, "reference_id": "REFUND-901", "description": "Cancelled order" }

6. Supported Payment Rails

1. M-Pesa (mpesa)

Instant STK mobile prompt, Paybill, Till & mobile money B2C disbursements.

2. Airtel Money (airtel_money)

Direct mobile push collections and instant payouts.

3. Card (card)

Local and international debit & credit cards in KES and USD with 3D-Secure 2.0.

4. PesaLink & Bank Accounts (pesalink)

Instant 24/7 bank-to-bank transfers and dedicated Choice Bank virtual accounts.

7. Drop-in Widget SDK (widget.js) & Inline iFrame

<script src="https://jayb.page.ke/widget.js"></script>
<script>
  JaybPay.open({
    sessionToken: "chk_live_a1b2c3d4...",
    host: "https://jayb.page.ke",
    onSuccess: (data) => window.location.href = "/receipt?id=" + data.reference,
    onCancel: () => console.log("Checkout closed")
  });
</script>

<!-- Or embed directly via responsive iFrame -->
<iframe src="https://jayb.page.ke/embed/checkout?session=chk_live_a1b2c3d4..." allow="payment"></iframe>

8. Checkout Sessions & Direct Invoice Collection API

/api/v1/checkout/*
# 1. Create a Hosted / Embedded Checkout Session
POST https://jayb.page.ke/api/v1/checkout/sessions
{
  "amount": 5000,
  "currency": "KES",
  "title": "Invoice #INV-2026-901",
  "subaccount": "kasoko-acc-441",
  "fee_coverage": { "mode": "split", "percentage": 2.5 },
  "award_points": true,
  "customer": {
    "name": "Amina Hassan",
    "phone": "+254712345678",
    "email": "amina@example.com"
  },
  "metadata": { "invoice_id": "INV-2026-901" },
  "success_url": "https://yourapp.com/orders/success",
  "cancel_url": "https://yourapp.com/orders/cancel"
}
# Response (Checkout & Payment Completion):
# {
#   "success": true,
#   "token": "chk_...",
#   "reference": "CHK-...",
#   "amount": 5000.0,
#   "covered_fee_amount": 62.5,
#   "total_charged_amount": 5062.5,
#   "currency": "KES",
#   "status": "pending",
#   "checkout_url": "https://jayb.page.ke/checkout/chk_...",
#   "embed_url": "https://jayb.page.ke/embed/checkout?session=chk_...",
#   "points_earned": 50,
#   "points_balance": 150,
#   "wallet_claimed": false,
#   "points_only": true,
#   "claim_wallet_url": "https://jayb.page.ke/claim?phone=%2B254712345678",
#   "kyc_url": "https://jayb.page.ke/portal/individual/kyc",
#   "transaction_message": "Payment of KSh 5,062.50 confirmed (Ref: CHK-...). You earned +50 Jayb Points! Your points balance is 150 PTS (worth KSh 150). Claim your wallet to redeem points anytime (complete KYC at your own time to hold fiat): https://jayb.page.ke/claim?phone=%2B254712345678"
# }

# 2. Retrieve, Initiate Payment, or Poll a Checkout Session
GET  https://jayb.page.ke/api/v1/checkout/sessions/:token_or_reference
POST https://jayb.page.ke/api/v1/checkout/sessions/:token_or_reference/pay
{ "payment_method": "mpesa", "phone_number": "+254712345678" }
GET  https://jayb.page.ke/api/v1/checkout/sessions/:token_or_reference/poll

# 3. Direct Headless Invoice Collection (M-Pesa STK Push or Dedicated Virtual Account)
POST https://jayb.page.ke/api/v1/checkout/invoice
{
  "invoice_id": "INV-2026-902",
  "amount_kes": 15000,
  "phone_number": "+254712345678",
  "customer_name": "Amina Hassan",
  "payment_channel": "mpesa_stk" # or "virtual_account" for PesaLink / Bank Transfer
}

9. Cross-Border Supplier Settlements & FX Desk API

/api/v1/fx/* • /api/v1/transfers/*

Query live customer exchange rates across all 9 currencies, lock 15-minute FX quotes, and dispatch cross-border factory/supplier settlements across china_cny, dubai_aed, global_usd, europe_eur, and uk_gbp. Supports funding from any currency wallet (e.g. wallet:KES, wallet:USD) or direct collection rails (direct:mpesa, direct:airtel_money, direct:pesalink).

# 1. Fetch Live Customer FX Rates Across All 9 Currencies
GET https://jayb.page.ke/api/v1/fx/rates?base_currency=KES

# 2. Request a 15-Minute Locked FX Quote
POST https://jayb.page.ke/api/v1/fx/quote
{ "from_currency": "KES", "to_currency": "CNY", "amount": 250000 }

# 3. Create (and Optionally Auto-Approve & Dispatch) an International Supplier Payout
POST https://jayb.page.ke/api/v1/transfers/request_payout
{
  "merchant_code": "582910",
  "corridor": "china_cny",              # "china_cny", "dubai_aed", "global_usd", "europe_eur", "uk_gbp"
  "funding_source": "wallet:KES",       # or "wallet:USD", "direct:mpesa", "direct:airtel_money", "direct:pesalink"
  "amount_local": 250000,               # or specify "amount_foreign": 13680.75
  "validate_balance": true,
  "auto_approve": true,                 # set true to debit & dispatch immediately; false to queue for approval
  "shipping_mark": "CRG-YW-889",
  "invoice_url": "https://cargo.ke/invoices/CRG-YW-889.pdf",
  "beneficiary_details": {
    "name": "Guangzhou Electronics Trading Co.",
    "bank_name": "ICBC Guangzhou Branch",
    "account_number": "6228480019283746519",
    "bank_code": "ICBKCNBJCAN"
  }
}

# 4. Approve a Queued Payout, Confirm Choice Bank OTP, or List / Inspect Transfers
POST https://jayb.page.ke/api/v1/transfers/:id/approve
{ "funding_source": "wallet:KES" }

POST https://jayb.page.ke/api/v1/transfers/:id/confirm_otp
{ "otp_code": "482910" }

GET  https://jayb.page.ke/api/v1/transfers?corridor=china_cny&status=processing
GET  https://jayb.page.ke/api/v1/transfers/:id

10. Bulk M-Pesa Disbursements & Auto-Sweep Rules

/api/v1/payouts/* • /api/v1/sweeps/*
# 1. Bulk M-Pesa B2C Disbursement (Requires Idempotency-Key Header)
POST https://jayb.page.ke/api/v1/payouts/bulk_mpesa
Idempotency-Key: payroll_batch_2026_11
{
  "funding_phone_number": "+254712345678",
  "purpose": "November Payroll",
  "recipients": [
    { "phone_number": "+254711000001", "amount": 25000, "name": "John Kamau" },
    { "phone_number": "+254722000004", "amount": 32000, "name": "Grace Otieno" }
  ]
}

# 2. Configure & Inspect Automated Bank Settlement Sweeps
POST https://jayb.page.ke/api/v1/sweeps/configure
{
  "destination_bank_name": "Equity Bank Kenya",
  "destination_bank_code": "68",
  "destination_account_number": "0180291827361",
  "destination_account_name": "Kasoko Marketplace Ltd",
  "sweep_mode": "threshold",
  "threshold_amount": 100000.0,
  "batch_time": "17:00"
}
GET https://jayb.page.ke/api/v1/sweeps/status

11. Webhooks & HMAC-SHA256 Signatures

Every outbound webhook includes X-Jayb-Signature (hex-encoded HMAC-SHA256 of "#{timestamp}.#{raw_body}" using your app's webhook_secret) and X-Jayb-Timestamp. Payment webhooks (payment.completed, invoice.paid) also include points_earned, points_balance, claim_wallet_url, and a ready-to-send transaction_message that partner apps (like Kasoko and cargo.ke) can show in-app or forward via SMS/WhatsApp so customers can claim their wallet and redeem points anytime.

computed = OpenSSL::HMAC.hexdigest("SHA256", webhook_secret, "#{timestamp}.#{raw_body}")
Rack::Utils.secure_compare(computed, request.headers["X-Jayb-Signature"])

12. Sandbox Testing & Test Numbers

Instant Success

+254711000001

Insufficient Balance

+254711000002

User Cancelled PIN

+254711000003