Skip to content

Payouts

Payouts allow you to send funds from your Maraboo wallet to recipients across multiple countries and payment channels. This guide covers everything you need to know about creating and managing outbound payments.

Overview

Maraboo supports two types of outbound payments:

  1. Payment Transactions: Send funds to third-party recipients (individuals, businesses)
  2. Withdrawal Transactions: Transfer funds to your own pre-configured accounts

Payment Transactions

When to Use

  • Paying suppliers or vendors
  • Sending money to individuals
  • Disbursing funds to beneficiaries
  • Processing payroll

Supported Payout Channels

West Africa (WAEMU) - XOF

  • mobile_money: MTN, Moov, Orange Money mobile money transfers
  • direct_deposit: Direct deposits to bank accounts
  • xpresscash: Cash pickup at partner locations
  • credit_ecobank_account: Direct credits to Ecobank accounts
  • billpay: Bill payment services

Countries: Benin (BJ), Burkina Faso (BF), Côte d'Ivoire (CI), Guinea-Bissau (GW), Mali (ML), Niger (NE), Senegal (SN), Togo (TG)

Canada - CAD

  • interac_send: Real-time Interac Send transfers
  • eft: Electronic Funds Transfer to bank accounts
  • billpay: Bill payment processing

United States - USD (Coming Soon)

  • swift: SWIFT international transfers
  • fednow: FedNow instant payments
  • bank_transfer_ach: ACH bank transfers

View available channels →

Creating a Payout

Step 1: Prepare Recipient Information

You can either use a pre-created recipient or provide recipient details inline.

Option A: Pre-create Recipients

javascript
const response = await fetch('https://sandbox.mara.boo/api-access/recipients', {
  method: 'POST',
  headers: {
    'Authorization': 'HMAC-SHA256 YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY',
    'X-Origin': 'third-party-api',
    'X-Timestamp': new Date().toISOString(),
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    first_name: 'John',
    last_name: 'Doe',
    email: 'john.doe@example.com',
    phone: '+22997123456',
    country: 'bj',
    transaction_type: 'mobile_money',
    recipient_type: 'individual',
    provider: 'mtn',
    currency: 'xof'
  })
});

const recipient = await response.json();
const recipient_id = recipient.data.id;

Learn more about recipients →

Option B: Inline Recipients

Provide recipient details directly in the payment request (useful for one-time payments).

Step 2: Get Payment Quote

Always get a quote before creating the payment to know the exact fees and exchange rates.

javascript
const quoteResponse = await fetch('https://sandbox.mara.boo/api-access/calculators/payment', {
  method: 'POST',
  headers: {
    'Authorization': 'HMAC-SHA256 YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY',
    'X-Origin': 'third-party-api',
    'X-Timestamp': new Date().toISOString(),
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    amount: 50000,
    country: 'bj',
    channel: 'mobile_money',
    currency: 'xof'
  })
});

const quote = await quoteResponse.json();
const quote_id = quote.data.quote_id;

View calculator endpoint →

Step 3: Create Payment Transaction

javascript
const paymentResponse = await fetch('https://sandbox.mara.boo/api-access/transactions/client/sessions/payment', {
  method: 'POST',
  headers: {
    'Authorization': 'HMAC-SHA256 YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY',
    'X-Origin': 'third-party-api',
    'X-Timestamp': new Date().toISOString(),
    'X-Idempotency-Key': `payment-${Date.now()}-${quote_id}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    description: 'Supplier payment',
    quote_id: quote_id,
    wallet_id: 'wallet-456',
    transaction: {
      amount: 50000,
      country: 'bj',
      channel: 'mobile_money',
      currency: 'xof'
    },
    recipient: {
      first_name: 'John',
      last_name: 'Doe',
      email: 'john.doe@example.com',
      phone: '+22997123456',
      country: 'bj',
      transaction_type: 'mobile_money',
      recipient_type: 'individual',
      provider: 'mtn',
      currency: 'xof'
    },
    metadata: {
      invoice_id: 'INV-12345',
      payment_purpose: 'goods'
    }
  })
});

const payment = await paymentResponse.json();
console.log('Transaction ID:', payment.data.transaction_id);
console.log('Session ID:', payment.data.session_id);

View full API reference →

Withdrawal Transactions

Withdrawals are used to transfer funds from your Maraboo wallet to your own bank accounts.

Key Differences from Payments

FeaturePaymentsWithdrawals
RecipientThird-party recipientsYour own accounts
Account SetupInline or pre-createdPre-configured in portal
Use CasePay othersMove your funds

Creating a Withdrawal

javascript
const withdrawalResponse = await fetch('https://sandbox.mara.boo/api-access/transactions/client/sessions/withdrawal', {
  method: 'POST',
  headers: {
    'Authorization': 'HMAC-SHA256 YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY',
    'X-Origin': 'third-party-api',
    'X-Timestamp': new Date().toISOString(),
    'X-Idempotency-Key': `withdrawal-${Date.now()}-${quote_id}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    description: 'Withdrawal to bank account',
    destination_account_id: 'account-123', // Pre-configured account
    quote_id: 'quote-789',
    transaction: {
      amount: 10000,
      country: 'ca',
      channel: 'eft',
      currency: 'cad'
    },
    wallet_id: 'wallet-456'
  })
});

const withdrawal = await withdrawalResponse.json();

View full API reference →

Recipient Types & Requirements

Different recipient types require different fields. Here are the common patterns:

Mobile Money Recipient

Required Fields:

  • first_name, last_name
  • phone: Mobile money number
  • country: Country code
  • transaction_type: mobile_money
  • provider: mtn, moov, orange, etc.
  • currency: Payout currency
json
{
  "first_name": "John",
  "last_name": "Doe",
  "phone": "+22997123456",
  "country": "bj",
  "transaction_type": "mobile_money",
  "recipient_type": "individual",
  "provider": "mtn",
  "currency": "xof"
}

Bank Transfer Recipient (EFT)

Required Fields (Canada - EFT):

  • first_name, last_name
  • email
  • country: ca
  • transaction_type: eft
  • account_number: Bank account number
  • institution_number: Bank institution code
  • transit_number: Branch transit number
  • currency: cad
json
{
  "first_name": "Jane",
  "last_name": "Smith",
  "email": "jane@example.com",
  "country": "ca",
  "transaction_type": "eft",
  "account_number": "1234567",
  "institution_number": "001",
  "transit_number": "12345",
  "currency": "cad"
}

Direct Deposit Recipient (XOF)

Required Fields (WAEMU - Direct Deposit):

  • first_name, last_name
  • email or phone
  • country: WAEMU country code
  • transaction_type: direct_deposit
  • account_number: Bank account number
  • bank_code: Bank identifier
  • currency: xof
json
{
  "first_name": "Amadou",
  "last_name": "Diallo",
  "phone": "+22997123456",
  "country": "sn",
  "transaction_type": "direct_deposit",
  "account_number": "SN12345678901234567890",
  "bank_code": "SN001",
  "currency": "xof"
}

Interac Send Recipient

Required Fields:

  • first_name, last_name
  • email or phone
  • country: ca
  • transaction_type: interac_send
json
{
  "first_name": "Bob",
  "last_name": "Johnson",
  "email": "bob@example.com",
  "country": "ca",
  "transaction_type": "interac_send",
  "currency": "cad"
}

View all recipient requirements →

Tracking Payout Status

Get Specific Transaction

javascript
const sessionId = 'session-123';
const response = await fetch(`https://sandbox.mara.boo/api-access/transactions/client/sessions/${sessionId}`, {
  method: 'GET',
  headers: {
    'Authorization': 'HMAC-SHA256 YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY',
    'X-Origin': 'third-party-api',
    'X-Timestamp': new Date().toISOString(),
    'Content-Type': 'application/json'
  }
});

const transaction = await response.json();
console.log('Status:', transaction.data.status);
console.log('Amount:', transaction.data.amount);
console.log('Recipient:', transaction.data.recipient);

View endpoint →

List Transactions with Filters

javascript
const response = await fetch('https://sandbox.mara.boo/api-access/transactions/client/sessions?status=completed&limit=20', {
  method: 'GET',
  headers: {
    'Authorization': 'HMAC-SHA256 YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY',
    'X-Origin': 'third-party-api',
    'X-Timestamp': new Date().toISOString(),
    'Content-Type': 'application/json'
  }
});

const transactions = await response.json();

Available Filters:

  • status: pending, processing, completed, failed
  • start_date / end_date: Date range
  • recipient_id: Filter by recipient
  • currency: Filter by currency
  • wallet: Filter by wallet ID

View endpoint →

Handling Payout Failures

Common Failure Reasons

Failure ReasonDescriptionSolution
insufficient_fundsWallet balance too lowFund wallet before retrying
invalid_recipientRecipient details incorrectValidate recipient information
provider_errorPayment provider issueRetry after some time
blocked_recipientRecipient on blocklistContact support
limit_exceededTransaction limit reachedWait for limit reset or contact support

Retry Strategy

  1. Check Failure Reason: Review failure_reason field in transaction response
  2. Fix Issues: Address the root cause (e.g., fund wallet, correct recipient details)
  3. Use Idempotency: Use Idempotency-Key header to prevent duplicates
  4. Exponential Backoff: Wait longer between retries (1s, 2s, 4s, 8s, etc.)

Learn about idempotency →

Webhook Notifications

Instead of polling for status updates, configure webhooks to receive real-time notifications:

json
{
  "event": "transaction.completed",
  "data": {
    "session_id": "session-123",
    "transaction_id": "txn-456",
    "status": "completed",
    "amount": 50000,
    "currency": "xof",
    "recipient": {
      "name": "John Doe",
      "phone": "+22997123456"
    },
    "timestamp": "2025-10-12T14:30:00.000Z"
  }
}

Learn about webhooks →

Fees

Transaction fees vary by:

  • Payment channel
  • Destination country
  • Transaction amount
  • Currency

Use the calculator endpoints to get accurate fee quotes before creating transactions.

View fees endpoint →

Testing Payouts

Sandbox Environment

Use the sandbox environment to test payouts without moving real funds:

Base URL: https://sandbox.mara.boo

Test Scenarios

  1. Successful Payout: Use valid test recipient details
  2. Insufficient Funds: Attempt payout with empty wallet
  3. Invalid Recipient: Use incorrect phone/account numbers
  4. Provider Failure: Test provider error handling

Learn about sandbox testing →

Next Steps