Logo

Validate Payment with IPN API Documentation

Instant Payment Notification (IPN) allows your server to listen for real-time payment events. When a payment is made or canceled, the system sends an HTTP POST request to your configured `ipn_url` with the payment details.

It is critical to validate the transaction notification to maintain security and ensure proper handling of payment statuses.


Key Points to Remember

  1. IPN Payload: The system sends a JSON payload with payment details when an event occurs.
  2. Security: Validate the IPN request, including headers and payload, to ensure authenticity.
  3. IPN Methods: Notifications are sent using the HTTP method you specify (GET, POST, PUT, DELETE, PATCH, OPTIONS, and HEAD). Default: POST).
  4. Status Management: Handle payment statuses (PENDING, FAILED, COMPLETED, CANCELED) appropriately.

Example Payloads

1. Bank Payments

When a bank payment is initiated, the system sends the following payload to the ipn_url:

{
  "payment_id": "673da53bc54320902b5e99fe",
  "reference": "PAY-100001",
  "amount": 100,
  "transaction_fee": 0,
  "total": 100,
  "metadata": "{\"order_id\": \"12345\", \"notes\": \"Payment for services\"}",
  "account_name": "John Doe",
  "account_number": "123456789",
  "branch_name": "Main Branch",
  "bank_name": "Brack",
  "bank_logo": "https://eazzpay.com/logo.svg",
  "business_name": "Ali Express",
  "business_logo": "https://eazzpay.com/logo.svg",
  "success_url": "https://eazzpay.com/logo.svg",
  "payment_method": "BANK",
  "status": "PENDING",
}
  • status: Always PENDING until confirmed manually or by subsequent updates.
  • payment_method: Always BANK until confirmed manually or by subsequent updates.

2. Mobile Banking Payments

For mobile banking payments (e.g., BKASH, ROCKET, NAGAD, UPAY, CELLFIN, TAP, OK_WALLET, IPAY), the payload is as follows:

{
  "payment_id": "673da9b8759373817d415a9d",
  "reference": "PAY-100001",
  "amount": 100,
  "transaction_fee": 2.5,
  "total": 102.5,
  "metadata": "{\"order_id\": \"12345\", \"notes\": \"Payment for services\"}",
  "account_name": "John Doe",
  "account_number": "123456782",
  "business_name": "Ali Express",
  "business_logo": "https://eazzpay.com/logo.svg",
  "success_url": "https://eazzpay.com/logo.svg",
  "payment_method": "MOBILE_BANKING",
  "mfs_payment_method": "ROCKET",
  "mfs_payment_account_type": "MERCHANT",
  "status": "PENDING"
}
  • payment_method: Always MOBILE_BANKING until confirmed manually or by subsequent updates.
  • mfs_payment_method: Identifies the mobile financial service (BKASH, ROCKET, NAGAD, UPAY, CELLFIN, TAP, OK_WALLET, IPAY).
  • mfs_payment_account_type: Specifies the account type (PERSONAL, AGENT or MERCHANT).
  • status: Can be PENDING, FAILED, or COMPLETED.

3. Canceled Payments

If the user cancels a payment, the payload is sent for both bank and mobile banking transactions:

{
  "payment_id": "6742c486aa6aa6dc115624fd",
  "reference": "PAY--100068",
  "amount": 100,
  "total": 100,
  "business_name": "Ali Express",
  "business_logo": "https://eazzpay.com/logo.svg",
  "cancel_url": "https://eazzpay.com/logo.svg",
  "metadata": "{\"order_id\": \"12345\", \"notes\": \"Payment for services\"}",
  "cancel_url": "https:/your-frontend.com/cancel",
  "status": "CANCELED"
}
  • Status: Always CANCELED.

Validating the IPN

Security Steps

  1. Validate Headers: Confirm the eazzpay-client-secret to authenticate the source of the notification.
  2. Check Payload Fields: Ensure all required fields are present and valid.
  3. Handle Status:
    • PENDING: Store the payment details for further confirmation.
    • COMPLETED: Update your system to mark the payment as successful.
    • CANCELED: Handle the cancellation process.

Example Requests

const express = require('express');
const app = express();
const EAZZPAY_CLIENT_SECRET  = 'your-secret-key';
 
app.use(express.json());
 
app.post('/ipn', (req, res) => {
  const eazzpayClientSecret = req.headers['eazzpay-client-secret'];
  
  // Validate client secret
  if (eazzpayClientSecret !== EAZZPAY_CLIENT_SECRET ) {
    return res.status(403).send('Invalid client secret');
  }
  
  // Extract payload
  const payload = req.body;
  console.log('Received IPN Payload:', payload);
 
  // Handle payment status
  switch (payload.status) {
    case 'PENDING':
      console.log('Payment is pending:', payload);
      break;
    case 'COMPLETED':
      console.error('Payment completed:', payload);
      break;
    case 'CANCELED':
      console.warn('Payment was canceled:', payload);
      break;
  }
 
  res.status(200).send('IPN processed');
});
 
app.listen(3000, () => {
  console.log('IPN Listener is running on port 3000');
});

Notes

  • Always validate the eazzpay-client-secret header to ensure the notification's authenticity.
  • Log incoming notifications for debugging and record-keeping.
  • Test the integration in a sandbox environment before going live.

On this page