Skip to content

Charges

The ChargeResource allows you to configure payment channels of your choice when initiating a payment directly from your server. This is often used for custom checkout experiences where you handle the UI and communicate with Paystack's API.

Create Charge

Initiate a payment by integrating the payment channel of your choice (Card, Bank, USSD, Mobile Money, etc.).

php

$response = paystack()->charge()->create([
    'email' => '[email protected]',
    'amount' => 10000, // 100.00
    'bank' => [
        'code' => '057',
        'account_number' => '0000000000'
    ],
    'metadata' => [
        'custom_fields' => [
            [
                'display_name' => 'Donation for',
                'variable_name' => 'donation_for',
                'value' => 'makurdi'
            ]
        ]
    ]
]);

Body Parameters

ParameterTypeRequiredDescription
emailStringYesCustomer's email address.
amountStringYesAmount in subunit of the supported currency.
bankObjectOptionalBank account to charge (don't send if charging an authorization code).
bank_transferObjectOptionalTakes the settings for the Pay with Transfer (PwT) channel. Pass in the account_expires_at param to set the expiry time.
ussdObjectOptionalUSSD type to charge (don't send if charging an authorization code, bank or card).
mobile_moneyObjectOptionalMobile money details (don't send if charging an authorization code, bank or card). Currently supported in Ghana and Kenya only.
qrObjectOptionalTakes a provider parameter with the value set to: scan-to-pay. Currently supported in South Africa only.
authorization_codeStringOptionalAn authorization code to charge (don't send if charging a bank account).
pinStringOptional4-digit PIN (send with a non-reusable authorization code).
metadataObjectOptionalUsed for passing additional details for your post-payment processes.
referenceStringOptionalUnique transaction reference. Only -, ., = and alphanumeric characters allowed.
device_idStringOptionalThis is the unique identifier of the device a user uses in making payment. Only -, ., = and alphanumeric characters allowed.
split_codeStringOptionalThe split code of a previously created split. e.g. SPL_98WF13Eb3w.
subaccountStringOptionalThe code for the subaccount that owns the payment. e.g. ACCT_8f4s1eq7ml6rlzj.
transaction_chargeIntegerOptionalAn amount used to override the split configuration for a single split payment. If set, the amount specified goes to the main account regardless of the split configuration.
bearerStringOptionalUse this param to indicate who bears the transaction charges. Allowed values are: account or subaccount (defaults to account).

Submit PIN

If the charge response requires a PIN (status send_pin), submit it using this method.

php
$response = paystack()->charge()->submitPin('1234', 'TRANS_REFERENCE');

Submit OTP

If the charge response requires an OTP (status send_otp), submit it using this method.

php
$response = paystack()->charge()->submitOtp('123456', 'TRANS_REFERENCE');

Submit Phone

If the charge response requires a phone number (status send_phone), submit it using this method.

php
$response = paystack()->charge()->submitPhone('08012345678', 'TRANS_REFERENCE');

Submit Birthday

If the charge response requires a birthday (status send_birthday), submit it using this method.

php
$response = paystack()->charge()->submitBirthday('1995-12-23', 'TRANS_REFERENCE');

Submit Address

If the charge response requires an address (status send_address), submit it using this method.

php
$response = paystack()->charge()->submitAddress([
    'reference' => 'TRANS_REFERENCE',
    'address' => '140 N 2ND ST',
    'city' => 'Stroudsburg',
    'state' => 'PA',
    'zip_code' => '18360'
]);

Check Pending Charge

When you get pending as a charge status, wait 10 seconds or more, then make a check to see if its status has changed.

php
$status = paystack()->charge()->checkStatus('TRANS_REFERENCE');

Use Cases

The Charge API is powerful for building custom payment flows. Here is an extensive look at how to handle a typical charge flow.

Handling a Charge Flow

When you initiate a charge, the response will contain a status field. You must handle different statuses to complete the payment.

php

// 1. Initiate Charge
$payload = [
    'email' => '[email protected]',
    'amount' => 500000,
    'bank' => ['code' => '057', 'account_number' => '0000000000']
];

$response = paystack()->charge()->create($payload);
$data = $response['data'];
$status = $data['status'];
$reference = $data['reference'];

// 2. Handle Status
switch ($status) {
    case 'success':
        // Payment successful immediately
        return "Payment Successful!";

    case 'send_pin':
        // Prompt user for PIN
        // ... get pin from user input ...
        $pin = '1234';
        return paystack()->charge()->submitPin($pin, $reference);

    case 'send_otp':
        // Prompt user for OTP
        // ... get otp from user input ...
        $otp = '123456';
        return paystack()->charge()->submitOtp($otp, $reference);

    case 'send_phone':
        // Prompt user for Phone
        $phone = '08012345678';
        return paystack()->charge()->submitPhone($phone, $reference);

    case 'send_birthday':
        // Prompt user for Birthday
        $birthday = '1990-01-01';
        return paystack()->charge()->submitBirthday($birthday, $reference);

    case 'pending':
        // Wait and check status later
        sleep(10);
        return paystack()->charge()->checkStatus($reference);

    case 'failed':
        return "Payment Failed: " . $data['message'];

    default:
        return "Unknown status: $status";
}

Charging a Returning Customer (Recurring)

If a customer has paid before, you can charge their authorization code without requiring them to input card details again.

php
$response = paystack()->charge()->create([
    'email' => '[email protected]',
    'amount' => 200000,
    'authorization_code' => 'AUTH_w123456789' // Saved from previous transaction
]);

Mobile Money Charge

Charge a mobile money account (e.g., in Ghana or Kenya).

php
$response = paystack()->charge()->create([
    'email' => '[email protected]',
    'amount' => 1000,
    'currency' => 'GHS',
    'mobile_money' => [
        'phone' => '0551234567',
        'provider' => 'mtn'
    ]
]);

Released under the MIT License.