NAV

API Reference

API Reference Status code Information

Order creation

App server establish order information then send to ZaloPay server to create order.

Processing flow

Sequence Flow

API specification

Environment Method Endpoint
Sandbox POST https://sb-openapi.zalopay.vn/v2/create
Real POST https://openapi.zalopay.vn/v2/create

application/x-www-form-urlencoded

application/json

application/xml

Order information

The order includes the following information:

Parameter
DataType Length Required Description Example
app_id Int Identification of the application that was issued when registering the application with ZaloPay. 1
app_user String 50 Identification information of the application user: Id / Username / Name / Phone Num / Email. If you cannot identify the user, you can use the default information, such as the application name user123
app_trans_id String 40 Order's transaction code. Must be preceded by yymmdd of the current date. The transaction-code's format should be yymmddOrder identifier

Note: yymmdd is correct TimeZone Vietnam (GMT+7) (Because of cross check transactions is in Vietnam time and date)

'
180208_007242
app_time Long The time of order creation, which calculated in milliseconds, and couldn't over 15 minutes from the time of payment 1459823610957
expire_duration_seconds Long Order expiration time. Time in seconds (minimum value: 300, maximum value: 2592000) 900
amount Long The amount of the order (VND) 50000
item JSON Array String 2048 Additional data, defined by Merchant. Use "{}" when empty. [{"itemid":"knb","itename":"kim nguyen bao","itemprice":198400,"itemquantity":1}]
description String 256 The description of the order, used to display to users on the ZaloPay app <Merchant/Service name> - Payment for the order #<Order ID>
Example:
Lazada - Payment for the order #180208_007242
embed_data JSON String 1024 Merchant's item data. Use "[]" when empty. {"promotioninfo":"","merchantinfo":"du lieu rieng cua ung dung"}
bank_code String 20 ✔ (*) Bank code, See how to get the list of supported banks VTB
mac String Authentication information of the order, see how to create authentication information for orders c8f49d523336f0a182586a70b71c20da96 4d37954711de9273152b500df74c0d
callback_url String ZaloPay will notify to this URL only when the payment is success; If not provided, the default app Callback URL will be used.
device_info JSON String 256 JSON string describes the device specification.
sub_app_id String 50 Identification of the service / service group that partner was registered with ZaloPay (only applicable to special partners) sub123
title String 256 Optional title of order.
currency String The currency of order. Default is VND.
phone String 50 User's phone number 0934568239
email String 100 User's email example@gmail.com
address String 1024 User's address TPHCM

Specific embed_data's fields

Name
DataType Format Description Example
preferred_payment_method Array String ["domestic_card", "vietqr", "..."]
Xem chi tiết cách khai báo tại đây
Dùng để hiển thị phương thức thanh toán tùy chọn trên cổng ZaloPay. {"preferred_payment_method":["vietqr"]}
redirecturl String URL Redirect to this url after successful / failure payment via ZaloPay Gateway (This will override the merchant's redirect url registered with ZaloPay) {"redirecturl": "https://docs.zalopay.vn/result"}
columninfo JSON String {"column_name": "value"} Add information into the section Management of transaction details on Merchant site, If the column does not yet exist, please go to the Display data configuration setting to configure
Note: For offline payment, it is necessary to transmit information such as branch_id, store_id, store_name, ...
{"columninfo": "{\"branch_id\": \"HCM\",\"store_id\": \"CH123\",\"store_name\": \"Saigon Centre\",\"mc_campaign_id\": \"FREESHIP\"}"}
promotioninfo JSON String {"campaigncode":"code"} Use to launch promotions campaign {"promotioninfo": "{\"campaigncode\":\"blackfriday\"}"}
zlppaymentid String -Payment information
-Only needed when you need to receive money for different accounts.
-ZaloPay system will generate a Payment code (corresponding to each partner bank account provided) and send it back to the partner to set up.
{"zlppaymentid": "P4201372"}

Create authentication information

mac = HMAC(hmac_algorihtm, key1, hmac_input)

With:

Example:


{
    "app_id": 2553,
    "app_user": "ZaloPayDemo",
    "app_time": 1660717311101,
    "amount": 10000,
    "app_trans_id": "220817_1660717311101",
    "bank_code": "zalopayapp",
    "embed_data": "{}",
    "item": "[]",
    "callback_url": "<https://domain.com/callback>",
    "description": "ZaloPayDemo - Thanh toán cho đơn hàng #220817_1660717311101",
    "mac": "cf0ff27956f4d6203ce4a2c55691d81b65de2d640ee65e95ae5627ce801cd962"
}

hmac_input: 2553|220817_1660717311101|ZaloPayDemo|10000|1660717311101|{}|[]
mac: cf0ff27956f4d6203ce4a2c55691d81b65de2d640ee65e95ae5627ce801cd962



app_id=2553&app_trans_id=220817_1660717311101&app_user=ZaloPayDemo&app_time=1660717311101&description=ZaloPayDemo - Thanh toán cho đơn hàng #220817_1660717311101&embed_data={}&item=[]&amount=10000&&mac=cf0ff27956f4d6203ce4a2c55691d81b65de2d640ee65e95ae5627ce801cd962

hmac_input: 2553|220817_1660717311101|ZaloPayDemo|10000|1660717311101|{}|[]
mac: cf0ff27956f4d6203ce4a2c55691d81b65de2d640ee65e95ae5627ce801cd962


<?xml version="1.0" encoding="UTF-8"?>
<OAOrder>
    <app_id>2553</app_id>
    <app_user>ZaloPayDemo</app_user>
    <app_trans_id>220817_1660717311101/app_trans_id>
    <app_time>1660717311101</app_time>
    <amount>10000</amount>
    <order_type>GOODS</order_type>
    <title>string</title>
    <description>ZaloPayDemo - Thanh toán cho đơn hàng #220817_1660717311101</description>
    <redirect_url>string</redirect_url>
    <device_info>string</device_info>
    <item>[]</item>
    <embed_data>{}</embed_data>
    <mac>cf0ff27956f4d6203ce4a2c55691d81b65de2d640ee65e95ae5627ce801cd962</mac>
    <currency>VND</currency>
    <bank_code>zalopayapp</bank_code>
    <phone>string</phone>
    <email>string</email>
    <address>string</address>
</OAOrder>

hmac_input: 2553|220817_1660717311101|ZaloPayDemo|10000|1660717311101|{}|[]
mac: cf0ff27956f4d6203ce4a2c55691d81b65de2d640ee65e95ae5627ce801cd962


Response data

Parameter Datatype Description
return_code Int

1: Success

2: Failure

return_message String Description of status code
sub_return_code Int Status code detail
sub_return_message String Detail description of status code
order_url String Used to create QR code or forward users to ZaloPay Gateway page
zp_trans_token String Transaction token
order_token String Order token
qr_code String Used to create NAPAS VietQR on Merchant system. NAPAS VietQR is one of our brand new payment solution, which accepts payments made by both ZaloPay & +40 banks belonged to NAPAS system. User can using bank app scan NAPAS VietQR for payment

Example:

{
  "return_code": 1,
  "return_message": "Giao dịch thành công",
  "sub_return_code": 1,
  "sub_return_message": "Giao dịch thành công",
  "zp_trans_token": "ACSMARlbXkIzcSCNHDWC_5jA",
  "order_url": "https://qcgateway.zalopay.vn/openinapp?order=eyJ6cHRyYW5zdG9rZW4iOiJBQ1NNQVJsYlhrSXpjU0NOSERXQ181akEiLCJhcHBpZCI6MTI0NzA1fQ==",
  "order_token": "ACSMARlbXkIzcSCNHDWC_5jA",
  "qr_code": "00020101021226520010vn.zalopay0203001010627000503173307089089161731338580010A000000727012800069704540114998002401295460208QRIBFTTA5204739953037045405690005802VN62210817330708908916173136304409F"
}

Sample code

/**
 * .Net core 2.1.505
 */
using System;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
using ZaloPay.Helper; // HmacHelper, RSAHelper, HttpHelper, Utils (download at DOWNLOADS page)
using ZaloPay.Helper.Crypto;
using Newtonsoft.Json; // https://www.newtonsoft.com/json

namespace ZaloPayExample
{
    class Program
    {
        static string app_id = "2553";
        static string key1 = "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL";
        static string create_order_url = "https://sb-openapi.zalopay.vn/v2/create";

        static async Task Main(string[] args) {

            Random rnd = new Random();
            var embed_data = new { };
            var items = new[]{new{}};
            var param = new Dictionary<string, string>();
            var app_trans_id   = rnd.Next(1000000); // Generate a random order's ID.
            var param = new Dictionary<string, string>();    

            param.Add("app_id", app_id);
            param.Add("app_user", "user123");
            param.Add("app_time", Utils.GetTimeStamp().ToString());
            param.Add("amount", "50000");
            param.Add("app_trans_id", DateTime.Now.ToString("yyMMdd") + "_" + app_trans_id); // the trading code must be in the format yymmdd_xxxx
            param.Add("embed_data", JsonConvert.SerializeObject(embed_data));
            param.Add("item", JsonConvert.SerializeObject(items));
            param.Add("description", "Lazada - Thanh toán đơn hàng #"+app_trans_id);
            param.Add("bank_code", "zalopayapp");

            var data = app_id + "|" + param["app_trans_id"] + "|" + param["app_user"] + "|" + param["amount"] + "|" 
                + param["app_time"] + "|" + param["embed_data"] + "|" + param["item"];
            param.Add("mac", HmacHelper.Compute(ZaloPayHMAC.HMACSHA256, key1, data));

            var result = await HttpHelper.PostFormAsync(create_order_url, param);

            foreach(var entry in result) {
                Console.WriteLine("{0} = {1}", entry.Key, entry.Value);
            }
        }
    }
}
// Java version "1.8.0_201"
import org.apache.http.NameValuePair; // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject; // https://mvnrepository.com/artifact/org.json/json
import vn.zalopay.crypto.HMACUtil; // download at DOWNLOADS page

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.*;

public class CreateOrder {
    private static Map<String, String> config = new HashMap<String, String>(){{
        put("app_id", "2553");
        put("key1", "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL");
        put("key2", "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz");
        put("endpoint", "https://sb-openapi.zalopay.vn/v2/create");
    }};

    public static String getCurrentTimeString(String format) {
        Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT+7"));
        SimpleDateFormat fmt = new SimpleDateFormat(format);
        fmt.setCalendar(cal);
        return fmt.format(cal.getTimeInMillis());
    }

    public static void main( String[] args ) throws Exception
    {
        Random rand = new Random();
        int random_id = rand.nextInt(1000000);
        final Map embed_data = new HashMap(){{}};

        final Map[] item = {
            new HashMap(){{}}
        };

        Map<String, Object> order = new HashMap<String, Object>(){{
            put("app_id", config.get("app_id"));
            put("app_trans_id", getCurrentTimeString("yyMMdd") +"_"+ random_id; // translation missing: en.docs.shared.sample_code.comments.app_trans_id
            put("app_time", System.currentTimeMillis()); // miliseconds
            put("app_user", "user123");
            put("amount", 50000);
            put("description", "Lazada - Payment for the order #"+random_id);
            put("bank_code", "zalopayapp");
            put("item", new JSONObject(item).toString());
            put("embed_data", new JSONObject(embed_data).toString());
        }};

        // app_id +”|”+ app_trans_id +”|”+ appuser +”|”+ amount +"|" + app_time +”|”+ embed_data +"|" +item
        String data = order.get("app_id") +"|"+ order.get("app_trans_id") +"|"+ order.get("app_user") +"|"+ order.get("amount")
                +"|"+ order.get("app_time") +"|"+ order.get("embed_data") +"|"+ order.get("item");
        order.put("mac", HMACUtil.HMacHexStringEncode(HMACUtil.HMACSHA256, config.get("key1"), data));

        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost post = new HttpPost(config.get("endpoint"));

        List<NameValuePair> params = new ArrayList<>();
        for (Map.Entry<String, Object> e : order.entrySet()) {
            params.add(new BasicNameValuePair(e.getKey(), e.getValue().toString()));
        }

        // Content-Type: application/x-www-form-urlencoded
        post.setEntity(new UrlEncodedFormEntity(params));

        CloseableHttpResponse res = client.execute(post);
        BufferedReader rd = new BufferedReader(new InputStreamReader(res.getEntity().getContent()));
        StringBuilder resultJsonStr = new StringBuilder();
        String line;

        while ((line = rd.readLine()) != null) {
            resultJsonStr.append(line);
        }

        JSONObject result = new JSONObject(resultJsonStr.toString());
        for (String key : result.keySet()) {
            System.out.format("%s = %s\n", key, result.get(key));
        }
    }
}
// go version go1.11.1 linux/amd64
package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
    "strconv"
    "time"
    "math/rand"

    "github.com/zpmep/hmacutil" // go get github.com/zpmep/hmacutil
)

type object map[string]interface{}

var (
    app_id = "2553"
    key1  = "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL"
    key2  = "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz"
)

func main() {
    rand.Seed(time.Now().UnixNano())
    transID := rand.Intn(1000000) // Generate random trans id
    embedData, _ := json.Marshal(object{})
    items, _ := json.Marshal([]object{})
    // request data
    params := make(url.Values)
    params.Add("app_id", app_id)                            
    params.Add("amount", "1000")                          
    params.Add("app_user", "user123")                         
    params.Add("embed_data", string(embedData))            
    params.Add("item", string(items))                     
    params.Add("description", "Lazada - Payment for the order #"+strconv.Itoa(transID))
    params.Add("bank_code", "zalopayapp")                  

    now := time.Now()
    params.Add("app_time", strconv.FormatInt(now.UnixNano()/int64(time.Millisecond), 10)) // miliseconds

    params.Add("app_trans_id", fmt.Sprintf("%02d%02d%02d_%v", now.Year()%100, int(now.Month()), now.Day(), transID)) // translation missing: en.docs.shared.sample_code.comments.app_trans_id

    // appid|app_trans_id|appuser|amount|apptime|embeddata|item
    data := fmt.Sprintf("%v|%v|%v|%v|%v|%v|%v", params.Get("app_id"), params.Get("app_trans_id"), params.Get("app_user"),
        params.Get("amount"), params.Get("app_time"), params.Get("embed_data"), params.Get("item"))
    params.Add("mac", hmacutil.HexStringEncode(hmacutil.SHA256, key1, data))

    // Content-Type: application/x-www-form-urlencoded
    res, err := http.PostForm("https://sb-openapi.zalopay.vn/v2/create", params)

    // parse response
    if err != nil {
        log.Fatal(err)
    }
    defer res.Body.Close()

    body, _ := ioutil.ReadAll(res.Body)

    var result map[string]interface{}

    if err := json.Unmarshal(body, &result); err != nil {
        log.Fatal(err)
    }

    for k, v := range result {
        log.Printf("%s = %+v", k, v)
    }
}
// Node v10.15.3
const axios = require('axios').default; // npm install axios
const CryptoJS = require('crypto-js'); // npm install crypto-js
const moment = require('moment'); // npm install moment

// APP INFO
const config = {
    app_id: "2553",
    key1: "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
    key2: "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz",
    endpoint: "https://sb-openapi.zalopay.vn/v2/create"
};

const embed_data = {};

const items = [{}];
const transID = Math.floor(Math.random() * 1000000);
const order = {
    app_id: config.app_id,
    app_trans_id: `${moment().format('YYMMDD')}_${transID}`, // translation missing: en.docs.shared.sample_code.comments.app_trans_id
    app_user: "user123",
    app_time: Date.now(), // miliseconds
    item: JSON.stringify(items),
    embed_data: JSON.stringify(embed_data),
    amount: 50000,
    description: `Lazada - Payment for the order #${transID}`,
    bank_code: "zalopayapp",
};

// appid|app_trans_id|appuser|amount|apptime|embeddata|item
const data = config.app_id + "|" + order.app_trans_id + "|" + order.app_user + "|" + order.amount + "|" + order.app_time + "|" + order.embed_data + "|" + order.item;
order.mac = CryptoJS.HmacSHA256(data, config.key1).toString();

axios.post(config.endpoint, null, { params: order })
    .then(res => {
        console.log(res.data);
    })
    .catch(err => console.log(err));
<?php
// PHP Version 7.3.3

$config = [
    "app_id" => 2553,
    "key1" => "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
    "key2" => "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz",
    "endpoint" => "https://sb-openapi.zalopay.vn/v2/create"
];

$embeddata = '{}'; // Merchant's data
$items = '[]'; // Merchant's data
$transID = rand(0,1000000); //Random trans id
$order = [
    "app_id" => $config["app_id"],
    "app_time" => round(microtime(true) * 1000), // miliseconds
    "app_trans_id" => date("ymd") . "_" . $transID, // translation missing: en.docs.shared.sample_code.comments.app_trans_id
    "app_user" => "user123",
    "item" => $items,
    "embed_data" => $embeddata,
    "amount" => 50000,
    "description" => "Lazada - Payment for the order #$transID",
    "bank_code" => "zalopayapp"
];

// appid|app_trans_id|appuser|amount|apptime|embeddata|item
$data = $order["app_id"] . "|" . $order["app_trans_id"] . "|" . $order["app_user"] . "|" . $order["amount"]
    . "|" . $order["app_time"] . "|" . $order["embed_data"] . "|" . $order["item"];
$order["mac"] = hash_hmac("sha256", $data, $config["key1"]);

$context = stream_context_create([
    "http" => [
        "header" => "Content-type: application/x-www-form-urlencoded\r\n",
        "method" => "POST",
        "content" => http_build_query($order)
    ]
]);

$resp = file_get_contents($config["endpoint"], false, $context);
$result = json_decode($resp, true);

foreach ($result as $key => $value) {
    echo "$key: $value<br>";
}
# ruby 2.5.1p57

require 'json'
require 'openssl' # gem install openssl
require 'net/http'

config = {
  app_id: '2553',
  key1: 'PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL',
  key2: 'kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz',
  endpoint: 'https://sb-openapi.zalopay.vn/v2/create'
}

trans_id = rand(1000000).to_s #Random trans id
apptime = (Time.now.to_f.round(3) * 1000).to_i # miliseconds
app_trans_id = Time.now.strftime('%y%m%d') + '_' + trans_id

embeddata = {}
items = [{}]

order = {
  app_id: config[:app_id],
  app_trans_id: app_trans_id, # translation missing: en.docs.shared.sample_code.comments.app_trans_id
  app_user: 'user123',
  app_time: apptime, # miliseconds 
  item: items.to_json, 
  embed_data: embeddata.to_json, 
  amount: 50_000, 
  description: "Lazada - Payment for the order ##{trans_id}", 
  bank_code: 'zalopayapp'
}

# appid|app_trans_id|appuser|amount|app_time|embed_data|item
data = config[:app_id] + '|' + app_trans_id + '|' + order[:app_user] + '|' + order[:amount].to_s + '|' +
       order[:app_time].to_s + '|' + order[:embed_data].to_s + '|' + order[:item].to_s

order[:mac] = OpenSSL::HMAC.hexdigest('sha256', config[:key1], data)

res = Net::HTTP.post_form(URI.parse(config[:endpoint]), order)
result = JSON.parse(res.body)

result.each do |key, value|
  puts "#{key}: #{value}"
end
# coding=utf-8
# Python 3.6

from time import time
from datetime import datetime
import json, hmac, hashlib, urllib.request, urllib.parse, random

config = {
  "app_id": 2553,
  "key1": "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
  "key2": "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz",
  "endpoint": "https://sb-openapi.zalopay.vn/v2/create"
}
transID = random.randrange(1000000)
print(random.randrange(1000000))
order = {
  "app_id": config["app_id"],
  "app_trans_id": "{:%y%m%d}_{}".format(datetime.today(), transID), # the trading code must be in the format yymmdd_xxxx
  "app_user": "user123",
  "app_time": int(round(time() * 1000)), # miliseconds
  "embed_data": json.dumps({}),
  "item": json.dumps([{}]),
  "amount": 50000,
  "description": "Lazada - Payment for the order #"+str(transID),
  "bank_code": "zalopayapp"
}

# app_id|app_trans_id|app_user|amount|apptime|embed_data|item
data = "{}|{}|{}|{}|{}|{}|{}".format(order["app_id"], order["app_trans_id"], order["app_user"], 
order["amount"], order["app_time"], order["embed_data"], order["item"])

order["mac"] = hmac.new(config['key1'].encode(), data.encode(), hashlib.sha256).hexdigest()

response = urllib.request.urlopen(url=config["endpoint"], data=urllib.parse.urlencode(order).encode())
result = json.loads(response.read())

for k, v in result.items():
  print("{}: {}".format(k, v))
curl -X POST https://sb-openapi.zalopay.vn/v2/create \
  -H "Content-type: application/x-www-form-urlencoded" \
  -d app_id=2553 \
  -d app_trans_id=200904_432565 \
  -d app_user='user123' \
  -d app_time=1599209942052 \
  -d item='[{}]' \
  -d embed_data='{}' \
  -d amount=50000 \
  -d description='Lazada - Payment for the order #432565' \
  -d bank_code=zalopayapp \
  -d mac=a921656413d6ef62d8d7fdab012f69be45335ebb158aeb483897b1b60acc80c2

Chú ý:
Thông tin đơn hàng trùng lắp

Khi merchant sử dụng API tạo đơn hàng để gửi thông tin một đơn hàng qua hệ thống ZaloPay, giá trị tham số app_trans_id phải là unique. Nếu giá trị app_trans_id bị trùng lắp, ZaloPay sẽ trả về sub_return_code=-68.

{
    "return_code": 2,
    "return_message": "Giao dịch thất bại",
    "sub_return_code": -68,
    "sub_return_message": "Mã giao dịch bị trùng",
    "zp_trans_token": "",
    "order_url": "",
    "order_token": ""
}

Callback

Merchant Server receives payment's results from ZaloPay Server, only when ZaloPay has received money from user successfully

Processing flow

Callback Flow

API specification

If ZaloPay successfully get money from user, then ZaloPay Server will notify to MerchantServer via CallbackURL which had been registered with ZaloPay or from callback_url. MerchantServer use key2 (provided by ZaloPay) to validate callback's data. Merchant can check callback log in Sandbox environment at Dev Tool on Merchant Site

Callback data:

Name DataType Description
data Json String ZaloPay transaction data callback to the application
mac String Confirmation of order information, using Callback Key (Key2) (had been provided) to verify the order
type Int Callback type

1: Order

2: Agreement

Data field:

Name
DataType Description Example
app_id Int Order's app_id 5
app_trans_id String Order's app_trans_id 180208181007242
app_time Long Order's app_time 1460543835849
app_user String Order's app_user pmqc
amount Long Amount received (VND) 50000
embed_data JSON String Order's embed_data
• Required json string
{"promotioninfo":"","merchantinfo":"du lieu rieng cua ung dung"}

Data empty: {}
item JSON Array String Order's item
• Required json array string
[{"itemid":"knb","itename":"kim nguyen bao","itemprice":198400,"itemquantity":1}]

Data empty: []
zp_trans_id Long ZaloPay's Transaction code 160413000003083
server_time Long ZaloPay's Transaction trading time (unix timestamp in milliseconds)' 1460543836370
channel Int Payment channel 38
merchant_user_id String ZaloPay user, who paid for the order 7ZMSl3nEg5sOUJzOLSoUFT8xKNQVaLOLXHB--8Eytqc
user_fee_amount Long Fee (VND) 220
discount_amount Long Discount (VND) 10000

Example:

{"data":"{\"app_id\":2553,\"app_trans_id\":\"200904_2553_1598435687208\",\"app_time\":1599189392817,\"app_user\":\"demo\",\"amount\":10000,\"embed_data\":\"{\\\"merchantinfo\\\":\\\"embeddata123\\\",\\\"promotioninfo\\\":\\\"\\\"}\",\"item\":\"[{\\\"itemid\\\":\\\"knb\\\",\\\"itemname\\\":\\\"kim nguyen bao\\\",\\\"itemprice\\\":198400,\\\"itemquantity\\\":1}]\",\"zp_trans_id\":200904000000389,\"server_time\":1599189413498,\"channel\":38,\"merchant_user_id\":\"7ZMSl3nEg5sOUJzOLSoUFT8xKNQVaLOLXHB--8Eytqc\",\"user_fee_amount\":0,\"discount_amount\":0}","mac":"d8d33baf449b31d7f9b94fa50d7c942c08cd4d83f28fa185557da21acb104f67","type":1}

Check if callback is valid

reqmac = HMAC(hmac_algorithm, key2, callback_data.data)
if (reqmac == callback_data.mac) {
  // valid callback
} else {
  // invalid callback
} 

With:

Supported payment channels:

Value Payment channel
36 Visa/Master/JCB
37 Bank Account
38 ZaloPay Wallet
39 ATM
41 Visa/Master Debit

The data that AppServer returns to ZaloPayServer after got the callback

Parameter Datatype Description
return_code Int

1: Success

2: ZaloPay zptransid or apptransid is duplicated

<>: failure (not callback again)

return_message String Details of the status code

Example:

{
  "return_code": "[return_code]",
  "return_message": "[return_message]"
}

Sample code

/**
 * .Net core 2.1.505
 */
using System;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using ZaloPay.Helper; // HmacHelper, RSAHelper, HttpHelper, Utils (download at DOWNLOADS page)
using ZaloPay.Helper.Crypto;
using Newtonsoft.Json; // https://www.newtonsoft.com/json

namespace ZaloPayExample.Controllers
{
    [Route("[controller]")]
    [ApiController]
    public class CallbackController: ControllerBase
    {
        private string key2 = "eG4r0GcoNtRGbO8";

        [HttpPost]
        public IActionResult Post([FromBody] dynamic cbdata)
        {
            var result = new Dictionary<string, object>();

            try {
              var dataStr = Convert.ToString(cbdata["data"]);
              var reqMac = Convert.ToString(cbdata["mac"]);

              var mac = HmacHelper.Compute(ZaloPayHMAC.HMACSHA256, key2, dataStr);

              Console.WriteLine("mac = {0}", mac);

              // check if the callback is valid (from ZaloPay server)
              if (!reqMac.Equals(mac)) {
                  // callback is invalid
                  result["return_code"] = -1;
                  result["return_message"] = "mac not equal";
              }
              else {
                  // payment success
                  // merchant update status for order's status
                  var dataJson = JsonConvert.DeserializeObject<Dictionary<string, object>>(dataStr);
                  Console.WriteLine("update order's status = success where app_trans_id = {0}", dataJson["app_trans_id"]);

                  result["return_code"] = 1;
                  result["return_message"] = "success";
              }
            } catch (Exception ex) {
              result["return_code"] = 0; // callback again (up to 3 times)
              result["return_message"] = ex.Message;
            }

            // returns the result for ZaloPay server
            return Ok(result); 
        }
    }
}
/**
 * Spring Boot v2.1.4.RELEASE
 * */
import org.json.JSONObject; // https://mvnrepository.com/artifact/org.json/json
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.util.logging.Logger;

@RestController
public class CallbackController {

    private Logger logger = Logger.getLogger(this.getClass().getName());
    private String key2 = "eG4r0GcoNtRGbO8";
    private Mac HmacSHA256;

    public CallbackController() throws Exception  {
        HmacSHA256 = Mac.getInstance("HmacSHA256");
        HmacSHA256.init(new SecretKeySpec(key2.getBytes(), "HmacSHA256"));
    }

    @PostMapping("/callback")
    public String callback(@RequestBody String jsonStr) {
        JSONObject result = new JSONObject();

        try {
          JSONObject cbdata = new JSONObject(jsonStr);
          String dataStr = cbdata.getString("data");
          String reqMac = cbdata.getString("mac");

          byte[] hashBytes = HmacSHA256.doFinal(dataStr.getBytes());
          String mac = DatatypeConverter.printHexBinary(hashBytes).toLowerCase();

          // check if the callback is valid (from ZaloPay server)
          if (!reqMac.equals(mac)) {
              // callback is invalid
              result.put("return_code", -1);
              result.put("return_message", "mac not equal");
          } else {
              // payment success
              // merchant update status for order's status
              JSONObject data = new JSONObject(dataStr);
              logger.info("update order's status = success where app_trans_id = " + data.getString("app_trans_id"));

              result.put("return_code", 1);
              result.put("return_message", "success");
          }
        } catch (Exception ex) {
          result.put("return_code", 0); // callback again (up to 3 times)
          result.put("return_message", ex.getMessage());
        }

        // returns the result for ZaloPay server
        return result.toString();
    }
}
// go version go1.11.1 linux/amd64
package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"

    "github.com/zpmep/hmacutil" // go get github.com/zpmep/hmacutil
)

// App config
var (
    key2 = "eG4r0GcoNtRGbO8"
)

func main() {
    mux := http.DefaultServeMux
    mux.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {
        defer r.Body.Close()
        var cbdata map[string]interface{}
        decoder := json.NewDecoder(r.Body)
        decoder.Decode(&cbdata)

        requestMac := cbdata["mac"].(string)
        dataStr := cbdata["data"].(string)
        mac := hmacutil.HexStringEncode(hmacutil.SHA256, key2, dataStr)
        log.Println("mac =", mac)

        result := make(map[string]interface{})

    // check if the callback is valid (from ZaloPay server)
        if mac != requestMac {
            // callback is invalid
            result["return_code"] = -1
            result["return_message"] = "mac not equal"
        } else {
            // payment success
            result["return_code"] = 1
            result["return_message"] = "success"

            // merchant update status for order's status
            var dataJSON map[string]interface{}
            json.Unmarshal([]byte(dataStr), &dataJSON)
            log.Println("update order's status = success where app_trans_id =", dataJSON["app_trans_id"])
        }

        // returns the result for ZaloPay server
        resultJSON, _ := json.Marshal(result)
        fmt.Fprintf(w, "%s", resultJSON)
    })

    log.Println("Server is listening at port :8888")
    http.ListenAndServe(":8888", mux)
}
// Node v10.15.3
const CryptoJS = require('crypto-js'); // npm install crypto-js
const express = require('express'); // npm install express
const bodyParser = require('body-parser'); // npm install body-parser
const app = express();

const config = {
  key2: "eG4r0GcoNtRGbO8"
};

app.use(bodyParser.json());

app.post('/callback', (req, res) => {
  let result = {};

  try {
    let dataStr = req.body.data;
    let reqMac = req.body.mac;

    let mac = CryptoJS.HmacSHA256(dataStr, config.key2).toString();
    console.log("mac =", mac);


    // check if the callback is valid (from ZaloPay server)
    if (reqMac !== mac) {
      // callback is invalid
      result.return_code = -1;
      result.return_message = "mac not equal";
    }
    else {
      // payment success
      // merchant update status for order's status
      let dataJson = JSON.parse(dataStr, config.key2);
      console.log("update order's status = success where app_trans_id =", dataJson["app_trans_id"]);

      result.return_code = 1;
      result.return_message = "success";
    }
  } catch (ex) {
    result.return_code = 0; // callback again (up to 3 times)
    result.return_message = ex.message;
  }

  // returns the result for ZaloPay server
  res.json(result);
});

app.listen(8888, function (){
  console.log('Server is listening at port :8888');
});
<?php

// PHP Version 7.3.3

$result = [];

try {
  $key2 = "eG4r0GcoNtRGbO8";
  $postdata = file_get_contents('php://input');
  $postdatajson = json_decode($postdata, true);
  $mac = hash_hmac("sha256", $postdatajson["data"], $key2);

  $requestmac = $postdatajson["mac"];

  // check if the callback is valid (from ZaloPay server)
  if (strcmp($mac, $requestmac) != 0) {
    // callback is invalid
    $result["return_code"] = -1;
    $result["return_message"] = "mac not equal";
  } else {
    // payment success
    // merchant update status for order's status
    $datajson = json_decode($postdatajson["data"], true);
    // echo "update order's status = success where app_trans_id = ". $dataJson["app_trans_id"];

    $result["return_code"] = 1;
    $result["return_message"] = "success";
  }
} catch (Exception $e) {
  $result["return_code"] = 0; // callback again (up to 3 times)
  $result["return_message"] = $e->getMessage();
}

// returns the result for ZaloPay server
echo json_encode($result);
# ruby 2.5.1p57
# rails 5.2.3

# config/routes.rb
Rails.application.routes.draw do
  match '/callback' => 'callback#handle', via: :post
end

# app/controllers/callback_controller.rb
require 'json'
require 'openssl' # gem install openssl

class CallbackController < ApplicationController 
  def initialize
    super
    @config = {
      key2: 'eG4r0GcoNtRGbO8'
    }
  end

  # POST /callback
  def handle
    result = {}

    begin
      cbdata = params
      mac = OpenSSL::HMAC.hexdigest('sha256', @config[:key2], cbdata['data'])

      # check if the callback is valid (from ZaloPay server)
      if cbdata['mac'] != mac
        # callback is invalid
        result[:return_code] = -1
        result[:return_message] = "mac not equal"
      else
        # payment success
        # merchant update status for order's status
        dataJson = JSON.parse(cbdata['data'])
        puts "update order's status = success where app_trans_id = " + dataJson['app_trans_id']

        result[:return_code] = 1
        result[:return_message] = "success"
      end
    rescue Exception => ex
      result[:return_code] = 0 # callback again (up to 3 times)
      result[:return_message] = ex.message
    end

    # returns the result for ZaloPay server
    render json: result, status: :ok
  end
end
# coding=utf-8
# Python 3.6

from flask import Flask, request, json # pip3 install Flask 
import hmac, hashlib

app = Flask(__name__)
config = {
  'key2': 'eG4r0GcoNtRGbO8'
}

@app.route('/callback', methods=['POST'])
def callback():
  result = {}

  try
    cbdata = request.json
    mac = hmac.new(config['key2'].encode(), cbdata['data'].encode(), hashlib.sha256).hexdigest()

    # check if the callback is valid (from ZaloPay server)
    if mac != cbdata['mac']:
      # callback is invalid
      result['return_code'] = -1
      result['return_message'] = 'mac not equal'
    else:
      # payment success
      # merchant update status for order's status
      dataJson = json.loads(cbdata['data'])
      print("update order's status = success where app_trans_id = " + dataJson['app_trans_id'])

      result['return_code'] = 1
      result['return_message'] = 'success'
  except Exception as e
    result['return_code'] = 0 # callback again (up to 3 times)
    result[' e'] = str(e)

  # returns the result for ZaloPay server
  return json.jsonify(result)

Get order's status

When the payment is successful, ZaloPay will call the callback (notify) to the Merchant, then the Merchant updates the status of Successful orders on the Merchant's system. But in reality, the callback may be missed due to Network timeout, Merchant Service unavailable Internal error,... so Merchant needs to make the call of the API to query the order status.

App Server send request to ZaloPay Server to get the transaction's payment status.

Processing flow

Get status flow

API specification

Environment Method Endpoint
Sandbox POST https://sb-openapi.zalopay.vn/v2/query
Real POST https://openapi.zalopay.vn/v2/query

Content-Type:

application/x-www-form-urlencoded

application/json

application/xml

Request data

Parameter
Datatype Required Description
app_id Int Order's app_id
app_trans_id String Order's app_trans_id
mac String • Authenticate data information'
= HMAC(hmac_algorithm, key1, app_id+"|"+app_trans_id+"|"+key1)

Response data

Parameter Datatype Description
return_code Int 1 : SUCCESS
2 : FAIL
3 : PROCESSING
return_message String Order's status information
sub_return_code Int Detail transaction code
sub_return_message String Detail description of the order transaction
is_processing Boolean Process's status
amount Long Amount received (only make sense when the payment is successful)
discount_amount Long Discount amount
zp_trans_id Long ZaloPay's transaction code

Sample code

/**
 * .Net core 2.1.505
 */
using System;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
using ZaloPay.Helper; // HmacHelper, RSAHelper, HttpHelper, Utils (download at DOWNLOADS page)
using ZaloPay.Helper.Crypto;
using Newtonsoft.Json; // https://www.newtonsoft.com/json

namespace ZaloPayExample
{
    class Program
    {
        static string appid = "2553";
        static string key1 = "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL";
        static string query_order_url = "https://sb-openapi.zalopay.vn/v2/query";

        static async Task Main(string[] args)
        {
            var app_trans_id = "<app_trans_id>";  // Input your app_trans_id

            var param = new Dictionary<string, string>();
            param.Add("app_id", appid);
            param.Add("app_trans_id", app_trans_id);
            var data = appid + "|" + app_trans_id + "|" + key1; 

            param.Add("mac", HmacHelper.Compute(ZaloPayHMAC.HMACSHA256, key1, data));

            var result = await HttpHelper.PostFormAsync(query_order_url, param);

            foreach(var entry in result) {
                Console.WriteLine("{0} = {1}", entry.Key, entry.Value);
            }
        }
    }
}
// Java version "1.8.0_201"

import org.apache.http.NameValuePair; // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject; // https://mvnrepository.com/artifact/org.json/json

import vn.zalopay.crypto.HMACUtil; // download at DOWNLOADS page

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

public class GetOrderStatus {
    private static final Map<String, String> config = new HashMap<String, String>(){{
        put("app_id", "2553");
        put("key1", "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL");
        put("key2", "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz");
        put("endpoint", "https://sb-openapi.zalopay.vn/v2/query");
    }};

    public static void main(String[] args) throws Exception {
      String app_trans_id = "210608_2553_1623145380738";  // Input your app_trans_id
      String data = config.get("app_id") +"|"+ app_trans_id  +"|"+ config.get("key1"); // appid|app_trans_id|key1
      String mac = HMACUtil.HMacHexStringEncode(HMACUtil.HMACSHA256, config.get("key1"), data);

      List<NameValuePair> params = new ArrayList<>();
      params.add(new BasicNameValuePair("app_id", config.get("app_id")));
      params.add(new BasicNameValuePair("app_trans_id", app_trans_id));
      params.add(new BasicNameValuePair("mac", mac));

      URIBuilder uri = new URIBuilder(config.get("endpoint"));
      uri.addParameters(params);

      CloseableHttpClient client = HttpClients.createDefault();
      HttpPost post = new HttpPost(uri.build());
      post.setEntity(new UrlEncodedFormEntity(params));

      CloseableHttpResponse res = client.execute(post);
      BufferedReader rd = new BufferedReader(new InputStreamReader(res.getEntity().getContent()));
      StringBuilder resultJsonStr = new StringBuilder();
      String line;

      while ((line = rd.readLine()) != null) {
        resultJsonStr.append(line);
      }

      JSONObject result = new JSONObject(resultJsonStr.toString());
      for (String key : result.keySet()) {
        System.out.format("%s = %s\n", key, result.get(key));
      }
    }
}
// go version go1.11.1 linux/amd64
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"

    "github.com/zpmep/hmacutil" // go get github.com/zpmep/hmacutil
)

var (
    appID      = 2553
    key1       = "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL"
    key2       = "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz"
    appTransID = "<app_trans_id>" // Input your app trans id
)

func main() {
    data := fmt.Sprintf("%v|%s|%s", appID, appTransID, key1) // appid|apptransid|key1
    params := map[string]interface{}{
        "app_id":       appID,
        "app_trans_id": appTransID,
        "mac":          hmacutil.HexStringEncode(hmacutil.SHA256, key1, data),
    }

    jsonStr, err := json.Marshal(params)
    if err != nil {
        log.Fatal(err)
    }

    res, err := http.Post("https://sb-openapi.zalopay.vn/v2/query", "application/json", bytes.NewBuffer(jsonStr))

    if err != nil {
        log.Fatal(err)
    }
    defer res.Body.Close()

    body, _ := ioutil.ReadAll(res.Body)

    var result map[string]interface{}

    if err := json.Unmarshal(body, &result); err != nil {
        log.Fatal(err)
    }

    for k, v := range result {
        log.Printf("%s = %+v", k, v)
    }
}
// Node v10.15.3
const axios = require('axios').default; // npm install axios
const CryptoJS = require('crypto-js'); // npm install crypto-js
const qs = require('qs')

const config = {
    app_id: "2553",
    key1: "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
    key2: "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz",
    endpoint: "https://sb-openapi.zalopay.vn/v2/query"
};

let postData = {
    app_id: config.app_id,
    app_trans_id: "<app_trans_id>", // Input your app_trans_id
}

let data = postData.app_id + "|" + postData.app_trans_id + "|" + config.key1; // appid|app_trans_id|key1
postData.mac = CryptoJS.HmacSHA256(data, config.key1).toString();


let postConfig = {
    method: 'post',
    url: config.endpoint,
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    data: qs.stringify(postData)
};

axios(postConfig)
    .then(function (response) {
        console.log(JSON.stringify(response.data));
    })
    .catch(function (error) {
        console.log(error);
    });
<?php

// PHP Version 7.3.3

$config = [
  "app_id" => 2553,
  "key1" => "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
  "key2" => "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz",
  "endpoint" => "https://sb-openapi.zalopay.vn/v2/query"
];

$app_trans_id = "<app_trans_id>";  // Input your app_trans_id
$data = $config["app_id"]."|".$app_trans_id."|".$config["key1"]; // app_id|app_trans_id|key1
$params = [
  "app_id" => $config["app_id"],
  "app_trans_id" => $app_trans_id,
  "mac" => hash_hmac("sha256", $data, $config["key1"])
];

$context = stream_context_create([
    "http" => [
        "header" => "Content-type: application/x-www-form-urlencoded\r\n",
        "method" => "POST",
        "content" => http_build_query($params)
    ]
]);

$resp = file_get_contents($config["endpoint"], false, $context);
$result = json_decode($resp, true);

foreach ($result as $key => $value) {
  echo "$key: $value<br>";
}
# ruby 2.5.1p57

require 'json'
require 'openssl' # gem install openssl
require 'net/http'

config = {
  app_id: '2553',
  key1: 'PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL',
  key2: 'kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz',
  endpoint: 'https://sb-openapi.zalopay.vn/v2/query'
}

params = {
  app_id: config[:app_id],
  app_trans_id: "<app_trans_id>",  # Input your app_trans_id
}

data = config[:app_id] +"|"+ params[:app_trans_id] +"|"+ config[:key1] # app_id|app_trans_id|key1
params[:mac] = OpenSSL::HMAC.hexdigest('sha256', config[:key1], data)

res = Net::HTTP.post_form(URI.parse(config[:endpoint]), params)
result = JSON.parse(res.body)

result.each do |key, value|
  puts "#{key}: #{value}"
end
# coding=utf-8
# Python 3.6

from time import time
import hmac, hashlib, urllib.parse, urllib.request

config = {
  "app_id": 2553,
  "key1": "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
  "key2": "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz",
  "endpoint": "https://sb-openapi.zalopay.vn/v2/query"
}

params = {
  "app_id": config["app_id"],
  "app_trans_id": "<app_trans_id>"  # Input your app_trans_id"
}

data = "{}|{}|{}".format(config["app_id"], params["app_trans_id"], config["key1"]) # app_id|app_trans_id|key1
params["mac"] = hmac.new(config['key1'].encode(), data.encode(), hashlib.sha256).hexdigest()

response = urllib.request.urlopen(url=config["endpoint"], data=urllib.parse.urlencode(params).encode())
result = json.loads(response.read())

for k, v in result.items():
  print("{}: {}".format(k, v))
curl https://sb-openapi.zalopay.vn/v2/query \
  -d app_id=2553 \
  -d app_trans_id=190419_123456 \
  -d mac=440f389ddd834b40f21f9baed9448b530b6d7a9af722d747f3fa0af68c007c2e # app_id|app_trans_id|key1

Refund

API allows to refund all or a part of the transaction's amount that has been successfully paid via ZaloPay.

Refund rules

PAYMENT METHOD WALLET REFUND TO REFUND TIME SUPPORTED BANKS
ZaloPay App ZaloPay Walet ZaloPay Walet Immediately Vietcombank, Vietinbank, BIDV, Sacombank, Eximbank, SCB, Viet Capital Bank, JCB
ATM / Bank Account ZaloPay Walet Immediately
Visa / Master / JCB Card 5 - 7 working days
Card payment / Bank Account via ZaloPay Gateway ATM / Bank Account Bank Account 3 - 5 working days (depend on the bank) ABBank, ACB, Agribank, Bac A Bank, Bao Viet Bank, BIDV, DongA Bank, Eximbank, GP Bank, HD Bank, Lien Viet Post Bank, Maritime Bank, MB Bank, NamA Bank, NCB, Viet Capital Bank, OCB, Ocean Bank, PG Bank, Sacombank, Saigon Bank, SCB, SeA Bank, SHB, Techcombank, TP Bank, VIB
Visa / Master / JCB Card 5 - 7 working days (depend on the bank)

Processing flow

Refund flow

API specification

Environment Method Endpoint
Sandbox POST https://sb-openapi.zalopay.vn/v2/refund
Real POST https://openapi.zalopay.vn/v2/refund

application/x-www-form-urlencoded

application/json

application/xml

Request data

Parameter
Datatype Length Required Description
m_refund_id String 45 • Merchant must be generate merchant own transaction code when submit refund requirement.
• Format: yymmdd_appid_xxxxxxxxxx
app_id Int Merchant app_id, which was provided by ZaloPay when registering.
zp_trans_id String 15 • Transaction code, which want to be refund.
• Transaction code of ZaloPay, retrieved from callback data
amount Long Refund amount for users
refund_fee_amount Long The fee of the refund transaction, which will be deducted from the amount that the buyer receives back from the refund transaction. Can be safely omitted in the request if you do not need this feature.
timestamp Long 13 • Time to refund (unix timestamp in millisecond).
• The time of making the refund, is calculated in milliseconds
mac String Authenticate information (See how to create authenticate information)
description String 100 Refund reason

Create authentication information

mac = HMAC(hmac_algorithm, key1, hmac_input)

With:

Response data

Parameter Datatype Description
return_code Int 1 : Successful refund
2 : Refund failure, need to redo
3 : Refunding processing, call getRefundStatus API to get final result
return_message String Status code information
sub_return_code Int
sub_return_message String Detail of status code
refund_id Long ZaloPay refund's transaction code, need to save for cross-check then

Sample code

/**
 * .Net core 2.1.505
 */
using System;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
using ZaloPay.Helper; // HmacHelper, RSAHelper, HttpHelper, Utils (download at DOWNLOADS page)
using ZaloPay.Helper.Crypto;
using Newtonsoft.Json; // https://www.newtonsoft.com/json

namespace ZaloPayExample
{
    class Program
    {
        static string app_id = "2553";
        static string key1 = "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL";
        static string refund_url = "https://sb-openapi.zalopay.vn/v2/refund";

        static async Task Main(string[] args)
        {
            var timestamp = Utils.GetTimeStamp().ToString();
            var rand = new Random();
            var uid = timestamp+""+rand.Next(111, 999).ToString(); 

            Dictionary<string, string> param = new Dictionary<string, string>();
            param.Add("app_id", app_id);
            param.Add("m_refund_id", DateTime.Now.ToString("yyMMdd") + "_" + app_id + "_" + uid); 
            param.Add("zp_trans_id", "1234567");
            param.Add("amount", "1000");
            param.Add("timestamp", timestamp);
            param.Add("description", "demo");

            var data = app_id + "|" + param["zp_trans_id"] + "|" + param["amount"] + "|" + param["description"] + "|" + param["timestamp"];
            param.Add("mac", HmacHelper.Compute(ZaloPayHMAC.HMACSHA256, key1, data));

            var result = await HttpHelper.PostFormAsync(refund_url, param);

            foreach(var entry in result) {
                Console.WriteLine("{0} = {1}", entry.Key, entry.Value);
            }
        }
    }
}
// Java version "1.8.0_201"
import org.apache.http.NameValuePair; // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject; // https://mvnrepository.com/artifact/org.json/json
import vn.zalopay.crypto.HMACUtil; // download at DOWNLOADS page

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Logger;

public class Refund {
    private static Logger logger = Logger.getLogger(App.class.getName());

    private static Map<String, String> config = new HashMap<String, String>(){{
        put("app_id", "2553");
        put("key1", "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL");
        put("key2", "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz");
        put("refund_url", "https://sb-openapi.zalopay.vn/v2/refund");
    }};

    private static String getCurrentTimeString(String format) {
        Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT+7"));
        SimpleDateFormat fmt = new SimpleDateFormat(format);
        fmt.setCalendar(cal);
        return fmt.format(cal.getTimeInMillis());
    }

    public static void main( String[] args ) throws Exception
    {
        String appid = config.get("appid");
        Random rand = new Random();
        long timestamp = System.currentTimeMillis(); // miliseconds
        String uid = timestamp + "" + (111 + rand.nextInt(888)); // unique id

        Map<String, Object> order = new HashMap<String, Object>(){{
            put("app_id", appid);
            put("zp_trans_id", 123456789);
            put("m_refund_id", getCurrentTimeString("yyMMdd") +"_"+ appid +"_"+uid);
            put("timestamp", timestamp);
            put("amount", 50000);
            put("description", "ZaloPay Intergration Demo");
        }};

        // appid|zptransid|amount|description|timestamp
        String data = order.get("app_id") +"|"+ order.get("zp_trans_id") +"|"+ order.get("amount")
                +"|"+ order.get("description") +"|"+ order.get("timestamp");
        order.put("mac", HMACUtil.HMacHexStringEncode(HMACUtil.HMACSHA256, config.get("key1"), data));

        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost post = new HttpPost(config.get("refund_url"));

        List<NameValuePair> params = new ArrayList<>();
        for (Map.Entry<String, Object> e : order.entrySet()) {
            params.add(new BasicNameValuePair(e.getKey(), e.getValue().toString()));
        }

        post.setEntity(new UrlEncodedFormEntity(params));

        CloseableHttpResponse res = client.execute(post);
        BufferedReader rd = new BufferedReader(new InputStreamReader(res.getEntity().getContent()));
        StringBuilder resultJsonStr = new StringBuilder();
        String line;

        while ((line = rd.readLine()) != null) {
            resultJsonStr.append(line);
        }

        JSONObject result = new JSONObject(resultJsonStr.toString());
        for (String key : result.keySet()) {
            System.out.format("%s = %s\n", key, result.get(key));
        }
    }
}
// go version go1.11.1 linux/amd64
package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
    "strconv"
    "time"

    "github.com/zpmep/hmacutil" // go get github.com/zpmep/hmacutil
)

var (
    appID = "2553"
    key1  = "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL"
    key2  = "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz"
)

func main() {
    params := make(url.Values)
    params.Add("app_id", appID)
    params.Add("zp_trans_id", "190508000000017")
    params.Add("amount", "50000")
    params.Add("description", "ZaloPay Refund Demo")

    now := time.Now()
    timestamp := now.UnixNano() / int64(time.Millisecond) // Miliseconds
    params.Add("timestamp", strconv.FormatInt(timestamp, 10))

  uid := fmt.Sprintf("%d%d", timestamp, 111+rand.Intn(888))

    params.Add("m_refund_id", fmt.Sprintf("%02d%02d%02d_%v_%v", now.Year()%100, int(now.Month()), now.Day(), appID, uid))

    // app_id|zp_trans_id|amount|description|timestamp
    data := fmt.Sprintf("%v|%v|%v|%v|%v", appID, params.Get("zp_trans_id"), params.Get("amount"), params.Get("description"), params.Get("timestamp"))
    params.Add("mac", hmacutil.HexStringEncode(hmacutil.SHA256, key1, data))

    log.Printf("%+v", params)

    // Content-Type: application/x-www-form-urlencoded
    res, err := http.PostForm("https://sb-openapi.zalopay.vn/v2/refund", params)

    if err != nil {
        log.Fatal(err)
    }
    defer res.Body.Close()

    body, _ := ioutil.ReadAll(res.Body)

    var result map[string]interface{}

    if err := json.Unmarshal(body, &result); err != nil {
        log.Fatal(err)
    }

    for k, v := range result {
        log.Printf("%s = %v", k, v)
    }
}
// Node v10.15.3
const axios = require('axios').default; // npm install axios
const CryptoJS = require('crypto-js'); // npm install crypto-js
const moment = require('moment'); // npm install moment

const config = {
  app_id: "2553",
  key1: "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
  key2: "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz",
  refund_url: "https://sb-openapi.zalopay.vn/v2/refund"
};

const timestamp = Date.now();
const uid = `${timestamp}${Math.floor(111 + Math.random() * 999)}`; // unique id

let params = {
  app_id: config.app_id,
  m_refund_id: `${moment().format('YYMMDD')}_${config.app_id}_${uid}`,
  timestamp, // miliseconds
  zp_trans_id: '190508000000022',
  amount: '50000',
  description: 'ZaloPay Refund Demo',
};

// app_id|zp_trans_id|amount|description|timestamp
let data = params.app_id + "|" + params.zp_trans_id + "|" + params.amount + "|" + params.description + "|" + params.timestamp;
params.mac = CryptoJS.HmacSHA256(data, config.key1).toString();

axios.post(config.refund_url, null, { params })
  .then(res => console.log(res.data))
  .catch(err => console.log(err));
<?php

// PHP Version 7.3.3

$config = [
  "app_id" => 2553,
  "key1" => "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
  "key2" => "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz",
  "refund_url" => "https://sb-openapi.zalopay.vn/v2/refund"
];

$timestamp = round(microtime(true) * 1000); // miliseconds
$uid = "$timestamp".rand(111,999); // unique id 

$params = [
  "app_id" => $config["app_id"],
  "m_refund_id" => date("ymd")."_".$config["app_id"]."_".$uid,
  "timestamp" => $timestamp,
  "zp_trans_id" => 123456789,
  "amount" => 50000,
  "description" => "ZaloPay Intergration Demo"
];

// app_id|zp_trans_id|amount|description|timestamp
$data = $params["app_id"]."|".$params["zp_trans_id"]."|".$params["amount"]
  ."|".$params["description"]."|".$params["timestamp"];
$params["mac"] = hash_hmac("sha256", $data, $config["key1"]);

$context = stream_context_create([
  "http" => [
    "header" => "Content-type: application/x-www-form-urlencoded\r\n",
    "method" => "POST",
    "content" => http_build_query($params)
  ]
]);

$resp = file_get_contents($config["refund_url"], false, $context);
$result = json_decode($resp, true);

foreach ($result as $key => $value) {
  echo "$key: $value<br>";
}
# ruby 2.5.1p57

require 'json'
require 'openssl'
require 'net/http'

config = {
  app_id: '2553',
  key1: 'PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL',
  key2: 'kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz',
  refund_url: 'https://sb-openapi.zalopay.vn/v2/refund'
}

app_id = config[:app_id]
timestamp = (Time.now.to_f.round(3) * 1000).to_i
uid = timestamp.to_s + '' + (111 + Random.rand(888)).to_s # unique id
m_refund_id = Time.now.strftime('%y%m%d') + '_' + app_id + '_' + uid

order = {
  app_id: app_id,
  zp_trans_id: "123456789",
  m_refund_id: m_refund_id,
  timestamp: timestamp,
  amount: 50_000,
  description: 'ZaloPay Integration Demo',
}

# app_id|zptransid|amount|description|timestamp
data = app_id + '|' + order[:zp_trans_id] + '|' + order[:amount].to_s + '|' + order[:description] + '|' + order[:timestamp].to_s

order[:mac] = OpenSSL::HMAC.hexdigest('sha256', config[:key1], data)

res = Net::HTTP.post_form(URI.parse(config[:refund_url]), order)
result = JSON.parse(res.body)

result.each do |key, value|
  puts "#{key}: #{value}"
end
# coding=utf-8
# Python 3.6

from time import time
from datetime import datetime
import random, json, hmac, hashlib, urllib.request, urllib.parse

config = {
  "app_id": 2553,
  "key1": "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
  "key2": "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz",
  "refund_url": "https://sb-openapi.zalopay.vn/v2/refund"
}

timestamp = int(round(time() * 1000)) # miliseconds
uid =  "{}{}".format(timestamp, random.randint(111, 999)) # unique id

order = {
  "app_id": config["app_id"],
  "m_refund_id": "{:%y%m%d}_{}_{}".format(datetime.today(), config["app_id"], uid),
  "timestamp": timestamp,
  "zp_trans_id": 123456789,
  "amount": 1000,
  "description": "ZaloPay Integration Demo",
}

# appid|zptransid|amount|description|timestamp
data = "{}|{}|{}|{}|{}".format(order["m_refund_id"], order["zp_trans_id"], order["amount"], order["description"], order["timestamp"])
order["mac"] = hmac.new(config['key1'].encode(), data.encode(), hashlib.sha256).hexdigest()

response = urllib.request.urlopen(url=config["refund_url"], data=urllib.parse.urlencode(order).encode())
result = json.loads(response.read())

for k, v in result.items():
  print("{}: {}".format(k, v))
curl -X POST https://sandbox.zalopay.com.vn/v001/tpe/partialrefund \
  -H "Content-type: application/x-www-form-urlencoded" \
  -d app_id=2553 \
  -d m_refund_id=190419_2553_352a73a0-6249-11e9-b146-9306e752a45c \
  -d timestamp=1555640217561 \
  -d zp_trans_id=1234567 \
  -d amount=1000 \
  -d description='ZaloPay Integration Demo' \
  -d mac=5d826b55da6b97525d3eb80a7484922300ae5e2be7d51a35be8e34763a899d73

Get refund's status

API is agree merchant to query the refund status of the Refund transaction.

Processing flow

Get refund status flow

API specification

Environment Method Endpoint
Sandbox POST https://sb-openapi.zalopay.vn/v2/query_refund
Real POST https://openapi.zalopay.vn/v2/query_refund

application/x-www-form-urlencoded

application/json

application/xml

Request data

Parameter
Datatype Length Required Description
app_id Int app_id provided by ZaloPay
m_refund_id String 45 • The transaction code, which was generated by merchant when querying refund transaction.
• Format: yymmdd_appid_xxxxxxxxxx
timestamp Long The time call API (timestamp in millisecond)
mac String = HMAC(hmac_algorithm, key1, app_id+"|"+m_refund_id+"|"+timestamp)

Response data

Parameter Datatype Description
return_code Int status code
return_message String status information
sub_return_code Int status code detail
sub_return_message String detail description of status code

Status code information

Status code Short description Meaning
1 REFUND_SUCCESS Successful refund.
2 REFUND_FAIL Refund failed.
3 PROCESSING The transaction is being refunding.
-3 Invalid authentication infor.
-10 Invalid app info.
-13 Over the time allow refund.
-24 Invalid m_refund_id.
-25 m_refund_id's time [ yymmdd ] invalid format.
-26 m_refund_id's appid is invalid.

Sample code

/**
 * .Net core 2.1.505
 */
using System;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
using ZaloPay.Helper; // HmacHelper, RSAHelper, HttpHelper, Utils (download at DOWNLOADS page)
using ZaloPay.Helper.Crypto;
using Newtonsoft.Json; // https://www.newtonsoft.com/json

namespace ZaloPayExample
{
    class Program
    {
        static string app_id = "2553";
        static string key1 = "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL";
        static string query_refund_url = "https://sb-openapi.zalopay.vn/v2/query_refund";

        static async Task Main(string[] args)
        {
            Dictionary<string, string> param = new Dictionary<string, string>();
            param.Add("app_id", app_id);
            param.Add("timestamp", "123456789");
            param.Add("m_refund_id", "190308_2553_xxxxxx");

            var data = app_id + "|" + param["m_refund_id"] + "|" + param["timestamp"];
            param.Add("mac", HmacHelper.Compute(ZaloPayHMAC.HMACSHA256, key1, data));

            var result = await HttpHelper.PostFormAsync(query_refund_url, param);

            foreach(var entry in result) {
                Console.WriteLine("{0} = {1}", entry.Key, entry.Value);
            }
        }
    }
}
// Java version "1.8.0_201"
import org.apache.http.NameValuePair; // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject; // https://mvnrepository.com/artifact/org.json/json
import vn.zalopay.crypto.HMACUtil; // tải về ở mục DOWNLOADS
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GetRefundStatus {
    private static final Map<String, String> config = new HashMap<String, String>(){{
        put("app_id", "2553");
        put("key1", "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL");
        put("key2", "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz");
        put("query_refund_url", "https://sb-openapi.zalopay.vn/v2/query_refund");
    }};

    public static void main(String[] args) throws Exception {
        String m_refund_id = "190308_2553_123456";
        String timestamp = Long.toString(System.currentTimeMillis()); // miliseconds
        String data = config.get("app_id") +"|"+ m_refund_id  +"|"+ timestamp; // app_id|m_refund_id|timestamp
        String mac = HMACUtil.HMacHexStringEncode(HMACUtil.HMACSHA256, config.get("key1"), data);

        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("app_id", config.get("app_id")));
        params.add(new BasicNameValuePair("m_refund_id", m_refund_id));
        params.add(new BasicNameValuePair("timestamp", timestamp));
        params.add(new BasicNameValuePair("mac", mac));

        URIBuilder uri = new URIBuilder(config.get("query_refund_url"));
        uri.addParameters(params);

        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost post = new HttpPost(uri.build());
        post.setEntity(new UrlEncodedFormEntity(params));

        CloseableHttpResponse res = client.execute(post);
        BufferedReader rd = new BufferedReader(new InputStreamReader(res.getEntity().getContent()));
        StringBuilder resultJsonStr = new StringBuilder();
        String line;

        while ((line = rd.readLine()) != null) {
          resultJsonStr.append(line);
        }

        JSONObject result = new JSONObject(resultJsonStr.toString());
        for (String key : result.keySet()) {
          System.out.format("%s = %s\n", key, result.get(key));
        }
    }
}
// go version go1.11.1 linux/amd64
package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
    "strconv"

    "github.com/zpmep/hmacutil" // go get github.com/zpmep/hmacutil
)

var (
    appID = "2553"
    key1  = "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL"
    key2  = "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz"
)

func main() {
    params := map[string]interface{}{
        "app_id":       appID,
        "m_refund_id": appTransID,
    "timestamp":  strconv.Itoa(12345678910),  // miliseconds
  }
    data := fmt.Sprintf("%v|%v|%v", appID, params["m_refund_id"], params["timestamp"]) // app_id|m_refund_id|timestamp
  params["mac"] = hmacutil.HexStringEncode(hmacutil.SHA256, key1, data)

  jsonStr, err := json.Marshal(params)
    if err != nil {
        log.Fatal(err)
  }

  res, err := http.Post("https://sb-openapi.zalopay.vn/v2/query_refund", "application/json", bytes.NewBuffer(jsonStr))

    if err != nil {
        log.Fatal(err)
    }
    defer res.Body.Close()

    body, _ := ioutil.ReadAll(res.Body)

    var result map[string]interface{}

    if err := json.Unmarshal(body, &result); err != nil {
        log.Fatal(err)
    }

    for k, v := range result {
        log.Printf("%s = %+v", k, v)
    }
}
// Node v10.15.3
const axios = require('axios').default; // npm install axios
const CryptoJS = require('crypto-js'); // npm install crypto-js

const config = {
  app_id: "2553",
  key1: "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
  key2: "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz",
  endpoint: "https://sb-openapi.zalopay.vn/v2/query_refund"
};

const params = {
  app_id: config.app_id,
  timestamp: Date.now(), // miliseconds
  m_refund_id: "190312_2553_123456", 
};

const data = config.app_id + "|" + params.m_refund_id + "|" + params.timestamp; // app_id|m_refund_id|timestamp
params.mac = CryptoJS.HmacSHA256(data, config.key1).toString()

axios.post(config.endpoint, null, { params })
  .then(res => console.log(res.data))
  .catch(err => console.log(err));
<?php

// PHP Version 7.3.3

$config = [
  "app_id" => 2553,
  "key1" => "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
  "key2" => "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz",
  "endpoint" => "https://sb-openapi.zalopay.vn/v2/query_refund"
];

$m_refund_id = "190308_2553_123456"; 
$timestamp = round(microtime(true) * 1000); // miliseconds
$data = $config["app_id"]."|".$m_refund_id."|".$timestamp; // app_id|m_refund_id|timestamp
$params = [
  "app_id" => $config["app_id"],
  "timestamp" => $timestamp,
  "m_refund_id" => $m_refund_id,
  "mac" => hash_hmac("sha256", $data, $config["key1"])
];

$context = stream_context_create([
    "http" => [
        "header" => "Content-type: application/x-www-form-urlencoded\r\n",
        "method" => "POST",
        "content" => http_build_query($params)
    ]
]);

$resp = file_get_contents($config["endpoint"], false, $context);
$result = json_decode($resp, true);

foreach ($result as $key => $value) {
  echo "$key: $value<br>";
}
# ruby 2.5.1p57

require 'json'
require 'openssl' # gem install openssl
require 'net/http'

config = {
  app_id: '2553',
  key1: 'PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL',
  key2: 'kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz',
  endpoint: 'https://sb-openapi.zalopay.vn/v2/query_refund'
}

params = {
  app_id: config[:app_id],
  m_refund_id: "190312_2553_123456",
  timestamp: (Time.now.to_f.round(3) * 1000).to_i # miliseconds
}

data = config[:app_id] +"|"+ params[:m_refund_id] +"|"+ params[:timestamp].to_s # app_id|m_refund_id|timestamp
params[:mac] = OpenSSL::HMAC.hexdigest('sha256', config[:key1], data)

res = Net::HTTP.post_form(URI.parse(config[:endpoint]), params)
result = JSON.parse(res.body)

result.each do |key, value|
  puts "#{key}: #{value}"
end
# coding=utf-8
# Python 3.6

from time import time
import hmac, hashlib, urllib.parse, urllib.request

config = {
  "app_id": 2553,
  "key1": "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
  "key2": "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz",
  "endpoint": "https://sb-openapi.zalopay.vn/v2/query_refund"
}

params = {
  "app_id": config["app_id"],
  "timestamp": int(round(time() * 1000)), # miliseconds
  "m_refund_id": "190409_2553_123456",
}

data = "{}|{}|{}".format(config["app_id"], params["m_refund_id"], params["timestamp"]) # app_id|m_refund_id|timestamp
params["mac"] = hmac.new(config["key1"].encode(), data.encode(), hashlib.sha256).hexdigest()

response = urllib.request.urlopen(url=config["endpoint"], data=urllib.parse.urlencode(params).encode())
result = json.loads(response.read())

for k, v in result.items():
  print("{}: {}".format(k, v))
curl https://sb-openapi.zalopay.vn/v2/query_refund \
  -d app_id=2553 \
  -d timestamp=1555640469224 \
  -d m_refund_id=190308_2553_123456 \
  -d mac=4255035bae2e65118887bc17110ab4b43a1cdd7c513aad9b25a5ef27e187196e
No matching results were found