ZaloPay Developer
Table of Contents
Mô tả
ZaloPay tiếp nhận thông tin đơn hàng từ Merchant bằng cách redirect sang ZaloPay Gateway
Luồng xử lý
Đặc tả API
Khi Merchant Server gọi request tạo đơn hàng cho ZaloPay Server, ZaloPay Server sẽ trả về một đoạn link chuyển tiếp đã được build sẵn gọi là orderurl
, Merchant sử dụng orderurl
này để redirect người dùng đến trang cổng thanh toán ZaloPay.
Ví dụ:
{
"returncode"
:
1
,
"returnmessage"
:
"Thành công"
,
"orderurl"
:
"https://sbgateway.zalopay.vn/openinapp?order=eyJ6cHRyYW5zdG9rZW4iOiJ4dGd1SEs1YnU0VDJkSHE3TUFwTFFnIiwiYXBwaWQiOjN9"
}
Ví dụ các trường hợp bankcode
bankcode
Kết quả hiển thị trên trang cổng thanh toán
Rỗng (""
) (*)
Danh sách toàn bộ các hình thức và ngân hàng được trợ giúp (CC
, ATM
, zalopayapp
, …)
zalopayapp
Hiển thị QR code để thanh toán bằng ví ZaloPay/ Mở ứng dụng ZaloPay để thanh toán qua ví so với mobileCC
Form nhập thông tin Credit Card
Mã ngân hàng ATM (VTB
, VCB
, …)
Form nhập thông tin thẻ của ngân hàng tương ứng
Chú thích
(*) Trong trường hợp Merchant muốn trang cổng thanh toán chỉ hiện thị danh sách các ngân hàng ATM, thì Merchant để bankcode=""
và thêm bankgroup
= ATM
vào embeddata
như ví dụ bên dưới
Ví dụ:
embeddata={"bankgroup": "ATM"}
bankcode=""
Lấy danh sách các ngân hàng được trợ giúp
Mặc định sẽ trả về danh sách toàn bộ các ngân hàng được ZaloPay trợ giúp. Nếu muốn trả về danh sách theo yêu cầu thì phải đăng ký với ZaloPay.
Luồng xử lý
Đặc tả API
Environment
Method
Endpoint
Sandbox
POST
https://sbgateway.zalopay.vn/api/getlistmerchantbanks
Real
POST
https://gateway.zalopay.vn/api/getlistmerchantbanks
- Content-Type:
application/x-www-form-urlencoded
Dữ liệu truyền vào api
Tham số
Kiểu dữ liệu
Bắt buộc
Ý nghĩa
appid
String
✔appid
của merchant được phân phối
reqtime
String
✔
• Thời điểm gọi api (unix timestamp in milisecond).
• Thời gian tính đến milisecond, và lấy theo current time.
mac
String
✔= HMAC(hmac_algorithm, key1, appid+"|"+reqtime)
Tham số api trả về
Tham số
Kiểu dữ liệu
Ý nghĩa
returncode
int
Mã lỗi
returnmessage
String
Thông tin lỗi
banks
Map(pmcid, List(bankdto))
Danh sách các ngân hàng
Định dạng bankdto
Tham số
Kiểu dữ liệu
Ý nghĩa
bankcode
String
Mã ngân hàng
name
String
Tên ngân hàng
displayorder
int
Thứ tự sắp xếp
pmcid
int
minamount
long
Số vốn thanh toán tối thiểu
maxamount
long
Số vốn thanh toán tối đa
Chú thích pmcid
Giá trị
Tên gọi
36
Visa/Master/JCB
37
Ngân hàng Tài khoản
38
ZaloPay
39
ATM
41
Visa/Master Debit
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
getBankListUrl
=
"https://sbgateway.zalopay.vn/api/getlistmerchantbanks"
;
class
BankDTO
{
public
string
bankcode
{
get
;
set
;
}
public
string
name
{
get
;
set
;
}
public
int
displayorder
{
get
;
set
;
}
public
int
pmcid
{
get
;
set
;
}
}
class
BankListResponse
{
public
string
returncode
{
get
;
set
;
}
public
string
returnmessage
{
get
;
set
;
}
public
Dictionary
<
string
,
List
<
BankDTO
>>
banks
{
get
;
set
;
}
}
static
async
Task
Main
(
string
[]
args
)
{
var
reqtime
=
Utils
.
GetTimeStamp
().
ToString
();
Dictionary
<
string
,
string
>
param
=
new
Dictionary
<
string
,
string
>();
param
.
Add
(
"appid"
,
appid
);
param
.
Add
(
"reqtime"
,
reqtime
);
param
.
Add
(
"mac"
,
HmacHelper
.
Compute
(
ZaloPayHMAC
.
HMACSHA256
,
key1
,
appid
+
"|"
+
reqtime
));
var
result
=
await
HttpHelper
.
PostFormAsync
<
BankListResponse
>(
getBankListUrl
,
param
);
Console
.
WriteLine
(
"returncode = {0}"
,
result
.
returncode
);
Console
.
WriteLine
(
"returnmessage = {0}"
,
result
.
returnmessage
);
foreach
(
var
entry
in
result
.
banks
)
{
var
pmcid
=
entry
.
Key
;
var
banklist
=
entry
.
Value
;
foreach
(
var
ngân hàng
in
banklist
)
{
Console
.
WriteLine
(
"{0}. {1} - {2}"
,
pmcid
,
bank
.
bankcode
,
bank
.
name
);
}
}
}
}
}
// 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
org.json.JSONArray
;
import
vn.zalopay.crypto.HMACUtil
;
// tải về ở mục DOWNLOADS
import
java.io.BufferedReader
;
import
java.io.InputStreamReader
;
import
java.util.*
;
public
class
GetBankList
{
private
static
Map
<
String
,
String
>
config
=
new
HashMap
<
String
,
String
>(){{
put
(
"appid"
,
"553"
);
put
(
"key1"
,
"9phuAOYhan4urywHTh0ndEXiV3pKHr5Q"
);
put
(
"key2"
,
"Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3"
);
put
(
"endpoint"
,
"https://sbgateway.zalopay.vn/api/getlistmerchantbanks"
);
}};
public
static
void
main
(
String
[]
args
)
throws
Exception
{
String
appid
=
config
.
get
(
"appid"
);
String
reqtime
=
Long
.
toString
(
System
.
currentTimeMillis
());
String
data
=
appid
+
"|"
+
reqtime
;
String
mac
=
HMACUtil
.
HMacHexStringEncode
(
HMACUtil
.
HMACSHA256
,
config
.
get
(
"key1"
),
data
);
List
<
NameValuePair
>
params
=
new
ArrayList
<>();
params
.
add
(
new
BasicNameValuePair
(
"appid"
,
appid
));
params
.
add
(
new
BasicNameValuePair
(
"reqtime"
,
reqtime
));
// miliseconds
params
.
add
(
new
BasicNameValuePair
(
"mac"
,
mac
));
URIBuilder
uri
=
new
URIBuilder
(
config
.
get
(
"endpoint"
));
uri
.
addParameters
(
params
);
CloseableHttpClient
client
=
HttpClients
.
createDefault
();
HttpGet
get
=
new
HttpGet
(
uri
.
build
());
CloseableHttpResponse
res
=
client
.
execute
(
get
);
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
());
JSONObject
banksObject
=
result
.
getJSONObject
(
"banks"
);
System
.
out
.
format
(
"returncode = %s"
,
result
.
getInt
(
"returncode"
));
System
.
out
.
format
(
"returnmessage = %s"
,
result
.
getString
(
"returnmessage"
));
for
(
String
pmcid
:
banksObject
.
keySet
())
{
JSONArray
banks
=
banksObject
.
getJSONArray
(
pmcid
);
banks
.
forEach
(
ngân hàng
->
{
System
.
out
.
format
(
"%s. %sn"
,
pmcid
,
bank
.
toString
());
});
}
}
}
// 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
=
"553"
key1
=
"9phuAOYhan4urywHTh0ndEXiV3pKHr5Q"
key2
=
"Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3"
)
func
main
()
{
params
:=
make
(
url
.
Values
)
params
.
Add
(
"appid"
,
"553"
)
params
.
Add
(
"reqtime"
,
strconv
.
FormatInt
(
time
.
Now
()
.
UnixNano
()
/
int64
(
time
.
Millisecond
),
10
))
// miliseconds
data
:=
fmt
.
Sprintf
(
"%v|%v"
,
params
.
Get
(
"appid"
),
params
.
Get
(
"reqtime"
))
//appid|reqtime
params
.
Add
(
"mac"
,
hmacutil
.
HexStringEncode
(
hmacutil
.
SHA256
,
key1
,
data
))
res
,
err
:=
http
.
Get
(
"https://sbgateway.zalopay.vn/api/getlistmerchantbanks?"
+
params
.
Encode
())
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
=
{
appid
:
"553"
,
key1
:
"9phuAOYhan4urywHTh0ndEXiV3pKHr5Q"
,
key2
:
"Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3"
,
endpoint
:
"https://sbgateway.zalopay.vn/api/getlistmerchantbanks"
};
let
reqtime
=
Date
.
now
();
let
params
=
reqtime
;
axios
.
get
(
config
.
endpoint
,
{
params
})
.
then
(
res
=>
{
let
banks
=
res
.
data
.
banks
;
for
(
let
id
in
banks
)
{
let
banklist
=
banks
[
id
];
console
.
log
(
id
+
"."
);
for
(
let
ngân hàng
of
banklist
)
{
console
.
log
(
bank
);
}
}
})
.
catch
(
err
=>
console
.
error
(
err
));
<?php
// PHP Version 7.3.3
$config
=
[
"appid"
=>
553
,
"key1"
=>
"9phuAOYhan4urywHTh0ndEXiV3pKHr5Q"
,
"key2"
=>
"Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3"
,
"endpoint"
=>
"https://sbgateway.zalopay.vn/api/getlistmerchantbanks"
];
$reqtime
=
round
(
microtime
(
true
)
*
1000
);
// miliseconds
$params
=
[
"appid"
=>
$config
[
"appid"
],
"reqtime"
=>
$reqtime
,
"mac"
=>
hash_hmac
(
"sha256"
,
$config
[
"appid"
]
.
"|"
.
$reqtime
,
$config
[
"key1"
])
// appid|reqtime
];
$resp
=
file_get_contents
(
$config
[
"endpoint"
]
.
"?"
.
http_build_query
(
$params
));
$result
=
json_decode
(
$resp
,
true
);
foreach
(
$result
as
$key
=>
$value
)
{
echo
"
$key
:
$value
<brandgt;"
;
}
# ruby 2.5.1p57
require
'json'
require
'openssl'
# gem install openssl
require
'net/http'
config
=
{
appid:
'553'
,
key1:
'9phuAOYhan4urywHTh0ndEXiV3pKHr5Q'
,
key2:
'Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3'
,
endpoint:
'https://sbgateway.zalopay.vn/api/getlistmerchantbanks'
}
params
=
{
appid:
config
[
:appid
],
reqtime:
(
Time
.
now
.
to_f
.
round
(
3
)
*
1000
).
to_i
# miliseconds
}
data
=
config
[
:appid
]
+
"|"
+
params
[
:reqtime
].
to_s
# appid|reqtime
params
[
:mac
]
=
OpenSSL
::
HMAC
.
hexdigest
(
'sha256'
,
config
[
:key1
],
data
)
uri
=
URI
(
config
[
:endpoint
])
uri
.
query
=
URI
.
encode_www_form
(
params
)
res
=
Net
::
HTTP
.
get_response
(
uri
)
result
=
JSON
.
parse
(
res
.
body
)
puts
"returncode: "
+
result
[
"returncode"
].
to_s
puts
"returnmessage: "
+
result
[
"returnmessage"
]
result
[
"banks"
].
each
do
|
pmcid
,
banklist
|
banklist
.
each
do
|
bank
|
puts
"
#{
pmcid
}
.
#{
bank
}
"
end
end
# coding=utf-8
# Python 3.6
from
time
import
time
import
hmac
,
hashlib
,
urllib
.
parse
,
urllib
.
request
config
=
{
"appid"
:
553
,
"key1"
:
"9phuAOYhan4urywHTh0ndEXiV3pKHr5Q"
,
"key2"
:
"Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3"
,
"endpoint"
:
"https://sbgateway.zalopay.vn/api/getlistmerchantbanks"
}
reqtime
=
int
(
round
(
time
()
*
1000
))
# miliseconds
data
=
"{}|{}"
.
format
(
config
[
"appid"
],
reqtime
)
# appid|reqtime
params
=
{
"appid"
:
config
[
"appid"
],
"reqtime"
:
reqtime
,
"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
())
print
(
"returncode: {}"
.
format
(
result
[
"returncode"
]))
print
(
"returnmessage: {}"
.
format
(
result
[
"returnmessage"
]))
for
pmcid
,
banklist
in
result
[
"banks"
]
.
items
():
for
ngân hàng
in
banklist
:
print
(
"{}. {}"
.
format
(
pmcid
,
bank
))
curl https://sbgateway.zalopay.vn/api/getlistmerchantbanks
-d appid
=
553
-d reqtime
=
1555640370536
-d mac
=
e2c88a751fc3862f79648e9524cf865ae05579b4435a74dae5992867c3b412ca
Redirect
Sau khoảng thời gian người dùng hoàn thiện thanh toán, ZaloPay Gateway sẽ redirect về trang hiển thị kết quả của Merchant (theo redirect_url
Merchant đã phân phối cho ZaloPay).
Dữ liệu truyền vào query string khi ZaloPay redirect về trang của Merchant:
Tham số
Kiểu dữ liệu
Ý nghĩa
appid
intappid
của đơn hàng
apptransid
Stringapptransid
của đơn hàng
pmcid
int
Kênh thanh toán
bankcode
String
Mã ngân hàng
amount
long
Giá trị của đơn hàng VND
discountamount
long
Giảm giá VND
status
int
Mã lỗichecksum
String
Dùng để xác minh redirect có hợp lệ hay không.
Xác minh hmac hợp lệ: HMAC(hmac_algorithm, key2, appid +"|"+ apptransid +"|"+ pmcid +"|"+ bankcode +"|"+ amount +"|"+ discountamount +"|"+ status)
Khi thu được redirect hợp lệ, Merchant cần xác minh xem đã thu được callback hay chưa, nếu chưa Merchant sử dụng API truy vấn trạng thái thanh toán của đơn hàng để lấy kết quả cuối cùng
Code mẫu xác minh Redirect hợp lệ
/*
ASP.Net core
*/
using
Microsoft.AspNetCore.Mvc
;
using
ZaloPay.Helper
;
// HmacHelper, RSAHelper, HttpHelper, Utils (tải về ở mục DOWNLOADS)
using
ZaloPay.Helper.Crypto
;
namespace
ZaloPayExample.Controllers
{
[
Route
(
"[controller]"
)]
[
ApiController
]
public
class
RedirectController
:
ControllerBase
{
private
string
key2
=
"Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3"
;
[
HttpGet
]
public
IActionResult
Get
()
{
var
data
=
Request
.
Query
;
var
checksumData
=
data
[
"appid"
]
+
"|"
+
data
[
"apptransid"
]
+
"|"
+
data
[
"pmcid"
]
+
"|"
+
data
[
"bankcode"
]
+
"|"
+
data
[
"amount"
]
+
"|"
+
data
[
"discountamount"
]
+
"|"
+
data
[
"status"
];
var
checksum
=
HmacHelper
.
Compute
(
ZaloPayHMAC
.
HMACSHA256
,
key2
,
checksumData
);
if
(!
checksum
.
Equals
(
data
[
"checksum"
]))
{
return
StatusCode
(
400
,
"Bad Request"
);
}
else
{
// xác minh xem đã thu được callback hay chưa, nếu chưa thì tiến hành gọi API truy vấn trạng thái thanh toán của đơn hàng để lấy kết quả cuối cùng
return
StatusCode
(
200
,
"OK"
);
}
}
}
}
import
org.json.JSONObject
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.website.bind.annotation.GetMapping
;
import
org.springframework.website.bind.annotation.RequestParam
;
import
javax.crypto.Mac
;
import
javax.crypto.spec.SecretKeySpec
;
import
javax.xml.bind.DatatypeConverter
;
import
java.util.Map
;
import
java.util.logging.Logger
;
@Controller
public
class
RedirectController
{
private
Logger
logger
=
Logger
.
getLogger
(
this
.
getClass
().
getName
());
private
String
key2
=
"Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3"
;
private
Mac
HmacSHA256
;
public
RedirectController
()
throws
Exception
{
HmacSHA256
=
Mac
.
getInstance
(
"HmacSHA256"
);
HmacSHA256
.
init
(
new
SecretKeySpec
(
key2
.
getBytes
(),
"HmacSHA256"
));
}
@GetMapping
(
"/redirect-from-zalopay"
)
public
ResponseEntity
redirect
(
@RequestParam
Map
<
String
,
String
>
data
)
{
String
checksumData
=
data
.
get
(
"appid"
)
+
"|"
+
data
.
get
(
"apptransid"
)
+
"|"
+
data
.
get
(
"pmcid"
)
+
"|"
+
data
.
get
(
"bankcode"
)
+
"|"
+
data
.
get
(
"amount"
)
+
"|"
+
data
.
get
(
"discountamount"
)
+
"|"
+
data
.
get
(
"status"
);
byte
[]
checksumBytes
=
HmacSHA256
.
doFinal
(
checksumData
.
getBytes
());
String
checksum
=
DatatypeConverter
.
printHexBinary
(
checksumBytes
).
toLowerCase
();
JSONObject
result
=
new
JSONObject
();
if
(!
checksum
.
equals
(
data
.
get
(
"checksum"
)))
{
return
ResponseEntity
.
badRequest
().
body
(
"Bad Request"
);
}
else
{
// xác minh xem đã thu được callback hay chưa, nếu chưa thì tiến hành gọi API truy vấn trạng thái thanh toán của đơn hàng để lấy kết quả cuối cùng
return
ResponseEntity
.
ok
(
"OK"
);
}
}
}
// go version go1.11.1 linux/amd64
package
main
import
(
"fmt"
"log"
"net/http"
"github.com/zpmep/hmacutil"
)
// App config
var
(
key2
=
"Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3"
)
func
main
()
{
mux
:=
http
.
DefaultServeMux
mux
.
HandleFunc
(
"/redirect-from-zalopay"
,
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
r
.
ParseForm
()
data
:=
r
.
Form
checksumData
:=
data
.
Get
(
"appid"
)
+
"|"
+
data
.
Get
(
"apptransid"
)
+
"|"
+
data
.
Get
(
"pmcid"
)
+
"|"
+
data
.
Get
(
"bankcode"
)
+
"|"
+
data
.
Get
(
"amount"
)
+
"|"
+
data
.
Get
(
"discountamount"
)
+
"|"
+
data
.
Get
(
"status"
)
checksum
:=
hmacutil
.
HexStringEncode
(
hmacutil
.
SHA256
,
key2
,
checksumData
)
if
checksum
!=
data
.
Get
(
"checksum"
)
{
w
.
WriteHeader
(
400
)
fmt
.
Fprint
(
w
,
"Bad Request"
)
}
else
{
// xác minh xem đã thu được callback hay chưa, nếu chưa thì tiến hành gọi API truy vấn trạng thái thanh toán của đơn hàng để lấy kết quả cuối cùng
fmt
.
Fprint
(
w
,
"Ok"
)
}
})
log
.
Println
(
"Server is listening at port :8001"
)
http
.
ListenAndServe
(
":8001"
,
mux
)
}
// Node v10.15.3
const
CryptoJS
=
require
(
'crypto-js'
);
const
express
=
require
(
'express'
);
const
app
=
express
();
const
config
=
{
key2
:
"Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3"
};
app
.
get
(
'/redirect-from-zalopay'
,
(
req
,
res
)
=>
{
let
data
=
req
.
query
;
let
checksumData
=
data
.
appid
+
'|'
+
data
.
apptransid
+
'|'
+
data
.
pmcid
+
'|'
+
data
.
bankcode
+
'|'
+
data
.
amount
+
'|'
+
data
.
discountamount
+
'|'
+
data
.
status
;
let
checksum
=
CryptoJS
.
HmacSHA256
(
checksumData
,
config
.
key2
).
toString
();
if
(
checksum
!=
data
.
checksum
)
{
res
.
sendStatus
(
400
);
}
else
{
// xác minh xem đã thu được callback hay chưa, nếu chưa thì tiến hành gọi API truy vấn trạng thái thanh toán của đơn hàng để lấy kết quả cuối cùng
res
.
sendStatus
(
200
);
}
});
app
.
listen
(
8001
,
function
()
{
console
.
log
(
'Server is listening at port :8001'
);
});
<?php
// PHP Version 7.3.3
$key2
=
"Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3"
;
$data
=
$GET
;
$checksumData
=
$data
[
"appid"
]
.
"|"
.
$data
[
"apptransid"
]
.
"|"
.
$data
[
"pmcid"
]
.
"|"
.
$data
[
"bankcode"
]
.
"|"
.
$data
[
"amount"
]
.
"|"
.
$data
[
"discountamount"
]
.
"|"
.
$data
[
"status"
];
$checksum
=
hash_hmac
(
"sha256"
,
$checksumData
,
$key2
);
if
(
strcmp
(
$mac
,
$data
[
"checksum"
])
!=
)
{
http_response_code
(
400
);
echo
"Bad Request"
;
}
else
{
// xác minh xem đã thu được callback hay chưa, nếu chưa thì tiến hành gọi API truy vấn trạng thái thanh toán của đơn hàng để lấy kết quả cuối cùng
http_response_code
(
200
);
echo
"Ok"
;
}
# ruby 2.5.1p57
# rails 5.2.3
# config/routes.rb
# Rails.application.routes.draw do
# match '/redirect-from-zalopay' => 'redirect#handle', via: :get
# end
# app/controllers/redirect_controller.rb
require
'json'
require
'openssl'
class
RedirectController
<
ApplicationController
def
initialize
super
@config
=
{
key2:
'Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3'
}
end
# POST /callback
def
handle
data
=
request
.
query_parameters
checksumData
=
data
[
"appid"
]
+
"|"
+
data
[
"apptransid"
]
+
"|"
+
data
[
"pmcid"
]
+
"|"
+
data
[
"bankcode"
]
+
"|"
+
data
[
"amount"
]
+
"|"
+
data
[
"discountamount"
]
+
"|"
+
data
[
"status"
]
checksum
=
OpenSSL
::
HMAC
.
hexdigest
(
'sha256'
,
@config
[
:key2
],
checksumData
)
if
checksum
!=
data
[
'checksum'
]
render
text:
'Bad Request'
,
status: :bad_request
else
# xác minh xem đã thu được callback hay chưa, nếu chưa thì tiến hành gọi API truy vấn trạng thái thanh toán của đơn hàng để lấy kết quả cuối cùng
render
text:
'OK'
,
status: :ok
end
end
end
# coding=utf-8
# Python 3.6
from
flask
import
Flask
,
request
,
json
import
hmac
,
hashlib
app
=
Flask
(
__name__
)
config
=
{
'key2'
:
'Iyz2habzyr7AG8SgvoBCbKwKi3UzlLi3'
}
@app.route
(
'/redirect-from-zalopay'
,
methods
=
[
'GET'
])
def
redirect
():
data
=
request
.
args
checksumData
=
"{}|{}|{}|{}|{}|{}|{}"
.
format
(
data
.
get
(
'appid'
),
data
.
get
(
'apptransid'
),
data
.
get
(
'pmcid'
),
data
.
get
(
'bankcode'
),
data
.
get
(
'amount'
),
data
.
get
(
'discountamount'
),
data
.
get
(
'status'
))
checksum
=
hmac
.
new
(
config
[
'key2'
]
.
encode
(),
checksumData
,
hashlib
.
sha256
)
.
hexdigest
()
if
checksum
!=
data
.
get
(
'checksum'
):
return
"Bad Request"
,
400
else
:
# xác minh xem đã thu được callback hay chưa, nếu chưa thì tiến hành gọi API truy vấn trạng thái thanh toán của đơn hàng để lấy kết quả cuối cùng
return
"Ok"
,
200
if
__name__
==
'__main__'
:
app
.
run
(
hosting
=
'0.0.0.0'
,
port
=
8001
)