Как подключиться к Vietnam Payment API? Разработка практических руководств
Практическое руководство по разработке платежного API-доступа во Вьетнаме
I. Обзор основных платежных платформ во Вьетнаме
Ниже перечислены основные платформы, которые следует рассматривать для интеграции платежных API во Вьетнаме:
- Кошелек Momo - Самые популярные электронные кошельки во Вьетнаме
- ZaloPay - Платежные решения под зонтиком социального программного обеспечения Zalo
- VNPAY - Услуги шлюза, поддерживаемые Банковским союзом
- Payoo - Способы оплаты во многих офлайн-магазинах
- OnePay - Программа локализации Visa/Mastercard
II. Подготовка к доступу
1. зарегистрируйте торговый счет
- Момо. https://business.momo.vn/
- VNPAY. https://vnpay.vn/merchant.html
- ZaloPay. https://zalopay.vn/business/
2. доступ к документации API
Самая свежая документация по API доступна в Центре разработчика каждой платформы:
- Портал для разработчиков Momo: https://developers.momo.vn/
- Техническая документация VNPAY: https://vnpay.vn/category/technical/
III. Пример доступа к API Momo (PHP)
<?php
function execPostRequest($url, $data) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen(json_encode($data)))
);
$result = curl_exec($ch);
return json_decode($result); // decode response JSON to object PHP
}
// Momo配置参数 (从商户后台获取)
$partnerCode = "MOMOXXXX";
$accessKey = "XXXXXXXXXX";
$secretKey = "XXXXXXXXXXXXXXXXXXXXXXXX";
//订单信息设置
$orderId = time() .""; // unique order ID
$orderInfo = "Thanh toán qua MoMo"; // payment content description
$amount = $_POST['total_amount']; // total amount need pay
$notifyUrl = "https://yourdomain.com/momo_notify.php"; // callback URL after payment success/fail
$returnUrl = "https://yourdomain.com/thankyou.php"; // redirect URL after payment complete
//生成签名(SHA256加密)
$requestId= time()."";
$rawHash= "accessKey=".$accessKey."&amount=".$amount."&extraData=&ipnUrl=".$notifyUrl."&orderId=".$orderId."&orderInfo=".$orderInfo."&partnerCode=".$partnerCode."&redirectUrl=".$returnUrl."&requestId=".$requestId;
if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
$base_url_payment='https';
} else {
$base_url_payment='http';
}
//拼接完整请求数据
array (
'partnerCode' => $partnerCode,
'accessKey' => $accessKey,
'requestId' => $requestId,
'amount' => strval ($amount),
'orderId' => strval ($order_id),
...
);
try {
/* call api to momo server */
if(!empty($_POST)){
header('Location : '.execPostRequest("...",...));
exit();
}
} catch(Exception ex){ ... }
?>
IV. Основные этапы интеграции VNPAY (пример Java)
public class VNPayConfig {
public static String vnp_PayUrl = "https://sandbox.vnpayment.vn/paymentv2/vpcpay.html";
public static String vnp_Returnurl = "http://localhost:8080/vnp_return.jsp";
public static String vnp_TmnCode = "YourTmnCodeHere";
...
// Генерируем защищенный хэш с помощью алгоритма HMAC-SHA512
private static String hmacSHA512(final String key,final String data){
попытка{
Mac sha512_HMAC=Mac.getInstance("HmacSHA512");
SecretKeySpec secret_key=new Secret KeySpec(key.getBytes(), "HmacSHA512");
sha512_HMAC.init(secret_key).
byte[] binary_data=sha512_HMAC.doFinal(data.getBytes());
StringBuilder sb=new StringBuilder(binary_data.length*2);
for(byte b : binary_data){
sb.append(String.format("%02x",b &0xff));
}
return sb.toString();
}catch(Exception e){throw new RuntimeException(e);}
}
public Map createPayment(Long amount,String bankcode) throws UnsupportedEncodingException{
Календарь cld=Calendar.getInstance();
SimpleDateFormat formatter=new SimpleDateFormat("yyyyMMddHHmmss");
Map params=new HashMap();
params.put("vnp_Version", "2.1.0");
params.put("vnp_Command", "pay");
...
List fieldNames=new ArrayList(params.keySet());
Collections.sort(fieldNames).
StringBuilder hashDataBuilder=new StringBuilder();
for(String fieldName : fieldNames){
if(params.get(fieldName)! =null&&!params.get(fieldName).isEmpty()){
hashDataBuilder.append((fieldName+""));
...
}
}
SecureRandom randomSecureRandom=SecureRandom.getInstanceStrong();
int randomNumber=(int)(randomSecure Random.nextDouble()*100000000)+10000000;
params.put(... ,String.valueOf(randomNumber));
return signedParams;
}
V. Общие проблемы и советы по отладке
1.Проверка подписи не удалась
- Правильно ли реализован алгоритм SHA256/HMAC-SHA512?
- Порядок расположения ключей и параметров строго соответствует документации?
2.обработка обратного вызова
if verify_signature(request.json): # Пользовательская функция проверки подписи
если result_code==0.
logger.info(f "Платеж прошел успешно:{trans_id}")
еще.
logger.warning("Обнаружена недопустимая подпись!")
return Response(status.HTTP_200_OK)
3.Рекомендации по испытательной среде
Все платформы предоставляют среду "песочницы", как и рекомендуется:
Практическое руководство по разработке доступа к платежному API во Вьетнаме (продолжение)
V. Рекомендации по тестовой среде и методы отладки (продолжение)
3.1 Адреса сред "песочницы" в зависимости от платформы
- Песочница Момо: https://test-payment.momo.vn
- Песочница VNPAY: https://sandbox.vnpayment.vn/apis/
- Тестовая среда ZaloPay: https://sb-openapi.zalopay.vn/
3.2 Пример отладки Postman
// Пример запроса на оплату Momo (POST /v2/gateway/api/create)
{
"PartnerCode": "MOMOXKXX".
"partnerName": "Test Merchant",
"storeId": "Test Store",
"requestType": "captureWallet".
"ipnUrl": "https://yourdomain.com/momo_callback",
//... Другие необходимые поля...
}
VI. Код ключа интеграции ZaloPay (пример на Node.js)
const crypto = require('crypto');
const axios = require('axios');
// ZaloPay配置参数
const config = {
app_id: '2554',
key1: 'sdngKKJmqEMzvh5QQcdD2A9XBSKUNaYn',
endpoint: 'https://sb-openapi.zalopay.vn/v2/create'
};
//生成MAC签名(HMAC-SHA256)
function generateMac(data, key) {
return crypto.createHmac('sha256', key)
.update(data)
.digest('hex');
}
async function createZaloPayment(order) {
const timestamp = Date.now();
const uid = `${timestamp}${Math.floor(Math.random() *999)}`;
const params = {
app_id: config.app_id,
app_trans_id: `${moment().format('YYMMDD')}_${order.id}`,
app_user: order.userId,
amount: order.amount,
item: JSON.stringify(order.items),
description:`Thanh toan don hang #${order.id}`,
};
//按文档要求排序并拼接签名字符串
let dataStr= Object.keys(params).sort()
.map(key=>`${key}=${params[key]}`).join("&");
params.mac= generateMac(dataStr,config.key1);
try{
const response= await axios.post(config.endpoint,params);
if(response.data.return_code===1){
return response.data.order_url; //跳转到ZaloPay的支付页面URL
}else{
throw new Error(`ZaloPay error:[${response.data.sub_return_code}] ${response.data.sub_return_message}`);
}
}catch(error){
console.error("调用ZALOPAY API失败:",error);
throw error;
}
}
VII. Заметки по развертыванию производственной среды
7.1 Требования к сертификату SSL
Все интерфейсы обратного вызова должны.
- Протокол HTTPS (HTTP не поддерживается)
- Версия TLS ≥ 1.2 (в соответствии с требованиями Центрального банка Вьетнама)
7.2 Настройки белых списков IP-адресов
Добавьте IP-адрес сервера в белый список в бэкенде торговца:
# VNPAY Merchant Back Office Пример.
120.72.*. * (сегмент IP вашего сервера)
14.. *. * (альтернативный сегмент IP)
7.3 Управление лимитами транзакций
терраса | Одиночный минимум | Одиночный максимум |
---|---|---|
MOMO | 10,000₫ | 50,000,000₫ |
VNPAY Unlimited | Максимальный остаток на банковском счете | |
Корпоративный счет Zalo Pay | – | ₫20 миллиардов в день |
VIII. Многоязычная программа обработки ошибок
public class PaymentErrorHandler {
private static final Map MOMO_ERRORS=new HashMap(){{
put(0, "Giao dịch thành công"); put(-6, "Signature không hợp lệ");}};
private static final Map VNPAY_ERRORS=new HashMap(){{
put("00", "GD thanh cong");put("07", "Trừ tiền thành công GD bị nghi ngờ");}};
public String localizeError(String provider,int code,String locale){
switch(locale.toLowerCase()){
случай "vi".
return "vi".equals(locale)?MOMO_ERRORS.get(code):getEnglishMessage(code);
по умолчанию.
return getEnglishMessage(code);}}
}
IX. Рекомендации по оптимизации производительности
Оптимизация проектирования баз данных:
id BIGSERIAL PRIMARY KEY ,
шлюз VARCHAR(20)/* momo/vnpay/zalopay */ ,
trans_id VARCHAR(64)/* Номер транзакции шлюза*/ ,
статус SMALLINT/*0= ожидание, 1= успех**/ ,
created_at TIMESTAMPT NOT NULL DEFAULT NOW(),
ИНДЕКС idx_gateway_status(gateway.status));`
Приложение для кэширования Redis:
cache_key=f'momo_callback_{transid}' if cache.get(cache_key).
logger.warning(f'Duplicate callback detected:{transid}')
еще.
cache.set(cache_key,'processed',timeout=300)#5 minutes expires`
Для более детальной реализации конкретной платформы или при возникновении специфических проблем вы можете сообщить мне о них.