最近项目中要用到银联支付,所以记录一下开发过程:
1.先去银联申请接口https://open.unionpay.com/tjweb/api/dictionary?apiSvcId=453,我用的是手机网页支付(WAP支付)
2.去个人中心查看产品和测试参数
这些测试数据写到config.php里,稍后会用到。
//银联支付部分配置信息(具体配置查看extend/unionpay/sdk/acp_sdk.ini)
'unionpay_config' => [
'merId' => '',//商户代码
'configFile' => Env::get('root_path') . 'config/acp_sdk.ini',//银联配置
],
3.下载银联官方实例:https://open.unionpay.com/tjweb/acproduct/list?apiSvcId=453
4.我的是放到extend里了:
重命名一下文件,在这些文件头部加上命名空间:namespace unionpay\sdk;
5.在application/common.php里面引入
use unionpay\sdk\SDKConfig;
use unionpay\sdk\AcpService;
然后就可以写方法调用了:
/**
* 银联支付
* @param array $data付款参数
* @return string
*/
function unionpay($order){
$SDKConfig = new SDKConfig();
$params = array(
//以下信息非特殊情况不需要改动
'version' => $SDKConfig->getSDKConfig()->version, //版本号
'encoding' => 'utf-8', //编码方式
'txnType' => '01', //交易类型
'txnSubType' => '01', //交易子类
'bizType' => '000201', //业务类型
'frontUrl' => $SDKConfig->getSDKConfig()->frontUrl, //前台通知地址
'backUrl' => $SDKConfig->getSDKConfig()->backUrl, //后台通知地址
'signMethod' => $SDKConfig->getSDKConfig()->signMethod, //签名方法
'channelType' => '08', //渠道类型,07-PC,08-手机
'accessType' => '0', //接入类型
'currencyCode' => '156', //交易币种,境内商户固定156
//TODO 以下信息需要填写
'merId' => $order['merId'], //商户代码,请改自己的测试商户号,此处默认取demo演示页面传递的参数
'orderId' => $order["orderId"], //商户订单号,8-32位数字字母,不能含“-”或“_”,此处默认取demo演示页面传递的参数,可以自行定制规则
'txnTime' => date("YmdHis",$order["txnTime"]), //订单发送时间,格式为YYYYMMDDhhmmss,取北京时间,此处默认取demo演示页面传递的参数
'txnAmt' => $order["txnAmt"], //交易金额,单位分,此处默认取demo演示页面传递的参数
// 订单超时时间。
// 超过此时间后,除网银交易外,其他交易银联系统会拒绝受理,提示超时。 跳转银行网银交易如果超时后交易成功,会自动退款,大约5个工作日金额返还到持卡人账户。
// 此时间建议取支付时的北京时间加15分钟。
// 超过超时时间调查询接口应答origRespCode不是A6或者00的就可以判断为失败。
'payTimeout' => date('YmdHis', strtotime('+15 minutes')),
'riskRateInfo' => $order["riskRateInfo"],
// 请求方保留域,
// 透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自己希望透传的数据。
// 出现部分特殊字符时可能影响解析,请按下面建议的方式填写:
// 1. 如果能确定内容不会出现&={}[]"'等符号时,可以直接填写数据,建议的方法如下。
// 'reqReserved' =>'透传信息1|透传信息2|透传信息3',
// 2. 内容可能出现&={}[]"'符号时:
// 1) 如果需要对账文件里能显示,可将字符替换成全角&={}【】“‘字符(自己写代码,此处不演示);
// 2) 如果对账文件没有显示要求,可做一下base64(如下)。
// 注意控制数据长度,实际传输的数据长度不能超过1024位。
// 查询、通知等接口解析时使用base64_decode解base64后再对数据做后续解析。
// 'reqReserved' => base64_encode('任意格式的信息都可以'),
//TODO 其他特殊用法请查看 special_use_purchase.php
);
$AcpService = new AcpService();
$AcpService->sign($params);
$uri = $SDKConfig->getSDKConfig()->frontTransUrl;
$html_form = $AcpService->createAutoFormHtml($params, $uri);
echo $html_form;
}
/**
* 银联支付验证签名
* @param array $data付款参数
* @return bool
*/
function checkUnionpaySign($data){
$AcpService = new AcpService();
return $AcpService->validate($data);
}
/**
* 银联支付查询订单
* @param array $data付款参数
* @return bool
*/
function checkUnionpayOrder($data){
$SDKConfig = new SDKConfig();
$params = array(
//以下信息非特殊情况不需要改动
'version' => $SDKConfig->getSDKConfig()->version, //版本号
'encoding' => 'utf-8', //编码方式
'signMethod' => $SDKConfig->getSDKConfig()->signMethod, //签名方法
'txnType' => '00', //交易类型
'txnSubType' => '00', //交易子类
'bizType' => '000000', //业务类型
'accessType' => '0', //接入类型
'channelType' => '07', //渠道类型
//TODO 以下信息需要填写
'orderId' => $data["orderId"], //请修改被查询的交易的订单号,8-32位数字字母,不能含“-”或“_”,此处默认取demo演示页面传递的参数
'merId' => $data["merId"], //商户代码,请改自己的测试商户号,此处默认取demo演示页面传递的参数
'txnTime' => date("YmdHis",$data["txnTime"]), //请修改被查询的交易的订单发送时间,格式为YYYYMMDDhhmmss,此处默认取demo演示页面传递的参数
);
$AcpService = new AcpService();
$AcpService->sign($params);// 签名
$url = $SDKConfig->getSDKConfig()->singleQueryUrl;
$result_arr = $AcpService->post($params, $url);
//没收到200应答的情况
if(count($result_arr) <= 0) {
return ['status'=>0,'msg'=>'无应答'];
}
//应答报文验签失败
if (!$AcpService->validate ($result_arr) ){
return ['status'=>2,'msg'=>'应答报文验签失败'];
}
if ($result_arr["respCode"] == "00"){
if ($result_arr["origRespCode"] == "00"){
//交易成功
//TODO
return ['status'=>1,'msg'=>'交易成功'];
} else if ($result_arr["origRespCode"] == "03"
|| $result_arr["origRespCode"] == "04"
|| $result_arr["origRespCode"] == "05"){
//后续需发起交易状态查询交易确定交易状态
//TODO
return ['status'=>3,'msg'=>'后续需发起交易状态查询交易确定交易状态'];
} else {
//其他应答码做以失败处理
//TODO
return ['status'=>4,'msg'=>'交易失败:'. $result_arr["origRespMsg"]];
}
} else if ($result_arr["respCode"] == "03"
|| $result_arr["respCode"] == "04"
|| $result_arr["respCode"] == "05" ){
//后续需发起交易状态查询交易确定交易状态
//TODO
return ['status'=>5,'msg'=>'处理超时,请稍微查询。'];
} else {
//其他应答码做以失败处理
//TODO
return ['status'=>6,'msg'=>'失败:'. $result_arr["respMsg"]];
}
}
6.然后在需要的地方就可以直接调用了:
/**
* 调用银联支付
* @param int $id 订单ID
* @return html 跳转到银联支付页面或调起云闪付app
*/
public function pay()
{
$id = input('id');
$row = Db::name('order')->where('id',$id)->find();
$uniopayData = [];
$uniopayData['merId'] = config('app.unionpay_config.merId');
$uniopayData['orderId'] = $row['order_id'];
$uniopayData['txnAmt'] = $row['money'];
$uniopayData['txnTime'] = time();
$uniopayData['riskRateInfo'] = '{commodityName=test}';
$tempRow = Db::name('unionpay')->where(['orderId'=>$row['order_id']])->find();
if(!$tempRow){
$id = Db::name('unionpay')->insertGetId($uniopayData);
if($id){
unionpay($uniopayData);
}else{
exit('请求失败,请联系客服');
}
}else{
unionpay($uniopayData);
}
}
/**
* 银联支付异步回调
*/
public function unionpayNotify(){
$notifyData = $_POST;
logStr("支付回调POST返回值:".json_encode($notifyData));
//判断订单是否存在
if(isset($notifyData['orderId'])){
$notifyRow = Db::name('unionpay_notify')->where(['orderId'=>$notifyData['orderId']])->find();
if(!$notifyRow){
$notifyData['time'] = time();
Db::name('unionpay_notify')->insertGetId($notifyData);
//验证签名
if (isset($_POST['signature'])){
$signCheck = checkUnionpaySign($_POST);
logStr("支付回调POST验证签名:".$signCheck);
//验证签名成功的话,查询一下订单,查询成功更新数据状态
if($signCheck){
$orderId = $_POST ['orderId']; //其他字段也可用类似方式获取
$respCode = $_POST ['respCode'];
logStr("支付回调POST状态码:".$respCode.($respCode == "00"));
//状态代码
if($respCode == "00"){
$unionpayRow = Db::name('unionpay')->where('orderId',$orderId)->find();
//数据存在且状态为未支付
if(!empty($unionpayRow) && $unionpayRow['status'] == 0){
//查询订单信息
$res = checkUnionpayOrder($unionpayRow);
logStr("支付回调POST查询订单:".json_encode($res));
if($res['status'] == 1){
//更新支付状态
Db::name('unionpay')->where('orderId',$orderId)->update(['status'=>1]);
}
}
}
}
}
}else{
if($notifyData['respCode'] != $notifyData['respCode']){
$notifyData['time'] = time();
Db::name('unionpay_notify')->where(['orderId'=>$notifyData['orderId']])->update($notifyData);
}
}
}
}
Mysql8新增用户,mysql8配置权限,mysql8配置,mysql8配置文件 Linux命令,scp,scp命令,Linux复制 git commit git add centos git 搭建FTP,Linux FTP,禁止FTP登录ssh 上传文件,阿里云OSS上传,文件上传到OSS,OSS文件上传,OSS上传 微信支付,微信支付V3,PHP微信支付,微信nativePay支付,微信jsapi支付 微信支付,微信支付V3,PHP微信支付 bootstrap4 modal, lavarel The subversion command line tools are no longer provided by Xcode. 银联支付,tp5.1银联支付 支付宝即时到账,PHP支付宝 system libzip must be upgraded to version >= 0.11 CMake 3.0.2 or higher is required Class 'ZipArchive' not found chr() expects parameter 1 to be int php7.4 tcpdf unexpected '='