PHP銀聯オンライン決済インターフェースの開発例
この記事では主に PHP UnionPay オンライン決済インターフェースの開発例を紹介し、皆様のお役に立てれば幸いです。
1. UnionPay セルフサービス テスト プラットフォームにログインします (ログイン アドレス: open.unionpay.com)。次のように、[マイ 製品] をクリックします。たとえば、モバイル Web 決済 (WAP 決済) がその例です。
2. 以下に示すように、左側のメニューのテスト パラメーターをクリックして、テスト プロセスに必要なパラメーターを表示します。 テスト証明書をクリックし、2 つの証明書をダウンロードします。1 つはサフィックスが付いた秘密キー証明書です。 .pfx、もう 1 つはサフィックス .cer が付いた公開キー証明書です。ダウンロード後、秘密キー証明書ファイルの名前は acp_test_sign.pfx に変更されます。または、ダウンロードしない場合は、この例を直接使用することもできます。 TP3.2 の例では、すべての証明書ファイルが Public/cer にあります。
3. TP3.2 のサンプルには、テストに使用できる関連コードが含まれています。コード内にコメントがあります。開始する前に、環境の PHP バージョンが 5.3 に基づいていることを確認してください。curl および openssl 機能を有効にする必要があり、テストはオンラインで実行する必要があります。問題が発生した場合は、このフォルダーにある PHP バージョンの SDK を参照してください。これは、私がテストしたときは実行できませんでした。何が起こったのか分かりません。
4. 運用環境に切り替えて、次の問題に注意してください:
4.1 まず、受け取った販売者アクティベーション電子メールの指示に従って、Web サイト http://cs.cfca.com.cn/ にアクセスします。実稼働証明書ファイル:
[ダウンロード] をクリックした後、ダウンロード操作が完了すると、ダウンロードが成功したことを示すプロンプトがページに表示されます。ダウンロードした証明書は自動的に IE に保存されます。次のステップは証明書をエクスポートすることです。
4.2 証明書ファイルをエクスポートする: IE ブラウザを開き、右上隅にある歯車をクリックし、ツール = "インターネット オプション =" コンテンツ = "証明書を開きます。図に示すように:
上の図で赤でマークされた名前は、ダウンロードしたものと同じである必要があります。
それを見つけて [エクスポート] をクリックします: 途中の次のステップでは、次の手順に注意する必要があります
エクスポートした acp_prod_sign.pfx ファイルをアップロードし、[アップロード] をクリックします。
次のステップでは、UnionPay 公開キーをダウンロードします
ファイルを解凍し、中にある 2 つの証明書を /Public/cer に置きます。次に、config.php に移動し、ファイルのコメントに従って実稼働環境に切り替えます。
TP3.2のコード情報は以下のとおりです:
/App/Home/Conf/config.php
<?phpreturn array( //'配置项'=>'配置值' 'UNIONPAY' => array(// 银联配置 //测试环境参数 'frontUrl' => 'https://101.231.204.80:5000/gateway/api/frontTransReq.do', //测试环境前台交易请求地址 //'frontUrl' => 'https://gateway.95516.com/gateway/api/frontTransReq.do', //生产环境前台交易请求地址 'singleQueryUrl' => 'https://101.231.204.80:5000/gateway/api/backTransReq.do', //测试环境单笔查询请求地址 //'singleQueryUrl' => 'https://gateway.95516.com/gateway/api/queryTrans.do', //生产环境单笔查询请求地址 'signCertPath' =>getcwd().'/Public/cer/acp_test_sign.pfx', //签名证书路径 这个证书就是你在https://open.unionpay.com/ajweb/account/testPara 上面下载的那个商户私钥证书 供你测试使用 //'signCertPath' =>getcwd().'/Public/cer/acp_prod_sign.pfx', //签名证书路径 这个证书就是你在 商户开通邮件里面叫你去 http://cs.cfca.com.cn/ 下载并把私钥上传至商户服务网站并启用的那个私钥文件 'signCertPwd' => '000000', //测试环境签名证书密码 //'signCertPwd' => '135246', //生产环境证书签名证书密码 这个密码是你在IE导出上述私钥文件时候你自己定义的6位数字密码 //'verifyCertPath' => getcwd().'/Public/cer/verify_sign_acp.cer', //测试环境验签证书路径 'verifyCertPath' => getcwd().'/Public/cer/acp_prod_verify_sign.cer', //验签证书路径 'merId' => '777290058138754', //测试商户代码 //'merId' => '8024400481****', //生产环境商户代码 从你的商户开通邮件里面有 ), 'UNIONPAY_CONFIG'=>array(// 银联配置 'version' => '5.0.0', //版本号 'encoding' => 'GBK', //编码方式 'signMethod' => '01', //签名方式 'txnType' => '01', //交易类型 'txnSubType' => '01', //交易子类 'bizType' => '000201', //产品类型 'channelType' => '07',//渠道类型 'frontUrl' => "http://win2.qbt8.com/ase_admin/index.php/Home/ypay/pay_success", //前台通知地址 'backUrl' => "http://win2.qbt8.com/ase_admin/index.php/Home/ypay/notify", //后台通知地址 'frontFailUrl' => "http://win2.qbt8.com/ase_admin/index.php/Home/ypay/pay_fail", //失败交易前台跳转地址 'accessType' => '0', //接入类型 'merId' => '777290058138754', //测试商户代码 //'merId' => '8024400481*****', //生产环境商户代码 'txnTime' => date('YmdHis'), //订单发送时间 'currencyCode' => '156', //交易币种 ), );?>
コントローラーのコードは以下のとおりです:
<?php /* |-------------------------------------------------------------| | 银联在线支付控制器 |author:shuguang date:2016-11-16 |-------------------------------------------------------------| */ namespace Home\Controller; use Think\Controller; class YpayController extends Controller { /** * 支付配置 * @var array */ public $config = array(); /** * 支付参数,提交到银联对应接口的所有参数 * @var array */ public $params = array(); /** * 自动提交表单模板 * @var string */ private $formTemplate = <<<HTML <!DOCTYPE HTML> <meta> <title>支付</title> <p>跳转中...</p>
支付成功!
"; } /*失败交易前台跳转地址*/ public function pay_fail(){ echo "支付失败!
"; } /*生产支付参数 提交支付 */ function usespay(){ $this->config = C('UNIONPAY');//从配置里读取 $config = C('UNIONPAY_CONFIG'); $config['certId'] = $this->getSignCertId(); //证书ID $config['orderId'] = mt_rand(111111111,999999999);//订单号 自定义 $config['txnAmt'] = I("post.money")*100; //交易金额,单位分 $this->params = $config; // $_SESSION['ceshi']=$config; /* 以下是自己的业务逻辑操作 生产支付记录到本地数据库 $money = I("post.money");; $user_id = $this->user_id; $OrderId = $config['orderId'];//生成随机订单号 $pay_type = "银联";//支付方式 1余额 2支付宝 $pay_fee = M('handfee')->find(2); if ($pay_fee['type'] == 1){ $fee=$pay_fee['rate']*$money; }else { $fee=$pay_fee['fee']; } //订单表数据 $order = array( "order_id"=>$OrderId, "uid"=>$user_id, "pay_mode"=>1, "pay_channels"=>2, "fee"=>$fee, "status"=>0,//待审核 "beizhu"=>"银联在线充值", "ent_money"=>$money-$fee, "time"=>time(), "sub_time"=>time(), "pay_money"=>$money, "pay_type"=>$pay_type,//1余额支付 2支付宝支付 //"type"=>2 );*/ //$Ord=M('pay'); //$Ord->add($order); $html = $this->createPostForm();//构建自动提交HTML表单 echo $html; } function ceshi(){ dump($_SESSION); } function usernotify(){// 付款后返回商家 } function notify(){//后台通知路径 /*付款后业务逻辑代码 */ $orderId = $_POST ['orderId']; //其他字段也可用类似方式获取 $respCode = $_POST ['respCode']; //判断respCode=00或A6即可认为交易成功 if ($respCode=='00'||$respCode=='A6'){ /*通过写入文件的方式记录返回的订单号等 */ $str = "--------- ".date('Y-m-d H:i:s')." ---------"; $str .= "orderId:".$orderId."\r\n"; $str .= "respCode:".$respCode."\r\n"; $str .= "--------- END -----------"."\r\n"; file_put_contents('unionpay_notify_log.log', $str); /* 以下是支付成功后的数据库操作 请根据需要自行操作 $order['status']=1; $order['check_time']=time(); M('pay')->where(array('order_id'=>$orderId))->save($order); $order_info = M('pay')->where(array('order_id'=>$orderId))->find(); $log['user_id']=$order_info['uid']; $log['user_money']=$order_info['pay_money']; $log['change_time']=time(); $log['desc']="银联在线充值"; M('account_log')->add($log); M('users')->where('user_id='.$order_info['uid'])->setInc('user_money',$order_info['ent_money']); */ } } function unionpayfail(){ } /* function orderPay($orderinfo,$state){ $filename = 'Log/yapy'; file_put_contents($filename.'/'.$orderinfo['orderId'].'.txt', json_encode($_POST), FILE_APPEND); //$order = D('order'); //$payment = D('payment'); //$where['order_sn'] = array('in', array($orderinfo['orderId'])); //$orinfo = $order->where($where)->find(); $rs = $payment->where($where)->find(); if (empty($rs) && $orinfo['order_state'] json_encode($where1))), true); $data1['order_state'] = (int) $state; //$orderwhere['order_sn'] = array('in', array($orderinfo['orderId'])); //$order->where($orderwhere)->save($data1); if($orinfo['balance'] >0 && $orinfo['isblance'] == 1){ if($userinfo1[0]['balance']-$orinfo['balance']>=0){ $total1 = $total1-$data['balance']; $istrue = req_api("api_key", C("API_KEY"), C('USER_API') . "user/api/removeBalance/", array('user' =>session('id'),'count'=>$orinfo['balance'],'type'=>'d')); //$this->BanlanceRecord(2,$orinfo['balance'],'购物消费',session('id')); } } if ($orinfo['jindou'] >0 && $orinfo['isjindou'] == 1) { if($userinfo1[0]['user_wealth']-$orinfo['jindou']>=0){ $istrue = req_api("api_key", C("API_KEY"), C('USER_API') . "user/api/AddJindou/", array('user' =>session('id'),'count'=>$orinfo['jindou'],'type'=>'d')); $this->ChangeRecord(2,$orinfo['jindou'],'购物抵消',session('id')); $total1 = $total1-($orinfo['jindou']/100); } } $data['order_sn'] = $orderinfo['orderId']; $data['buyer_id'] = $orderinfo['certId']; $data['buyer_user'] = '银联支付'; $data['is_success'] = 'T'; $data['notify_time'] = substr($orderinfo['txnTime'],0,4)."-".substr($orderinfo['txnTime'],4,2).'-'.substr($orderinfo['txnTime'],6,2).' '.substr($orderinfo['txnTime'],8,2).':'.substr($orderinfo['txnTime'],10,2).':'.substr($orderinfo['txnTime'],12,2); $data['trade_no'] = $orderinfo['queryId']; $data['seller_id'] = $orderinfo['merId']; $data['total_fee'] = $orderinfo['txnAmt']*100; $data['sign'] = $orderinfo['signature']; $data['user_id'] = $orinfo['user_id']; $data['order_state'] = (int) $state; $data['status'] = 0; $payment->data($data)->filter('strip_tags')->add(); } $record = A('Shop/Orderrecord'); $shuju['order_state'] = (string) $state; $shuju['action_user_id'] = session('id'); $shuju['action_descrption'] = $type.'支付宝付款' . $orinfo['payable_total']; $record->ChangeOrderRecords($orinfo['_id'], $shuju); $orderrecord = A('Shop/Order'); $orderrecord->CashMoneyRecord(2, $orinfo['payable_total'], '购物消费--订单(' . $orderinfo['out_trade_no'] . ')', session('id')); layout(false); $this->assign('orderinfo', $orinfo); $this->display('Order:PaySuccess6'); } */ /** * 构建自动提交HTML表单 * @return string */ public function createPostForm() { $this->params['signature'] = $this->sign(); $input = ''; foreach($this->params as $key => $item) { $input .= "\t\t\n"; } return sprintf($this->formTemplate, $this->config['frontUrl'], $input); } /** * 验证签名 * 验签规则: * 除signature域之外的所有项目都必须参加验签 * 根据key值按照字典排序,然后用&拼接key=value形式待验签字符串; * 然后对待验签字符串使用sha1算法做摘要; * 用银联公钥对摘要和签名信息做验签操作 * * @throws \Exception * @return bool */ public function verifySign() { $publicKey = $this->getVerifyPublicKey(); $verifyArr = $this->filterBeforSign(); ksort($verifyArr); $verifyStr = $this->arrayToString($verifyArr); $verifySha1 = sha1($verifyStr); $signature = base64_decode($this->params['signature']); $result = openssl_verify($verifySha1, $signature, $publicKey); if($result === -1) { // throw new \Exception('Verify Error:'.openssl_error_string()); echo 'Verify Error:'.openssl_error_string(); } return $result === 1 ? true : false; } /** * 取签名证书ID(SN) * @return string */ public function getSignCertId() { return $this->getCertIdPfx($this->config['signCertPath']); } /** * 签名数据 * 签名规则: * 除signature域之外的所有项目都必须参加签名 * 根据key值按照字典排序,然后用&拼接key=value形式待签名字符串; * 然后对待签名字符串使用sha1算法做摘要; * 用银联颁发的私钥对摘要做RSA签名操作 * 签名结果用base64编码后放在signature域 * * @throws \InvalidArgumentException * @return multitype|string */ private function sign() { $signData = $this->filterBeforSign(); ksort($signData); $signQueryString = $this->arrayToString($signData); if($this->params['signMethod'] == 01) { //签名之前先用sha1处理 //echo $signQueryString;exit; $datasha1 = sha1($signQueryString); $signed = $this->rsaSign($datasha1); } else { //throw new \InvalidArgumentException('Nonsupport Sign Method'); echo 'Nonsupport Sign Method'; } return $signed; } /** * 数组转换成字符串 * @param array $arr * @return string */ private function arrayToString($arr) { $str = ''; foreach($arr as $key => $value) { $str .= $key.'='.$value.'&'; } return substr($str, 0, strlen($str) - 1); } /** * 过滤待签名数据 * signature域不参加签名 * * @return array */ private function filterBeforSign() { $tmp = $this->params; unset($tmp['signature']); return $tmp; } /** * RSA签名数据,并base64编码 * @param string $data 待签名数据 * @return mixed */ private function rsaSign($data) { $privatekey = $this->getSignPrivateKey(); $result = openssl_sign($data, $signature, $privatekey); if($result) { return base64_encode($signature); } return false; } /** * 取.pfx格式证书ID(SN) * @return string */ private function getCertIdPfx($path) { $data = fopen($path); $pkcs12certdata = file_get_contents($path); openssl_pkcs12_read($pkcs12certdata, $certs, $this->config['signCertPwd']); $x509data = $certs['cert']; openssl_x509_read($x509data); $certdata = openssl_x509_parse($x509data); return $certdata['serialNumber']; } /** * 取.cer格式证书ID(SN) * @return string */ private function getCertIdCer($path) { $x509data = file_get_contents($path); openssl_x509_read($x509data); $certdata = openssl_x509_parse($x509data); return $certdata['serialNumber']; } /** * 取签名证书私钥 * @return resource */ private function getSignPrivateKey() { $pkcs12 = file_get_contents($this->config['signCertPath']); openssl_pkcs12_read($pkcs12, $certs, $this->config['signCertPwd']); return $certs['pkey']; } /** * 取验证签名证书 * @throws \InvalidArgumentException * @return string */ private function getVerifyPublicKey() { //先判断配置的验签证书是否银联返回指定的证书是否一致 if($this->getCertIdCer($this->config['verifyCertPath']) != $this->params['certId']) { // throw new \InvalidArgumentException('Verify sign cert is incorrect'); echo 'Verify sign cert is incorrect'; } return file_get_contents($this->config['verifyCertPath']); } }ビューファイルの内容は以下のとおりです:
nbsp;html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <meta> <title>银联支付测试</title> <h1 id="银联支付测试">银联支付测试</h1>
証明書ファイルはここにアップロードできません。これはスクリーンショットです。自分でダウンロードできます:
交通銀行オンラインバンキングオンライン支払いインターフェース PHP で実装された ECSHOP プラグインと使用例
以上がPHP銀聯オンライン決済インターフェースの開発例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。
