PHP icbc工商銀行オープンプラットフォーム集約支払い、QRコードスキャン支払いドッキングステップ
66970 ワード
前言最近、仕事の原因で工商銀行の微信重合支払いインターフェースとQRコードスキャン支払いインターフェースをドッキングし、ネット上のphpチュートリアルが少なすぎるので、ドッキング手順を記録します.プログラム開発前の準備
1、関連インタフェースのドキュメントを読んで、工商銀行の支払いインタフェースの呼び出しの流れを熟知して、インタフェースのドキュメントの住所は以下の通りです:工商銀行のインタフェースのドキュメント.添付:集約支払インタフェース、QRコードスキャン支払インタフェース
2、関連するパラメータを準備する.共通パラメータは以下の通りである.
appid:工商銀行appid mer_id:工商銀行口座番号、商戸線下ファイル番号、特約商戸12位、特約部門15位store_code:e生活ファイル番号icbc_pulic_key:ゲートウェイ公開鍵private_key:秘密鍵publicを適用するkey:公開鍵encryptKeyの適用:AES暗号化鍵
2.1、関連パラメータソースappid,mer_id,store_code,icbc_pulic_keyはすべて工行のスタッフに提供して、private_keyは公開秘密鍵ペアを適用してjavaSdkをダウンロードした後、自分で生成することができる.Windows環境では、RSAアルゴリズムの生成を例に、binディレクトリに入り、keygen_をダブルクリックします.rsa.batファイルは、一対のRSA公開鍵と鍵を生成します.Linux環境、RSAアルゴリズムの生成を例に:binディレクトリに切り替え、実行./keygen_rsa.shコマンドは、一対のRSA公開鍵と鍵を生成します.公開秘密鍵ペアを生成した後、公開鍵をスタッフに構成します.アルゴリズムの復号化のためにencryptKey(AES暗号化鍵)構成も提供する必要があることに注意してください.
3、従業員と関連インタフェースの開通を申請して、工行はインタフェースを分けて開放して、インタフェースはあなたの口座の下に配置しなければならなくて、やっと呼び出すことができます.
4、ダウンロード工行のphpsdk注意事項:中にphpをインストールすることを要求するinfosec拡張、この拡張はca検証を完了するためにインストールされたもので、公衆番号集約支払いとQRコードスキャン支払いインタフェースは一般的にca検証ではなく、RSA 2とAESだけでは使用できないはずです.公開アルゴリズムだからです.
5、コード例、コードクラスを使用するときは、主にSDKファイルをクラスに導入します.
6、ピット注意6.1、工行公式サイトsdkファイル【DefaultIcbcClient.php】の【execute】メソッドが提供する【IcbcSignature::verify】メソッドにはパラメータが欠けており、$this->passwordパラメータを補う必要があります.そうしないと呼び出しに成功しません.完全に次のとおりです.
6.2、【AES.php】ファイル中、@mcrypt_module_OpenシリーズメソッドはPHP 7.2から廃棄されており,エラーを報告した後にエラー抑制子を付けるか,置換スキームを書き換える必要がある.
6.3、低バージョンの工行SDK【IcbcConstants.php】ファイルの中でタイムゾーンの設定が間違っていて、東八区上海に修正する必要があります.正しいコードは以下の通りです.
6.4、注文時間について現在、工行には4セットのテスト環境があり、各テスト環境のシステム時間は現実時間と一致しない.注文時間が無効なエラーと間違えた場合、工行開発者が提供した小道具を使ってテスト環境の時間を取得し、テスト環境の時間で注文有効時間を交換してください.
1、関連インタフェースのドキュメントを読んで、工商銀行の支払いインタフェースの呼び出しの流れを熟知して、インタフェースのドキュメントの住所は以下の通りです:工商銀行のインタフェースのドキュメント.添付:集約支払インタフェース、QRコードスキャン支払インタフェース
2、関連するパラメータを準備する.共通パラメータは以下の通りである.
appid:工商銀行appid mer_id:工商銀行口座番号、商戸線下ファイル番号、特約商戸12位、特約部門15位store_code:e生活ファイル番号icbc_pulic_key:ゲートウェイ公開鍵private_key:秘密鍵publicを適用するkey:公開鍵encryptKeyの適用:AES暗号化鍵
2.1、関連パラメータソースappid,mer_id,store_code,icbc_pulic_keyはすべて工行のスタッフに提供して、private_keyは公開秘密鍵ペアを適用してjavaSdkをダウンロードした後、自分で生成することができる.Windows環境では、RSAアルゴリズムの生成を例に、binディレクトリに入り、keygen_をダブルクリックします.rsa.batファイルは、一対のRSA公開鍵と鍵を生成します.Linux環境、RSAアルゴリズムの生成を例に:binディレクトリに切り替え、実行./keygen_rsa.shコマンドは、一対のRSA公開鍵と鍵を生成します.公開秘密鍵ペアを生成した後、公開鍵をスタッフに構成します.アルゴリズムの復号化のためにencryptKey(AES暗号化鍵)構成も提供する必要があることに注意してください.
3、従業員と関連インタフェースの開通を申請して、工行はインタフェースを分けて開放して、インタフェースはあなたの口座の下に配置しなければならなくて、やっと呼び出すことができます.
4、ダウンロード工行のphpsdk注意事項:中にphpをインストールすることを要求するinfosec拡張、この拡張はca検証を完了するためにインストールされたもので、公衆番号集約支払いとQRコードスキャン支払いインタフェースは一般的にca検証ではなく、RSA 2とAESだけでは使用できないはずです.公開アルゴリズムだからです.
5、コード例、コードクラスを使用するときは、主にSDKファイルをクラスに導入します.
/**
* Created by PhpStorm.
* User: lv
* Date: 2020/3/10
* Time: 13:37
*/
/**
* :
*/
class IcbcPay
{
function __construct()
{
//
require_once(ROOT_PATH . 'data/extend/icbc/icbc-api-sdk-cop-php/DefaultIcbcClient.php');
require_once(ROOT_PATH . 'data/extend/icbc/icbc-api-sdk-cop-php/UiIcbcClient.php');
}
public function index()
{
//
}
/**
*
*
* @return unknown
*/
public function getIcbcpayConfig()
{
// appid( )
$icbc_config['appid'] = '';
// ( ( 12 , 15 ))
$icbc_config['mer_id'] = '';
// e
$icbc_config['store_code'] = '';
// , 1.0.0.1
$icbc_config['interface_version'] = '1.0.0.1';
// ID; , appid
$icbc_config['tp_app_id'] = '';
//
$icbc_config['icbc_pulic_key'] = '';
//
$icbc_config['private_key'] = '';
//
$icbc_config['encrypt_key'] = '';
return $icbc_config;
}
/**
* @param $msg_id // , ,APP
* @param $tp_open_id // ; / , appid 。
* @param $out_trade_no // ;
* @param string $tran_type // OfflinePay- ,OnlinePay-
* @param $goods_body //
* @param $goods_detail // {‘good_name’:’ 300ml ’,’good_id’:’1001’,’good_num’:’1’}
* @param $order_amount // ( : )
* @param $return_url // 。 ,
* @param $notify_url // ;
* @param $mer_hint // 。 ,
* @param $attach // 。
* @return string
* , !
*/
public function setAPV2Pay($msg_id, $tp_open_id, $out_trade_no, $tran_type = 'OnlinePay', $goods_body, $goods_detail, $order_amount, $return_url, $notify_url, $mer_hint, $attach)
{
$icbc_config = $this->getIcbcpayConfig();
// ID; , ID; , ID。
$tp_app_id = $icbc_config['tp_app_id'];
// 。 1- ,
$install_times = '1';
// , 。 “HS”: , , notify_url ; “AG”:
$notify_type = 'HS';
// , HS 。 “0”: , ; “1”, ,
$result_type = '0';
$content = array(
"interface_version" => (string)$icbc_config['interface_version'],
"mer_id" => (string)$icbc_config['mer_id'],
"tp_app_id" => (string)$tp_app_id,
"tp_open_id" => (string)$tp_open_id,
"out_trade_no" => (string)$out_trade_no,
"tran_type" => (string)$tran_type,
"order_date" => (string)date("YmdHis", $_SERVER['REQUEST_TIME']),
"end_time" => (string)date("YmdHis", $_SERVER['REQUEST_TIME'] + 300), // order_date 5
"goods_body" => (string)$goods_body,
"goods_detail" => (string)$goods_detail,
"order_amount" => (string)bcmul($order_amount, 100), // ( )
"spbill_create_ip" => (string)$_SERVER['REMOTE_ADDR'],
"install_times" => (string)$install_times,
"return_url" => (string)$return_url, //
"notify_url" => (string)$notify_url, //
"notify_type" => (string)$notify_type,
"result_type" => (string)$result_type,
);
if (!empty($attach)) $content['attach'] = $attach;
if (!empty($mer_hint)) $content['mer_hint'] = $mer_hint;
//
$serviceUrl = 'https://gw.open.icbc.com.cn/ui/aggregate/payment/request/V2';
//
$request = array(
"serviceUrl" => $serviceUrl,
"method" => 'POST',// , POST GET
"isNeedEncrypt" => true,//
"extraParams" => null,// , array
"biz_content" => $content,
);
// form
$resp = $this->icbcClientForm($icbc_config, $request, $msg_id);
return $resp;
}
/**
*
* , 。
*/
public function getPayQrCode($msg_id, $out_trade_no, $pay_expire, $order_amt, $notify_url, $attach)
{
$icbc_config = $this->getIcbcpayConfig();
// 0- ;1- ; 1 0 ,
$notify_flag = '1';
// ,0: ,1: ; 1 0 ,
$sp_flag = '0';
$content = array(
'mer_id' => (string)$icbc_config['mer_id'],
'out_trade_no' => (string)$out_trade_no,
'store_code' => (string)$icbc_config['store_code'],//e
'order_amt' => (string)bcmul($order_amt, 100), // ( )
'trade_date' => (string)date("Ymd", $_SERVER['REQUEST_TIME']), //
'trade_time' => (string)date("His", $_SERVER['REQUEST_TIME']), //
'tporder_create_ip' => (string)$_SERVER['REMOTE_ADDR'],
'notify_url' => (string)$notify_url, //
'notify_flag' => (string)$notify_flag,
'sp_flag' => (string)$sp_flag,
'pay_expire' => (string)$pay_expire,//
);
if (!empty($attach)) $content['attach'] = $attach;
//
$serviceUrl = 'https://gw.open.icbc.com.cn/api/qrcode/V2/generate';
//
$request = array(
"serviceUrl" => $serviceUrl,
"method" => 'POST',// , POST GET
"isNeedEncrypt" => false,//
"extraParams" => null,// , array
"biz_content" => $content,
);
// curl ,
$resp = $this->icbcClientCurl($icbc_config, $request, $msg_id);
return $resp;
}
/**
* , , form
* @param $icbc_config
* @param $json_content
* @param $msg_id
*/
public function icbcClientForm($icbc_config, $request, $msg_id)
{
//APP , API
$appId = $icbc_config['appid'];
//
$privateKey = $icbc_config['private_key'];
// ,CA- ,RSA-RSAWithSha1,RSA2-RSAWithSha256, RSA2,
$signType = \IcbcConstants::$SIGN_TYPE_RSA2;
// , UTF-8
$charset = 'UTF-8';
// , json
$format = 'json';
//
$icbcPulicKey = $icbc_config['icbc_pulic_key'];
//AES ,
$encryptKey = $icbc_config['encrypt_key'];
// , AES
$encryptType = 'AES';
// ca , , ,php php_infosec.dll, sdk php7.0
$ca = '';
// CA , ,
$password = '';
//
$client = new \UiIcbcClient($appId, $privateKey, $signType, $charset, $format,
$icbcPulicKey, $encryptKey, $encryptType, $ca, $password);
//
$resp = $client->buildPostForm($request, $msg_id, '');
return $resp;
}
/**
* , , curl
* @param $icbc_config
* @param $json_content
* @param $msg_id
*/
public function icbcClientCurl($icbc_config, $request, $msg_id)
{
//APP , API
$appId = $icbc_config['appid'];
//
$privateKey = $icbc_config['private_key'];
// ,CA- ,RSA-RSAWithSha1,RSA2-RSAWithSha256, RSA2,
$signType = \IcbcConstants::$SIGN_TYPE_RSA2;
// , UTF-8
$charset = 'UTF-8';
// , json
$format = 'json';
//
$icbcPulicKey = $icbc_config['icbc_pulic_key'];
//AES ,
$encryptKey = $icbc_config['encrypt_key'];
// , AES
$encryptType = 'AES';
// ca , , ,php php_infosec.dll, sdk php7.0
$ca = '';
// CA , ,
$password = '';
// , sdk 【IcbcSignature::verify】 , $password , 。
$client = new \DefaultIcbcClient($appId, $privateKey, $signType, $charset, $format,
$icbcPulicKey, $encryptKey, $encryptType, $ca, $password);
//
$resp = $client->execute($request, $msg_id, '');
$resp = $resp ? json_decode($resp, true) : '';
return $resp;
}
/**
* *
* @param $postArr
* @param $notify_url url
* @return int|void
* @throws Exception
*/
public function icbcCheckSign($postArr, $notify_url)
{
$icbc_config = $this->getIcbcpayConfig();
//
$postParame = $postArr;
$sign = $postParame['sign'];
unset($postParame['sign']);
//
$WebUtils = new \WebUtils();
$IcbcSignature = new \IcbcSignature();
$path = parse_url($notify_url, PHP_URL_PATH);
$content = $WebUtils->buildOrderedSignStr($path, $postParame);
// ,CA- ,RSA-RSAWithSha1,RSA2-RSAWithSha256, RSA2,
$signType = \IcbcConstants::$SIGN_TYPE_RSA;
// , UTF-8
$charset = \IcbcConstants::$CHARSET_UTF8;
// CA , ,
$password = '';
//
$icbcPulicKey = $icbc_config['icbc_pulic_key'];
(boolean)$signVerified = $IcbcSignature->verify($content, $signType, $icbcPulicKey, $charset, $sign, $password);
return $signVerified;
}
/**
* demo
*/
public function demo()
{
include_once('data\extend\icbc\icbc-api-sdk-cop-php/UiIcbcClient.php');
$msg_id = 'aa' . rand(10000000, 999999999);
$content = array(
"interface_version" => "1.0.0.1",
"mer_id" => 'mer_id',
"tp_app_id" => 'tp_app_id',
"tp_open_id" => 'tp_open_id',
"out_trade_no" => '12311212',
"tran_type" => "OfflinePay",
"order_date" => date("YmdHis", $_SERVER['REQUEST_TIME']),
"end_time" => date("YmdHis", $_SERVER['REQUEST_TIME'] + 300), // order_date 5
"goods_body" => '12',
"goods_detail" => "{'good_name':1,'good_id':2,'good_num':'1'}",
"order_amount" => bcmul(0.01, 100), // ( )
"spbill_create_ip" => $_SERVER['REMOTE_ADDR'],
"install_times" => "1",
"return_url" => "http://ip/index/pay/successful", //
"notify_url" => "http://ip/index/pay/notify", //
"notify_type" => "HS",
"result_type" => "0",
);
$request = array(
"serviceUrl" => 'https://gw.open.icbc.com.cn/api/qrcode/V2/generate',
"method" => 'POST',
"isNeedEncrypt" => true,
"extraParams" => null,
"biz_content" => $content,
);
$client = new \UiIcbcClient('appid',
' key',
\IcbcConstants::$SIGN_TYPE_RSA2,
'UTF-8',
'json',
' ',
'AES key',
'AES',
'',
'');
$resp = $client->buildPostForm($request, $msg_id, '');
echo $resp;
die;
}
}
6、ピット注意6.1、工行公式サイトsdkファイル【DefaultIcbcClient.php】の【execute】メソッドが提供する【IcbcSignature::verify】メソッドにはパラメータが欠けており、$this->passwordパラメータを補う必要があります.そうしないと呼び出しに成功しません.完全に次のとおりです.
//
$passed = IcbcSignature::verify($respBizContentStr, IcbcConstants::$SIGN_TYPE_RSA, $this->icbcPulicKey, $this->charset, $sign,$this->password);
6.2、【AES.php】ファイル中、@mcrypt_module_OpenシリーズメソッドはPHP 7.2から廃棄されており,エラーを報告した後にエラー抑制子を付けるか,置換スキームを書き換える必要がある.
6.3、低バージョンの工行SDK【IcbcConstants.php】ファイルの中でタイムゾーンの設定が間違っていて、東八区上海に修正する必要があります.正しいコードは以下の通りです.
/** Date **/
//public static $DATE_TIMEZONE = "Etc/GMT+8";//java GMT+8
public static $DATE_TIMEZONE = "Asia/Shanghai";//
6.4、注文時間について現在、工行には4セットのテスト環境があり、各テスト環境のシステム時間は現実時間と一致しない.注文時間が無効なエラーと間違えた場合、工行開発者が提供した小道具を使ってテスト環境の時間を取得し、テスト環境の時間で注文有効時間を交換してください.