Implementation
This section outlines the technical steps required for aggregator merchants to initiate and complete a transaction using the Payloft Payment Gateway.
Step 1: Create Order Payload
To initiate a transaction, construct a JSON payload with the following structure:
{
"id": "MERCHANTID",
"secretKey": "AJAHD45S45F4S4S45AS45D54S",
"description": "Your Payment description",
"amount": 200,
"fee": 0,
"currency": "566",
"returnUrl": "http://mywebsite.com/returnurl",
"callbackUrl": "https://mywebsite.com/callbackurl",
"scheme": "",
"vendorId": "",
"referenceId": "Your Transaction reference",
"customerName": "Customer Name",
"customerEmail": "customer.email@gmail.com",
"isJson": "false",
"count": 0
}
Payload Parameters
Parameter | Required | Description |
|---|
id
| Yes | Your unique merchant identifier. |
secretKey
| Yes | Your secure authentication and encryption key. |
description
| Yes | A brief description of the transaction (e.g., "Purchase of product X"). |
amount
| Yes | The total amount to be charged for the transaction. |
fee
| No | Any applicable transaction fee (can be set to 0 if not applicable). |
currency
| Yes | The currency code for the transaction, following ISO 4217 standards (e.g., 566 for NGN, 840 for USD). |
returnUrl
| Yes | The URL to which the customer is redirected after transaction completion. |
callbackUrl
| No | The webhook URL to receive transaction status updates via a POST request. |
scheme
| No | The payment card scheme (visa, mastercard, verve, payattitude). |
vendorId
| No | The identifier of a sub-merchant or vendor, if applicable. |
referenceId
| No | A merchant-defined reference ID for internal tracking. |
customerName
| No | The customer's full name. |
customerEmail
| No | The customer's email address. |
isJson
| Yes | Determines the response format at the end of the transaction: false for POST form data, true for GET query string. |
count
| No | The transaction attempt count, typically 0 for the initial request. |
Step 2: Sending a Transaction Request
To initiate a transaction, make a POST request to the following endpoint:
POST https://test.mypayloft.com/{Aggregator}
Merchant Identification
Replace {Aggregator} with your MerchantID, which can be found under:
➡ Settings > API Keys on the Payloft Onboarding Platform.
Include the following headers in your request:
{
"Accept": "application/json",
"Content-Type": "application/json"
}
Step 3: Retrieve Encryption Key
To perform secure transactions, you'll need your EncryptionKey.
➡ Navigate to Settings > API on the Payloft Onboarding Platform to obtain it.
Step 4: Create Card Details Payload
For card-based transactions, prepare the card details in the following JSON structure. This payload will later be encrypted using AES (see Step 5):
{
"secretKey": "AJAHD45S45F4S4S45AS45D54S",
"scheme": "visa",
"cardNumber": "4999082100029373",
"expiry": "01/27",
"cvv": "126",
"cardholder": "",
"mobile": "",
"pin": ""
}
Schemes Field Requirements
Card Scheme | Required Fields |
|---|
Visa / Mastercard / Amex | secretKey, scheme, cardNumber, expiry, cvv Leave cardholder, mobile, and pin empty
|
Verve | All fields must be populated: secretKey, scheme, cardNumber, expiry, cvv, cardholder, mobile, pin |
PayAttitude | Only secretKey and mobile are required All other fields should be empty |
PayAttitude Payload
{
"secretKey": "AJAHD45S45F4S4S45AS45D54S",
"scheme": "",
"cardNumber": "",
"expiry": "",
"cvv": "",
"cardholder": "",
"mobile": "08069493993",
"pin": ""
}
Step 5: Encrypt Card Data (AES Encryption)
Use the AES encryption algorithm to encrypt the JSON payload from Step 4 using the secretKey obtained in Step 3.
public static string Encrypt(byte[] dataToEncrypt, byte[] key, byte[] iv)
{
using (var aes = new AesCryptoServiceProvider())
{
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.Key = key;
aes.IV = iv;
using (var memoryStream = new MemoryStream())
{
var cryptoStream = new CryptoStream(memoryStream,
aes.CreateEncryptor(), CryptoStreamMode.Write);
cryptoStream.Write(dataToEncrypt, 0, dataToEncrypt.Length);
cryptoStream.FlushFinalBlock();
return memoryStream.ToArray().Aggregate("", (current, b) => current + b.ToString("X2"));
}
}
}
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import binascii
def encrypt(data_to_encrypt: bytes, key: bytes, iv: bytes) -> str:
cipher = AES.new(key, AES.MODE_CBC, iv)
padded_data = pad(data_to_encrypt, AES.block_size)
encrypted = cipher.encrypt(padded_data)
return binascii.hexlify(encrypted).decode().upper()
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class Encryptor {
public static String encrypt(byte[] dataToEncrypt, byte[] key, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encrypted = cipher.doFinal(dataToEncrypt);
StringBuilder hex = new StringBuilder();
for (byte b : encrypted) {
hex.append(String.format("%02X", b));
}
return hex.toString();
}
}
Step 6: Redirect User for Payment Processing
Card Transactions
Redirect the customer to the following GET request URL to complete the transaction:
GET https://test.mypayloft.com/Home/TransactionPost/TRANSACTIONID?mid=MERCHANTID&payload=ENCRYPTEDDATA
Where:
TRANSACTIONID → Obtained from Step 2.
MERCHANTID → Your unique merchant identifier.
ENCRYPTEDDATA → The encrypted payload from Step 5.
After the transaction is completed, the Payment Gateway will post back the following data:
{
"trxId": "1234567",
"approved": "true",
"status": "APPROVED"
}
PayAttitude Transactions
For PayAttitude, submit a POST request to complete the transaction:
POST https://test.mypayloft.com/Home/PayAttitudeTransactionPost
Request Payload:
{
"Id": "TRANSACTIONID",
"Mid": "MERCHANTID",
"Payload": "ENCRYPTEDDATA"
}
{
"Accept": "application/json"
}
Response Example
{
"OrderId": "TRANSACTION ID",
"Amount": "TRANSACTION AMOUNT",
"Description": "DESCRIPTION OF TRANSACTION",
"Currency": "TRANSACTION CURRENCY",
"Status": "TRANSACTION STATUS",
"PAN": "CUSTOMER PHONE NUMBER",
"TranTime": "TRANSACTION DATETIME",
"StatusDescription": "DESCRIPTION OF THE TRANSACTION STATUS"
}
Step 7 Status
Transaction Query
To query the status of a transaction, send a GET request in the format below.
https://test.mypayloft.com/Status/Transactionid
Where transactionID is the ID received as a response after the order was created.
The status is the status of the transaction, this could be either of the following in the table below:
Status | Description |
|---|
Approved/Approved Successful
| A transaction is Approved when the customer is successfully debited and value for transaction is received. |
Cancelled
| A transaction is Cancelled when the customer decides to not enter payment details and returns back to the merchant site. |
Declined
| A transaction is Declined when one of the following happens: 1. Unsuccessful authentication 2. Unsuccessful authorization 3. System error |
Initiated
| A transaction is Initiated when the customer abandons a transaction. |
Step 8: Callback Signature Verification
When a payment is completed or updated, the Payloft Gateway (UP MPI) sends a POST request to your configured callbackUrl. This request includes:
The signature is included in the x-api-key header of the callback POST request.
POST /callbackurl HTTP/1.1
Host: mywebsite.com
Content-Type: application/json
x-api-key: 5ASD599DFSA21SDS13S536SFS98968390
Body:
{
"Order Id": "1027079",
"Amount": "50000.00",
"Description": "^WEBID107079",
"Convenience Fee": "0.00",
"Approval Code": "233644",
"Currency": "566",
"Status": "APPROVED",
"Card Holder": "",
"PAN": "499908XXXXXX9373",
"Scheme": "VISA",
"TranTime": "7/3/2025 2:25:19 PM",
"TranDateTime": "7/3/2025 2:25:19 PM",
"StatusDescription": "Approved",
"CustomerName": "Customer Name",
"CustomerEmail": "CustomerEmail@gmail.com",
"RRN": "12324575919",
"ThreeDSVerification": null
}
Need help or support during implementation? Contact our support team for assistance.
03 July 2025