参考文档:
- TP5实现支付宝电脑网站支付学习笔记https://blog.csdn.net/weixin_34199335/article/details/88628841
- 支付宝手机网站支付passback_params传递数组https://www.jianshu.com/p/14c46838e567
- 支付宝接口:系统有点忙,一会再试试https://blog.csdn.net/qq2942713658/article/details/84965512
- 支付宝的异步回调里面无法获取session里面的值为什么(通过sessionid也不可)https://ask.csdn.net/questions/766442
- 使用urlencode(json_encode($arr));var_export可以将一个数组转为一个字符串不同于var_dump,var_export并不会输出数据的类型以及字符大小等,只会简单把数组的key跟value拼接成一个字符串
遇到的问题:
2019/09/14
- 沙箱测试 私钥公钥啥的(B站视频讲解
2019/09/15
- 解决调不出收银台问题(金融传值多了个元
- 不能账号密码登录(当前页面框架内打开所以不能
2019/09/16
- passback_param参数使用出错(urlencode(json_encode($arr)); 及异步接收时处理 json_decode(urldecode($arr));
- 只能付88的点别的付不了款(自己好了
- 产品切换快出现金额不改变,会造成少付(点击确认支付后根据所选产品再次查询其金额
- passback_param参数超过规定限制(传点必须的
2019/09/20
- 支付宝异步回调函数中操作session(异步回调属于阿里请求,无法获取你存储的session;只能你本地判断如果回调处理了你的业务,然后自己调用更新session,可以考虑用拦截器 缓存实现)
- 通过passback_param将sessionID传回异步也是无法获取对应session(正常情况好用
2019/09/21
- 支付宝换为正式应用出现支付异常(AppId未换成正式应用的
- 支付宝换为正式应用出现支付异常(正式环境需要支付宝开放平台的应用审核通过状态为上线
2019/09/22
- 异步通知存储多次存储(存储支付宝交易号判断唯一性
2019/09/24
- 同一用户同时在不同浏览器购买商品出现重叠(passback_param仅传递owner_id,异步通知时再次进行查询得到用户的到期时间,算出用户所购买产品的起始日期
1 <?php 2 namespace app\index\controller; 3 4 use think\Controller; 5 use think\Request; 6 use think\Db; 7 8 9 class Alipay extends Controller 10 { 11 public function index(Request $request){ 12 header("Content-type:text/html;charset=utf-8"); 13 require_once VENDOR_PATH.'/alipay/config.php'; 14 require_once VENDOR_PATH.'/alipay/pagepay/service/AlipayTradeService.php'; 15 require_once VENDOR_PATH.'/alipay/pagepay/buildermodel/AlipayTradePagePayContentBuilder.php'; 16 $param = $request->param(); 17 // var_dump($param);die; 18 //必传参数 19 if (empty($param['WIDout_trade_no']) || !array_key_exists('WIDout_trade_no',$param)){ 20 $result = [ 21 'status' => '201', 22 'msg' => '参数错误', 23 'param' => $param 24 ]; 25 exit(json_encode($result)); 26 } 27 if (empty($param['WIDsubject']) || !array_key_exists('WIDsubject',$param)){ 28 $result = [ 29 'status' => '201', 30 'msg' => '参数错误', 31 'param' => $param 32 ]; 33 exit(json_encode($result)); 34 } 35 if (empty($param['WIDtotal_amount']) || !array_key_exists('WIDtotal_amount',$param)){ 36 $result = [ 37 'status' => '201', 38 'msg' => '参数错误', 39 'param' => $param 40 ]; 41 exit(json_encode($result)); 42 } 43 44 45 //商户订单号,商户网站订单系统中唯一订单号,必填 46 $out_trade_no = trim($param['WIDout_trade_no']); 47 48 //订单名称,必填 49 $subject = trim($param['WIDsubject']); 50 51 //付款金额,必填 52 $total_amount = trim($param['WIDtotal_amount']); 53 54 //商品描述,可空 55 $body = trim($param['WIDbody']); 56 57 //公用回传参数 58 // $passback_params = http_build_query($param['purchaseInfo']); 59 $passback_params = urlencode($param['buyer']); 60 61 62 //构造参数 63 $payRequestBuilder = new \AlipayTradePagePayContentBuilder(); 64 $payRequestBuilder->setBody($body); 65 $payRequestBuilder->setSubject($subject); 66 $payRequestBuilder->setTotalAmount($total_amount); 67 $payRequestBuilder->setOutTradeNo($out_trade_no); 68 $payRequestBuilder->setPassbackParams($passback_params); 69 70 // var_dump($payRequestBuilder);die; 71 $aop = new \AlipayTradeService($config); 72 73 /** 74 * pagePay 电脑网站支付请求 75 * @param $builder 业务参数,使用buildmodel中的对象生成。 76 * @param $return_url 同步跳转地址,公网可以访问 77 * @param $notify_url 异步通知地址,公网可以访问 78 * @return $response 支付宝返回的信息 79 */ 80 $response = $aop->pagePay($payRequestBuilder, $config['return_url'], $config['notify_url']); 81 82 //输出表单 83 echo $response; 84 } 85 86 /** 87 * 异步 88 * @param Request $request 89 * @throws \Exception 90 */ 91 public function notifyUrl(Request $request){ 92 $param = $request->param(); 93 require_once VENDOR_PATH.'/alipay/config.php'; 94 require_once VENDOR_PATH.'/alipay/pagepay/service/AlipayTradeService.php'; 95 require_once VENDOR_PATH.'/alipay/pagepay/buildermodel/AlipayTradePagePayContentBuilder.php'; 96 $alipaySevice = new \AlipayTradeService($config); 97 $alipaySevice->writeLog(var_export($param,true)); 98 $result = $alipaySevice->check($param); 99 100 if($result) { 101 //验证成功 102 $buyer = urldecode($param['passback_params']); 103 if ($param['trade_status'] == 'TRADE_SUCCESS') { 104 //判断该笔订单是否在商户网站中已经做过处理 105 //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 106 //请务必判断请求时的total_amount与通知时获取的total_fee为一致的 107 //如果有做过处理,不执行商户的业务程序 108 //注意: 109 //付款完成后,支付宝系统发送该交易状态通知 110 $db2 = Db::connect('pfpartner2'); 111 $db = Db::connect('pfpartner'); 112 113 ///通过ownerid获取用户信息S//////////////////////////////////////////////// 114 $userInfo = $db->name('open_user')->where('owner_id','=',$buyer)->find(); 115 ///通过ownerid获取用户信息E//////////////////////////////////////////////// 116 117 // file_put_contents("alipaytext4.txt",$userInfo);die; 118 119 ///获取所购产品的起始时间S////////////////////////////////////////////////////// 120 $goodWhere['project'] = $param['subject']; 121 $goodWhere['type'] = $param['body']; 122 $projectArr = $db2->name('goods')->where($goodWhere)->find(); 123 if ($userInfo['role'] == 0){ 124 $projectArr['startDatetime'] = date("Y-m-d H:i:s"); 125 $projectArr['expirationDatetime'] = date("Y-m-d H:i:s",time()+$projectArr['day']*24*3600); 126 }else{ 127 $projectArr['startDatetime'] = $userInfo['lock_time']; 128 $projectArr['expirationDatetime'] = date("Y-m-d H:i:s", 129 strtotime($userInfo['lock_time']) + $projectArr['day']*24*3600); 130 } 131 ///获取所购产品的起始时间E////////////////////////////////////////////////////// 132 133 // file_put_contents("alipaytext2.txt",$puchaseInfo); 134 135 ///创建购买记录信息S////////////////////////////////////////////////////// 136 $puchaseInfo['owner_id'] = $userInfo['owner_id']; 137 $puchaseInfo['mall_name'] = $userInfo['mall_name']; 138 $puchaseInfo['data_date'] = date("Y-m-d"); 139 $puchaseInfo['product_name'] = $projectArr['project']; 140 $puchaseInfo['product_type'] = $projectArr['type']; 141 $puchaseInfo['payment_method'] = '0'; 142 $puchaseInfo['product_details'] = $projectArr['detailed']; 143 $puchaseInfo['start_time'] = $projectArr['startDatetime']; 144 $puchaseInfo['end_time'] = $projectArr['expirationDatetime']; 145 $puchaseInfo['day'] = $projectArr['day']; 146 $puchaseInfo['original_price'] = $projectArr['original_price']; 147 $puchaseInfo['discount_price'] = $projectArr['discount']; 148 $puchaseInfo['actual_price'] = $projectArr['price']; 149 $puchaseInfo['trade_no'] = $param['trade_no']; 150 ///创建购买记录信息E////////////////////////////////////////////////////// 151 152 // file_put_contents("alipaytext3.txt",$puchaseInfo); 153 154 //判断是否存储过该条记录 155 $res = $db2->name('purchase_record')->where('trade_no',$param['trade_no'])->find(); 156 if (!$res){ 157 //未购买过,新增购买记录并修改用户表中的到期时间等字段 158 $db2->name('purchase_record')->insert($puchaseInfo); 159 $user['lock_time'] = $projectArr['expirationDatetime']; 160 $user['role'] = '1'; 161 $user['is_lock'] = '0'; 162 $db->name('open_user')->where('owner_id','=',$buyer)->update($user); 163 } 164 echo "success"; 165 } 166 }else { 167 //验证失败 168 echo "fail"; 169 170 } 171 172 } 173 174 /** 175 * 同步 176 * @param Request $request 177 * @throws \Exception 178 */ 179 public function returnUrl(Request $request){ 180 $param = $request->param(); 181 require_once VENDOR_PATH.'/alipay/config.php'; 182 require_once VENDOR_PATH.'/alipay/pagepay/service/AlipayTradeService.php'; 183 require_once VENDOR_PATH.'/alipay/pagepay/buildermodel/AlipayTradePagePayContentBuilder.php'; 184 $alipaySevice = new \AlipayTradeService($config); 185 $result = $alipaySevice->check($param); 186 187 /* 实际验证过程建议商户添加以下校验。 188 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号, 189 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额), 190 3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email) 191 4、验证app_id是否为该商户本身。 192 */ 193 if($result) { 194 //验证成功 195 return $this->redirect('index/Home/index',['code' => 1]); 196 } 197 else { 198 //验证失败 199 echo "验证失败"; 200 } 201 } 202 203 } 204 205 ?>