Handling Callbacks (IPN)
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The ZaloPay Instant Payment Notification (IPN) is a callback mechanism used by the ZaloPay server to asynchronously notify the merchant's server about the status of a transaction. This system is crucial for confirming whether a payment was successful or failed after the user has completed the transaction on the ZaloPay platform. The server must expose an endpoint to receive these callbacks, cryptographically verify their authenticity to prevent tampering, and then process the transaction status accordingly.
This document outlines the architecture and implementation of the IPN callback handler within this project. It covers the API endpoint, the control flow for processing a notification, the cryptographic verification process, and the configuration required.
Sources: controllers/payment.controller.js, services/zalopay.service.js
Callback Handling Architecture
The callback handling process is distributed across several components: the router, the controller, the service layer, and utility functions. When ZaloPay sends an IPN, the request flows through these layers to be validated and processed.
The following diagram illustrates the high-level flow of an incoming IPN request.
This diagram shows the journey of a ZaloPay IPN from its origin to the final response sent by the server.
Sources: routes/payment.route.js, controllers/payment.controller.js, services/zalopay.service.js
Callback Endpoint
The system exposes a single endpoint to receive IPN notifications from ZaloPay.
| Method | Path | Handler | Description |
|---|---|---|---|
POST | /payment/callback | paymentController.ZaloPayCallback | Receives payment status from ZaloPay IPN. |
This route is defined in payment.route.js and is registered in the main application entry point.
Sources: routes/payment.route.js:5, index.js:17
Controller Logic
The ZaloPayCallback function in the payment.controller.js file is the primary entry point for handling incoming IPN requests.
Its responsibilities are:
- Receive the
POSTrequest from ZaloPay. - Extract the
data(a JSON string) andmac(the signature) from the request body. - Call the
ZaloPayService.VerifyCallbackmethod to validate the authenticity of the notification. - Based on the verification result, send a structured JSON response back to the ZaloPay server to acknowledge receipt and indicate the processing status.
The sequence of operations within the controller is shown below.
If the callback is successfully verified, the controller logs the result and sends a success response. If verification fails, it logs an error and sends a failure response.
Sources: controllers/payment.controller.js:25-41
IPN Verification
Verifying the IPN is a critical security measure to ensure the data comes from ZaloPay and has not been altered. This process relies on HMAC (Hash-based Message Authentication Code).
Verification Service
The VerifyCallback function in zalopay.service.js orchestrates the verification.
- It retrieves the HMAC key (
key2) from the application's configuration. - It calls the
Utils.VerifyMachelper function, passing themacfrom ZaloPay, thekey2, and thedatastring. - Based on the boolean result from
VerifyMac, it prepares a response object.
| Verification Status | return_code | return_message |
|---|---|---|
| Success | 1 | "Success" |
| Failure | 0 | "Failed" |
This structured response is what the controller will ultimately send back to ZaloPay.
Sources: services/zalopay.service.js:47-58
Cryptographic Signature Check
The core cryptographic logic resides in the VerifyMac function within common/utils.js. This function performs the actual HMAC-SHA256 signature comparison.
The verification flow is as follows:
This flowchart details the steps to validate the MAC signature.
The implementation uses Node.js's built-in crypto module.
// common/utils.js:15-18
const VerifyMac = (mac, key, data) => {
const hmac = crypto.createHmac("sha256", key).update(data, "utf-8").digest("hex");
return hmac === mac;
};
This function is fundamental to the security of the callback mechanism, ensuring data integrity and authenticity.
Sources: common/utils.js:15-18
Configuration
The verification process depends on a secret key shared between the application and ZaloPay. This key is stored in the application configuration.
| Key | Description | Used In |
|---|---|---|
key2 | The secret key used to verify the HMAC signature of incoming IPN callbacks. | ZaloPayService.VerifyCallback |
This key is defined in the main configuration object.
// config/config.js:8
const config = {
// ...
key2: "eG4r0GcoNtRGbO8"
// ...
};
Note: The key shown is from the public repository and should be treated as an example. In a production environment, this key must be kept secret and managed securely.
Sources: config/config.js:8, services/zalopay.service.js:49
Summary
The IPN callback handling system is a secure and robust mechanism for processing asynchronous payment notifications from ZaloPay. It follows a clear, layered architecture, starting from a dedicated API endpoint, moving through a controller for flow management, and into a service layer for business logic. The security of the entire process is anchored by a cryptographic HMAC-SHA256 verification utility, which ensures that only authentic and untampered notifications are processed. The successful acknowledgment of these callbacks is vital for maintaining accurate transaction state within the application.