PHP로 베트남 결제 게이트웨이에 액세스하는 방법은 무엇인가요?
PHP를 사용하여 베트남에서 결제 게이트웨이에 액세스하는 방법 가이드
PHP를 사용하여 베트남 전자결제 대행사에 액세스하려면 아래 단계를 따라야 합니다. 몇 가지 인기있는 베트남 결제 게이트웨이를 예로 들어보겠습니다.
일반적인 베트남 결제 게이트웨이 옵션
- VNPay - 가장 인기 있는 현지 결제 솔루션 중 하나
- Momo - 모바일 지갑 결제
- ZaloPay - 또 다른 인기 전자지갑
- OnePay - 비자/마스터카드 프로세서
VNPay 통합 예시
1. 준비 작업
- VNPay 판매자 계정 등록하기
- 판매자 ID 가져오기(
vnp_TmnCode
)와 키(vnp_해시시크릿
) - VNPay에서 제공하는 API 문서 및 엔드포인트 URL
2. PHP 연동 코드 예제
<?php
// config.php - VNPay配置参数
$vnp_Url = "https://sandbox.vnpayment.vn/paymentv2/vpcpay.html";
$vnp_Returnurl = "https://yourdomain.com/return_url.php"; //回调URL
$vnp_TmnCode = "YOUR_MERCHANT_CODE"; //商户号
$secretKey = "YOUR_SECRET_KEY"; //安全密钥
// vnpay_create_payment.php -创建付款请求
function createVNPayPayment($orderId, $amount, $orderInfo) {
global $vnp_Url, $vnp_Returnurl, $vnp_TmnCode, $secretKey;
date_default_timezone_set('Asia/Ho_Chi_Minh');
//准备参数数组
$inputData = array(
"version" => "2",
"command" => "pay",
'merchant' => 'VNPAY',
'tmn_code' => trim($tmnCode),
'create_date' => date('YmdHis'),
'expire_date' => date('YmdHis', strtotime('+15 minutes')),
//订单信息
'order_id' => time(),
//金额(单位为VND)
'amount'=> intval(str_replace(',','',$amount))*100,
//订单描述
'order_desc'=> urlencode($orderInfo),
return_url=> urlencode($return_url),
ip_address=> $_SERVER['REMOTE_ADDR'],
currency=>"VND",
locale=> ($lang == "") ? vn : en,
bank_code=> "",
);
ksort($inputData);
query="";
foreach ($inputData as key value){
if(substr(key0)=="_") continue;
if(!empty(query)) query.= &".key."=".$value; else query=key."=".$value;}
secureHash=hash("sha256", secret_key.query);
inputData["secure_hash"]=$secureHash;
paymentUrl=vpn_URL ."?".http_build_query(input_data);
header("Location: ".payment_url); exit();}
모모 월렛 통합 예시
<?php
// momo_config.php
define("PARTNER_CODE", "");//모모의 파트너 코드").
define("ACCESS_KEY",""); ///모모의 액세스 키").
define("SECRET_KEY",""); ///모모의 비밀키").
함수 execPostRequest(url data){
ch curl_init();
curl_setopt(ch CURLOPT_URL url).
curl_setopt(ch CURLOPT_POST true).
curl_setopt(ch CURLOPT_POSTFIELDS 데이터).
curl_setopt(ch CURLOPT_USERAGENT $_SERVER['HTTP_USER_AGENT']);
curl_setopt(ch CURLOPT_RETURNTRANSFER true);
result=curl_exec ch );curl_close ch ); return result;}
function createMomoPayment(orderId 금액 주문정보 콜백 URL redirectUrl){
엔드포인트 = "https://test-payment.momo.vn/gw_payment/transactionProcessor";
requestId time()."" 각 요청에 대한 고유 ID
rawHash = "partnerCode=" 파트너 코드.
&accessKey 액세스 키.
&requestId 요청 ID.
금액을 입력합니다.
&orderId 주문 ID .
주문 정보 .
반환 Url 콜백 Url .
알림 Url 콜백 Url .extra 데이터 "";
서명 해시 hmac sha256 원시 해시 비밀 키)).
데이터 배열(
파트너 코드 파트너 코드 ,
액세스 키 액세스 키 ,
요청 아이디 요청 아이디 ,
금액 금액 ,
주문 ID 주문 ID ,
주문 정보 urldecode(주문 정보),
리턴 URL 리디렉션 URL ,
URL 콜백 알림 URl ,
추가 데이터 "",
요청 유형 캡처 MO 지갑 ",
서명 서명 ).
JSON encode(data)).
응답 실행 포스트 리퀘스트(엔드포인트 json 인코딩 데이터)).
JSON 디코딩(응답 참);
if isset(result pay UrL )) header 위치 결과 pay UrL ]); else echo 결제 생성 오류 ;}? >}?
Zalo Pay 연동 예시(유사한 구조)
클래스 잘로페이헬퍼 {
const APP_ID 앱 ID ;
const KEY1 당신의 key1 ;
const EMBED DATA ["판매자 정보"=> embeddata json encode(["판매자 이름"=> 스토어 이름 ])];;
public static 함수 CreateOrder( 문자열 설명 긴 가격 문자열 콜백 URL ){
날짜 기본 표준 시간대 설정 아시아 호치민 ).
타임스탬프 라운드(마이크로타임(참)*1000).
매개변수 [
appid 자체 앱 ID,
앱 트랜지드 날짜(YMD). _. 타임스탬프,# 형식 yyMMdd 타임스탬프 예: 21092740765200
앱 사용자 Zalo Pay 데모 및 설명,
amoun tprice.
항목 JSON 인코딩([]),
은행코드 zalopayapp ,
콜백URL 콜백URL ];.
Mac=자신 계산 Mac(매개변수);
params[ mac]=Mac;
응답 Http 헬퍼 포스트 https sb 오픈에이피 잘로페이 베트남 /vp/create 매개변수 );
반환 JSON 디코딩 응답 본문) ;
}
비공개 정적 함수 Compute Mac(배열 매개 변수 ):문자열 {
orderedParams [].
foreach ([ 앱ID , 앱트랜시드 , 앱사용자명 , 앱시간 엠베드타 항목 ]as param){{
if isset params param]) ordered Params[]=$param.'='.$params[$param];}
메시지 임포딩(& 정렬된 매개변수 ).
반환 해시 hmac sha256 메시지 self::KEY 하나 거짓 );}}
One Pay 국제 카드 처리(신용 카드용)
원 페이 인터내셔널 클래스 {
개인 정적 엔드포인트 샌드박스 onep ay 국제 com API/V 2 /프로세서 ;}
공용 정적 프로세스 결제 카드 번호 만료 월 만료 년 만료 이력서 v금액 통화 설명 ){{
날짜 기본 표준 시간대 설정 아시아 호치민 ).
NONCE BIN 16진수 임의 바이트 16 )).
포스트 필드 [
번호 카드 번호 ],
만료 월 만료 월 ],
만료 연도 만료 연도 ],CVV CV V],
통화 스트링 터퍼 통화 ),
금액 *100 ),# (센트/펜스 등).
설명 하위 설명 오십 ),
세 개의 DSecure 거짓 ];
제이슨 페이로드 제이슨 인코딩 포스트 필드 기본 육십 네 인코딩 nonce.json 페이로드)).
서명 기본 60 4 인코딩 해시 해시 해시 샤 2 5 6 논스.페이로드 YOUR API SECRE Ttrue)).
헤더 [
콘텐츠 유형은 'application/json'입니다,
권한 보유자.
서명 ];
ch init();
set opt ch,CUR LOP TSSL VERIFYPEERfalse);
set opt ch,CUR LOP THEADE R 헤더 );
옵치 CUR LOP POSTtrue)를 설정합니다;
set optch CUR LOP POS TFIELDS 페이로드 );.
옵치 CUR LOP RET UR NTR ANSFE Rtrue)를 설정합니다.
실행 curlexe cch close (ch 반환 응답 ;}}
? >"
중요 팁:
위의 모든 코드는 기본 프레임워크일 뿐이며 실제 구현은 참고해야 합니다:
입력 유효성 검사, 오류 처리 및 로깅과 같은 보안 조치가 마련되어 있어야 합니다.
프로덕션 환경에서는 HTTPS를 사용하고 민감한 데이터를 안전한 위치에 저장해야 합니다.
최신 API 문서에 따라 매개변수 이름과 값 형식을 조정하세요.
먼저 각 결제의 샌드박스 환경에서 구현을 테스트하는 것이 좋습니다.
베트남 결제 게이트웨이에 대한 PHP 액세스를 계속하기 위한 자세한 가이드
아래에서 콜백 처리, 보안 조치, 일반적인 문제 해결 방법 등 결제 통합을 개선하는 방법에 대해 자세히 알아보겠습니다.
1. VNPay 콜백 처리 구현
사용자가 결제를 완료하면 VNPay는 두 가지 방법으로 시스템에 알림을 보냅니다:
- 브라우저 리디렉션(return_url)
- 서버 비동기 알림(IPN - 즉시 결제 알림)
return_url.php 샘플 코드
<?php
// config.php
require_once('config.php');
// 모든 GET 매개변수 가져오기
$vnp_Params = $_GET;
$secureHash = $vnp_Params['vnp_SecureHash'];
unset($vnp_Params['vnp_SecureHash']);
// 매개변수를 알파벳순으로 정렬
ksort($vnp_Params).
// 인증용 해시값 생성하기
$hashData = "";
foreach ($vnp_Params as $key => $value) {
if (substr($key, 0, 4) == "vnp_") {
$hashData . = urlencode($key) . "=" . urlencode($value) . "&";
}
}
$hashData = rtrim($hashData, '&');
$secureSecret = $secretKey; // config.php에서
$mySecureHash = hash_hmac('sha512', $hashData, $secureSecret);
if ($mySecureHash === $secureHash) {
if ($_GET['vnP_ResponseCode'] == '00') {
// 결제 성공 로직
/*
* :: TODO.
* :: - 주문 상태를 결제됨으로 업데이트
* :: -- 데이터베이스에 거래 정보 기록
* - vnP_TxnRef는 주문 ID(원래 VNPay에 전달한 주문 ID)입니다.
*/
echo "주문 결제 성공: ".$_GET['vnP_TxnRef'];
} else {
// 사용자가 결제 실패 또는 취소
/*
* :: TODO.
* 데이터베이스에서 주문 상태를 실패/취소로 업데이트합니다.
*/
"결제 실패/취소됨"이라는 메시지가 울립니다;
}
} else {
die("잘못된 서명").
}
IPN 처리 스크립트(ipn_listener.php)
<?php
require_once('config.php');
파일 내용 넣기 ('ipn log.txt', 인쇄 r($_POST true)." \n", 파일 추가 );
if (!empty($_POST)) {
입력 데이터=$ POST.
보안 해시=입력 데이터 ['vn p 보안 해시'];
unset(입력 데이터 ['vn p 보안 해시']);
ksort(입력 데이터).
i=0;
해시 Data="";
foreach (키 값으로 데이터 입력){
if substr(key04)=="vn p"){
if strlen(해시 Dat a)>0){
해시 Dat a.='&'.url encode(key).' ='.url 인코딩(값);
}else{
해시 Dat a.=url encode(키). ='.url 인코딩(값);
}
}
}
확인 합계=해시 hmac sha512(h 애쉬 다 타 비밀 키 );
if check 합계== 보안 Has h){
트랜잭션 Id=입력 Da ta ['vp Txn Ref'].
응답 코드=입력 다 ['vp 응답 코드'];
/* TODO.
1 예상 금액과 일치하는지 확인합니다.
2 중복 알림이 아닌지 확인하세요.
3 그에 따라 데이터베이스를 업데이트하세요 */.
switch(response Co de){ case "00": /* SUCCESS */ break ; default : /* FAILURE */ break ; }}else{ http response code(403);//Forbidden exit();}? >
MoMo 월렛 고급 통합 팁
웹훅 인증 예시
함수 검증 모모웹 훅(요청 ){}
파트너 코드 요청 입력('파트너 코드').
액세스 키 요청 입력('액세스 키');
요청 아이디 시간()."" //원본과 일치해야 함
주문 ID 요청 입력('orderId');
금액 요청->입력 금액)).
주문 정보 urldecode(요청->입력 desc )))).
응답 시간 요청->입력 응답 시간 )))).
메시지 요청->입력 메시 세이지 )))).
trans Id 요청->입력 transId )))).
오류 코드 ->에러코드 입력)) ? :0.
추가 D ata "";//처음에 전달한 사용자 지정 데이터는 이제 변경되지 않은 상태로 반환됩니다.
원시 해시 = "파트너코드={ 파트너코드}&액세스키={ 액세스키}&요청아이디={ 요청아이디}&금액={ 아모 운트}&주문아이디={ 주문아이디}"" &orderInfo={ 주문 정보}&응답 시간={ 응답 시간}{ 내선 번호}";".
signatureFromMomo=요구 사항 >아이 엔입력 서명 특성);
ourSignature=ha sh hm ac sha256 rawH ash SECRET KEY ).
서명!= 서명 모모에서 || 오류C ode ! =0){
로그 정보("유효하지 않은 MoMo 웹훅 수신".json encodereq est all())).
abort(400, "Bad Request");}
/* 여기에서 결제 성공 처리 */
반환 응답 json 성공 참 메시지 확인 ]200 헤더 콘텐츠 유형 application/json ];}
Zalo Pay 환불 프로세스 구현
class ZalopayService{
const REFUND ENDPOINT https sb openapi zalopay vn /vp/refund ;
public static function process Refund(string zp Trans Token long refund Amount string description ){
timestamp round microtime true)*1000 );
params [
appid self APP ID,
zptransid zpTransToken ,
amoun t refundAmount ,
description substr description fifty ),
timestamp timestamp ];
Mac=self Compute Mac params );
params mac]=Mac;
response Http Helper post self REFUND ENDPOINT params );
result json decode response body true );
if isset result return code])&& result return code]==1){
/*
TODO:
Update your database to reflect refund status*/
return true;}else{
Log error ("ZaloPay refund failed".print r(resulttrue));
throw new Exception Failed to process refund with Zalo Pay.);}}
One Pay 국제 카드 결제를 위한 3D 보안 통합
3D 인증이 필요한 거래의 경우:
ThreeDSecureHandler 클래스 {
public static function initiateThreeDSecure(배열 카드 세부 정보 float 금액 문자열 통화 ){
하나의 페이 클라이언트 새 하나의 페이 인터내셔널();
인증 응답 하나 지불 클라이언트 생성 인증 요청 카드 세부 정보 금액 통화 세 DSEnabled=>true]);.
세 개의 DS 메서드 URL 인증 응답 세 개의 DS 메서드 URL ? null.
세 개의 DS 서버 트랜잭션 ID 인증 응답 세 개의 DS 서버 트랜잭션 ID ? null.
세션 현재 결제 세션 넣기 [... .cardDetails ,... authResponse ]);
리디렉션 URL 경로 체크아웃.스레드 챌린지 이름 ]).
return view checkout.threeds 시작 컴팩트 리디렉션Ul threeDsMethodUl threeDsServerTransId 금액 통화 카드 세부 정보 마지막 네 자리]))) ;)
}
공용 정적 함수 핸들 챌린지 완료(Request req ){{
세션 현재 결제 세션 가져오기 ;
하나의 페이 클라이언트 새 OnePayInternational();
최종 결과 하나의 payClient 완료 세 개의 DS 인증 세션 가져 오기 서버 트랜잭션 ID ],요청 모두());.
/* MAC/ 서명 등 확인*/
switch finalize 결과 상태]){
케이스가 성공했습니다.
주문 서비스 마크 유료 세션 주문 ID 가져오기 ]);;
break;
기본값입니다.
주문 서비스 표시 실패(세션 주문 ID 가져오기 ]).
새 결제 실패 예외()를 던집니다;
}}}
보안 모범 사례
필수 보안 조치.
1.항상 콜백 유효성 검사서명을 확인하지 않고 수신 요청을 신뢰하지 마세요.
2.모든 곳에서 HTTPS 사용: 특히 콜백 URL과 민감한 데이터를 전송할 때 유용합니다.
3.CSRF 보호 구현:: 결제를 시작하는 페이지에서.
4.모든 입력 항목 소독XSS/SQL 인젝션 공격 방지.
5.중요한 이벤트 기록하지만 전체 카드 정보나 민감한 토큰은 기록하지 마세요.
6.최소한의 데이터 저장: 처리가 성공적으로 완료된 후에는 PAN/CVV를 저장하지 마세요.
7. 최신 TLS 버전(v1.2 이상)을 사용합니다.
8. 특히 직원이 변경된 후에는 API 키/비밀을 정기적으로 교체합니다.
9.여러 번의 시도 실패와 같은 의심스러운 활동을 모니터링합니다.
10.알려진 취약점에 대해 PHP 및 종속성을 패치합니다.
일반적인 문제 해결
문제 현상 | 가능한 원인 | 솔루션 |
---|---|---|
유효하지 않은/누락된 서명 오류 | 잘못된 해싱 알고리즘 알고리즘 불일치 매개변수 순서 문제 인코딩 문제 |
게이트웨이 문서 유효성 검사 재확인 정확히 동일한 매개변수 순서 보장 테스트 데이터를 사용하여 샘플 값으로 테스트하여 유효성을 검사합니다. |
콜백 미수신 | 방화벽 차단 URL이 잘못되었습니다. 일시적인 게이트웨이 중단으로 인해 일시적으로 서비스를 이용할 수 없습니다. |
게이트웨이 IP 화이트리스트 화이트리스트 설정 판매자 대시보드 판매자 백엔드 확인에서 URL 확인 지원팀에 문의 지원팀에 문의 |
결제 보류 상태는 항상 보류 중입니다. | 비동기 처리 정산 배치 타이밍 정산 배치 타이밍 차이 사기 의심 사기 의심 검토 진행 중 거래 상태를 확인하거나 고객 서비스에 문의할 때까지 적절한 시간을 기다리세요. |
각 베트남 결제 서비스 공급업체마다 특정 요구 사항이 있을 수 있으므로 연동을 시작하기 전에 항상 최신 공식 문서를 참조하세요. 통합을 시작하기 전에 항상 최신 공식 문서를 참조하세요.