베트남 결제 API에 연결하는 방법은 무엇인가요? 실용적인 튜토리얼 개발
베트남 결제 API 액세스 개발 실무 가이드
I. 베트남의 주요 결제 플랫폼 개요
베트남에서 결제 API 통합을 위해 고려해야 할 주요 플랫폼은 다음과 같습니다:
- 모모 월렛 - 베트남에서 가장 인기 있는 전자지갑
- ZaloPay - Zalo 소셜 소프트웨어의 결제 솔루션
- VNPAY - 은행 연합에서 지원하는 게이트웨이 서비스
- Payoo - 오프라인 매장이 많은 결제 방법
- OnePay - 비자/마스터카드 현지화 프로그램
II. 액세스 준비
1. 판매자 계정 등록
- Momo. https://business.momo.vn/
- VNPAY. https://vnpay.vn/merchant.html
- ZaloPay. https://zalopay.vn/business/
2. API 문서 액세스
최신 API 문서는 각 플랫폼의 개발자 센터에서 확인할 수 있습니다:
- 모모 개발자 포털: https://developers.momo.vn/
- VNPAY 기술 문서: https://vnpay.vn/category/technical/
III. 모모 API 액세스 예시(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 예제)
공용 클래스 VNPayConfig {
공용 정적 문자열 vnp_PayUrl = "https://sandbox.vnpayment.vn/paymentv2/vpcpay.html";
공용 정적 문자열 vnp_Returnurl = "http://localhost:8080/vnp_return.jsp";
공용 정적 문자열 vnp_TmnCode = "YourTmnCodeHere";
...
// HMAC-SHA512 알고리즘으로 보안 해시 생성하기
private static String hmacSHA512(final String key,final String data){
try{
Mac sha512_HMAC=Mac.getInstance("HmacSHA512");
비밀 키 사양 secret_key=새 비밀 키 사양(key.getBytes(), "HmacSHA512");
sha512_HMAC.init(secret_key);
byte[] binary_data=sha512_HMAC.doFinal(data.getBytes());
문자열 빌더 sb=새 문자열 빌더(binary_data.length*2);
for(바이트 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{
캘린더 cld=Calendar.getInstance();
SimpleDateFormat 포맷터=새 SimpleDateFormat("yyyyMMddHHmmss");
맵 매개변수=새 해시맵();
params.put("vnp_Version", "2.1.0");
params.put("vnp_Command", "pay");
...
필드 이름 목록=새 배열 목록(params.keySet());
컬렉션.정렬(필드 이름).
문자열 빌더 해시데이터빌더=새 문자열 빌더();
for(String fieldName : fieldNames){
if(params.get(fieldName)! =null&&!params.get(fieldName).isEmpty()){
해시데이터빌더.추가((필드명+""));
...
}
}
SecureRandom 무작위 무작위=SecureRandom.getInstanceStrong();
int randomNumber=(int)(randomSecure Random.nextDouble()*100000000)+10000000;
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}")
else.
logger.warning("잘못된 서명이 감지되었습니다!")
반환 응답(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 포스트맨 디버깅 예제
// 모모 결제 요청 예시 (POST /v2/gateway/api/create)
{
"파트너코드": "MOMOXKXX".
"파트너 이름": "테스트 판매자",
"storeId": "테스트 스토어",
"요청 유형": "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 무제한 | 최대 은행 계좌 잔액 | |
Zalo Pay 기업 계정 | – | 200억/일 |
VIII. 다국어 오류 처리 프로그램
공용 클래스 PaymentErrorHandler {
private static final Map MOMO_ERRORS=새 해시맵(){{
put(0, "Giao dịch thành công"); put(-6, "Signature không hợp lệ");}};
private static final Map VNPAY_ERRORS=새 해시맵(){{
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".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(),
INDEX idx_gateway_status(gateway.status));`
Redis 캐싱 애플리케이션:
cache_key=f'momo_callback_{transid}' if cache.get(cache_key).
logger.warning(f'중복 콜백 감지:{transid}')
else.
cache.set(cache_key,'processed',timeout=300)#5분 만료`
특정 플랫폼에 대한 자세한 구현이 필요하거나 특정 문제가 발생하는 경우 우려되는 영역을 알려주세요.