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.).
$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
| Parameter | Type | Required | Description |
|---|---|---|---|
email | String | Yes | Customer's email address. |
amount | String | Yes | Amount in subunit of the supported currency. |
bank | Object | Optional | Bank account to charge (don't send if charging an authorization code). |
bank_transfer | Object | Optional | Takes the settings for the Pay with Transfer (PwT) channel. Pass in the account_expires_at param to set the expiry time. |
ussd | Object | Optional | USSD type to charge (don't send if charging an authorization code, bank or card). |
mobile_money | Object | Optional | Mobile money details (don't send if charging an authorization code, bank or card). Currently supported in Ghana and Kenya only. |
qr | Object | Optional | Takes a provider parameter with the value set to: scan-to-pay. Currently supported in South Africa only. |
authorization_code | String | Optional | An authorization code to charge (don't send if charging a bank account). |
pin | String | Optional | 4-digit PIN (send with a non-reusable authorization code). |
metadata | Object | Optional | Used for passing additional details for your post-payment processes. |
reference | String | Optional | Unique transaction reference. Only -, ., = and alphanumeric characters allowed. |
device_id | String | Optional | This is the unique identifier of the device a user uses in making payment. Only -, ., = and alphanumeric characters allowed. |
split_code | String | Optional | The split code of a previously created split. e.g. SPL_98WF13Eb3w. |
subaccount | String | Optional | The code for the subaccount that owns the payment. e.g. ACCT_8f4s1eq7ml6rlzj. |
transaction_charge | Integer | Optional | An 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. |
bearer | String | Optional | Use 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.
$response = paystack()->charge()->submitPin('1234', 'TRANS_REFERENCE');Submit OTP
If the charge response requires an OTP (status send_otp), submit it using this method.
$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.
$response = paystack()->charge()->submitPhone('08012345678', 'TRANS_REFERENCE');Submit Birthday
If the charge response requires a birthday (status send_birthday), submit it using this method.
$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.
$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.
$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.
// 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.
$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).
$response = paystack()->charge()->create([
'email' => '[email protected]',
'amount' => 1000,
'currency' => 'GHS',
'mobile_money' => [
'phone' => '0551234567',
'provider' => 'mtn'
]
]);