Direct Disbursements API

The Direct Disbursements API enables merchants and platforms to efficiently send immediate payments to multiple recipients simultaneously. Unlike escrow disbursements which require fulfillment conditions, direct disbursements process payments instantly to all recipients upon successful validation.

Overview

Direct disbursements are perfect for scenarios requiring immediate payment distribution without conditional holds:

Common Use Cases:

  • Payroll Processing: Monthly salary payments to employees

  • Affiliate Payouts: Commission payments to partners and affiliates

  • Contractor Payments: Immediate payments for completed services

  • Refund Processing: Bulk refunds to customers

  • Marketplace Settlements: Vendor payouts for completed orders

  • Gaming Rewards: Prize distributions and tournament winnings

  • Survey Incentives: Compensation for research participants

Key Features:

  • Instant payment processing to all recipients

  • Support for multiple payment methods (Mobile Money, Bank Transfer, Card)

  • Bulk recipient management with CSV upload support

  • Real-time status tracking and reporting

  • Comprehensive webhook notifications

  • Fraud detection and compliance checks

  • Multi-currency support with automatic conversion

Comparison: Direct vs Escrow Disbursements

Feature

Direct Disbursements

Escrow Disbursements

Payment Speed

Immediate upon validation

After fulfillment completion

Recipient Action

None required

Must fulfill terms/conditions

Use Case

Payroll, refunds, rewards

Services, deliverables, milestones

Risk Level

Lower (instant completion)

Higher (conditional release)

Complexity

Simple bulk payment

Complex term management

Authentication and Security

Direct disbursements require enhanced authentication due to their immediate nature and bulk processing capabilities.

Required Authentication Methods:

Disbursement Amount

Required Auth

Additional Security

< $1,000 USD

API Key

IP allowlisting recommended

$1,000 - $10,000

API Key + OTP

IP allowlisting required

> $10,000 USD

OAuth2 + OTP + MFA

Enhanced monitoring, approval workflow

Security Best Practices:

  • Enable IP allowlisting for production environments

  • Implement request signing for high-value disbursements

  • Use webhook signature verification

  • Monitor for unusual disbursement patterns

  • Implement internal approval workflows for large amounts

  • Store recipient data securely with encryption

  • Regular audit of disbursement activities

Rate Limiting:

  • Create disbursements: 30 requests per minute

  • Status checks: 100 requests per minute

  • List operations: 60 requests per minute

  • Bulk operations: 5 requests per minute

API Endpoints

Creating Direct Disbursements

Create a new disbursement to send payments to multiple recipients immediately.

POST /api/disbursements

Request Parameters:

Parameter

Type

Required

Description

recipients

array

Yes

List of recipient objects with payment details

currency

string

Yes

ISO 4217 currency code (UGX, USD, EUR, etc.)

payment_method

string

Yes

Payment method: mtn, airtel, bank_transfer, card

description

string

No

Internal description for the disbursement

reference

string

No

Your internal reference ID

notify_recipients

boolean

No

Send SMS/email notifications to recipients (default: true)

callback_url

string

No

Custom webhook URL for this disbursement

Recipient Object Structure:

{
  "recipient_id": "string (optional)",
  "email": "string (required if no recipient_id)",
  "phone_number": "string (required for mobile money)",
  "account_number": "string (required for bank transfers)",
  "bank_code": "string (required for bank transfers)",
  "amount": "string (required)",
  "reference": "string (optional)",
  "metadata": "object (optional)"
}

Example request - Mobile Money Disbursement:

POST /api/disbursements HTTP/1.1
Host: api.gopiaxis.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json

{
  "recipients": [
    {
      "email": "[email protected]",
      "phone_number": "+256700123456",
      "amount": "1500000.00",
      "reference": "SALARY-JUNE-001",
      "metadata": {
        "employee_id": "EMP001",
        "department": "Engineering"
      }
    },
    {
      "email": "[email protected]",
      "phone_number": "+256700654321",
      "amount": "1200000.00",
      "reference": "SALARY-JUNE-002",
      "metadata": {
        "employee_id": "EMP002",
        "department": "Marketing"
      }
    }
  ],
  "currency": "UGX",
  "payment_method": "mtn",
  "description": "June 2025 Salary Payments",
  "reference": "PAYROLL-JUNE-2025",
  "notify_recipients": true,
  "callback_url": "https://yourapp.com/webhooks/disbursements"
}

Example response:

{
  "disbursement_id": "disburs_a1b2c3d4e5f6",
  "status": "processing",
  "total_amount": "2700000.00",
  "currency": "UGX",
  "payment_method": "mtn",
  "recipient_count": 2,
  "successful_count": 0,
  "failed_count": 0,
  "pending_count": 2,
  "created_at": "2025-06-05T14:30:00Z",
  "estimated_completion": "2025-06-05T14:35:00Z",
  "fee_amount": "13500.00",
  "reference": "PAYROLL-JUNE-2025"
}

Example request - Bank Transfer Disbursement:

POST /api/disbursements HTTP/1.1
Host: api.gopiaxis.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json

{
  "recipients": [
    {
      "email": "[email protected]",
      "account_number": "1234567890",
      "bank_code": "CENTUGKX",
      "amount": "5000000.00",
      "reference": "PROJECT-PAYMENT-001"
    },
    {
      "email": "[email protected]",
      "account_number": "0987654321",
      "bank_code": "STANBUGX",
      "amount": "7500000.00",
      "reference": "PROJECT-PAYMENT-002"
    }
  ],
  "currency": "UGX",
  "payment_method": "bank_transfer",
  "description": "Contractor payments for Q2 projects",
  "reference": "CONTRACTOR-Q2-2025"
}

Status Codes:

  • 201 Created: Disbursement created successfully

  • 400 Bad Request: Invalid request parameters

  • 401 Unauthorized: Authentication required

  • 403 Forbidden: Insufficient permissions or limits exceeded

  • 429 Too Many Requests: Rate limit exceeded

Retrieving Disbursement Details

Get comprehensive information about a specific disbursement and track the status of all recipients.

GET /api/disbursements/{disbursement_id}

Path Parameters:

  • disbursement_id (string): The unique disbursement identifier

Example request:

GET /api/disbursements/disburs_a1b2c3d4e5f6 HTTP/1.1
Host: api.gopiaxis.com
Authorization: Bearer YOUR_ACCESS_TOKEN

Example response:

{
  "disbursement_id": "disburs_a1b2c3d4e5f6",
  "status": "partially_completed",
  "total_amount": "2700000.00",
  "currency": "UGX",
  "payment_method": "mtn",
  "description": "June 2025 Salary Payments",
  "reference": "PAYROLL-JUNE-2025",
  "created_at": "2025-06-05T14:30:00Z",
  "completed_at": null,
  "recipient_count": 2,
  "successful_count": 1,
  "failed_count": 1,
  "pending_count": 0,
  "fee_amount": "13500.00",
  "recipients": [
    {
      "recipient_id": "recip_x1y2z3",
      "email": "[email protected]",
      "phone_number": "+256700123456",
      "amount": "1500000.00",
      "status": "completed",
      "reference": "SALARY-JUNE-001",
      "transaction_id": "txn_mtn_abc123",
      "completed_at": "2025-06-05T14:32:15Z",
      "metadata": {
        "employee_id": "EMP001",
        "department": "Engineering"
      }
    },
    {
      "recipient_id": "recip_a2b3c4",
      "email": "[email protected]",
      "phone_number": "+256700654321",
      "amount": "1200000.00",
      "status": "failed",
      "reference": "SALARY-JUNE-002",
      "error_code": "INSUFFICIENT_BALANCE",
      "error_message": "Recipient account has insufficient balance to receive payment",
      "failed_at": "2025-06-05T14:33:00Z",
      "metadata": {
        "employee_id": "EMP002",
        "department": "Marketing"
      }
    }
  ],
  "summary": {
    "total_requested": "2700000.00",
    "total_successful": "1500000.00",
    "total_failed": "1200000.00",
    "total_fees": "7500.00",
    "success_rate": 50.0
  }
}

Listing Disbursements

Retrieve a paginated list of all disbursements with comprehensive filtering options.

GET /api/disbursements

Query Parameters:

Parameter

Type

Description

status

string

Filter by status: processing, completed, partially_completed, failed, cancelled

payment_method

string

Filter by payment method: mtn, airtel, bank_transfer, card

currency

string

Filter by currency code

from_date

string

ISO 8601 date string for start date filter

to_date

string

ISO 8601 date string for end date filter

min_amount

string

Minimum total amount filter

max_amount

string

Maximum total amount filter

reference

string

Filter by reference containing text

limit

integer

Number of results per page (default: 50, max: 100)

offset

integer

Number of results to skip (default: 0)

Example request:

GET /api/disbursements?status=completed&payment_method=mtn&from_date=2025-06-01T00:00:00Z&limit=25 HTTP/1.1
Host: api.gopiaxis.com
Authorization: Bearer YOUR_ACCESS_TOKEN

Example response:

{
  "total": 45,
  "limit": 25,
  "offset": 0,
  "has_more": true,
  "results": [
    {
      "disbursement_id": "disburs_a1b2c3d4e5f6",
      "status": "completed",
      "total_amount": "2700000.00",
      "currency": "UGX",
      "payment_method": "mtn",
      "recipient_count": 2,
      "successful_count": 2,
      "failed_count": 0,
      "created_at": "2025-06-05T14:30:00Z",
      "completed_at": "2025-06-05T14:35:12Z",
      "reference": "PAYROLL-JUNE-2025",
      "description": "June 2025 Salary Payments"
    }
  ]
}

Cancelling Disbursements

Cancel a disbursement that is still in processing status. Only pending recipients will be cancelled.

POST /api/disbursements/{disbursement_id}/cancel

Path Parameters:

  • disbursement_id (string): The unique disbursement identifier

Request Body:

Parameter

Type

Description

reason

string

Reason for cancellation (required)

cancel_pending_only

boolean

Only cancel pending recipients, leave successful ones (default: true)

Example request:

POST /api/disbursements/disburs_a1b2c3d4e5f6/cancel HTTP/1.1
Host: api.gopiaxis.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json

{
  "reason": "Incorrect payment amounts detected",
  "cancel_pending_only": true
}

Example response:

{
  "disbursement_id": "disburs_a1b2c3d4e5f6",
  "status": "partially_cancelled",
  "cancelled_count": 3,
  "successful_count": 2,
  "cancelled_at": "2025-06-05T15:00:00Z",
  "cancellation_reason": "Incorrect payment amounts detected"
}

Bulk CSV Upload

Upload recipient lists via CSV for large disbursements.

POST /api/disbursements/bulk-upload

Request Headers:

  • Content-Type: multipart/form-data

Form Data:

  • file: CSV file with recipient data

  • payment_method: Payment method for all recipients

  • currency: Currency for all payments

  • description: Disbursement description

CSV Format:

email,phone_number,amount,reference,metadata_key1,metadata_key2
[email protected],+256700123456,1500000,EMP001,Engineering,Senior
[email protected],+256700654321,1200000,EMP002,Marketing,Junior

Error Handling

The Disbursements API uses standard HTTP status codes and provides detailed error information to help with debugging and resolution.

Common Error Codes:

HTTP Code

Error Code

Description & Resolution

400

INVALID_RECIPIENTS

One or more recipients have invalid data. Check email formats, phone numbers, and amounts.

400

DUPLICATE_RECIPIENTS

Duplicate recipients detected in the same disbursement. Remove duplicates.

400

INVALID_AMOUNT

Amount format is invalid or exceeds limits. Use decimal strings with proper precision.

400

UNSUPPORTED_CURRENCY

Currency not supported for the selected payment method.

403

INSUFFICIENT_BALANCE

Account balance insufficient for the total disbursement amount plus fees.

403

DAILY_LIMIT_EXCEEDED

Daily disbursement limit exceeded. Contact support to increase limits.

403

RECIPIENT_LIMIT_EXCEEDED

Too many recipients in single disbursement. Maximum is 1000 per request.

404

DISBURSEMENT_NOT_FOUND

Disbursement ID does not exist or belongs to different account.

409

ALREADY_PROCESSED

Disbursement has already been processed and cannot be modified.

422

VALIDATION_FAILED

Request validation failed. Check required fields and data formats.

429

RATE_LIMIT_EXCEEDED

Too many requests. Implement exponential backoff retry logic.

Error Response Format:

{
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Account balance insufficient for disbursement",
    "details": {
      "required_amount": "2700000.00",
      "available_balance": "2000000.00",
      "currency": "UGX"
    },
    "request_id": "req_abc123def456"
  }
}

Recipient-Level Errors:

When individual recipients fail, they are included in the disbursement response:

{
  "recipient_id": "recip_failed123",
  "status": "failed",
  "error_code": "INVALID_PHONE_NUMBER",
  "error_message": "Phone number format is invalid for MTN network",
  "retry_possible": true,
  "suggested_action": "Update phone number format to +256XXXXXXXXX"
}

SDK Integration Examples

Python Integration

Complete Python implementation for disbursement management:

import requests
import json
from typing import List, Dict, Optional
from dataclasses import dataclass
from datetime import datetime

@dataclass
class Recipient:
    email: str
    amount: str
    phone_number: Optional[str] = None
    account_number: Optional[str] = None
    bank_code: Optional[str] = None
    reference: Optional[str] = None
    metadata: Optional[Dict] = None

class PiaxisDisbursementClient:
    def __init__(self, api_key: str, base_url: str = "https://api.gopiaxis.com"):
        self.api_key = api_key
        self.base_url = base_url
        self.session = requests.Session()
        self.session.headers.update({
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json'
        })

    def create_disbursement(
        self,
        recipients: List[Recipient],
        currency: str,
        payment_method: str,
        description: Optional[str] = None,
        reference: Optional[str] = None,
        notify_recipients: bool = True,
        callback_url: Optional[str] = None
    ) -> Dict:
        """Create a new disbursement to multiple recipients."""
        payload = {
            'recipients': [
                {k: v for k, v in {
                    'email': r.email,
                    'phone_number': r.phone_number,
                    'account_number': r.account_number,
                    'bank_code': r.bank_code,
                    'amount': r.amount,
                    'reference': r.reference,
                    'metadata': r.metadata
                }.items() if v is not None}
                for r in recipients
            ],
            'currency': currency,
            'payment_method': payment_method,
            'notify_recipients': notify_recipients
        }

        if description:
            payload['description'] = description
        if reference:
            payload['reference'] = reference
        if callback_url:
            payload['callback_url'] = callback_url

        response = self.session.post(
            f'{self.base_url}/api/disbursements',
            json=payload
        )
        response.raise_for_status()
        return response.json()

    def get_disbursement(self, disbursement_id: str) -> Dict:
        """Get disbursement details and recipient statuses."""
        response = self.session.get(
            f'{self.base_url}/api/disbursements/{disbursement_id}'
        )
        response.raise_for_status()
        return response.json()

    def list_disbursements(
        self,
        status: Optional[str] = None,
        payment_method: Optional[str] = None,
        currency: Optional[str] = None,
        from_date: Optional[datetime] = None,
        to_date: Optional[datetime] = None,
        limit: int = 50,
        offset: int = 0
    ) -> Dict:
        """List disbursements with filtering options."""
        params = {'limit': limit, 'offset': offset}

        if status:
            params['status'] = status
        if payment_method:
            params['payment_method'] = payment_method
        if currency:
            params['currency'] = currency
        if from_date:
            params['from_date'] = from_date.isoformat()
        if to_date:
            params['to_date'] = to_date.isoformat()

        response = self.session.get(
            f'{self.base_url}/api/disbursements',
            params=params
        )
        response.raise_for_status()
        return response.json()

    def cancel_disbursement(
        self,
        disbursement_id: str,
        reason: str,
        cancel_pending_only: bool = True
    ) -> Dict:
        """Cancel a disbursement."""
        payload = {
            'reason': reason,
            'cancel_pending_only': cancel_pending_only
        }

        response = self.session.post(
            f'{self.base_url}/api/disbursements/{disbursement_id}/cancel',
            json=payload
        )
        response.raise_for_status()
        return response.json()

# Usage Example
if __name__ == "__main__":
    client = PiaxisDisbursementClient("your-api-key")

    # Create payroll disbursement
    recipients = [
        Recipient(
            email="[email protected]",
            phone_number="+256700123456",
            amount="1500000.00",
            reference="SALARY-JUNE-001",
            metadata={"employee_id": "EMP001", "department": "Engineering"}
        ),
        Recipient(
            email="[email protected]",
            phone_number="+256700654321",
            amount="1200000.00",
            reference="SALARY-JUNE-002",
            metadata={"employee_id": "EMP002", "department": "Marketing"}
        )
    ]

    try:
        # Create disbursement
        disbursement = client.create_disbursement(
            recipients=recipients,
            currency="UGX",
            payment_method="mtn",
            description="June 2025 Salary Payments",
            reference="PAYROLL-JUNE-2025"
        )

        print(f"Disbursement created: {disbursement['disbursement_id']}")

        # Monitor progress
        import time
        while True:
            status = client.get_disbursement(disbursement['disbursement_id'])
            print(f"Status: {status['status']}")
            print(f"Progress: {status['successful_count']}/{status['recipient_count']}")

            if status['status'] in ['completed', 'partially_completed', 'failed']:
                break

            time.sleep(5)

        print("Final results:")
        for recipient in status['recipients']:
            print(f"  {recipient['email']}: {recipient['status']}")

    except requests.RequestException as e:
        print(f"API Error: {e}")

Node.js Integration

Complete Node.js implementation with TypeScript support:

import axios, { AxiosInstance, AxiosResponse } from 'axios';

interface Recipient {
  email: string;
  amount: string;
  phone_number?: string;
  account_number?: string;
  bank_code?: string;
  reference?: string;
  metadata?: Record<string, any>;
}

interface DisbursementRequest {
  recipients: Recipient[];
  currency: string;
  payment_method: string;
  description?: string;
  reference?: string;
  notify_recipients?: boolean;
  callback_url?: string;
}

interface DisbursementResponse {
  disbursement_id: string;
  status: string;
  total_amount: string;
  currency: string;
  recipient_count: number;
  successful_count: number;
  failed_count: number;
  pending_count: number;
}

class PiaxisDisbursementClient {
  private client: AxiosInstance;

  constructor(apiKey: string, baseURL: string = 'https://api.gopiaxis.com') {
    this.client = axios.create({
      baseURL,
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      }
    });
  }

  async createDisbursement(request: DisbursementRequest): Promise<DisbursementResponse> {
    try {
      const response: AxiosResponse<DisbursementResponse> = await this.client.post(
        '/api/disbursements',
        request
      );
      return response.data;
    } catch (error) {
      this.handleError(error);
      throw error;
    }
  }

  async getDisbursement(disbursementId: string): Promise<any> {
    try {
      const response = await this.client.get(`/api/disbursements/${disbursementId}`);
      return response.data;
    } catch (error) {
      this.handleError(error);
      throw error;
    }
  }

  async listDisbursements(params: {
    status?: string;
    payment_method?: string;
    currency?: string;
    from_date?: string;
    to_date?: string;
    limit?: number;
    offset?: number;
  } = {}): Promise<any> {
    try {
      const response = await this.client.get('/api/disbursements', { params });
      return response.data;
    } catch (error) {
      this.handleError(error);
      throw error;
    }
  }

  async cancelDisbursement(
    disbursementId: string,
    reason: string,
    cancelPendingOnly: boolean = true
  ): Promise<any> {
    try {
      const response = await this.client.post(
        `/api/disbursements/${disbursementId}/cancel`,
        {
          reason,
          cancel_pending_only: cancelPendingOnly
        }
      );
      return response.data;
    } catch (error) {
      this.handleError(error);
      throw error;
    }
  }

  private handleError(error: any): void {
    if (error.response) {
      console.error('API Error:', error.response.data);
      console.error('Status:', error.response.status);
    } else if (error.request) {
      console.error('Network Error:', error.request);
    } else {
      console.error('Error:', error.message);
    }
  }
}

// Usage Example
async function processPayroll() {
  const client = new PiaxisDisbursementClient('your-api-key');

  const recipients: Recipient[] = [
    {
      email: '[email protected]',
      phone_number: '+256700123456',
      amount: '1500000.00',
      reference: 'SALARY-JUNE-001',
      metadata: {
        employee_id: 'EMP001',
        department: 'Engineering'
      }
    },
    {
      email: '[email protected]',
      phone_number: '+256700654321',
      amount: '1200000.00',
      reference: 'SALARY-JUNE-002',
      metadata: {
        employee_id: 'EMP002',
        department: 'Marketing'
      }
    }
  ];

  try {
    // Create disbursement
    const disbursement = await client.createDisbursement({
      recipients,
      currency: 'UGX',
      payment_method: 'mtn',
      description: 'June 2025 Salary Payments',
      reference: 'PAYROLL-JUNE-2025'
    });

    console.log(`Disbursement created: ${disbursement.disbursement_id}`);

    // Monitor progress
    let completed = false;
    while (!completed) {
      const status = await client.getDisbursement(disbursement.disbursement_id);
      console.log(`Status: ${status.status}`);
      console.log(`Progress: ${status.successful_count}/${status.recipient_count}`);

      if (['completed', 'partially_completed', 'failed'].includes(status.status)) {
        completed = true;

        console.log('Final results:');
        status.recipients.forEach((recipient: any) => {
          console.log(`  ${recipient.email}: ${recipient.status}`);
        });
      } else {
        await new Promise(resolve => setTimeout(resolve, 5000));
      }
    }
  } catch (error) {
    console.error('Disbursement failed:', error);
  }
}

export { PiaxisDisbursementClient, Recipient, DisbursementRequest };

Webhook Integration

Disbursement webhooks provide real-time updates on payment status changes. Implement webhook handling to automatically update your systems when disbursements are processed.

Webhook Events:

  • disbursement.created: New disbursement initiated

  • disbursement.processing: Payment processing started

  • disbursement.recipient.completed: Individual recipient payment completed

  • disbursement.recipient.failed: Individual recipient payment failed

  • disbursement.completed: All recipients processed successfully

  • disbursement.partially_completed: Some recipients failed, others succeeded

  • disbursement.failed: Entire disbursement failed

  • disbursement.cancelled: Disbursement cancelled

Webhook Payload Example:

{
  "event": "disbursement.recipient.completed",
  "timestamp": "2025-06-05T14:32:15Z",
  "data": {
    "disbursement_id": "disburs_a1b2c3d4e5f6",
    "recipient_id": "recip_x1y2z3",
    "status": "completed",
    "amount": "1500000.00",
    "currency": "UGX",
    "transaction_id": "txn_mtn_abc123",
    "recipient_email": "[email protected]",
    "recipient_phone": "+256700123456",
    "reference": "SALARY-JUNE-001",
    "completed_at": "2025-06-05T14:32:15Z"
  }
}

Flask Webhook Handler:

from flask import Flask, request, jsonify
import hmac
import hashlib
import json

app = Flask(__name__)
WEBHOOK_SECRET = "your-webhook-secret"

@app.route('/webhooks/disbursements', methods=['POST'])
def handle_disbursement_webhook():
    # Verify webhook signature
    signature = request.headers.get('X-Piaxis-Signature')
    if not verify_signature(request.data, signature):
        return jsonify({'error': 'Invalid signature'}), 401

    payload = request.json
    event_type = payload['event']
    data = payload['data']

    if event_type == 'disbursement.recipient.completed':
        # Update employee payment status
        update_employee_payment_status(
            data['recipient_email'],
            'completed',
            data['transaction_id']
        )
    elif event_type == 'disbursement.recipient.failed':
        # Handle failed payment
        handle_failed_payment(
            data['recipient_email'],
            data.get('error_code'),
            data.get('error_message')
        )

    return jsonify({'status': 'received'}), 200

def verify_signature(payload, signature):
    expected_signature = hmac.new(
        WEBHOOK_SECRET.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, f'sha256={expected_signature}')

Production Best Practices

Pre-deployment Checklist:

  1. Security Configuration:

    • Enable IP allowlisting for production API access

    • Implement webhook signature verification

    • Use OAuth2 for high-value disbursements

    • Enable multi-factor authentication for admin accounts

  2. Monitoring and Alerting:

    • Set up monitoring for disbursement success rates

    • Configure alerts for failed disbursements above threshold

    • Monitor API response times and error rates

    • Track daily/monthly disbursement volumes and limits

  3. Error Handling:

    • Implement retry logic with exponential backoff

    • Set up dead letter queues for failed webhooks

    • Create manual review process for high-value failures

    • Maintain audit logs for all disbursement activities

  4. Testing:

    • Test all payment methods in sandbox environment

    • Validate webhook handling and signature verification

    • Test error scenarios and recovery procedures

    • Perform load testing for bulk disbursements

  5. Compliance:

    • Ensure PCI DSS compliance for stored payment data

    • Implement data retention policies

    • Set up transaction reporting for regulatory requirements

    • Maintain detailed audit trails

Performance Optimization:

  • Use bulk CSV upload for disbursements > 100 recipients

  • Implement pagination for large result sets

  • Cache frequently accessed disbursement data

  • Use asynchronous processing for webhook handling

  • Implement database connection pooling

Troubleshooting Guide:

Issue

Resolution

High failure rates

Check recipient data quality, validate phone numbers and account information

Slow processing

Verify network connectivity, check for rate limiting, consider smaller batches

Missing webhooks

Verify webhook URL accessibility, check signature verification, review logs

Authentication errors

Refresh access tokens, verify API key permissions, check IP allowlist

Balance issues

Monitor account balance, set up low balance alerts, implement pre-validation

Support and Resources

Documentation:

API Reference:

  • Base URL: https://api.gopiaxis.com

  • Sandbox URL: https://sandbox-api.gopiaxis.com

  • Status Page: https://status.gopiaxis.com

Support Channels:

Rate Limits:

  • Standard: 1000 requests/hour

  • Premium: 5000 requests/hour

  • Enterprise: Custom limits available