原文转载:https://www.yundashi168.com/342.html

场景概述

微信公众号开发微信支付功能遇到的一个坑:微信支付提示 调用支付JSAPI缺少参数:appId

鉴于去年做过微信app支付,小程序支付,支付宝app支付,云闪付app支付等方面的功能和研究。最近要完成一个在微信公众号支付的场景。其中遇到了一个坑,坑了我足足一上午多的时间。所以我想写下来记录,以后遇到微信相关API调用的时候,就不会花这么久的时间了。

技术场景:微信公众号支付

本文不会详细讲解微信公众号支付的具体流程,因为官网文档已经说得很详细,至少比我写的详细。而且本文的目的是记录我自己遇到的坑,而不是写支付教程。放心,下次有时间多的话,我会手把手的写下相关教程步骤的。

技术概况

开发前的准备工作

  • 微信公众号服务号+微信支付商户号(都是需要企业资格)

  • 备案的域名一个

  • 后端支付程序部署测试:
    1:本地服务+花生壳端口映射的方式(我采用的方案)
    2:购买服务器和购买域名并且通过备案

    微信公众号需要是服务号认证,需要开通微信支付功能,这些都需要交钱 300大洋一年。这里就不多讲了,如果开通服务号,商户号,网上资料很多。
    我选择花生壳的目的是:第一:本地调式程序速度快,虽然本人拥有很多台阿里云的服务器,而且我也熟悉后端程序发布,但是我还是选择在开发测试阶段,先用花生壳本地端口映射。第二:花生壳提供的域名是经过备案的,做做测试用还是可以的。

    看见没,花生壳端口映射的域名,支持外网80端口(只能提供一个80端口)和外网随机端口。内网主机的端口,你自定义定义。是不是非常方便和适合测试微信,支付宝,云闪付之类的开发测试呢?

开发阶段

因为本人需要自己搞定移动前端网页和后端支付接口,所以前端我采用我熟悉的技术栈React来开发,后端采用的是SpringBoot框架来开发。

后端接口程序

核心代码:微信公众号后端支付接口
接口URL: http://qq784602719.imwork.net/school/wxpay/webPay
请求参数:需要传入openId(微信公众号身份标识)和total_fee(支付金额)

/*** 公众号支付*/
@RequestMapping(value ="/webPay",method = {RequestMethod.POST,RequestMethod.GET})
@ResponseBody
public AjaxResult webPay(HttpServletRequest request,HttpServletResponse response,@RequestParam("total_fee") String total_fee,@RequestParam("openId") String openId) {// openId,采用 网页授权获取 access_token API:SnsAccessTokenApi获取//String openId = (String) request.getSession().getAttribute("openId");System.out.println("openId:"+openId);System.out.println("total_fee:"+total_fee);if (StrKit.isBlank(openId)) {result.addError("openId is null");return result;}if (StrKit.isBlank(total_fee)) {result.addError("请输入数字金额");return result;}String ip = IpKit.getRealIp(request);System.out.println("ip:"+ip);if (StrKit.isBlank(ip)) {ip = "127.0.0.1";}System.out.println("AppId:"+WxPayApiConfigKit.getWxPayApiConfig().getAppId());System.out.println("MchId:"+WxPayApiConfigKit.getWxPayApiConfig().getMchId());System.out.println("PaternerKey:"+WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey());System.out.println("notify_url:"+notify_url);Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig().setAttach("微信公众号支付测试  -By arison").setBody("微信公众号支付测试  -By arison").setOpenId(openId).setSpbillCreateIp(ip).setTotalFee(total_fee).setTradeType(TradeType.JSAPI).setNotifyUrl(notify_url).setOutTradeNo(String.valueOf(System.currentTimeMillis())).build();String xmlResult = WxPayApi.pushOrder(false,params);log.info(xmlResult);Map<String, String> resultMap = PaymentKit.xmlToMap(xmlResult);String return_code = resultMap.get("return_code");String return_msg = resultMap.get("return_msg");if (!PaymentKit.codeIsOK(return_code)) {result.addError(return_msg);return result;}String result_code = resultMap.get("result_code");if (!PaymentKit.codeIsOK(result_code)) {result.addError(return_msg);return result;}// 以下字段在return_code 和result_code都为SUCCESS的时候有返回String prepay_id = resultMap.get("prepay_id");Map<String, String> packageParams = PaymentKit.prepayIdCreateSign(prepay_id);String jsonStr = JSON.toJSONString(packageParams);result.success(jsonStr);System.out.println("data:"+jsonStr);return result;
}

接口方法里面有些参数加密的方法用进行了封装(对微信公众号支付提供的demo中的工具类),在这里代码就不一一展示了。因为并不是很重要。

前端支付程序

这里用的是React技术,网络请求用的是fetchPost。请求的时候,后端需要配合处理下跨域问题。
这里的userOpenid是在前端项目绑定页面中绑定成功之后,把微信公众号给的openId通过Redux传给其它React界面。所以这里通过this.props.userOpenid就拿到了Redux传过来的openId。

 wxPayRequest = () => {Toast.loading("")// const data="wxpay/webPay"; this.props.userOpenidfetchPost("http://qq784602719.imwork.net/school/wxpay/webPay", {openId: this.props.userOpenid,total_fee: '1'}).then((response) => {Toast.hide();console.log("response:" + JSON.stringify(response));const data = response.data;if (typeof WeixinJSBridge == "undefined") {if (document.addEventListener) {document.addEventListener('WeixinJSBridgeReady', this.onBridgeReady(data), false);} else if (document.attachEvent) {document.attachEvent('WeixinJSBridgeReady', this.onBridgeReady(data));document.attachEvent('onWeixinJSBridgeReady', this.onBridgeReady(data));}} else {this.onBridgeReady(data);}}).catch((error) => {console.log("error:" + JSON.stringify(error));})
}onBridgeReady = (json) => {const that = this;WeixinJSBridge.invoke('getBrandWCPayRequest', JSON.parse(json),function (res) {if (res.err_msg == "get_brand_wcpay_request:ok") {// 使用以上方式判断前端返回,微信团队郑重提示://res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。Toast.success("支付成功!")} else {message.info("支付失败:" + res.err_msg)that.setState({payInfo: json,payResult: "支付失败:" + JSON.stringify(res)});}});
}

当我在前端写的支付界面中调用上面的 wxPayRequest 方法后,遇到了错误 get_brand_wcpay_request:fail
我马上通过JSON.stringify(res)把错误对象解析成字符串放入界面展示,为了看到更全的报错信息。如图:

错误信息:

{"err_desc":"调用支付JSAP缺少参数appId","err_msg":"get_brand_wcpay_request:fail","err_code":"-1"}

我当时就在想,我openId在本地后端程序日志窗口打印发现,我参数传到后端接口方法是对的啊,而且我微信公众号和商户号也设置正确了。尤其是设置了商户平台的 支付授权目录。

支付授权目录是:你的支付界面访问路径

http://qq784602719.imwork.net/school/rechargeHome 去掉最后一个斜杠后面的字符串

支付授权目录 http://qq784602719.imwork.net/school/

但是我设置了正确的支付授权目录之后,还是提示上面那个问题,缺少参数appId。很是纳闷啊。不过我感觉是前端JS调用方面确实出现了问题,于是开始排查JS端写的代码。

后面经过多次排查,问题果然还是被我找到了,找到之后,发现居然是一个很简单的问题。不过还是最终解决了问题。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-engR74XM-1627704480086)(https://i.loli.net/2019/07/19/5d319049e6fc481333.jpg)]

问题的关键之处是我出问题的代码写成了如下:

onBridgeReady = (json) => {const that = this;WeixinJSBridge.invoke('getBrandWCPayRequest', json,function (res) {if (res.err_msg == "get_brand_wcpay_request:ok") {// 使用以上方式判断前端返回,微信团队郑重提示://res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。Toast.success("支付成功!")} else {message.info("支付失败:" + res.err_msg)that.setState({payInfo: json,payResult: "支付失败:" + JSON.stringify(res)});}});
}

微信JSAP 接口 WeixinJSBridge.invoke中第二个参数是javascript对象,而不是json字符串!!!后面我用JSON.parse(json)把服务器接口给我的json字符串转化为javascript对象,就能顺利支付成功了。

附属参考文档:

微信公众号支付文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
微信支付提示 调用支付JSAPI缺少参数:appId :https://bbs.csdn.net/topics/391028145
微信支付JSAPI支付授权目录陷阱:https://blog.csdn.net/a7442358/article/details/85766204

解决我错误的启发文章:微信公众号支付JSAPI,提示:2支付缺少参数:appId

微信公众号微信支付提示 调用支付JSAPI缺少参数:appId相关推荐

  1. 小程序 php wecahtpay,PHP 微信公众号,小程序获取支付参数。微信支付

    PHP 微信公众号,小程序获取支付参数.微信支付 发布时间:2018-09-26 11:19, 浏览次数:278 , 标签: PHP 首先下载微信官方demo放入项目中 地址:https://gith ...

  2. python微信库有哪些_GitHub - zwczou/weixin-python: 微信SDK - 包括微信支付,微信公众号,微信登陆,微信消息处理等...

    微信SDK 提供微信登陆,公众号管理,微信支付,微信消息的全套功能 文档目录 如果需要单独使用其中的某些模块,可以见文档目录的具体模块 如果需要组合在一起可以参考快速开始 目录 安装 使用pip su ...

  3. 微信公众号自动回复一直提示服务出现故障,原来官方文档很坑人!

    微信公众号自动回复 一直提示 服务出现故障,各种参数都没错,而且居然都是直接从微信官方文档复制代码过来也不行!后来才发现,原来官方的代码是个坑! 如图所示,官方的代码多了很多的空格,在网上查了,许多新 ...

  4. 微信公众号/微信小程序获取用户信息以及推送微信模版消息_MQ

    微信公众号/微信小程序获取用户信息以及推送微信模版消息_MQ 一.获取用户信息 1.首先我们需要了解什么是微信用户的OpenID 在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密 ...

  5. 自动获取微信公众号微信文章信息(每日自动推送)

    自动获取微信公众号微信文章信息 目录 前言 一.获取文章列表 二.自动化获取微信公众号cookie 1.影刀自动登录微信 2.获取公众号cookie 1.安装mitmproxy 2.配合切换代理脚本, ...

  6. 如何编辑微信公众号(微信公众号内容制作流程)

    如何编辑微信公众号(微信公众号内容制作流程) 一.关于申请事项的常见问题概述 1 .注册要花钱吗? 微信官方账号注册完全免费. 微信官方账号唯一需要交钱的地方就是年度认证费.作为个人账户,目前没有认证 ...

  7. 微信公众号注册时提示该主体注册数量已超过上限怎么办?

    很多用户在注册或认证微信公众号时,遇到"该主体注册数量已超过上限"的问题,这是怎么回事呢? 原因是2018年11月16日微信官方对公众号注册数量做了调整: 1.个人主体注册公众号数 ...

  8. 微信公众号分享功能无法调用

    我之前做微信分享功能的时候,做好发现移动端无法进行分享,放在微信开发者工具上测试,会发现出现errmsg 错误 这个问题,主要还是权限问题,可以进微信公众号后台权限管理查看 注意: 这里看清楚,账户主 ...

  9. 个人怎么申请微信公众号-微信公众号使用教程33

    在以前的<秦子恒微信课堂>中, 子恒老师介绍公众号是以公司申请并认证的, 但是随着公众号的普及, 很多个人也申请了公众号, 并且运营得非常好. 有学员问是否可以介绍下个人公众号方面的内容, ...

  10. java微信公众号——微信JS-SDK的使用

    微信JS-SDK介绍 微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包. 通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统的能力,同 ...

最新文章

  1. Oracle中的数据字典技术及常用数据字典总结
  2. Javascript 获取Url值 --转
  3. Hadoop生成HFile直接入库HBase心得
  4. indows 平台下 Go 语言的安装和环境变量设置
  5. 35、Power Query-分组中国式排名
  6. robocopy file backup script
  7. 【Spring】Spring第一天 - 环境搭建、IoC 详解、DI 详解等
  8. 怎样编写测试类测试分支_编写干净的测试-被认为有害的新内容
  9. C语言中关于字符数组输入,scanf没执行
  10. java 继承作用_java三大特性之继承
  11. ultrascale和arm区别_[原创] Avnet Zynq UltraScale+MPSoC系列Ultra96开发方案
  12. 应该怎么样学习前端呢?
  13. Mysql中Check约束无效的原因以及解决方法
  14. 小D课堂 - 新版本微服务springcloud+Docker教程_4-04 高级篇幅之服务间调用之负载均衡策略调整实战...
  15. [UE]EpicGames Launcher 添加/识别本地已有编辑器版本
  16. 如何在面试中介绍自己的项目经验
  17. Bundle Adjustment — A Modern Synthesis(一)
  18. 迪文串口屏幕DMG10600T101_01WTR实现图片切换并和串口通讯
  19. 推荐模型-上下文感知-2016:FNN模型【FM家族】【FM+MLP=FNN】
  20. 单片机毕业设计 stm32智能路灯设计与实现

热门文章

  1. JS代码计算正方教务系统目前成绩的加权平均分和平均绩点
  2. 明哥,给大学生的几点建议
  3. web中间件应用系列:负载均衡(二)负载均衡算法和常见实现方式
  4. 在MonthCalendar控件中选中日期
  5. JPEG图像格式解析
  6. 什么是OneData?阿里数据中台实施方法论解读
  7. JVET专家组下360Lib全景视频投影格式测试平台
  8. 用C/C++手撕CPlus语言的集成开发环境(1)—— 语言规范 + 词法分析器
  9. 【2021年】百度搜索词获取,获取百度搜索的关键词
  10. 【免填邀请码】让邀请裂变活动事半功倍