The strong shift from a cash economy to a digital economy in Vietnam has established a new context, where e-wallets are no longer simply payment tools but become a super application (Super App) that plays a central role in consumer behavior. MoMo, as a leading platform, has built a complex but unified technical ecosystem, providing businesses with solutions from online payment, over-the-counter payment to smart marketing and corporate financial management models. Integrating the MoMo payment system into business operations is not just a technical requirement but a strategic decision to reach a network of more than 50 million users and process an average of more than one million transactions per day. According to analysis from experts at Tan Phat Digital, this report provides an in-depth, comprehensive and practical view of the MoMo integration process, from legal aspects, system architecture to security protocols and post-integration operating procedures.
Chapter 1: Overview architecture and strategic position of MoMo in the Fintech ecosystem
MoMo's position is reinforced by strong technological capabilities and high adaptability to market changes. MoMo's system is designed to ensure business continuity and outstanding system capacity. MoMo's solutions are not limited to online payments but also expand to IoT devices, AIoT and solutions that do not require deep integration (Non-Integration), meeting the needs of all types of businesses from micro to multinational corporations.
1.1. Growth indicators and network strength
Partners' trust in MoMo is demonstrated through stable growth figures. Sharing market share in a strongly growing network is an opportunity for businesses to optimize revenue and minimize payment barriers for customers.
Number of active users: Over 50,000,000 people. Meaning: Ability to access huge potential market.
Average number of transactions: More than 1,000,000 transactions/day. Meaning: The system operates stably and reliably.
Online Partners (Online Merchants): More than 1,000 businesses. Meaning: Wide connection network.
Payment acceptance points (Offline Outlets): More than 50,000 points. Meaning: Ability to cover physical sales channels.
Agent and partner system: More than 910,000 agents and 626,000 partners. Meaning: Infrastructure to support deposits/withdrawals and dense financial services.
1.2. Classification of core integration solutions
MoMo provides a wide range of products, allowing businesses to choose the method that suits their resources and business model. Tan Phat Digital identifies this flexibility as the key to optimizing customer experience (UX) on every touch point.
Payment Gateway (Payment Gateway): All-in-One (AiO) solution allows integrating a variety of payment methods such as MoMo wallet, domestic ATM card, international card (VISA/Master/JCB) and postpaid money sources through just a single connection process
Automated Payments: Supports One-Click Payment with one-time authentication, suitable for recurring subscription services.
SDK For Enhancements (MDK - MoMo Customized SDK): Software development kit optimized for deep integration into partner mobile applications, delivering performance High quality and smooth experience.
IoT & AIoT Solutions: Solutions for smart devices such as vending machines, Kiosk, SmartTV or dual-screen POS, supporting both facial recognition and QR code scanning.
Non-Integration Solutions: For businesses without a strong technical team, including Static QR Code and Bar Link Payment Link to send via SMS or social networks.
Chapter 2: Business profile registration and authentication strategy (M4B)
To establish an official presence in the MoMo ecosystem, businesses must go through the MoMo for Business (M4B) administration portal. This is not just an administrative procedure but a fundamental step to establish technical identification parameters and manage cash flow later.
2.1. M4B account registration process
The process starts at business.momo.vn. Businesses need to fill in full account information including login name (used to look up information) and high security password (from 8 to 18 characters). For businesses that have used management platforms such as Haravan, Sapo or CukCuk, registering an M4B account is a mandatory step to obtain API connection parameters.
The standardized roadmap from registration to official operation (Go-live) is summarized by Tan Phat Digital through strict steps:
Registering a merchant profile (Merchant) Profile).
Technical integration on the Test environment (Sandbox).
Complete SIT (System Integration Testing) testing on the Test environment.
Perform business account authentication through legal documents.
Request identification information (Credentials) for the actual environment (Production).
Perform testing User acceptance (UAT) on Production environment and final approval required.
Approved and officially deployed the service.
2.2. Legal documents and authentication requirements
Providing accurate documents determines the speed of approval by MoMo's QA and Legal teams. Documentation requirements include:
For Enterprises: Original Business Registration License (GPKD) or notarized copy, clear image.
For Individual Business Households: ID card/CCCD of representative (front and back photo, not blurred or cut corners).
Unit does not have one. Business license: ID card/CCCD and store owner information (applicable to small models, without full legal status).
Additional documents: Brand logo (100x100 pixel format), Tax payment paper, Power of attorney.
An important feature of the M4B system is the support for signing electronic contracts, helping to speed up the process onboarding without having to meet face to face.
Chapter 3: Technical architecture of All-in-One (AiO) Unified API solution
MoMo's AiO Unified API solution represents standardization in payment connectivity. Instead of having to maintain multiple connection flows for different card types and funds, partners only need to deploy a single API.
3.1. Connection identifier parameters (Credentials)
In an integrated environment, partners will work with a set of security keys. The difference between Test and Production environments lies in these key values and the server address (Domain).
Partner Code: Unique identifier for the business in the MoMo system.
Access Key: Key used to grant access to MoMo's API system.
Secret Key: Secret key used to create electronic signatures Signature for each HTTP request. This is the most important component in ensuring data integrity.
Public Key: Used in RSA data encryption algorithms for solutions requiring higher security.
3.2. Infrastructure and network configuration (IP Whitelisting)
MoMo system requires partners to configure firewalls to allow specific IP address ranges to communicate with partner servers:
Sandbox environment (Test): Domain
test-payment.momo.vn. Incoming IP:210.245.113.71. Outgoing IP:118.69.210.244,118.68.171.198.Production environment: Domain
payment.momo.vn. Incoming IP:118.69.212.158. Outgoing IP:118.69.210.244,116.103.110.134(Updated September 11, 2024).
Chapter 4: Security mechanism and digital signature protocol
Transaction information security is a top priority in Fintech systems. MoMo uses digital signatures to authenticate data, ensuring that information has not been altered by third parties.
4.1. HMAC-SHA256 algorithm
MoMo uses the HMAC-SHA256 hash algorithm to create signatures. This is a symmetric algorithm, using the same Secret Key for calculation. Formula:
Signature = HMAC_SHA256(SecretKey, RawString)
4.2. Rules for creating Raw String
Parameter sorting: Field names (key names) must be arranged alphabetically from
a-z.String format: Concatenate
key=valuepairs together, separated by&characters.Data hashing: Use Secret Key to hash the newly created string. The result is a hexadecimal string of 64 characters.
Tan Phat Digital note: Absolutely never reveal the Secret Key in the Client side source code (Frontend). Signature creation must always be done Server-side.
Chapter 5: One-Time Payments technical integration process (captureWallet API)
This is the most common payment flow, including transaction initiation, user navigation and result processing.
5.1. Initiate Payment
Partner server sends HTTP POST request to MoMo endpoint with parameters: partnerCode, requestId, amount (Min 1,000 VND), orderId, orderInfo, redirectUrl, ipnUrl, requestType (captureWallet), and extraData.
5.2. Navigation and User Experience
After a successful API call, MoMo returns JSON containing:
deeplink: Directly opens the MoMo app (App-to-App optimization).
payUrl: Payment page URL on the browser (Desktop/Mobile Web optimization).
qrCodeUrl: Data data to create a QR code displayed on the spot.
Chapter 6: Instant Payment Notification (IPN) mechanism
IPN is an important mechanism that ensures synchronization through server-to-server communication, even if the user loses connection after paying.
Principle: MoMo sends HTTP POST to
ipnUrl. Payload containsresultCode,transId,amount, andsignature.Server processing: Requires signature validation,
orderId/amountcheck, and response with HTTP code 204 (No Content) within 15 seconds.
Chapter 7: Status management and post-payment operations
Check Status: Used when IPN or navigation results are not received after 30 seconds.
Refund: Applicable for successful transaction. Note that the
orderIdrefund must be a new code.Cancel transaction (Reverse): Pay immediately when the transaction is pending or there is a technical error on the partner's side.
Chapter 8: MoMo Mini App ecosystem - "App-in-App" strategy
MoMo Mini App allows businesses to deploy web-based applications right on the MoMo platform, helps reach a huge user base without investing in an independent application on the Store.
Chapter 9: Offline payment solutions and POS devices
MoMo expands payment capabilities into the physical space through:
QR Static Code (Static QR): The simplest, customers scan the code and enter the amount themselves.
Dynamic QR Code: POS generates Unique QR code for each invoice, customers only need to scan and confirm.
Chapter 10: Duplicate control and immutability (Idempotency)
MoMo uses the requestId field (UUID V4 should be used) to control duplicates for 31 days. If the same requestId is received, the system returns the old result instead of deducting money again.
Chapter 11: Error code system and exception handling strategy
2xx: Successfully processed.
4xx: Counterparty error (wrong signature, missing parameters number).
5xx: MoMo system error.
Code 0: Success.
Code 1001: Insufficient funds.
Code 1006: User cancels.
Chapter 12: Testing process SIT and UAT
This phase uses the Sandbox environment and the MoMo Test App. The default test wallet account has a password/OTP of 000000. It is necessary to test successful flows, error flows (not enough money, expired QR) and security flows (change amount).
Chapter 13: Reference sample source code (Code Samples)
Below is an executable sample source code compiled by Tan Phat Digital to help partners deploy quickly.
13.1. Node.js
JavaScript
// parameters
var partnerCode = "MOMO";
var accessKey = "F8BBA842ECF85";
var secretkey = "K951B6PE1waDMi640xX08PD3vg6EkVlz";
var requestId = partnerCode + new Date().getTime();
var orderId = requestId;
var orderInfo = "pay with MoMo";
var redirectUrl = "https://momo.vn/return";
var ipnUrl = "https://callback.url/notify";
var amount = "50000";
var requestType = "captureWallet"
var extraData = "";
// raw signature construction
var rawSignature = "accessKey="+accessKey+"&amount=" + amount+"&extraData=" + extraData+"&ipnUrl=" + ipnUrl+"&orderId=" + orderId+"&orderInfo=" + orderInfo+"&partnerCode=" + partnerCode +"&redirectUrl=" + redirectUrl+"&requestId=" + requestId+"&requestType=" + requestType
const crypto = require('crypto');
var signature = crypto.createHmac('sha256', secretkey)
.update(rawSignature)
.digest('hex');
const requestBody = JSON.stringify({
partnerCode : partnerCode,
accessKey : accessKey,
requestId : requestId,
amount : amount,
orderId : orderId,
orderInfo : orderInfo,
redirectUrl : redirectUrl,
ipnUrl : ipnUrl,
extraData : extraData,
requestType : requestType,
signature : signature,
lang: 'en'
});
const https = require('https');
const options = {
hostname: 'test-payment.momo.vn',
port: 443,
path: '/v2/gateway/api/create',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(requestBody)
}
}
const req = https.request(options, res => {
res.setEncoding('utf8');
res.on('data', (body) => {
console.log('payUrl: ' + JSON.parse(body).payUrl);
});
})
req.write(requestBody);
req.end();
13.2. Go (Golang)
Go
package main
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"net/http"
"strconv"
"github.com/sony/sonyflake"
)
type Payload struct {
PartnerCode string `json:"partnerCode"`
AccessKey string `json:"accessKey"`
RequestID string `json:"requestId"`
Amount string `json:"amount"`
OrderID string `json:"orderId"`
OrderInfo string `json:"orderInfo"`
RedirectUrl string `json:"redirectUrl"`
IpnUrl string `json:"ipnUrl"`
ExtraData string `json:"extraData"`
RequestType string `json:"requestType"`
Signature string `json:"signature"`
}
func main() {
flake := sonyflake.NewSonyflake(sonyflake.Settings{})
a, _ := flake.NextID()
b, _ := flake.NextID()
var orderId = strconv.FormatUint(a, 16)
var requestId = strconv.FormatUint(b, 16)
var endpoint = "https://test-payment.momo.vn/v2/gateway/api/create"
var secretKey = "PPuDXq1KowPT1ftR8DvlQTHhC03aul17"
var payload = Payload{
PartnerCode: "MOMOIQA420180417",
AccessKey: "SvDmj2cOTYZmQQ3H",
RequestID: requestId,
Amount: "1000",
OrderID: orderId,
OrderInfo: "momo all-in-one",
RedirectUrl: "https://webhook.site/...",
IpnUrl: "https://webhook.site/...",
ExtraData: "",
RequestType: "captureWallet",
}
var rawSignature bytes.Buffer
rawSignature.WriteString("accessKey=" + payload.AccessKey + "&amount=" + payload.Amount + "&extraData=" + payload.ExtraData + "&ipnUrl=" + payload.IpnUrl + "&orderId=" + payload.OrderID + "&orderInfo=" + payload.OrderInfo + "&partnerCode=" + payload.PartnerCode + "&redirectUrl=" + payload.RedirectUrl + "&requestId=" + payload.RequestID + "&requestType=" + payload.RequestType)
h := hmac.New(sha256.New,byte(secretKey))
h.Write(rawSignature.Bytes())
payload.Signature = hex.EncodeToString(h.Sum(nil))
jsonPayload, _ := json.Marshal(payload)
resp, _ := http.Post(endpoint, "application/json", bytes.NewBuffer(jsonPayload))
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println("PayUrl is: ", result["payUrl"])
}
13.3. Python
Python
import json
import uuid
import requests
import hmac
import hashlib
endpoint = "https://test-payment.momo.vn/v2/gateway/api/create"
partnerCode = "MOMO"
accessKey = "F8BBA842ECF85"
secretKey = "K951B6PE1waDMi640xX08PD3vg6EkVlz"
orderInfo = "pay with MoMo"
redirectUrl = "https://webhook.site/..."
ipnUrl = "https://webhook.site/..."
amount = "50000"
orderId = str(uuid.uuid4())
requestId = str(uuid.uuid4())
requestType = "captureWallet"
extraData = ""
rawSignature = "accessKey=" + accessKey + "&amount=" + amount + "&extraData=" + extraData + "&ipnUrl=" + ipnUrl + "&orderId=" + orderId + "&orderInfo=" + orderInfo + "&partnerCode=" + partnerCode + "&redirectUrl=" + redirectUrl + "&requestId=" + requestId + "&requestType=" + requestType
h = hmac.new(bytes(secretKey, 'ascii'), bytes(rawSignature, 'ascii'), hashlib.sha256)
signature = h.hexdigest()
data = {
'partnerCode': partnerCode,
'requestId': requestId,
'amount': amount,
'orderId': orderId,
'orderInfo': orderInfo,
'redirectUrl': redirectUrl,
'ipnUrl': ipnUrl,
'lang': "vi",
'extraData': extraData,
'requestType': requestType,
'signature': signature
}
data = json.dumps(data)
response = requests.post(endpoint, data=data, headers={'Content-Type': 'application/json'})
print(response.json()['payUrl'])
13.4. Ruby
Ruby
require 'net/https'
require 'uri'
require 'json'
require 'openssl'
require 'securerandom'
endpoint = "https://test-payment.momo.vn/v2/gateway/api/create"
partnerCode = "MOMO"
accessKey = "F8BBA842ECF85"
secretKey = "K951B6PE1waDMi640xX08PD3vg6EkVlz"
amount = "50000"
orderId = SecureRandom.uuid
requestId = SecureRandom.uuid
rawSignature = "accessKey="+accessKey+"&amount="+amount+"&extraData=&ipnUrl=...&orderId="+orderId+"&orderInfo=...&partnerCode="+partnerCode+"&redirectUrl=...&requestId="+requestId+"&requestType=captureWallet"
signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), secretKey, rawSignature)
jsonRequest = {
:partnerCode => partnerCode,
:requestId => requestId,
:amount => amount,
:orderId => orderId,
:signature => signature,
:requestType => "captureWallet"
}
uri = URI.parse(endpoint)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.path, {'Content-Type' => 'application/json'})
request.body = jsonRequest.to_json
response = http.request(request)
puts JSON.parse(response.body)["payUrl"]
13.5. PHP (Initialization & IPN)
PHP
// Initiate Payment
$partnerCode, 'requestId' => $requestId, 'amount' => $amount, 'orderId' => $orderId, 'orderInfo' => $orderInfo, 'redirectUrl' => $redirectUrl, 'ipnUrl' => $ipnUrl, 'extraData' => $extraData, 'requestType' => $requestType, 'signature' => $signature);
$result = executePostRequest($endpoint, json_encode($data));
$jsonResult = json_decode($result, true);
header('Location: '. $jsonResult['payUrl']);
?>
// IPN Handling
13.6. C# (.NET)
C#
// MoMoSecurity.cs
using System.Security.Cryptography;
using System.Text;
namespace MoMo {
class MoMoSecurity {
public string signSHA256(string message, string key) {
byte keyByte = Encoding.UTF8.GetBytes(key);
bytes messageBytes = Encoding.UTF8.GetBytes(message);
using (var hmacsha256 = new HMACSHA256(keyByte)) {
byte hashmessage = hmacsha256.ComputeHash(messageBytes);
string hex = BitConverter.ToString(hashmessage);
return hex.Replace("-", "").ToLower();
}
}
}
}
// MoMoForm.cs
string endpoint = "https://test-payment.momo.vn/v2/gateway/api/create";
string partnerCode = "MOMO5RGX20191128";
string accessKey = "SvDmj2cOTYZmQQ3H";
string secretkey = "PPuDXq1KowPT1ftR8DvlQTHhC03aul17";
string orderId = Guid.NewGuid().ToString();
string requestId = Guid.NewGuid().ToString();
string amount = "50000";
// Build rawHash in alphabetical order...
MoMoSecurity crypto = new MoMoSecurity();
string signature = crypto.signSHA256(rawHash, secretkey);
// Send HTTP Post request...
Integrating MoMo is not simply about installing a payment method, but a comprehensive digital transformation journey. By complying with technical standards on signature, IPN, and key security, businesses can not only build a reliable payment system but also build solid trust with customers in today's digital era. The success of integration lies in the combination of technical precision and flexibility in business operations strategies from reputable units such as Tan Phat Digital.
Share








