本文共 5377 字,大约阅读时间需要 17 分钟。
1.当我们自己有微信公众号,开通了微信支付业务
2.我们到微信支付的官
网, 公众号支付的开发文档共同下单是微信支付的基础,他是又商家发起,当用户在商家的网站或则公众号,下单时.商家的商城系统会生成一个订单,与此同时,我们需要给微信发出一个请求,让微信也生成一个对应的订单
下面是初始化一些配置,在写这些配置的时候不要忘了引入我们之前下载的sdk包,这个包中的WxPay.Api.php,需要提前引入.sdk中也有demo,在example文件中.
对应的参数意思,在微信的开发文档中有很详细的说明,这里就不再赘述/** * 流程: * 1、调用统一下单,取得code_url,生成二维码 * 2、用户扫描二维码,进行支付 * 3、支付完成之后,微信服务器会通知支付成功 * 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php) */$input = new WxPayUnifiedOrder();$input->SetBody("test");$input->SetAttach("test");$input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));$input->SetTotal_fee("1");$input->SetTime_start(date("YmdHis"));$input->SetTime_expire(date("YmdHis", time() + 600));$input->SetGoods_tag("test");$input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php");$input->SetTrade_type("NATIVE");$input->SetProduct_id("123456789");$result = $notify->GetPayUrl($input);$url2 = $result["code_url"];
重点来了!!!
$input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php");
在配置这一项中要注意,一定要是一个外网能访问的url地址,并且不能携带任何参数.这个url地址会用于,微信服务器进行回调,并发送支付相关的数据.(如果是使用yii2的朋友要注意了.微信回调是使用post传值,需把csrf验证给关闭,否则无法传值)
当这些参数正确的情况下,会生成一个url地址
$url2 = $result["code_url"];
这个url地址就是用于支付的url地址了.当用户访问这个地址时,就是看到订单的一些介绍和金额.用户可以使用微信或则银行卡里的钱,来进行支付.
下面需要修补的地方有三个
- 微信生成的是url地址,并不是我们常见的二维码形式
解决方案:
一. 在之前下载的sdk中,还有一个插件,叫做phpqrcode.这个插件主要就是用来将url地址转换为二维码. 首先我们要引入phpqrcode.php这个php文件 这个文件里有个QRcode类,类里面有个png静态方法,我们调用这个方法就可以完成二维码的生成啦public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false) { $enc = QRencode::factory($level, $size, $margin); return $enc->encodePNG($text, $outfile, $saveandprint=false); }
这个方法,有很多参数,我们常用的应该就是前两个参数了,
其余参数,大家看一下就行了
二.我们要解决用户支付完成后的提示问题.
首先我们知道,当用户下单成功后,就会跳往支付页面.我就是在这个支付页面来放置我们的支付二维码的.当用户支付完成时,弹出提示.我们这里要使用微信的另一个接口--查询订单
在sdk中,微信同样封装了方法,我们只需要写一个供前端访问的一个接口就可以了/** * 异步访问请求支付状态 */ public function actionCheckPay() { //获取前端页面的请求 $data = \Yii::$app->request->post()['order_no']; //声明一个配置对象 $input = new \WxPayOrderQuery(); //调用配置对象上的设置商户订单号的方法 $input->SetOut_trade_no($data); //调用查询订单方法,传入配置对象.当放回数据中的trade_state==success时,说明支付完成 if (\WxPayApi::orderQuery($input)['trade_state'] == 'SUCCESS') { //如果成功 echo json_encode(['status' => 1]); } else { echo json_encode(['status' => 0]); } }
这里注意了.前端传递数据,可以是商户订单号,也可以使用微信订单号(transaction_id).我这里使用的商户订单号
前端页面就比较简单了.只需要设置一个定时器,不停发送ajax请求,我刚刚写的那个接口.当返回的json对象status=1时,则说明用户已经支付,停止计时器弹出提示.
$(function () { //判断是否支付成功 var timer = setInterval(function () { $.post( ' ', {"order_no": ' '} , function (data) { if (data.status == 1) { //成功后,将二维码改成打勾图片,弹出提示,清除定时器 alert('支付成功'); $("#ma").attr('src', 'http://grx.azxs.net/paySuccess.png'); $("#ma").fadeIn("show"); window.clearInterval(timer); } else { //未支付,则不做任何操作 } }, 'json' ) }, 2000) })
三.我们要解决的是修改订单状态的问题
其实之前我们已经获取到了用户的支付状态了,我们可以把操作数据库的方法写在之前的那个接口中,不过我们对那个接口采用的计时器请求,如果把数据库操作写在接口中的话,无疑会对数据库造成极大的压力.所以我们换个地方来操作
那么我们就要说到开头我们设置的用于微信回调的url地址了.我们在这个方法中来完成订单修改
public function actionNotify() { //获取xml格式的数据 $data = $GLOBALS['HTTP_RAW_POST_DATA']; //将xml转换为数组; $arr = (array)simplexml_load_string($data, "SimpleXMLElement", LIBXML_NOCDATA); $payLog = new PayLog(); if ($arr['return_code'] == 'SUCCESS') { //如果返回成功,下单成功 $payLog->content = serialize($arr); $payLog->save(); $order_no = $arr['out_trade_no']; //细节:微信返回的金额是以分为单位所以要*100 $payMoney = $arr['total_fee'] / 100; $orderModel = Order::find() ->where(['order_no' => $order_no, 'amount' => $payMoney, 'status' => 2]) ->one(); if (!empty($order_no) && $arr['result_code'] == 'SUCCESS') { //如果查询不为空的话,修改订单状态 $orderModel->pay_method = 1; $orderModel->status = 1; $orderModel->save(); echo ""; } else { $payLog->content = '订单无效'; $payLog->save(); } } else { $payLog->content = '支付失败'; $payLog->save(); } }
以上代码注意两个细节,当微信传递回来的数据中包含return_code和result_code两个键名,这代表的是不同的意义的,首先,我们在代码的上半部分,判断的是return_code.这里是判断是订单创建是否成功,result_code才是判断用户是否支付.我在开始也出现了这个错误.会导致,订单修改失败,写入日志失败
好了,本次微信支付的介绍了就写到这里了,如果有什么地方不对,希望大神指正.谢谢
以上
转载地址:http://uqizo.baihongyu.com/