Collect Payment from Customer (STK Push)

Request payment FROM a customer TO your JulyPay wallet. This is the most commonly used endpoint for businesses collecting payments.

POST/api/v1/wallet/collect-payment

Required permission: wallet:collect

Request Body

{
  "customer_phone": "256701234567",
  "amount": 50000,
  "description": "Payment for invoice #1234",
  "customer_name": "John Doe"
}

Parameters

Parameter

Type

Required

Description

customer_phone

string

Yes

Customer's Uganda phone number

amount

number

Yes

Amount to collect from customer (1000 - 5,000,000)

description

string

No

Payment description for customer

customer_name

string

No

Customer name for your records

Response Example

{
  "success": true,
  "message": "Payment collection request sent successfully",
  "data": {
    "transaction_id": 12345,
    "reference": "API_COL_1642000000_123",
    "customer_phone": "256701234567",
    "customer_name": "John Doe",
    "amount_requested": 50000,
    "collection_fee": 2500,
    "net_amount_to_receive": 47500,
    "status": "processing",
    "external_reference": "REL_ABC123",
    "instructions": "Customer will receive STK push notification to complete payment",
    "created_at": "2025-01-12T10:30:00Z"
  }
}Copy

Check Collection Status

GET/api/v1/wallet/collections/{transactionId}/status

Perfect for E-commerce & Services

This endpoint is ideal for businesses like Centipid who need to collect payments from customers. Customer pays full amount, you receive net amount after collection fee.

Fee Structure

  • Collection Fee - Deducted from collected amount (configurable in admin settings)

  • Customer Pays Full Amount - No surprise fees for customer

  • You Receive Net Amount - Amount after collection fee credited to your wallet

  • Example: Customer pays UGX 100,000 → You receive net amount after collection fee

<?php

$apiKey = 'your_api_key_here';
$baseUrl = 'https://app.julypay.net/api/v1';

// Collect payment from customer (STK Push)
function collectPayment($customerPhone, $amount, $description = '', $customerName = '') {
    global $apiKey, $baseUrl;
    
    $data = [
        'customer_phone' => $customerPhone,
        'amount' => $amount,
        'description' => $description,
        'customer_name' => $customerName
    ];

    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL => $baseUrl . '/wallet/collect-payment',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($data),
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json',
            'Accept: application/json'
        ]
    ]);

    $response = curl_exec($curl);
    $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);

    $result = json_decode($response, true);

    if ($httpCode === 200 && $result['success']) {
        echo "Collection request sent!";
        echo "Transaction ID: " . $result['data']['transaction_id'];
        echo "Customer will receive STK push";
        echo "You'll receive: UGX " . number_format($result['data']['net_amount_to_receive']);
        
        return $result['data']['transaction_id'];
    } else {
        echo "Error: " . $result['message'];
        return false;
    }
}

// Check collection status
function checkCollectionStatus($transactionId) {
    global $apiKey, $baseUrl;
    
    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL => $baseUrl . '/wallet/collections/' . $transactionId . '/status',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . $apiKey,
            'Accept: application/json'
        ]
    ]);

    $response = curl_exec($curl);
    curl_close($curl);
    $result = json_decode($response, true);

    switch ($result['status']) {
        case 'completed':
            echo "Payment received! Amount credited: UGX " . number_format($result['net_amount_received']);
            break;
        case 'failed':
            echo "Collection failed: " . $result['failure_reason'];
            break;
        case 'processing':
            echo "Still waiting for customer payment...";
            break;
    }
    
    return $result;
}

// Usage example for e-commerce
$transactionId = collectPayment('256701234567', 50000, 'Payment for Order #1234', 'John Doe');
if ($transactionId) {
    // Poll for status or use webhooks for real-time updates
    sleep(30); // Wait a bit for customer to pay
    checkCollectionStatus($transactionId);
}

?>Copy

JavaScript Collection Example

const axios = require('axios');

const apiKey = 'your_api_key_here';
const baseUrl = 'https://app.julypay.net/api/v1';

// Collect payment from customer
async function collectPayment(customerPhone, amount, description = '', customerName = '') {
    try {
        const response = await axios.post(`${baseUrl}/wallet/collect-payment`, {
            customer_phone: customerPhone,
            amount: amount,
            description: description,
            customer_name: customerName
        }, {
            headers: {
                'Authorization': `Bearer ${apiKey}`,
                'Content-Type': 'application/json'
            }
        });

        if (response.data.success) {
            console.log('Collection request sent successfully!');
            console.log('Transaction ID:', response.data.data.transaction_id);
            console.log('Customer will receive STK push');
            console.log('You will receive: UGX', response.data.data.net_amount_to_receive.toLocaleString());
            
            return response.data.data.transaction_id;
        }
    } catch (error) {
        console.error('Collection failed:', error.response.data.message);
        return false;
    }
}

// Check collection status
async function checkCollectionStatus(transactionId) {
    try {
        const response = await axios.get(`${baseUrl}/wallet/collections/${transactionId}/status`, {
            headers: {
                'Authorization': `Bearer ${apiKey}`
            }
        });

        const result = response.data;
        
        switch (result.status) {
            case 'completed':
                console.log('Payment received! Amount credited: UGX', result.net_amount_received.toLocaleString());
                break;
            case 'failed':
                console.log('Collection failed:', result.failure_reason);
                break;
            case 'processing':
                console.log('Still waiting for customer payment...');
                break;
        }
        
        return result;
    } catch (error) {
        console.error('Error checking status:', error.message);
    }
}

// Usage example
(async () => {
    const transactionId = await collectPayment('256701234567', 50000, 'Payment for services', 'John Doe');
    
    if (transactionId) {
        // Monitor status (in production, use webhooks)
        const checkStatus = setInterval(async () => {
            const status = await checkCollectionStatus(transactionId);
            
            if (status && ['completed', 'failed'].includes(status.status)) {
                clearInterval(checkStatus);
            }
        }, 10000); // Check every 10 seconds
    }
})();Copy

cURL Collection Example

# Collect payment from customer
curl -X POST "https://app.julypay.net/api/v1/wallet/collect-payment" \
  -H "Authorization: Bearer your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_phone": "256701234567",
    "amount": 50000,
    "description": "Payment for invoice #1234",
    "customer_name": "John Doe"
  }'

# Check collection status
curl -X GET "https://app.julypay.net/api/v1/wallet/collections/12345/status" \
  -H "Authorization: Bearer your_api_key_here" \
  -H "Content-Type: application/json"
Updated on