PHP的Web端接入微信支付
1、话不多说找到文档下载PHP版本的sdk
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
2、目前的压缩包名为:WxpayAPI_php_v3,下载完毕后,解压到桌面,里面一共含有5个文件夹
SDK目录结构
|– lib
|– logs
`– example
cert //可以自己新建 证书存放路径,证书可以登录商户平台https://pay.weixin.qq.com/index.php/account/api_cert
lib API接口封装代码
WxPay.Api.php 包括所有微信支付API接口的封装
WxPay.Config.Interface.php 商户配置 , 业务需要从这里继承(请注意保管自己的密钥/证书等)
WxPay.Data.php 输入参数封装
WxPay.Exception.php 异常类
WxPay.Notify.php 回调通知基类
doc 官方文档
log 日志文件
example 官方示例文件夹
快速搭建指南
①、建SDK解压到网站根目录
②、修改lib/WxPay.Config.php为自己申请的商户号的信息(配置详见说明)
③、下载证书替换cert下的文件
搭建完成
图是网上的,本地环境被谷歌自己添加的https证书拦住进不去了
在这里我们选择扫码支付
将API放到YII2 vender/wxpay目录下
然后找到对应的 方法 下面是我们用微信扫码支付的模式二 获取支付的二维码
require_once \'../../vendor/wxpay/lib/WxPay.Api.php\'; require_once \'../../vendor/wxpay/example/phpqrcode/phpqrcode.php\'; require_once "../../vendor/wxpay/example/WxPay.NativePay.php"; use Yii; class WxPayMent{ public static function getQcCode($price,$user_id){ $notify = new \NativePay(); $price = $price*100; // //模式二 /** * 流程: * 1、调用统一下单,取得code_url,生成二维码 * 2、用户扫描二维码,进行支付 * 3、支付完成之后,微信服务器会通知支付成功 * 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php) */ $order_sn = Payment::createOrderSn(); //支付模型 创建订单号 $input = new \WxPayUnifiedOrder(); $input->SetBody("原创文档充值"); //商品描述 $input->SetAttach($user_id); //自定义数据 $input->SetOut_trade_no($order_sn); //订单号 $input->SetTotal_fee($price); //支付的钱 单位是分!! $input->SetTime_start(date("YmdHis")); $input->SetGoods_tag("原创文档充值"); $input->SetNotify_url("http://www.***.com/personal-center/notify"); //异步通知地址 来修改我们后台数据库 $input->SetTrade_type("NATIVE"); $input->SetProduct_id($order_sn); $result = $notify->GetPayUrl($input); if($result[\'return_code\'] == \'FAIL\'){ Yii::warning(date(\'Y-m-d h:i:s\',time()).\'错误:\'.$result[\'return_msg\'],\'wxpay\'); return [\'error\'=>1,\'msg\'=>\'获取二维码失败\']; } $url = $result["code_url"]; $file_name = Payment::createOrderSn().\'.png\'; $QrCodeUrl = \'QrCodeUrl\'; if(!file_exists($QrCodeUrl)){ mkdir($QrCodeUrl,0777); } $file_name = $QrCodeUrl.\'/\'.$file_name; if(substr($url, 0, 6) == "weixin"){ \QRcode::png($url,$file_name,\'\',\'\',true); }else{ header(\'HTTP/1.1 404 Not Found\'); } $file_name = Yii::$app->request->hostInfo.\'/\'.$file_name; $order = [\'error\'=>0,\'qc_code\' => $file_name,\'order_sn\' => $order_sn]; return $order; } }
这里返回二维码跟订单号 用户扫码支付
异步处理:
/** * 微信支付 * 微信异步修改数据库 * @Author WangSai * @DateTime 2020-03-14 * @version [version] * @return [type] [description] */ public function actionNotify() { $testxml = file_get_contents("php://input"); $jsonxml = json_encode(simplexml_load_string($testxml, \'SimpleXMLElement\', LIBXML_NOCDATA)); if(!file_exists("../logs/")){ mkdir("../logs/",0777); } $result = json_decode($jsonxml, true);//转成数组 if($result){ //如果成功返回了 $out_trade_no = $result[\'out_trade_no\']; $is_pay = UserPay::find()->where([\'out_trade_no\' => $out_trade_no])->orWhere([\'trade_no\' => $result[\'transaction_id\']])->asArray()->one(); //这里是我保存交易记录的地方轮训修改的地方,如果修改过则不用再进入下面的循环 if($is_pay){ die; } if($result[\'return_code\'] == \'SUCCESS\' && $result[\'result_code\'] == \'SUCCESS\'){ //执行业务逻辑 } } }
我们在前台可以用订单号轮训来查看 支付情况
data () { return { timer: null, timerNum:60, } }, methods: { cx(){ this.$axios .get(\'pay-ment/wx-pay-order-query\',{ params:{ orderSn:this.orderSn, } }) .then(res => { if(res.data.code == 200){ this.timerNum = 0; } }) }, getStatus() { this.loading(); // 启动定时器 this.timer = setInterval(() => { //创建定时器 if (this.timerNum === 0) { // 设置的定时器时间为0后执行的操作 this.timer && this.clearTimer(); // 关闭定时器 } else { this.cx(); this.loading(); } }, 1000); }, loading() { // 启动定时器 this.timerNum -= 1; // 定时器减1 }, clearTimer() {//清除定时器 clearInterval(this.timer); this.timer = null; }, }, // 最后在beforeDestroy()生命周期内清除定时器: beforeDestroy() { clearInterval(this.timer); this.timer = null; },
后台接口查询
/** * [actionOrderQuery 轮询微信查询接口查看是否支付] * @Author WangSai * @DateTime 2020-03-20 * @version [version] * @return [array] [返回查询结果] */ public function actionWxPayOrderQuery(){ $order_sn = Yii::$app->getRequest()->get(\'orderSn\'); require_once "../../vendor/wxpay/lib/WxPay.Api.php"; require_once "../../vendor/wxpay/example/WxPay.Config.php"; // $user_account = UserAccount::find()->where([\'user_id\' => $this->user_id])->asArray()->one(); if(isset($order_sn) && $order_sn != ""){ $input = new \WxPayOrderQuery(); $input->SetOut_trade_no($order_sn); $config = new \WxPayConfig(); $order_type = \WxPayApi::orderQuery($config, $input); // $order_type[\'total_price\'] = $user_account[\'price\']; // return $this->msg(\'200\',$order_type); } if($order_type[\'trade_state\'] == \'SUCCESS\'){ return $this->msg(\'200\',$order_type); }else{ return $this->msg(\'201\'); } }