PHPでベトナムペイメントゲートウェイにアクセスするには?
ベトナムの決済ゲートウェイにアクセスするためのPHPガイド
PHPを使ってベトナムの決済ゲートウェイにアクセスするには、以下の手順に従う必要があります。例として、人気のあるベトナムの決済ゲートウェイをいくつか使用します。
一般的なベトナムの決済ゲートウェイオプション
- VNPay - 最も人気のある現地決済ソリューションのひとつ
- モモ - モバイル・ウォレット決済
- ザロペイ - もう一つの人気電子財布
- ワンペイ - Visa/MasterCardプロセッサー
VNPayの統合例
1.準備作業
- VNPay加盟店口座の登録
- マーチャントIDの取得
vnp_TmnCode
)とキー(vnp_HashSecret
) - 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();}
Momoウォレットの統合例
<?php
// momo_config.php
define("PARTNER_CODE", "");//MoMo からのパートナーコード").
define("ACCESS_KEY",""); ///MoMoからのアクセスキー").
define("SECRET_KEY",""); ///MoMoからの秘密キー").
関数 execPostRequest(url data){
ch curl_init();
curl_setopt(ch CURLOPT_URL url)。
curl_setopt(ch CURLOPT_POST true)。
curl_setopt(ch CURLOPT_POSTFIELDS data)。
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 amount orderInfo callbackUrl redirectUrl){.
endpoint = "https://test-payment.momo.vn/gw_payment/transactionProcessor";
requestId time()."";//リクエストごとにユニークなID
rawHash = "partnerCode=" PARTNER CODE.
&accessKey ACCESS KEY.
requestIdリクエストID。
金額
orderIdオーダーID .
注文情報 .
戻り Url コールバック Url .
通知 Url コールバック Url .extra データ "";
署名ハッシュ hmac sha256 生ハッシュ SECRET KEY)).
データ配列(
パートナーコード パートナーコード 、
アクセスキー ACCESS KEY 、
リクエスト Id リクエスト Id 、
金額 金額
注文 ID 注文 ID 、
注文情報 urldecode(order Info )、
リターンURL リダイレクトURL 、
コールバックURLの通知 URl 、
余分なデータ""、
リクエストタイプのキャプチャ MOウォレット "、
署名署名 ).
JSON encode(data))。
response exec Post Request(endpoint json encodedata))。
json decode(response true);
if isset(result pay UrL )) header Location result pay UrL ]); else echo Error creating payment ;}?>}?
ザロペイの統合例(同様の構造)
クラス ZalopayHelper {
const APP_ID あなたのアプリID ;
const KEY1 あなたのキー1 ;
const EMBED DATA [" merchantinfo"=> embeddata json encode([" merchant name"=> Your Store Name ])];;
public static function CreateOrder( string description long price string callback url ) {
デフォルトのタイムゾーンはアジア・ホーチミンです。)
timestamp round(microtime(true)*1000).
params [
appid self APP ID、
apptransid date(Ymd)._. timestamp,#フォーマット yyMMdd timestamp 例:21092740765200
appuser Zalo Pay Demo mの説明、
価格。
項目のJSONエンコード([])、
bankcode zalopayapp 、
callbackurlコールバックURL ];.
Mac=self Mac(params)を計算する;
params[ mac]=Mac;
response Http Helper post https sb openapi zalopay vn /vp/create params );
return json decode response body ) ;
}
private static function Compute Mac(array params ):string { {{{{{Mac(array params ):string {{{Mac(array params ):string
orderedParams [].
foreach ([ appid , apptransid , appuser amoun t apptime embda ta item ]as param){。
if isset params param]) ordered Params[]=$param.'='.$params[$param];}.
message implode(& ordered Params ).
return hash hmac sha256 message self::KEY one false );}}.
ワンペイ国際カード決済(クレジットカード用)
クラス One PayInternational
private static endpoint sandbox onep ay international com api/v two /processor ;Â
public static process 支払いカード 番号 有効期限 月 有効期限 年 cv vAmount 通貨 説明 ){.
デフォルトのタイムゾーンはアジア・ホーチミンです。)
nonce bin hex random bytes 16 ))。
ポストフィールド [...
番号札 番号 ]、
exp月満了月 ]、
exp year expiry Year ],cvv cv v]、
currency str toupper currency )、
amoun tround float val 金額 *100 ),# 単位:セント/ペンス/その他。
description substr Description fifty )、
three DSecure false ];
json payload json encode post fields base sixty four encode nonce.json payload)).
署名 base 64 encode hash hmac sha two five six nonce.payload YOUR API SECRE Ttrue))。
ヘッダー [
Content Type application/json'、
認証ベアラー。
署名;]
ch init();
set opt ch,CUR LOP TSSL VERIFYPEERfalse);
set opt ch,CUR LOP THEADE R headers );
optch CUR LOP POSTtrue)を設定する;
set optch CUR LOP POS TFIELDS payload );.
set optch CUR LOP RET UR NTR ANSFE Rtrue).
exec curlexe cch close (ch return response ;}}.
?>"
重要なヒント
上記のコードはすべて基本的なフレームワークに過ぎず、実際の実装には注意が必要である:
入力バリデーション、エラー処理、ロギングなどのセキュリティ対策が施されていなければならない。
本番環境では、HTTPSを使用し、機密データを安全な場所に保管すべきである。
最新のAPIドキュメントに従って、パラメータ名と値のフォーマットを調整する。
まず、各決済のサンドボックス環境で実装をテストすることをお勧めします。
ベトナムペイメントゲートウェイへのPHPアクセスを継続するための詳細ガイド
以下では、コールバック処理、セキュリティ対策、よくある問題の解決策など、支払い統合を改善する方法について詳しく説明する。
1.VNPayコールバック処理の実装
ユーザーが支払いを完了すると、VNPayは2つの方法でシステムに通知します:
- ブラウザのリダイレクト(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_") { { ($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) { { { ($mySecureHash === $secureHash)
if ($_GET['vnP_ResponseCode'] == '00') { { { ($_GET['vnP_ResponseCode'] == '00')
// 支払い成功のロジック
/*
* :: TODO.
* 注文ステータスを支払済みに更新する
* トランザクション情報をデータベースに記録する。
* - vnP_TxnRef は、お客様の注文 ID (VNPay に最初に渡したもの) です。
*/
echo "注文の支払いに成功しました: ".$_GET['vnP_TxnRef'];
} else {
// ユーザーによる支払いの失敗またはキャンセル
/*
* :: TODO.
* データベースの注文ステータスを失敗/キャンセルに更新する。
*/
echo "支払いに失敗しました/キャンセルされました";
}
} else {
die("無効な署名").
}
IPN処理スクリプト (ipn_listener.php)
<?php
require_once('config.php');
ファイル put contents ('ipn log.txt', print r($_POST true).".\FILE APPEND );
if (!empty($_POST)) {。
入力 Data=$ POST.
secure Hash=input Data ['vn p Secure Hash'];
unset(input Data ['vn p Secure Hash']);
ksort(入力データ).
i=0;
hash Data="";
foreach (input データをキー値として){。
if substr(key04)=="vn p"){。
if strlen(hash Dat a)>0){.
ハッシュ Dat a.='&'.url encode(key).='.url encode(value);
}else{
ハッシュ Dat a.=url encode(key).='.url encode(value);
}
}
}
check Sum=hash hmac sha512(h ash Da ta secret Key );
if check Sum== secure Has h){
トランザクションId=input Da ta ['vp Txn Ref'];
response Code=input Da ta ['vp Response Co de'];
/* TODO.
1 金額が予定額と一致しているか確認する
2 重複通知でないことを確認する
3 それに応じてデータベースを更新する */
switch(response Co de){ case "00": /* SUCCESS */ break ; default : /* FAILURE */ break ; }}else{ http response code(403);//Forbidden exit();}?>
MoMo Wallet高度な統合のヒント
Webhook認証の例
関数 verify MomoWeb フック(Request ){。
パートナーコードのリクエスト input('partner Code').
アクセスキーのリクエスト input('access Key');
リクエスト Id time()."";//元の
注文 ID リクエスト input('orderId');
量要求->入力量))。
order Info urldecode(req uest->input desc ))).
応答時間 req uest->input resp onse Time ))).
message req uest->input mes sage ))).
trans Id req uest->input transId ))).
error Cod e re quest ->in put errorCode )) ? :0.
extra D ata "";/最初に渡したカスタムデータを変更せずに返す
生灰 = "partnerCode={ partnerCo de}&accessKey={ accessKe y}&requestId={ requestI d}&amount={ amo unt}&orderId={ orderI d}".".&orderInfo={ orderInfo}&responseTime={ resonseTime}{ ext raData}";".
signatureFromMomo=req est >i nput sig nature );
ourSignature=ha sh hm ac sha256 rawH ash SECRET KEY ).
if our Signature!= Signature From Momo || errorC ode !=0){
log info ("Invalid MoMo webhook received".json encodereq est all())).
abort(400, "不正なリクエスト");}。
/* 成功した支払いはここで処理される。
return response json success truemessage OK ]200 headers Content Type application/json ];};}.
ザロペイ払い戻しプロセスの導入
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.);}}
ワンペイ国際カード決済の3Dセキュア統合
3D認証を必要とする取引の場合:
クラス ThreeDSecureHandler {
public static function initiateThreeDSecure(array カード詳細 float 金額 string 通貨 ){.
One Pay Client new One PayInternational();
auth Response one pay Client create Auth Request card Details amount currency three DSEnabled=>true]);.
three Ds Method Url auth Response three ds method url ?null.
three Ds Server Trans ID auth Response three Ds Server Trans ID ?null。
session put current payment session [ ....cardDetails ,... authResponse ]);
リダイレクトUrlルートcheckout.threedsチャレンジ名 ])。
return view checkout.threeds initiate compact redirectUrl threeDsMethodUrl threeDsServerTransId amount currency cardDetails lastFour digits]))。;)
}
public static function handle チャレンジ完了(リクエストreq ){。
session 現在の支払いセッションを取得する;
One Pay Client new OnePayInternational();
result one payClient complete Three DS Auth session get threeds server trans id ],req all());.
/* MAC/署名などを検証する。
switch finalize 結果ステータス]){。
ケースは成功した。
注文サービスマーク 有料セッションは、注文IDを取得 ]);;
ブレイク
デフォルトだ。
Order Service mark Failed(session get order id ]).
新しい PaymentFailedException() をスローする;
}}}
セキュリティのベストプラクティス
不可欠なセキュリティ対策。
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を確認する サポートへのお問い合わせ サポートチームへのお問い合わせ |
支払いは常に保留状態 | 非同期処理 決済バッチのタイミング 決済バッチのタイミング差 不正の疑い 審査中 取引状況を確認したり、カスタマーサービスに連絡したりするために、妥当な時間を待つこと。 |
各ベトナム決済プロバイダーには固有の要件があります。を参照してください。