NAV

Mô hình tích hợp

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

Thanh toán QR

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

Mô tả

ZaloPay App tiếp nhận thông tin đơn hàng từ AppClient bằng phương thức QR Code.

ZaloPay cung cấp 2 cách để tạo QR code cho đơn hàng:

Đơn hàng có kích thước lớn

Đối với các đơn hàng có kích thước lớn việc quét QR code sẽ kém hiệu quả, do vậy ZaloPay hỗ trợ api để tạo đơn hàng ở server side. Sau khi gọi api này ZaloPay Server sẽ trả về response có chứa orderurl, AppClient sẽ sử dụng orderurl này để tạo QR Code.

Ví dụ:

Dữ liệu nhận được khi tạo đơn hàng thành công:

{
  "zptranstoken": "190719000001129n9Z6V9O",
  "orderurl": "https://sbgateway.zalopay.vn/openinapp?order=eyJ6cHRyYW5zdG9rZW4iOiIxOTA3MTkwMDAwMDExMjluOVo2VjlPIiwiYXBwaWQiOjU1M30",
  "returncode": 1,
  "returnmessage": ""
}

AppClient sử dụng trường orderurl để tạo QR code, ZaloPay App sẽ tiếp nhận thông tin QR code này để tiến hành thanh toán.

https://sbgateway.zalopay.vn/openinapp?order=eyJ6cHRyYW5zdG9rZW4iOiIxOTA3MTkwMDAwMDExMjluOVo2VjlPIiwiYXBwaWQiOjU1M30

QR code của orderurl trên:

OrderUrl QR Code

Luồng xử lý

QR Code Flow

Đơn hàng có kích thước nhỏ

Đối với những đơn hàng có kích thước nhỏ, thông tin đơn hàng được chuyển đổi thành chuỗi json sau đó chuyển thành thành base64_data_with_urlencode rồi cộng thêm QRCode URL phía trước để tạo QR code.

Environment QRCode URL
Sandbox https://sbgateway.zalopay.vn/openinapp?order={base64_data_with_urlencode}
Real https://gateway.zalopay.vn/openinapp?order={base64_data_with_urlencode}

Ví dụ:

Chuỗi json của đơn hàng:

{
  "appid": 553,
  "apptransid": "200904_000234",
  "appuser": "user123",
  "apptime": 1599202366026,
  "item": "[]",
  "embeddata": "{}",
  "amount": 10000,
  "description": "Demo - Thanh toán đơn hàng #200904_000234",
  "bankcode": "zalopayapp",
  "mac": "7e95836a9feace32458f23416feea423172ef0a098f27a668a1e10788b5a6838"
}

Chuỗi json trên được chuyển thành base64_data_with_urlencode và kết hợp với QRCode URL như sau:

https://sbgateway.zalopay.vn/openinapp?order=ewogICJhcHBpZCI6IDU1MywKICAiYXBwdHJhbnNpZCI6ICIyMDA5MDRfMDAwMjM0IiwKICAiYXBwdXNlciI6ICJ1c2VyMTIzIiwKICAiYXBwdGltZSI6IDE1OTkyMDIzNjYwMjYsCiAgIml0ZW0iOiAiW10iLAogICJlbWJlZGRhdGEiOiAie30iLAogICJhbW91bnQiOiAxMDAwMCwKICAiZGVzY3JpcHRpb24iOiAiRGVtbyAtIFRoYW5oIHRvw6FuIMSRxqFuIGjDoG5nICMyMDA5MDRfMDAwMjM0IiwKICAiYmFua2NvZGUiOiAiemFsb3BheWFwcCIsCiAgIm1hYyI6ICI3ZTk1ODM2YTlmZWFjZTMyNDU4ZjIzNDE2ZmVlYTQyMzE3MmVmMGEwOThmMjdhNjY4YTFlMTA3ODhiNWE2ODM4Igp9

QR code của chuỗi QRCode URL + base64_data_with_urlencode trên:

QR Code Small

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 = "2553";
        static string key1 = "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL";

        static async Task Main(string[] args)
        {
            var transid = Guid.NewGuid().ToString(); 
            var order = new Dictionary<string, string>();    

            order.Add("appid", appid);
            order.Add("appuser", "demo");
            order.Add("apptime", Utils.GetTimeStamp().ToString());
            order.Add("amount", "50000");
            order.Add("apptransid", DateTime.Now.ToString("yyMMdd") + "_" + transid);
            order.Add("embeddata", "{}");
            order.Add("item",  "[]");
            order.Add("description", "Demo - Thanh toán đơn hàng #" + transid);
            order.Add("bank_code", "zalopayapp");

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

            var orderJSON = Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(order));

            Console.WriteLine("https://sbgateway.zalopay.vn/openinapp?order=" + Convert.ToBase64String(orderJSON));
        }
    }
}
// Java version "1.8.0_201"
import org.json.JSONObject; // https://mvnrepository.com/artifact/org.json/json
import vn.zalopay.crypto.HMACUtil; // tải về ở mục DOWNLOADS

import java.text.SimpleDateFormat;
import java.util.*;

public class Gateway {
    private static Map<String, String> config = new HashMap<String, String>(){{
        put("appid", "2553");
        put("key1", "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL");
        put("key2", "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz");
    }};

    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 appTransID =  getCurrentTimeString("yyMMdd") +"_"+ UUID.randomUUID()
        JSONObject order = new JSONObject(){{
            put("appid", config.get("appid"));
            put("apptransid", appTransID); // mã giao dich có định dạng yyMMdd_xxxx
            put("apptime", System.currentTimeMillis()); // miliseconds
            put("appuser", "demo");
            put("amount", 50000);
            put("description", "Demo - Thanh toán đơn hàng #" + appTransID);
            put("bank_code", "zalopayapp");
            put("item", "[]");
            put("embeddata", "{}");
        }};

        // 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");
        order.put("mac", HMACUtil.HMacHexStringEncode(HMACUtil.HMACSHA256, config.get("key1"), data));

        String base64Order = Base64.getUrlEncoder().withoutPadding().encodeToString(order.toString().getBytes());

        // https://sbgateway.zalopay.vn/openinapp?order={base64_data_with_urlencode}
        System.out.println("https://sbgateway.zalopay.vn/openinapp?order="+ base64Order);
    }
}
// go version go1.11.1 linux/amd64
package main

import (
    "encoding/base64"
    "encoding/json"
    "fmt"
    "log"
    "time"

    "github.com/google/uuid" // go get github.com/google/uuid
    "github.com/tiendung1510/hmacutil" // go get github.com/tiendung1510/hmacutil
)

type object map[string]interface{}

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

func main() {

    now := time.Now()
    order["apptime"] = now.UnixNano() / int64(time.Millisecond) // miliseconds

    transid := uuid.New().String()                                                                             // unique id
  order["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

    order := make(object)
    order["appid"] = 2553                              
    order["amount"] = 1000                            
    order["appuser"] = "demo"                         
    order["embeddata"] = "{}"        
    order["item"] = "[]"                    
    order["description"] = "Demo - Thanh toán đơn hàng #" + transid
    order["bank_code"] = "zalopayapp"                  

    // appid|apptransid|appuser|amount|apptime|embeddata|item
    data := fmt.Sprintf("%v|%v|%v|%v|%v|%v|%v", order["appid"], order["apptransid"], order["appuser"],
        order["amount"], order["apptime"], order["embeddata"], order["item"])
    order["mac"] = hmacutil.HexStringEncode(hmacutil.SHA256, key1, data)

    orderJSON, _ := json.Marshal(order)

    // https://sbgateway.zalopay.vn/openinapp?order={base64_data_with_urlencode}
    log.Printf("%+v", "https://sbgateway.zalopay.vn/openinapp?order="+base64.RawURLEncoding.EncodeToString(orderJSON))
}
// Node v10.15.3
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: "2553",
  key1: "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
  key2: "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz"
};

let appTransID = `${moment().format('YYMMDD')}_${uuid()}` // mã giao dich có định dạng yyMMdd_xxxx

const order = {
  appid: config.appid, 
  apptransid: appTransID,
  appuser: "demo", 
  apptime: Date.now(), // miliseconds
  item: "[]", 
  embeddata: "{}", 
  amount: 50000, 
  description: "Demo - Thanh toán đơn hàng #" + appTransID, 
  bank_code: "zalopayapp", 
};

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

const b64Order = Buffer.from(JSON.stringify(order)).toString('base64');

// https://sbgateway.zalopay.vn/openinapp?order={base64_data_with_urlencode}
console.log("https://sbgateway.zalopay.vn/openinapp?order=" + encodeURIComponent(b64Order));
<?php

// PHP Version 7.3.3

$config = [
  "appid" => 2553,
  "key1" => "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
  "key2" => "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz"
];

$appTransID =  date("ymd")."_".uniqid(); // mã giao dich có định dạng yyMMdd_xxxx

$order = [
  "appid" => $config["appid"],
  "apptime" => round(microtime(true) * 1000), // miliseconds
  "apptransid" => $appTransID
  "appuser" => "demo",
  "item" => "[]",
  "embeddata" => "{}",
  "amount" => 50000,
  "description" => "Demo - Thanh toán đơn hàng #" + $appTransID,
  "bank_code" => "zalopayapp"
];

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

echo "https://sbgateway.zalopay.vn/openinapp?".http_build_query([
  "order" => base64_encode(json_encode($order, JSON_UNESCAPED_UNICODE))
]);
# ruby 2.5.1p57

require 'securerandom'
require 'json'
require 'openssl' # gem install openssl
require 'base64'
require 'addressable/uri' # gem install addressable

config = {
  appid: '2553',
  key1: 'PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL',
  key2: 'kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz',
  endpoint: 'https://sbgateway.zalopay.vn/openinapp'
}

apptime = (Time.now.to_f.round(3) * 1000).to_i # miliseconds
apptransid = Time.now.strftime('%y%m%d') + '_' + SecureRandom.uuid # mã giao dich có định dạng yyMMdd_xxxx

order = {
  appid: config[:appid],
  apptransid: apptransid, # mã giao dich có định dạng yyMMdd_xxxx
  appuser: 'demo',
  apptime: apptime, # miliseconds 
  item: '[]', 
  embeddata: "{}", 
  amount: 50_000, 
  description: 'Demo - Thanh toán đơn hàng #' + apptransid, 
  bank_code: 'zalopayapp'
}

# 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

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

payUri = URI.parse(config[:endpoint])
payUri.query = URI.encode_www_form(order: Base64.urlsafe_encode64(order.to_json))

# https://sbgateway.zalopay.vn/openinapp?order={base64_data_with_urlencode}
puts payUri.to_s
# coding=utf-8
# Python 3.6

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

config = {
  "appid": 2553,
  "key1": "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL",
  "key2": "kLtgPl8HHhfvMuDHPwKfgfsY4Ydm9eIz",
  "endpoint": "https://sbgateway.zalopay.vn/openinapp"
}

appTransID =  "{:%y%m%d}_{}".format(datetime.today(), uuid.uuid4()) # mã giao dich có định dạng yyMMdd_xxxx

order = {
  "appid": config["appid"],
  "apptransid": appTransID,
  "appuser": "demo",
  "apptime": int(round(time() * 1000)), # miliseconds
  "embeddata": "{}",
  "item": "[]",
  "amount": 50000,
  "description": "Demo - Thanh toán đơn hàng #" + appTransID,
  "bank_code": "zalopayapp"
}

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

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

orderJsonBytes = json.dumps(order).encode()

params = urllib.parse.urlencode({
  "order": base64.b64encode(orderJsonBytes)
})

# https://sbgateway.zalopay.vn/openinapp?order={base64_data_with_urlencode}
print("{}?{}".format(config["endpoint"], params))

Định dạng QR code trên website của Merchant

QR Code Format

Không tìm thấy kết quả phù hợp