微信公众号内H5调用微信支付国内服务商模式

最近在折微信公众号内H5用JSAPI调用微信支付,境内服务商版支付,微信支付给出的官方文档以及SDK不够详细,导至我们走了一些弯路,把他分享出来,我这边主要是用PHP开发,所以未加说的话示例都是PHP代码

微信的官方文档  https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=7_1

1.服务商模式下调用统一下单

独立商户模式统一下单:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

服务商模式下统一下单:https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_1

统一下单与与独立商户模式之间有一点点修改,两个参数,sub_mch_id,sub_appid,原来的openid 参数改为sub_openid


** * 文件:WxPayPubHelper.php
 * 统一支付接口类
 * Class UnifiedOrder_pub
 */
class UnifiedOrder_pub extends Wxpay_client_pub
{
    public function __construct()
    {
        //设置接口链接
        $this->url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        //设置curl超时时间
        $this->curl_timeout = WxPayConf_pub::getParams(‘curl_timeout‘);
    }

    /**
     * 生成接口参数xml
     * @return string|void
     */
    public function createXml()
    {
        try {
            //检测必填参数
            if ($this->parameters["out_trade_no"] == null) {
                throw new SDKRuntimeException("缺少统一支付接口必填参数out_trade_no!" . "<br>");
            } elseif ($this->parameters["body"] == null) {
                throw new SDKRuntimeException("缺少统一支付接口必填参数body!" . "<br>");
            } elseif ($this->parameters["total_fee"] == null) {
                throw new SDKRuntimeException("缺少统一支付接口必填参数total_fee!" . "<br>");
            } elseif ($this->parameters["notify_url"] == null) {
                throw new SDKRuntimeException("缺少统一支付接口必填参数notify_url!" . "<br>");
            } elseif ($this->parameters["trade_type"] == null) {
                throw new SDKRuntimeException("缺少统一支付接口必填参数trade_type!" . "<br>");
            } elseif ($this->parameters["trade_type"] == "JSAPI" &&
                $this->parameters["openid"] == NULL
            ) {
                throw new SDKRuntimeException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!" . "<br>");
            }
/************************************服务商模式修改***********************************/
        if(WxPayConf_pub::getParams(‘sub_mchid‘)){      //服务商模式

            $this->parameters["sub_mch_id"] = WxPayConf_pub::getParams(‘sub_mchid‘);
            $this->parameters["sub_appid"] = WxPayConf_pub::getParams(‘sub_appid‘);
            $this->parameters["sub_openid"] = $this->parameters["openid"];
            unset($this->parameters["openid"]);//去掉原来的openid
        }
/************************************服务商模式修改结束***********************************/

            $this->parameters["appid"] = WxPayConf_pub::getParams(‘appid‘);//公众账号ID
            $this->parameters["mch_id"] = WxPayConf_pub::getParams(‘mchid‘);//商户号
            $this->parameters["spbill_create_ip"] = $_SERVER[‘REMOTE_ADDR‘];//终端ip
            $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
            $this->parameters["sign"] = $this->getSign($this->parameters);//签名
            return $this->arrayToXml($this->parameters);
        } catch (SDKRuntimeException $e) {
            die($e->errorMessage());
        }
    }

  

2.服务商模式下JSAPI调用微信支付

官方给出H5调用API支付文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=7_7&index=6

而我们之前一直立商户模式,用的是JSSDK :https://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html

调试统一下单时还算比较顺利,因为获取prepay_id不成功无非就是参数的问题,并且返回给我们的错误也非常详细,可以很快定位问题。可是这个JSAPI可就把我弄惨了,先看代码(javascript)

// 微信支付调用方法
  function weixinpayFun() {  var buildformUrl = ‘http://local.test/pay/getparams?orderid=订单号‘;//获取微信支付相关参数
    $.post(buildformUrl, {}, function (res) {
      $.hideLoading();
      if (res.status) {
        var wxpayParam = res.data;
        // 发起一个支付请求
        wx.chooseWXPay({
          timestamp: wxpayParam.timeStamp,
          nonceStr: wxpayParam.nonceStr,
          package: wxpayParam.package,
          signType: wxpayParam.signType,
          paySign: wxpayParam.paySign,
          trigger: function (res) {

          },
          complete: function (res) {

          },
          success: function (res) {
            $.alert(‘支付成功‘);
          },
          cancel: function (res) {
            $.alert(‘支付已取消‘);
          },
          fail: function (res) {
            alert(JSON.stringify(res));
            $.alert(‘支付失败‘);
          }
        });
      } else {
        $.alert(‘微信支付失败!‘);
      }
    }, ‘json‘);
  }

由这段代码可以看到,我们是通过Ajax方式调用微信支付统一下单并获取到JSAPI的支付参数的,这在独立商户模式下是没有问题的,并且是使用了很长一段时间。

改用服务商模式后,奇怪的问题就来了,每次请求从日志中看到统一下单是成功的,也就是说我的参数与签名也都是没有问题的,但是返回给我的错误见下图

从各方了解到,出现这个错误的原因是签名错误,于是我就各种各样的调整签名参数,把sub_appid ,appid 换来换去,或者一起结合起试,都不行。中间有咨询过微信支付的技术人员,对方也是帮忙分析了一下确认是签名错误,但根据他要求提供了相关参数检查后签名是正确的。最终也是没有完全搞定。

今天上午因为要处理另外一个问题,公众号从公众平台授权会引起独立商户支付出错,完全调不出支付界面,(因为之前我们都是让客户填写url,token appid,appsecret之类的参数的,现在改成了公众平台授权) 发现我们在一个初始的地方做了个JSSDK的初始化主要用于调用分享 ,见下面的代码

 <script>
    window.onload = function onload() {
      var share_link = ‘{$share[url]}‘;
      var share_href = share_link != ‘‘
          ? Config.SERVER_HOST + share_link
          : Config.SERVER_HOST;
      jwx.initialize({
        appId: ‘{$sys_params.jsapi_param.appId}‘,
        timestamp: ‘{$sys_params.jsapi_param.timestamp}‘,
        nonceStr: ‘{$sys_params.jsapi_param.nonceStr}‘,
        signature: ‘{$sys_params.jsapi_param.signature}‘
      }, function () {
        jwx.setShareData({
          title: ‘{$share[title]}‘,
          desc: ‘{$share[description]}‘ + ‘, 在微信轻松点单、预订‘,
          link: share_href,
          imgUrl: ‘{$share[photo]}‘
        });
        if ("function" === typeof jwxCallback) {
          jwxCallback();
        }
      });
    };
  </script>

由于是授权所以没有了appsecret这个参数,导致无法正常获取JSAPI初始化参数,经过一番代码修改,终于授权的公众号可以正常使用独立商户的微信支付了,改完突然想起,中间咨询微信支付的技术大神有提到过config文件中的nonceStr和timestamp,由此想到会不会是这个JSAPI初始参数用的appid与appsecret 用的是子商户的appid和appsecret引起的呢?把他换成服务商的试试呢,这一试可不就把问题给解决了.

3.总结

微信支付使用JSAPI发起支付时要注意 JSAPI初始参数与调用统一下单时的参数(appid,appsecret)要一致,否则会出现莫名的签名错误

时间: 2024-10-29 09:56:01

微信公众号内H5调用微信支付国内服务商模式的相关文章

java微信支付--------公众号内H5调起支付

谨以此做记录,方便下次实现,不适合新手拷贝,如有指教,欢迎留言讨论! 新手请参考博文:https://blog.csdn.net/javaYouCome/article/details/79473743,致谢该博主! 微信支付官方文档:https://pay.weixin.qq.com/wiki/doc/api/index.html 记录几个容易出问题的点: 1.参与签名的参数名大小写保持与官方文档一致, 2.在商户平台配置支付目录,类似配置js安全接口域名 3.调用统一下单接口获取prepay

免费微信公众号专用h5在线电影票API

免费h5在线电影票API,通过嵌套返回的h5页面url,实现电影票购买. 接口文档:https://www.juhe.cn/docs/api/id/252,通过此申请APPKEY 接口备注:通过请求返回H5的URL,一次获取永久有效,嵌套到对应的应用或网站中即可使用 接口地址:http://v.juhe.cn/wepiao/query 支持格式:json 请求方式:http get/post 请求示例:http://v.juhe.cn/wepiao/query?key=xxxxx 调用样例及调试

微信小程序、微信公众号、H5之间相互跳转

转自慕课网 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加小程序. 图片有点小,我把文字打出来吧: 可关联已有的小程序或快速创建小程序.已关联的小程序可被使用在自定义菜单和模版消息等场景中. 公众号可关联同主体的10个小程序及不同主体的3个小程序.同一个小程序可关联最多50个公众号. 1.公众号跳小程序 比如说 "丰巢快递柜" 公众号关联的小程序:丰巢寄快递. 2.小程序跳公众号 打开"丰巢寄快递",点击右上角的菜单选项,然后点击"关于

[转]微信小程序、微信公众号、H5之间相互跳转

本文转自:https://www.cnblogs.com/colorful-paopao1/p/8608609.html 转自慕课网 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加小程序. 图片有点小,我把文字打出来吧: 可关联已有的小程序或快速创建小程序.已关联的小程序可被使用在自定义菜单和模版消息等场景中. 公众号可关联同主体的10个小程序及不同主体的3个小程序.同一个小程序可关联最多50个公众号. 1.公众号跳小程序 比如说 “丰巢快递柜” 公众号关联的小程序:丰巢寄快

你所误解的微信公众号开发、以及微信公众号开发遇到的问题及详解

前言:有一星期没跟新博客了,最近太忙.项目赶进度就没把时间花在博客上:今天来说说所谓的微信公众号开发和填坑记录: 微信公众号:运行在微信终端的应用 (对于开发者来说比较爽的你只需考虑兼容微信浏览器,因为它是在微信浏览器环境下运行的) 微信公众号开发分为两部分: 一.传统开发(前后端分离) 推荐  页面量大的时候优点就尤其突出了 1. 微信首页 (即首页菜单.跳转链接.扫二维码.消息推送回复等功能) 不要慌  这些百分之90%都是后天来配置的,他们调用下微信公众平台提供的接口就ok了:为什么是后台

.NET微信公众号开发-5.0微信支付

一.前言 在开始做这个功能之前,我们要做的第一件事情就是思考,如何做这个微信支付,从哪里开始,从哪里入手,官方的sdk说明什么的,有没有什么官方的demo,还有就是老板给我的一些资料齐全不,那些要申请的接口什么的都有没有. 经过自己的一些探索,在老板的催促下终于硬着头皮做完了这个,很坑很坑的微信支付,在此做一些总结,希望对你们有所帮助,本人能力有限,如果有什么说的不好,希望大家多多包涵. 二.开发前准备. 1.0微信支付官方开发者文档 2.0官方demo下载 我们用c#所以选择.net版本 不过

NET微信公众号开发-5.0微信支付(待测试)

开发前准备. 1.0微信支付官方开发者文档 2.0官方demo下载 我们用c#所以选择.net版本 不过这个官方的demo根本跑步起来 3.0官方demo运行起来解决方案 4.0微信支付官方.net版之坑你没商量 5.0开发前的微信公众平台的一些配置,请务必认真检查配置. 编码 做好了这些准备工作之后,我们知道微信支付有两种,1.原生态的,2.jsapi直接调用的,我项目中用到的是第二种 经过自己的一些业务逻辑处理,来到了我们的订单详情页面,现在需要去点击我们的支付按钮去支付,支付页面pay.a

微信公众号(h5移动端)如何长长按保存图片?

工具:hbuilderX 框架:uniapp 项目:公众号(h5)换装小游戏 项目描述:用户通过微信登录公众号简介,然后根据自己的喜爱选择人物头部(脸部表情.帽子).身体(衣服).配饰.然后生成海报.用户可通过长按图片将生成的海报保存到自己的手机中. 问题:当时认为这个不是什么问题,因为在uniapp中有uni.saveImageToPhotosAlbum可以将图片保存到系统中.后来项目快结束了,说这个功能很重要,然后才发现 不支持h5,这时候,还不是很急,因为在plus还有保存图片的方法plu

微信公众号开发系列-获取微信OpenID

在微信开发时候在做消息接口交互的时候须要使用带微信加密ID(OpenId),下面讲讲述2中类型方式获取微信OpenID.接收事件推送方式和网页授权获取用户基本信息方式获取. 1.通过接收被动消息方式获取OpenId(接收事件推送方式).下面事件中都能够获取到OpenID 关注/取消关注事件 用户在关注与取消关注公众号时.微信会把这个事件推送到开发人员填写的URL.方便开发人员给用户下发欢迎消息或者做帐号的解绑. 微信server在五秒内收不到响应会断掉连接,而且又一次发起请求,总共重试三次 关于