ベトナム決済APIに接続するには?実践的なチュートリアルの開発

ベトナム決済APIアクセス開発実践ガイド

I. ベトナムの主要決済プラットフォームの概要

ベトナムでの決済API統合のために考慮すべき主なプラットフォームは以下の通りである:

  1. モモ・ウォレット - ベトナムで最も人気のある電子財布
  2. ザロペイ - Zaloソーシャル・ソフトウェア傘下の決済ソリューション
  3. ブイエヌペイ - 銀行同盟がサポートするゲートウェイ・サービス
  4. パユ - 多くのオフライン店舗での支払い方法
  5. ワンペイ - Visa/Mastercardローカリゼーション・プログラム

アクセスの準備

1.マーチャントアカウントの登録

2.APIドキュメントへのアクセス

最新のAPIドキュメントは、各プラットフォームのデベロッパーセンターでご覧いただけます:

  • Momo Developer Portal: https://developers.momo.vn/
  • VNPAY技術文書:https://vnpay.vn/category/technical/

III.MomoAPIアクセス例(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));
}
sb.toString() を返す;
}catch(Exception e){throw new RuntimeException(e);}.
}

public Map createPayment(Long amount,String bankcode) throws UnsupportedEncodingException{
Calendar 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)+1000000000;

params.put(... ,String.valueOf(randomNumber));

を返します;
}

V. よくある問題とデバッグのヒント

1.署名検証に失敗

  • SHA256/HMAC-SHA512アルゴリズムの実装は正しいですか?
  • キーとパラメーターの順番はドキュメントに忠実ですか?

2.コールバック処理

    if verify_signature(request.json): #カスタム署名検証機能			
if result_code==0.
logger.info(f "支払い成功:{trans_id}")
そうでなければ
logger.warning("Invalid signature detected!")
return Response(status.HTTP_200_OK)

3.テスト環境の推奨
どのプラットフォームも、推奨されるサンドボックス環境を提供している:

ベトナム決済APIアクセス開発実践ガイド(続き)

V. テスト環境の推奨とデバッグ技術(続き)

3.1 プラットフォーム別サンドボックス環境のアドレス

3.2 Postmanのデバッグ例

// Momo支払いリクエストの例 (POST /v2/gateway/api/create)
{
「partnerCode": "MOMOXKXX".
「partnerName": "Test Merchant"、
「storeId": "テスト店"、
「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マーチャントバックオフィスの例。
120.72.*.* サーバーのIPセグメント
14..*.* 代替IPセグメント

7.3 取引限度額の管理

テラス シングル・ミニマム シングル最大
MOMO 10,000₫ 50,000,000₫
VNPAYアンリミテッド 銀行口座残高の上限
ザロペイ法人口座 200億ドル/日

多言語エラー処理プログラム

パブリッククラス 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)/* ゲートウェイ取引番号*/ 、
status SMALLINT/*0=pending, 1=success**/ 、
created_at TIMESTAMPT NOT NULL DEFAULT NOW()、
INDEX 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`.

特定のプラットフォームのより詳細な実装や、特定の問題が発生した場合は、懸念事項を私に伝えることができます。