博客列表 >商城项目-微信支付流程

商城项目-微信支付流程

岂几岂几
岂几岂几原创
2020年07月15日 00:11:361567浏览

商城项目-微信支付流程

  • 没有企业APPID, 只记录老师视频中的实现过程

1. 微信文档说明

  • 微信支付文档很乱, 新的旧的方式掺杂在一起. 在微信支付的首页, 点击”产品中心”, 在”支付产品”点击自己希望接入微信支付的应用场景(课程实例是PC站接入, 所以选择Native支付).

  • 微信支付根据不同的支付场景, 提供不同的接入方式. 微信支付场景.

    • 付款码支付: 生成永久付款二维码供别人扫码支付.
    • JSAPI支付: 在公众号中接入支付.
    • 小程序支付: 微信小程序中支付.
    • Native支付: PC端网站接入支付, 即生成临时付款二维码, 用户扫码支付.
    • APP支付: 安卓和IOS端的APP接入支付.
    • H5支付: 手机/平板等移动端的浏览器中接入支付.
  • 点击Native支付中的”开发文档”, 在Native支付中的开发文档中, 这里是微信推荐的支付页面样式, 并提供了素材下载. 开发模式一已不被推荐, 开发模式二是老师推荐的方式. API列表新手直接放弃阅读, 难度很大, 坑也多; 作为替代方案, 使用新提供的sdk方式实现模式二接入相对来说更加简单一些.

  • 开始之前, 先按照开发步骤中的流程, 申请到APPID, MCHID(商户号), KEY和APPSECRET.

2. 把Native支付示例嵌入到laravel项目中

2.1 调通微信支付并从微信获取支付二维码

  • sdk方式中下载PHP版本的SDK包, 解压到laravel的vendor目录(假设重命名为wxpay). 在 /wxpay/example 中有各种支付场景的接入方式的示例( index.php 文件中列出了各种接入方式的链接). 其中, Native方式接入的示例文件是 /wxpay/example/native.php .

  • /wxpay/example/native.php 中把模式二用到的代码拷贝到生成二维码的控制器方法中, 并改对引用到的文件路径(注意, 引入的文件中, 还引入了其他文件, 引入其他文件的也要改), 修改代码中微信支付相关的类为完全限定名称方式的调用(都在全局命名空间中).

    • 控制器方法中的路径修改和微信支付相关类改为完全限定名称调用
  1. public function pay() {
  2. // __DIR__ = X:/.../laravel/app/Http/Controllers/front;
  3. // 用相对路径导航到wxpay根目录
  4. $wxpayPath = __DIR__ . "/../../../../vendor/wxpay/";
  5. // 微信二维码支付需要用到的文件
  6. require_once $wxpayPath . "lib/WxPay.Api.php";// 改成
  7. require_once $wxpayPath . "/example/WxPay.NativePay.php";
  8. /* 改成完全限定名称 */
  9. $notify = new \NativePay();
  10. //模式二
  11. /**
  12. * 流程:
  13. * 1、调用统一下单,取得code_url,生成二维码
  14. * 2、用户扫描二维码,进行支付
  15. * 3、支付完成之后,微信服务器会通知支付成功
  16. * 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)
  17. */
  18. /* 改成完全限定名称 */
  19. $input = new \WxPayUnifiedOrder();
  20. // 模式二的其他业务逻辑
  21. $input->SetBody("test");
  22. $input->SetAttach("test");
  23. // 这里要改成站点自己生成的订单号
  24. $input->SetOut_trade_no("sdkphp123456789".date("YmdHis"));
  25. // 设置支付金额(单位: 分)
  26. $input->SetTotal_fee("1");
  27. $input->SetTime_start(date("YmdHis"));
  28. // 二维码有效时长
  29. $input->SetTime_expire(date("YmdHis", time() + 600));
  30. $input->SetGoods_tag("test");
  31. // 处理微信返回的用户支付结果(xml文件格式数据)的请求地址.
  32. $input->SetNotify_url("http://www.myweb.com/notify.php");
  33. // 设置支付场景(Native)
  34. $input->SetTrade_type("NATIVE");
  35. $input->SetProduct_id("123456789");
  36. $result = $notify->GetPayUrl($input);
  37. $data['code_url'] = '';
  38. // 调通的情况下, 把二维码地址发送到视图中渲染;
  39. if($result['return_code'] == 'SUCCESS') $url2 = $result["code_url"];
  40. // 调试时打印输出看看效果
  41. var_dump($result);
  42. return view('/front/shop/pay', $data);
  43. }
  • SDK中的文件引入路径修改- /vendor/wxpay/example/WxPay.NativePay.php
  1. require_once __DIR__ . "/../lib/WxPay.Api.php";
  2. require_once __DIR__ . "/WxPay.Config.php";
  3. require_once __DIR__ . '/log.php';
  4. // ......
  • SDK中的文件引入路径修改- /vendor/wxpay/example/WxPay.Config.php
  1. require_once __DIR__ . "/../lib/WxPay.Config.Interface.php";
  • SDK中的日志方法修改- /vendor/wxpay/example/log.php
  1. // 注释写日志方法
  2. public static function ERROR($msg)
  3. {
  4. // 修改为直接打印错误并返回.
  5. echo $mes;return;
  6. $debugInfo = debug_backtrace();
  7. $stack = "[";
  8. foreach($debugInfo as $key => $val){
  9. if(array_key_exists("file", $val)){
  10. $stack .= ",file:" . $val["file"];
  11. }
  12. if(array_key_exists("line", $val)){
  13. $stack .= ",line:" . $val["line"];
  14. }
  15. if(array_key_exists("function", $val)){
  16. $stack .= ",function:" . $val["function"];
  17. }
  18. }
  19. $stack .= "]";
  20. //self::$instance->write(8, $stack . $msg);
  21. }
  • 做完上述修改后, 调通该做的工作基本完成, 此时要把申请到的4个配置值设置到 WxPay.Config.php 中.

    • 把申请到的APPID, MCHID(商户号), KEY和APPSECRET值添加到配置文件 WxPay.Config.php
  1. /**
  2. * TODO: 修改这里配置为您自己申请的商户信息
  3. * 微信公众号信息配置
  4. *
  5. * APPID:绑定支付的APPID(必须配置,开户邮件中可查看)
  6. *
  7. * MCHID:商户号(必须配置,开户邮件中可查看)
  8. *
  9. */
  10. public function GetAppId()
  11. {
  12. // 返回APPID
  13. return '';
  14. }
  15. public function GetMerchantId()
  16. {
  17. // 返回MCHID, 即商户号.
  18. return '';
  19. }
  20. // ......
  21. /*
  22. * KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置), 请妥善保管, 避免密钥泄露
  23. * 设置地址:https://pay.weixin.qq.com/index.php/account/api_cert
  24. *
  25. * APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置, 登录公众平台,进入开发者中心可设置), 请妥善保管, 避免密钥泄露
  26. * 获取地址:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
  27. * @var string
  28. */
  29. public function GetKey()
  30. {
  31. // 返回KEY
  32. return '';
  33. }
  34. public function GetAppSecret()
  35. {
  36. // 返回APPSECRET
  37. return '';
  38. }
  39. // ......
  • 当前实例没有设置证书, 所以需要修改 WxPay.Api.php 中的配置, 把相关配置设置成不需要证书:
  1. private static function postXmlCurl($config, $xml, $url, $useCert = false, $second = 30) {
  2. // ......
  3. // 原文件中的567-568行
  4. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE); // 设置为FALSE表示不需要证书
  5. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0); // 设置为0表示不执行严格校验, 默认值是2, 严格校验.
  6. // ......
  7. }
  • 经过上面一通操作后, var_dump($result) 就有值打印出来了, 即设置完成. 创建一个控制器方法, 复制 /wxpay/example/qrcode.php 中的逻辑到方法中(注意修改相关文件的引入路径), 供前端 <img> 元素获取生成的二维码图片

    • 生成二维码的控制器方法()
  1. // 获取二维码的控制器方法
  2. public function createQrccode() {
  3. $wxpayPath = __DIR__ . '/../../../../vendor/wxpay/';
  4. require_once $wxpayPath . 'example/phpqrccode/phpqrccode.php';
  5. $url = urldecode($_GET['data']);
  6. if(substr($url, 0, 6) == 'weixin') {
  7. /* 改成完全限定名称 */
  8. \QRcode::png($url);
  9. } else {
  10. header('HTTP/1.1 404 Not Found');
  11. }
  12. }
  • 前端 <img> 元素获取二维码图片(记得设置路由)
    1. <img src="/shop/qrccode?data=<?php echo urlencode($url2); ?>" alt="" class="qrccode">
  • 到这里, 应该能正常显示二维码了.

tips: 在SDK中, 没有移动端浏览器支付的实例, 只要设置该方法传入参数”mweb”即可: $input->SetTrade_type("mweb"); .

2.2 获取从微信返回的支付结果

  • 用户支付完成后, 微信会发送一个post请求, 发送用户支付结果(xml文件格式数据). 接收该post请求的url地址, 是在调通微信支付时设置的: $input->SetNotify_url("处理微信返回的用户支付结果的请求地址"); . 该请求必须能通过外网访问.
  • 支付结果信息中包含这些内容. 其中:

    • openid : 谁付的钱.
    • out_trade_no : 站点生成的订单号.
    • result_code : 支付结果, SUCCES(成功)/FEIL().
    • total_fee : 支付的金额(单位: 分).
    • transaction_id : 微信内部的交易号.
  • 支付界面(二维码扫码页面)需要设置一个定时器, 定时去查询订单的支付状态, 当支付状态为”已支付”时, 就使用调用 window.parent.location.reload() 的js表达式调用父页面的js方法, 完成父页面的刷新或跳转(到支付成功页面).

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议