Payment Channels

In A Nutshell
In a nutshell
Paystack enables you accept payments from customers using different payment channels such as: cards, mobile money accounts, QR codes, directly from their bank account or USSD.

If you use the the Popup or Redirect method, the paying customer will be shown all the payment methods selected on your dashboard. But if you don't want to use either option, you can initiate all the different payment channels directly from your server using the charge API.

What channels are available?
Card payment channels are available on all Paystack accounts, while the other payment channels are only available in countries where they are supported.

Cards

We strongly discourage passing card information directly to the API to avoid transmitting card data through systems that are not PCI compliant.

If you are PCI-DSS certified and would like to be able to send cardholder information directly to our APIs from your servers, reach out to us!

Bank accounts

Where is this available?
This feature is currently only available for Naira collections in Nigeria.

The Pay with Bank feature allows customers pay through internet banking portal or by providing their bank account number and authenticating using an OTP sent to their phone or email.

This is different from Bank Transfers where customers transfer money into a bank account.

Collect bank details

To collect bank details, you would need to prompt the user to select their bank and enter their account number. To fetch the list of supported banks, make a GET request to the list banksAPI endpoint, with the additional filter pay_with_bank=true.

The banks can be listed in a dropdown or any other format that allows the user to easily pick their bank of choice.

Create a charge

Send email, amount, metadata, bank (an object that includes code of bank and account_number supplied by customer), birthday to our Charge endpoint as available to start.

Show Response
1curl https://api.paystack.co/charge
2-H "Authorization: Bearer YOUR_SECRET_KEY"
3-H "Content-Type: application/json"
4-d '{ email: "[email protected]", amount: "10000", "bank": {
5 "code": "057", "account_number": "0000000000" }}'
6-X POST
1{
2 "status": true,
3 "message": "Charge attempted",
4 "data": {
5 "reference": "z8q981z5kp7sfde",
6 "status": "send_birthday",
7 "display_text": "Please enter your birthday"
8 }
9}

When the API call is made, the value of the data.status key is pending as the payment is being processed in the background. The data.status then updates to either, success or failed depending on whether the transaction was successful or not.

USSD

This Payment method is specifically for Nigerian customers. Nigerian Banks provide USSD services that customers use to perform transactions, and we've integrated with some of them to enable customers complete payments.

The Pay via USSD channel allows your Nigerian customers to pay you by dialling a USSD code on their mobile device. This code is usually in the form of * followed by some code and ending with #. The user is prompted to authenticate the transaction with a PIN and then it is confirmed.

All you need to initiate a USSD charge is the customer email and the amount to charge.

When the user pays, a response will be sent to your webhook. Hence, for this to work properly as expected, webhooks must be set up on your Paystack Dashboard.

Create a charge

Send an email and amount to the chargeAPI endpoint. Specify the USSD type you are charging as well.

Below are all the USSD types we support. We'll add to list as we have more:

BankType
Guaranty Trust Bank737
United Bank of Africa919
Sterling Bank822
Zenith Bank966
Show Response
1curl https://api.paystack.co/charge
2-H "Authorization: Bearer YOUR_SECRET_KEY"
3-H "Content-Type: application/json"
4-d '{ "email": "[email protected]",
5 "amount":"10000",
6 "ussd": {
7 "type": "737"
8 },
9 "metadata": {
10 "custom_fields":[{
11 "value": "makurdi",
12 "display_name": "Donation for",
13 "variable_name":
14 "donation_for"
15 }]
16 }
17 }'
18-X POST
1{
2 "status": true,
3 "message": "Charge attempted",
4 "data": {
5 "reference": "yjr1r8rwhedara4",
6 "status": "pay_offline",
7 "display_text": "Please dial *737*33*4*18791# on your mobile phone to complete the transaction",
8 "ussd_code": "*737*33*4*18791#"
9 }
10}

When a charge is made, the default response provides a USSD code for the customer to dial to complete the payment.

Handle response

When the user completes payment, a response is sent to the merchant’s webhook. Hence, for this to work properly as expected, webhooks must be set up for the merchant..

The charge.success event is raised on successful payment. The sample response to be sent to the user’s webhook would look like:

1{
2 "event": "charge.success",
3 "data": {
4 "id": 53561,
5 "domain": "live",
6 "status": "success",
7 "reference": "2ofkbk0yie6dvzb",
8 "amount": 150000,
9 "message": "madePayment",
10 "gateway_response": "Payment successful",
11 "paid_at": "2018-06-25T12:42:58.000Z",
12 "created_at": "2018-06-25T12:38:59.000Z",
13 "channel": "ussd",
14 "currency": "NGN",
15 "ip_address": "54.246.237.22, 162.158.38.185, 172.31.15.210",
16 "metadata": "",
17 "log": null,
18 "fees": null,
19 "fees_split": null,
20 "authorization": {
21 "authorization_code": "AUTH_4c6mhnmmeusp4yd",
22 "bin": "XXXXXX",
23 "last4": "XXXX",
24 "exp_month": "05",
25 "exp_year": "2018",
26 "channel": "ussd",
27 "card_type": "offline",
28 "bank": "Guaranty Trust Bank",
29 "country_code": "NG",
30 "brand": "offline",
31 "reusable": false,
32 "signature": null,
33 "account_name": null
34 },
35 "customer": {
36 "id": 16200,
37 "first_name": "John",
38 "last_name": "Doe",
39 "email": "[email protected]",
40 "customer_code": "CUS_bpy9ciomcstg55y",
41 "phone": "",
42 "metadata": null,
43 "risk_action": "default"
44 },
45 "plan": {
46
47 },
48 "subaccount": {
49
50 },
51 "paidAt": "2018-06-25T12:42:58.000Z"
52 }
53}
USSD recurring charge
Charging returning customers directly is not currently available. Simply call the endpoint to start a new transaction.

Mobile money

The Pay via Mobile Money channel allows Ghanaian customers to pay you by entering the phone number enabled for mobile money.

When the customer clicks pay, they will receive a prompt on the mobile device attached to their number asking them to confirm the payment by inputting a PIN.

When the user pays, a response will be sent to your webhook. This means that you must have webhooks set up on your Paystack Dashboard.

Create a charge

Send an email and amount to the chargeAPI endpoint along with a mobile_money object.

1curl https://api.paystack.co/charge
2-H "Authorization: Bearer YOUR_SECRET_KEY"
3-H "Content-Type: application/json"
4-d '{ "amount": 100,
5 "email": "[email protected]",
6 "currency": "GHS",
7 "mobile_money": {
8 "phone" : "0551234987",
9 "provider" : "mtn"
10 }
11 }'
12-X POST

Provider code

Here are the 3 character code for the 3 supported mobile money providers:

ProviderCharacter code
MTN"mtn"
Vodafone"vod"
Airtel/Tigo"tgo"

Airtel and MTN requires the customer to complete the transaction process offline, the data.status field would be pay_offline, once you get this status, there's nothing left to do. You're expected to display the data.display_text to your user, and then listen for webhook for transaction notification or requery the verify transaction endpoint at interval.

Here is a sample response that requires the customer to complete the process offline:

1{
2 "status": true,
3 "message": "Charge attempted",
4 "data": {
5 "reference": "8nn5fqljd0suybr",
6 "status": "pay_offline",
7 "display_text": "Please complete authorization process on your mobile phone"
8 }
9}

For Vodafone, the customer is required to generate a voucher code by dialing the USSD code show in the data.display_text field, this voucher code should be collected and passed to the submit OTPAPI endpoint to authorize the transaction.

1{
2 "status": true,
3 "message": "Charge attempted",
4 "data": {
5 "reference": "r13havfcdt7btcm",
6 "status": "send_otp",
7 "display_text": "Please dial *110# to generate a voucher code. Then input the voucher"
8 }
9}

If the mobile money customer enters the otp on time and we are able to get a response just in time, we return the success response:

1{
2 "message": "Charge attempted",
3 "status": true,
4 "data": {
5 "amount": 100,
6 "channel": "mobile_money",
7 "created_at": "2018-11-17T14:39:56.000Z",
8 "currency": "GHS",
9 "domain": "live",
10 "fees": 153,
11 "gateway_response": "Approved",
12 "id": 59333,
13 "ip_address": "35.177.189.123, 162.158.155.220",
14 "message": "madePayment",
15 "paid_at": "2018-11-17T14:40:18.000Z",
16 "reference": "l7lvu4y3xcka6zu",
17 "status": "success",
18 "transaction_date": "2018-11-17T14:39:56.000Z",
19 "authorization": {
20 "authorization_code": "AUTH_33lz7ev5tq",
21 "bank": "MTN Mobile Money",
22 "bin": "055XXX",
23 "brand": "Mtn mobile money",
24 "channel": "mobile_money",
25 "country_code": "GH",
26 "exp_month": 12,
27 "exp_year": 9999,
28 "last4": "X149",
29 "reusable": false,
30 "account_name": null
31 },
32 "customer": {
33 "customer_code": "CUS_s3aa4mx0yyvrqye",
34 "email": "[email protected]",
35 "id": 16763,
36 "risk_action": "default"
37 }
38 }
39}

If the transaction is started successfully and the pin is not entered on time, we return this:

1{
2 "status": true,
3 "message": "Charge attempted",
4 "data": {
5 "reference": "84oow6t0rf715g6",
6 "status": "pending"
7 }
8}

Handle response

When the user completes payment, a response is sent to the merchant’s webhook. Hence, for this to work properly as expected, webhooks must be set up for the merchant.

The charge.success event is raised on successful payment. The sample response to be sent to the user’s webhook would look like:

1{
2 "event": "charge.success",
3 "data": {
4 "id": 59214,
5 "domain": "live",
6 "status": "success",
7 "reference": "gf4n3ykzj6a7u89",
8 "amount": 100,
9 "message": "madePayment",
10 "gateway_response": "Approved",
11 "paid_at": "2018-11-15T06:10:54.000Z",
12 "created_at": "2018-11-15T06:10:32.000Z",
13 "channel": "mobile_money",
14 "currency": "GHS",
15 "ip_address": "18.130.236.148, 141.101.99.73",
16 "metadata": "",
17 "log": null,
18 "fees": 153,
19 "fees_split": null,
20 "authorization": {
21 "authorization_code": "AUTH_0aqm8ddx6s",
22 "bin": "055XXX",
23 "last4": "X149",
24 "exp_month": "12",
25 "exp_year": "9999",
26 "channel": "mobile_money",
27 "card_type": "",
28 "bank": "MTN Mobile Money",
29 "country_code": "GH",
30 "brand": "Mtn mobile money",
31 "reusable": false,
32 "signature": null,
33 "account_name": "BoJack Horseman"
34 },
35 "customer": {
36 "id": 16678,
37 "first_name": "Babafemi",
38 "last_name": "Aluko",
39 "email": "[email protected]",
40 "customer_code": "CUS_2jk1i8ezoam49br",
41 "phone": "",
42 "metadata": null,
43 "risk_action": "allow"
44 },
45 "plan": {},
46 "subaccount": {},
47 "subaccount_group": {},
48 "paidAt": "2018-11-15T06:10:54.000Z"
49 }
50}

Charging returning customers directly is not currently available. Simply call the endpoint to start a new transaction.

Test Phone number
The test phone number is 0551234987 and is only available for MTN. No PIN/OTP authorization is required for this phone number.

QR code

The QR option generates a QR code which allows customers to use their bank's mobile app to complete payments. We currently have only Visa QR option available. We'll have more options later.

When the customer scans the code, they authenticate on their bank app to complete the payment. When the user pays, a response will be sent to your webhook. This means that you need to have webhooks set up on your Paystack Dashboard.

Create a charge

Send an email and amount to the chargeAPI endpoint along with a qr object.

Show Response
1curl https://api.paystack.co/charge
2-H "Authorization: Bearer YOUR_SECRET_KEY"
3-H "Content-Type: application/json"
4-d '{ "amount": 100,
5 "email": "[email protected]",
6 "currency": "NGN",
7 "qr": {
8 "provider" : "visa"
9 }
10 }'
11-X POST
1{
2 "status": true,
3 "message": "Charge attempted",
4 "data": {
5 "reference": "48rx32f1womvcr4",
6 "status": "pay_offline",
7 "qr_code": "0002010216421527000104176552045499530356654031005802NG5920Babafemi enterprises6005Lagos62230519PSTK_104176000926|16304713a",
8 "url": "https://files.paystack.co/qr/visa/104176/Babafemi_enterprises_visaqr_1544025482956.png"
9 }
10}
11

Handle response

When the user completes payment, a response is sent to the merchant’s webhook. Hence, for this to work properly as expected, webhooks must be set up for the merchant.

The charge.success event is raised on successful payment. The sample response to be sent to the user’s webhook would look like:

1{
2 "event": "charge.success",
3 "data": {
4 "id": 59565,
5 "domain": "test",
6 "status": "success",
7 "reference": "48rx32f1womvcr4",
8 "amount": 10000,
9 "message": "madePayment",
10 "gateway_response": "Payment successful",
11 "paid_at": "2018-12-05T15:58:45.000Z",
12 "created_at": "2018-12-05T15:58:02.000Z",
13 "channel": "qr",
14 "currency": "NGN",
15 "ip_address": "18.130.45.28, 141.101.107.157",
16 "metadata": "",
17 "log": null,
18 "fees": null,
19 "fees_split": null,
20 "authorization": {
21 "authorization_code": "AUTH_2b4zs69fgy7qflh",
22 "bin": "483953",
23 "last4": "6208",
24 "exp_month": "12",
25 "exp_year": "2018",
26 "channel": "qr",
27 "card_type": "DEBIT",
28 "bank": "Visa QR",
29 "country_code": "NG",
30 "brand": "VISA",
31 "reusable": false,
32 "signature": null,
33 "account_name": "BoJack Horseman"
34 },
35 "customer": {
36 "id": 16787,
37 "first_name": "I",
38 "last_name": "SURRENDER",
39 "email": "[email protected]",
40 "customer_code": "CUS_ehg851zbxon0bvx",
41 "phone": "",
42 "metadata": null,
43 "risk_action": "default"
44 },
45 "plan": {},
46 "subaccount": {},
47 "subaccount_group": {},
48 "paidAt": "2018-12-05T15:58:45.000Z"
49 }
50}
QR code recurring charge
Charging returning customers directly is not currently available. Simply call the endpoint to start a new transaction.