微信支付文档很乱, 新的旧的方式掺杂在一起. 在微信支付的首页, 点击”产品中心”, 在”支付产品”点击自己希望接入微信支付的应用场景(课程实例是PC站接入, 所以选择Native支付).
微信支付根据不同的支付场景, 提供不同的接入方式. 微信支付场景.
点击Native支付中的”开发文档”, 在Native支付中的开发文档中, 这里是微信推荐的支付页面样式, 并提供了素材下载. 开发模式一已不被推荐, 开发模式二是老师推荐的方式. API列表新手直接放弃阅读, 难度很大, 坑也多; 作为替代方案, 使用新提供的sdk方式实现模式二接入相对来说更加简单一些.
开始之前, 先按照开发步骤中的流程, 申请到APPID, MCHID(商户号), KEY和APPSECRET.
在sdk方式中下载PHP版本的SDK包, 解压到laravel的vendor目录(假设重命名为wxpay). 在 /wxpay/example 中有各种支付场景的接入方式的示例( index.php 文件中列出了各种接入方式的链接). 其中, Native方式接入的示例文件是 /wxpay/example/native.php .
在 /wxpay/example/native.php 中把模式二用到的代码拷贝到生成二维码的控制器方法中, 并改对引用到的文件路径(注意, 引入的文件中, 还引入了其他文件, 引入其他文件的也要改), 修改代码中微信支付相关的类为完全限定名称方式的调用(都在全局命名空间中).
public function pay() {// __DIR__ = X:/.../laravel/app/Http/Controllers/front;// 用相对路径导航到wxpay根目录$wxpayPath = __DIR__ . "/../../../../vendor/wxpay/";// 微信二维码支付需要用到的文件require_once $wxpayPath . "lib/WxPay.Api.php";// 改成require_once $wxpayPath . "/example/WxPay.NativePay.php";/* 改成完全限定名称 */$notify = new \NativePay();//模式二/*** 流程:* 1、调用统一下单,取得code_url,生成二维码* 2、用户扫描二维码,进行支付* 3、支付完成之后,微信服务器会通知支付成功* 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)*//* 改成完全限定名称 */$input = new \WxPayUnifiedOrder();// 模式二的其他业务逻辑$input->SetBody("test");$input->SetAttach("test");// 这里要改成站点自己生成的订单号$input->SetOut_trade_no("sdkphp123456789".date("YmdHis"));// 设置支付金额(单位: 分)$input->SetTotal_fee("1");$input->SetTime_start(date("YmdHis"));// 二维码有效时长$input->SetTime_expire(date("YmdHis", time() + 600));$input->SetGoods_tag("test");// 处理微信返回的用户支付结果(xml文件格式数据)的请求地址.$input->SetNotify_url("http://www.myweb.com/notify.php");// 设置支付场景(Native)$input->SetTrade_type("NATIVE");$input->SetProduct_id("123456789");$result = $notify->GetPayUrl($input);$data['code_url'] = '';// 调通的情况下, 把二维码地址发送到视图中渲染;if($result['return_code'] == 'SUCCESS') $url2 = $result["code_url"];// 调试时打印输出看看效果var_dump($result);return view('/front/shop/pay', $data);}
/vendor/wxpay/example/WxPay.NativePay.php
require_once __DIR__ . "/../lib/WxPay.Api.php";require_once __DIR__ . "/WxPay.Config.php";require_once __DIR__ . '/log.php';// ......
/vendor/wxpay/example/WxPay.Config.php
require_once __DIR__ . "/../lib/WxPay.Config.Interface.php";
/vendor/wxpay/example/log.php
// 注释写日志方法public static function ERROR($msg){// 修改为直接打印错误并返回.echo $mes;return;$debugInfo = debug_backtrace();$stack = "[";foreach($debugInfo as $key => $val){if(array_key_exists("file", $val)){$stack .= ",file:" . $val["file"];}if(array_key_exists("line", $val)){$stack .= ",line:" . $val["line"];}if(array_key_exists("function", $val)){$stack .= ",function:" . $val["function"];}}$stack .= "]";//self::$instance->write(8, $stack . $msg);}
做完上述修改后, 调通该做的工作基本完成, 此时要把申请到的4个配置值设置到 WxPay.Config.php 中.
WxPay.Config.php
/*** TODO: 修改这里配置为您自己申请的商户信息* 微信公众号信息配置** APPID:绑定支付的APPID(必须配置,开户邮件中可查看)** MCHID:商户号(必须配置,开户邮件中可查看)**/public function GetAppId(){// 返回APPIDreturn '';}public function GetMerchantId(){// 返回MCHID, 即商户号.return '';}// ....../** KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置), 请妥善保管, 避免密钥泄露* 设置地址:https://pay.weixin.qq.com/index.php/account/api_cert** APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置, 登录公众平台,进入开发者中心可设置), 请妥善保管, 避免密钥泄露* 获取地址:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN* @var string*/public function GetKey(){// 返回KEYreturn '';}public function GetAppSecret(){// 返回APPSECRETreturn '';}// ......
WxPay.Api.php 中的配置, 把相关配置设置成不需要证书:
private static function postXmlCurl($config, $xml, $url, $useCert = false, $second = 30) {// ......// 原文件中的567-568行curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE); // 设置为FALSE表示不需要证书curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0); // 设置为0表示不执行严格校验, 默认值是2, 严格校验.// ......}
经过上面一通操作后, var_dump($result) 就有值打印出来了, 即设置完成. 创建一个控制器方法, 复制 /wxpay/example/qrcode.php 中的逻辑到方法中(注意修改相关文件的引入路径), 供前端 <img> 元素获取生成的二维码图片
// 获取二维码的控制器方法public function createQrccode() {$wxpayPath = __DIR__ . '/../../../../vendor/wxpay/';require_once $wxpayPath . 'example/phpqrccode/phpqrccode.php';$url = urldecode($_GET['data']);if(substr($url, 0, 6) == 'weixin') {/* 改成完全限定名称 */\QRcode::png($url);} else {header('HTTP/1.1 404 Not Found');}}
<img> 元素获取二维码图片(记得设置路由)
<img src="/shop/qrccode?data=<?php echo urlencode($url2); ?>" alt="" class="qrccode">
tips: 在SDK中, 没有移动端浏览器支付的实例, 只要设置该方法传入参数”mweb”即可:
$input->SetTrade_type("mweb");.
$input->SetNotify_url("处理微信返回的用户支付结果的请求地址"); . 该请求必须能通过外网访问.支付结果信息中包含这些内容. 其中:
openid : 谁付的钱.out_trade_no : 站点生成的订单号. result_code : 支付结果, SUCCES(成功)/FEIL().total_fee : 支付的金额(单位: 分).transaction_id : 微信内部的交易号.支付界面(二维码扫码页面)需要设置一个定时器, 定时去查询订单的支付状态, 当支付状态为”已支付”时, 就使用调用 window.parent.location.reload() 的js表达式调用父页面的js方法, 完成父页面的刷新或跳转(到支付成功页面).
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号