laravel集成支付宝,微信,招商一卡通支付 ## 背景 公司原来有个项目是laravel做的,但是前同事离职了,需要我这只用过tp的接手维护并新增商城模块。 在苦读laravel文档后可以尝试写下基础的功能,商城的体系还是比较简单的,但是支付这块需要重头对接有点恶心,赶紧去[composer](https://packagist.org "composer")库里找下是否有点大神的包能减轻我的工作量。 最终选定使用payment作为项目的支付库。 地址: `https://packagist.org/packages/riverslei/payment` ## 安装 首先通过composer集成库 ` composer require "riverslei/payment:~4.0.0"` 基础操作可以通过文档查看。 ## 步骤 复制库里的examples下的aliconfi.php与wxconfig.php与cmbconfig.php 各个文件修改为自己的配置项 准备工作完毕。 接下来就是调起支付 #### 支付宝支付调起(网页支付) ```php use Payment\Client\Charge; use Payment\Common\PayException; $aliConfig = require_once base_path()."/config/aliconfig.php";//配置文件地址 $payData = [ 'body' => 'XXXX商城--订单支付', 'subject' => 'XXXX商城--订单支付', 'order_no' => '20171212112233', 'timeout_express' => time() + 600,// 表示必须 600s 内付款 'amount' => 0.01,// 单位为元 ,最小为0.01 'return_param' => '0',//传递给支付宝,支付宝会原样回传,需要UrlEncode,可使用此参 数区别业务 'client_ip' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1',// 客户地址 'goods_type' => '1',//0为虚拟商品,1为实物 'store_id' => '',//商户的门店编号 // 建议什么也不填 'qr_mod' => '', ]; try { $reback['payUrl'] = Charge::run(\Payment\Config::ALI_CHANNEL_WEB, $aliConfig, $payData); return $this->suc($reback); } catch (PayException $e) { return $this->err($e->errorMessage()); } ``` 返回前端一个路径,前端需要使用虚拟from表单提交在新页打开(为什么要有虚拟from?因为如果直接跳转打开浏览器可能以为是广告,拦截打开新页)。 #### 支付宝支付回调 参考作者文档 http://blog.csdn.net/hel12he/article/details/71075461 ```php $callback = new PayNotify(); $config = require_once base_path()."/config/aliconfig.php"; $type = 'ali_charge'; try { //获取第三方的原始数据,未进行签名检查,根据自己需要决定是否需要该步骤 // $retData = Notify::getNotifyData($type, $config); $ret = Notify::run($type, $config, $callback);// 处理回调,内部进行了签名检查 } catch (PayException $e) { Log::error($e->errorMessage()); exit; } return $ret; ``` 支付宝网页支付分为同步回调与异步回调,建议同步回调不做任何处理(不安全),只在异步支付处理业务逻辑 其中Notify实现接口PayNotifyInterface。 #### 微信支付调起(扫码支付) ```php $wxConfig = require_once base_path()."/config/wxconfig.php"; $payData = [ 'body' => 'XXXX商城--订单支付', 'subject' => 'XXXX商城--订单支付', 'order_no' => '20171212112233', 'timeout_express' => time() + 600,// 表示必须 600s 内付款 'amount' => 3.01,// 微信沙箱模式,需要金额固定为3.01 'return_param' => '0',//回调附带参数,原样返回 'client_ip' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1',// 客户地址 'product_id' => '1', ]; try { $reback['payUrl'] = Charge::run(\Payment\Config::WX_CHANNEL_QR, $wxConfig, $payData); return $this->suc($reback); } catch (PayException $e) { return $this->err($e->errorMessage()); } ``` 调起后返回前端为一串URL,前端需要把这串URL使用插件转化为二维码 #### 微信支付回调 参考作者文档 http://blog.csdn.net/hel12he/article/details/71075461 ```php /** * 微信异步回调 * $type ali_charge wx_charge cmb_charge */ public function wxNotifyUrl(Request $request){ $callback = new PayNotify(); $config = require_once base_path()."/config/wxconfig.php"; $type = 'wx_charge'; try { // 获取第三方的原始数据,未进行签名检查,根据自己需要决定是否需要该步骤 //$retData = Notify::getNotifyData($type, $config); $ret = Notify::run($type, $config, $callback);// 处理回调,内部进行了签名检查 } catch (PayException $e) { echo $e->errorMessage(); exit; } return $ret; } ``` 其中Notify实现接口PayNotifyInterface。 前端需要定期查询订单状态接口,如发现订单状态改变,则执行跳转支付成功界面。 ## 经验 支付宝交换秘钥可能引起的错误: 公钥生成方式 参看文档:https://docs.open.alipay.com/58/103242 支付宝公私钥上传与交换参看文档:https://helei112g.github.io/2017/03/09/Payment%EF%BC%9A%E6%94%AF%E4%BB%98%E5%AE%9D%E6%94%AF%E4%BB%98%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AE%BE%E7%BD%AE%E6%95%99%E7%A8%8B/  需要注意的是 ali_public_key并不是本地生成的公钥,也不是你传给支付宝的公钥,而是你上传后交换后的支付宝公钥  **看图,教训啊,折磨了我大半天**