NAV

Mô hình tích hợp

Chọn mô hình tích hợp ZaloPay phù hợp

POS - QuickPay

Giới thiệu Demo Hướng dẫn tích hợp

translation missing: vi.docs.quickpay.api.describe.title

translation missing: vi.docs.quickpay.api.describe.desc

Luồng xử lý

Sequence Flow

Đặc tả API

Environment Method Endpoint
Sandbox POST https://sandbox.zalopay.com.vn/v001/tpe/submitqrcodepay
Real POST https://zalopay.com.vn/v001/tpe/submitqrcodepay

Dữ liệu truyền vào api

Tham số Kiểu dữ liệu Kích thước Bắt buộc Ý nghĩa Ví dụ
appid int t 1
appuser String 50 r pmqc
apptime long a 1459823610957
amount long n 50000
apptransid String 40 s 180208_007242
embeddata String 1024 l {"promotioninfo":"","merchantinfo":"du lieu rieng cua ung dung"}
item String 256 a [{"itemid":"knb","itename":"kim nguyen bao","itemprice":198400,"itemquantity":1}]
mac String t(javascript:scrollToElement('#dac-ta-api_du-lieu-truyen-vao-api_tao-thong-tin-chung-thuc')) c8f49d523336f0a182586a70b71c20 da964d37954711de9273152b500df74c0d
paymentcode String i =RSA(paymentcoderaw, publicKey) aoSCLACtsQM5g5blVNLgEBBBIz8KNg+Pz0LbcdhX8AoQR TWGEH/BrbHG8rIkNo3JIpOc7U7na0CZQ+HU8Zwhgw==
description String 100 o Mua kim nguyên bảo cho game VLTK
userIP String n 127.0.0.1

Tạo thông tin chứng thực

mac = HMAC(hmac_algorithm, key1, hmac_input)

Trong đó:

Tham số api trả về

Tham số Kiểu dữ liệu Ý nghĩa
returncode int

1: t

10: r

<>: a

returnmessage String n
isprocessing boolean true: s
false: l
zptransid long Mã giao dịch của ZaloPay

Code mẫu

/**
 * .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 (tải về ở mục DOWNLOADS)
using ZaloPay.Helper.Crypto;
using Newtonsoft.Json; // https://www.newtonsoft.com/json

namespace ZaloPayExample
{
    class Program
    {
        static string appid = "553";
        static string key1 = "9phuAOYhan4urywHTh0ndEXiV3pKHr5Q";
        static string quickPayUrl = "https://sandbox.zalopay.com.vn/v001/tpe/submitqrcodepay";
        static string rsaPublicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOfB6/x0b5UiLkU3pOdcnXIkuCSzmvlVhDJKv1j3yBCyvsgAHacVXd+7WDPcCJmjSEKlRV6bBJWYam5vo7RB740CAwEAAQ==";

        static async Task Main(string[] args)
        {
            var transid = Guid.NewGuid().ToString(); 
            var embeddata = new { merchantinfo = "embeddata123" };
            var items = new []{
                new { itemid = "knb", itemname = "kim nguyen bao", itemprice = 198400, itemquantity = 1 }
            };
            var paymentCodeRaw = "174830909300000096"; 
            var param = new Dictionary<string, string>();

            param.Add("appid", appid);
            param.Add("appuser", "demo");
            param.Add("apptime", Utils.GetTimeStamp().ToString());
            param.Add("amount", "1000");
            param.Add("apptransid", DateTime.Now.ToString("yyMMdd") + "_" + transid);
            param.Add("embeddata", JsonConvert.SerializeObject(embeddata));
            param.Add("item", JsonConvert.SerializeObject(items));
            param.Add("description", "ZaloPay QickPay Demo");
            param.Add("userip", "127.0.0.1"); 
            param.Add("paymentcode", RSAHelper.Encrypt(paymentCodeRaw, rsaPublicKey)); 

            var data = appid + "|" + param["apptransid"] + "|" + param["appuser"] + "|" + param["amount"] + "|" 
                + param["apptime"] + "|" + param["embeddata"] + "|" + param["item"] + "|" + paymentCodeRaw;
            param.Add("mac", HmacHelper.Compute(ZaloPayHMAC.HMACSHA256, key1, data));

            var result = await HttpHelper.PostFormAsync(quickPayUrl, 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; // tải về ở mục DOWNLOADS
import vn.zalopay.crypto.RSAUtil; // tải về ở mục DOWNLOADS

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

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

    private static Map<String, String> config = new HashMap<String, String>(){{
        put("appid", "553");
        put("key1", "9phuAOYhan4urywHTh0ndEXiV3pKHr5Q");
        put("key2", "Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3");
        put("endpoint", "https://sandbox.zalopay.com.vn/v001/tpe/submitqrcodepay");
        put("publicKey", "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOfB6/x0b5UiLkU3pOdcnXIkuCSzmvlVhDJKv1j3yBCyvsgAHacVXd+7WDPcCJmjSEKlRV6bBJWYam5vo7RB740CAwEAAQ==");
    }};

    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
    {
        final Map embeddata = new HashMap(){{
            put("merchantinfo", "embeddata123");
        }};

        final Map[] item = {
            new HashMap(){{
                put("itemid", "knb");
                put("itemname", "kim nguyen bao");
                put("itemprice", 198400);
                put("itemquantity", 1);
            }}
        };

        final String paymentCodeRaw = "977254910200000006"; // translation missing: vi.docs.quickpay.api.sample_code.comments.paymentcode

        Map<String, Object> order = new HashMap<String, Object>(){{
            put("appid", config.get("appid"));
            put("apptransid", getCurrentTimeString("yyMMdd") +"_"+ UUID.randomUUID()); // mã giao dich có định dạng yyMMdd_xxxx
            put("apptime", System.currentTimeMillis()); // miliseconds
            put("appuser", "demo");
            put("amount", 50000);
            put("description", "ZaloPay Intergration Demo");
            put("item", new JSONObject(item).toString());
            put("embeddata", new JSONObject(embeddata).toString());
            put("userip", "127.0.0.1");
            put("paymentcode", RSAUtil.encrypt(config.get("publicKey"), paymentCodeRaw));
        }};

        // appid +”|”+ apptransid +”|”+ appuser +”|”+ amount +"|" + apptime +”|”+ embeddata +"|" +item
        String data = order.get("appid") +"|"+ order.get("apptransid") +"|"+ order.get("appuser") +"|"+ order.get("amount")
                +"|"+ order.get("apptime") +"|"+ order.get("embeddata") +"|"+ order.get("item") +"|"+ paymentCodeRaw;
        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()));
        }

        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 (
    "crypto/rand"
    "crypto/rsa"
    "encoding/base64"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
    "strconv"
    "time"

    "github.com/google/uuid" // go get github.com/google/uuid
    "github.com/zpmep/hmacutil" // go get github.com/zpmep/hmacutil
    "github.com/zpmep/rsautil" // go get github.com/zpmep/rsautil
)

var (
    endpoint = "https://sandbox.zalopay.com.vn/v001/tpe/submitqrcodepay"
    appid    = "553"
    key1     = "9phuAOYhan4urywHTh0ndEXiV3pKHr5Q"
    key2     = "Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3"
)
var rsaPublicKey = []byte(`
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOfB6/x0b5UiLkU3pOdcnXIkuCSzmvlV
hDJKv1j3yBCyvsgAHacVXd+7WDPcCJmjSEKlRV6bBJWYam5vo7RB740CAwEAAQ==
-----END PUBLIC KEY-----
`)

func check(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

type object map[string]interface{}

func main() {
    embeddata, _ := json.Marshal(object{
        "merchantinfo": "embeddata123",
    })
    items, _ := json.Marshal([]object{
        object{"itemid": "knb", "itemname": "kim nguyen bao", "itemprice": 198400, "itemquantity": 1},
    })
    params := make(url.Values)
    params.Add("machineid", appid)
    params.Add("appid", appid)                         
    params.Add("amount", "1000")                       
    params.Add("appuser", "dungpqt@vng.com.vn")        
    params.Add("embeddata", string(embeddata))         
    params.Add("item", string(items))                  
    params.Add("description", "ZaloPay Quickpay Demo") 

    pub, err := rsautil.BytesToPublicKey(rsaPublicKey)
    check(err)

    paymentcodeRaw := "215956908800000020" // translation missing: vi.docs.quickpay.api.sample_code.comments.paymentcode
    cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, pub, []byte(paymentcodeRaw))
    check(err)

    paymentcode := base64.StdEncoding.EncodeToString(cipherText)
    params.Add("paymentcode", paymentcode)

    ip := "127.0.0.1"
    params.Add("userip", ip)

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

    transid := uuid.New().String()                                                                                 // unique id
    params.Add("apptransid", fmt.Sprintf("%02d%02d%02d_%v", now.Year()%100, int(now.Month()), now.Day(), transid)) // mã giao dich có định dạng yyMMdd_xxxx

    data := fmt.Sprintf("%v|%v|%v|%v|%v|%v|%v|%v", params.Get("appid"), params.Get("apptransid"), params.Get("appuser"),
        params.Get("amount"), params.Get("apptime"), params.Get("embeddata"), params.Get("item"), paymentcodeRaw)
    params.Add("mac", hmacutil.HexStringEncode(hmacutil.SHA256, key1, data))

    // Content-Type: application/x-www-form-urlencoded
    res, err := http.PostForm(endpoint, params)
    check(err)

    // parse response
    defer res.Body.Close()

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

    log.Printf("%+v", string(body))
}
// Node v10.15.3
const NodeRSA = require('node-rsa'); // npm install node-rsa
const axios = require('axios').default; // npm install axios
const CryptoJS = require('crypto-js'); // npm install crypto-js
const uuid = require('uuid/v1'); // npm install uuid
const moment = require('moment'); // npm install moment

// APP INFO
const config = {
  appid: "553",
  key1: "9phuAOYhan4urywHTh0ndEXiV3pKHr5Q",
  key2: "Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3",
  endpoint: "https://sandbox.zalopay.com.vn/v001/tpe/submitqrcodepay"
};

config.rsaPublicKey = `
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOfB6/x0b5UiLkU3pOdcnXIkuCSzmvlV
hDJKv1j3yBCyvsgAHacVXd+7WDPcCJmjSEKlRV6bBJWYam5vo7RB740CAwEAAQ==
-----END PUBLIC KEY-----
`;

const embeddata = {
  merchantinfo: "embeddata123"
};

const items = [{
  itemid: "knb",
  itename: "kim nguyen bao",
  itemprice: 198400,
  itemquantity: 1
}];

const paymentcodeRaw = "542373909900000106"; // translation missing: vi.docs.quickpay.api.sample_code.comments.paymentcode
const key = new NodeRSA(config.rsaPublicKey, {
  encryptionScheme: 'pkcs1'
});
const paymentcode = key.encrypt(paymentcodeRaw, 'base64');

const order = {
  appid: config.appid, 
  apptransid: `${moment().format('YYMMDD')}_${uuid()}`, // mã giao dich có định dạng yyMMdd_xxxx
  appuser: "demo", 
  apptime: Date.now(), // miliseconds
  item: JSON.stringify(items), 
  embeddata: JSON.stringify(embeddata), 
  amount: 1000, 
  description: "ZaloPay Integration Demo",  
  userip: "127.0.0.1",
  paymentcode,
};

// appid|apptransid|appuser|amount|apptime|embeddata|item|paymentcodeRaw
const data = config.appid + "|" + order.apptransid + "|" + order.appuser + "|" + order.amount + "|" +
  order.apptime + "|" + order.embeddata + "|" + order.item + "|" + paymentcodeRaw;
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 = [
  "appid" => 553,
  "key1" => "9phuAOYhan4urywHTh0ndEXiV3pKHr5Q",
  "key2" => "Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3",
  "endpoint" => "https://sandbox.zalopay.com.vn/v001/tpe/submitqrcodepay",
  "publickey" => "
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOfB6/x0b5UiLkU3pOdcnXIkuCSzmvlV
hDJKv1j3yBCyvsgAHacVXd+7WDPcCJmjSEKlRV6bBJWYam5vo7RB740CAwEAAQ==
-----END PUBLIC KEY-----
"
];

$embeddata = [
  "merchantinfo" => "embeddata123"
];
$items = [
  [ "itemid" => "knb", "itemname" => "kim nguyen bao", "itemprice" => 198400, "itemquantity" => 1 ]
];
$paymentcoderaw = "885313909500000206";
$ok = openssl_public_encrypt($paymentcoderaw, $encrypted, $config["publickey"]);
if (!$ok) {
  die("Can not encrypt paymentcode");
}

$order = [
  "appid" => $config["appid"],
  "apptime" => round(microtime(true) * 1000), // miliseconds
  "apptransid" => date("ymd")."_".uniqid(), // mã giao dich có định dạng yyMMdd_xxxx
  "appuser" => "demo",
  "item" => json_encode($items, JSON_UNESCAPED_UNICODE),
  "embeddata" => json_encode($embeddata, JSON_UNESCAPED_UNICODE),
  "amount" => 50000,
  "description" => "ZaloPay Intergration Demo",
  "userip" => "127.0.0.1",
  "paymentcode" => base64_encode($encrypted)
];

// appid|apptransid|appuser|amount|apptime|embeddata|item|paymentcoderaw
$data = $order["appid"]."|".$order["apptransid"]."|".$order["appuser"]."|".$order["amount"]
  ."|".$order["apptime"]."|".$order["embeddata"]."|".$order["item"]."|".$paymentcoderaw;
$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 'securerandom'
require 'json'
require 'openssl' # gem install openssl
require 'net/http'
require 'base64'

# cat public_key.pem
#
# -----BEGIN PUBLIC KEY-----
# MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOfB6/x0b5UiLkU3pOdcnXIkuCSzmvlV
# hDJKv1j3yBCyvsgAHacVXd+7WDPcCJmjSEKlRV6bBJWYam5vo7RB740CAwEAAQ==
# -----END PUBLIC KEY-----

config = {
  appid: '553',
  key1: '9phuAOYhan4urywHTh0ndEXiV3pKHr5Q',
  key2: 'Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3',
  endpoint: 'https://sandbox.zalopay.com.vn/v001/tpe/submitqrcodepay',
  publickey: 'public_key.pem'
}

apptime = (Time.now.to_f.round(3) * 1000).to_i
apptransid = Time.now.strftime('%y%m%d') + '_' + SecureRandom.uuid

embeddata = {
  merchantinfo: 'embeddata123'
}
items = [{
  itemid: 'knb',
  itemname: 'kim nguyen bao',
  itemprice: 198_400,
  itemquantity: 1
}]

pubkey = OpenSSL::PKey::RSA.new(File.read(config[:publickey]))

paymentCodeRaw = '508920910200000017'
encrypted = pubkey.public_encrypt(paymentCodeRaw)

order = {
  appid: config[:appid],
  apptransid: apptransid, # mã giao dich có định dạng yyMMdd_xxxx
  appuser: 'demo',
  apptime: apptime, # miliseconds
  item: items.to_json, 
  embeddata: embeddata.to_json, 
  amount: 50_000, 
  description: 'ZaloPay Integration Demo', 
  userip: '127.0.0.1',
  paymentcode: Base64.urlsafe_encode64(encrypted)
}

# appid|apptransid|appuser|amount|apptime|embeddata|item
data = config[:appid] + '|' + apptransid + '|' + order[:appuser] + '|' + order[:amount].to_s + '|' +
       order[:apptime].to_s + '|' + order[:embeddata].to_s + '|' + order[:item].to_s + '|' + paymentCodeRaw

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 uuid, json, hmac, hashlib, urllib.request, urllib.parse, base64

from Crypto.PublicKey import RSA # pip3 install pycrypto
from Crypto.Cipher import PKCS1_v1_5
from Crypto import Random

config = {
  "appid": 553,
  "key1": "9phuAOYhan4urywHTh0ndEXiV3pKHr5Q",
  "key2": "Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3",
  "endpoint": "https://sandbox.zalopay.com.vn/v001/tpe/submitqrcodepay"
}

# Public key lấy ở trang quản lý app của merchant
config["rsaPublicKey"] = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOfB6/x0b5UiLkU3pOdcnXIkuCSzmvlVhDJKv1j3yBCyvsgAHacVXd+7WDPcCJmjSEKlRV6bBJWYam5vo7RB740CAwEAAQ=="

# RSA encrypt paymentcode
paymentCodeRaw = "542373909900000106" # translation missing: vi.docs.quickpay.api.sample_code.comments.paymentcode

keyPub = RSA.importKey(base64.b64decode(config["rsaPublicKey"]))
cipher = PKCS1_v1_5.new(keyPub)

cipherText = cipher.encrypt(paymentCodeRaw.encode())
paymentCode = base64.b64encode(cipherText)

order = {
  "appid": config["appid"],
  "apptransid": "{:%y%m%d}_{}".format(datetime.today(), uuid.uuid4()), # mã giao dich có định dạng yyMMdd_xxxx
  "appuser": "demo",
  "apptime": int(round(time() * 1000)), # miliseconds
  "embeddata": json.dumps({ 
    "merchantinfo": "embeddata123"
  }),
  "item": json.dumps([
    { "itemid": "knb", "itemname": "kim nguyen bao", "itemprice": 198400, "itemquantity": 1 }
  ]),
  "amount": 50000,
  "description": "ZaloPay Integration Demo",
  "userip": "127.0.0.1",
  "paymentcode": paymentCode
}

# appid|apptransid|appuser|amount|apptime|embeddata|item|paymentcoderaw
data = "{}|{}|{}|{}|{}|{}|{}|{}".format(order["appid"], order["apptransid"], order["appuser"], 
order["amount"], order["apptime"], order["embeddata"], order["item"], paymentCodeRaw)

# tính mac
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://sandbox.zalopay.com.vn/v001/tpe/submitqrcodepay \
  -H "Content-type: application/x-www-form-urlencoded" \
  -d appid=553 \
  -d apptransid=190419_56355af0-624a-11e9-8cbe-2bcce7cb9c36 \
  -d appuser=demo \
  -d apptime=1555640702494 \
  -d item='[{"itemid":"knb","itemname":"kim nguyen bao","itemprice":198400,"itemquantity":1}]' \
  -d embeddata='{"merchantinfo":"embeddata123"}' \
  -d amount=1000 \
  -d description='ZaloPay Intergration Demo' \
  -d userip=127.0.0.1 \
  -d paymentcode=W0QduaBV3oeAFp%2BV0Hhp8Pyoqt3s7TjryXWH8upqTK4bl1dJv431SKNwqumQyKgMxU%2FsM2SPaYjWUeiMOBoUsw%3D%3D \
  -d mac=ddf063288219e3d82d4058faf7403b436e20a8324ba3d6b29cff85060b19f413
Không tìm thấy kết quả phù hợp