微信公众号支付开发流程与避坑手册-Java篇

导数与微分在 FPS 射击游戏中的实际应用:把“手感”算出来 摘要:射击游戏开发中,单线程适用于简单小游戏(如单机打靶),所有任务由主线程顺序处理,代码简单但效率较低;多线程则适合复杂场景(如多人在线3D大作),通过渲染、逻辑、网络、音效等线程分工协作,确保画面流畅、响应迅速和实时同步。选择依据取决于游戏复杂度、联网需求和性能要求,小型游戏用单线程,大型高要求项目必须采用多线程架构。(149字) 阅读详情
前言

最近完成了微信公众号内的支付功能,在开发的过程中遇到了各种各样的问题,在这里,我把开发的过程分享出来,给大家做个参考。

首先,在准备开发的时候需要进行必要的配置。

1.登录微信商户平台,在产品中心->开发配置中对支付授权目录进行配置
(注意:支付授权目录的配置规则是你使用微信支付控件页面的上一级目录,比如:你在www.xxx.cpm/wx/pay/pay.html中调用微信支付控件,那么你需要配置的目录是www.xxx.cpm/wx/pay/)
这里写图片描述

2.在账户中心->API安全中配置key值,此参数在生成签名时需要用到。
这里写图片描述

3.其他参数与配置:appid,开发者密码以及网页授权
这里写图片描述

在做完这些配置以后,我们就可以进行微信支付的开发了。在这里推荐参考微信平台提供的demo。https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

按照文档中统一接口的实现流程,我们需要先实现发起微信支付的请求。这里的请求链接是统一下单的链接,POST请求

  /**
     * 发起微信支付请求 
     * @param requestUrl  请求链接
     * @param method  请求方式
     * @param param  请求参数
     * @param connectTimeOut  连接超时时间
     * @param readTimeOut  读取超时时间
     * @return 请求结果
     */
public String requestOnce(final String requestUrl, final String method, String param, boolean useCert, int connectTimeOut, int readTimeOut) {
        HttpURLConnection conn = null;
        StringBuilder builder = new StringBuilder();
        try {
            URL url = new URL(requestUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod(method);
            conn.setConnectTimeout(connectTimeOut);
            conn.setReadTimeout(readTimeOut);
            OutputStream out = conn.getOutputStream();
            out.write(param.getBytes());
            out.flush();
            out.close();
            int responseCode = conn.getResponseCode();
            if (responseCode == 200) {
                InputStream inputStream = conn.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
                String line = null;
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                }
                reader.close();
                inputStream.close();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return builder.toString();
    }

在这里我们将微信支付所需要的参数进行填充。

 /**
     * 填充微信支付参数
     * @param data 需要填充的Hashmap
     * @return 参数
     */
    public Map<String, String>  fillRequestData(Map<String, String> data) throws Exception {
        data.put("appid", config.getAPPID());
        data.put("mch_id", config.getMCHID());
        data.put("nonce_str", WXPayUtil.generateNonceStr());
        data.put("notify_url",config.getNOTIFY_URL());
        data.put("spbill_create_ip", config.getSERVER_IP());
        data.put("trade_type", config.getJSAPI());
        if (WXPayConstants.SignType.MD5.equals(this.signType)) {
            data.put("sign_type", WXPayConstants.MD5);
        }
        else if (WXPayConstants.SignType.HMACSHA256.equals(this.signType)) {
            data.put("sign_type", WXPayConstants.HMACSHA256);
        }
        data.put("sign", WXPayUtil.generateSignature(data, config.getKEY(), this.signType));
        return data;
    }

在请求成功之后,微信服务器会返回xml形式的参数,我们可以将xml转换为Map(此方法在微信demo中有实现)。此外在结果返回成功以后,需要再次生成签名,此签名是由于前端页面调起微信支付控件所用。

 /**
     * 发起微信支付认证请求
     * @param requestUrl 请求链接
     * @param method 请求方式
     * @param param 请求参数
     * @param useCert 是否使用证书
     * @return 认证结果
     */
    private Map<String, String> request(final String requestUrl, final String method, String param, boolean useCert) {
        String strXml = wxPayRequest.request(requestUrl, method, param, useCert, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs());
        Map<String, String> data;
        try {
            data = WXPayUtil.xmlToMap(strXml);
        } catch (Exception e) {
            data = null;
            e.printStackTrace();
        }
        return data;
    }

private Map<String, String> returnAuthParam(Map<String, String> temp, String key) {
        Map<String, String> result = new HashMap<String, String>();
        long timestamp = System.currentTimeMillis() / 1000;
        result.put("appId", temp.get("appid"));
        result.put("timeStamp", String.valueOf(timestamp));
        result.put("nonceStr", temp.get("nonce_str"));
        result.put("package", "prepay_id=" + temp.get("prepay_id"));
        result.put("signType", WXPayConstants.MD5);
        String sign = null;
        try {
            sign = WXPayUtil.generateSignature(result, key, WXPayConstants.SignType.MD5);
        } catch (Exception e) {
            e.printStackTrace();
        }
        result.put("paySign", sign);
        result.put("return_code", temp.get("return_code"));
        result.put("result_code", temp.get("result_code"));
        return result;
    }

签名生成方法:

/**
     * 生成签名 MD5 HMACSHA256
     * @param data 参数
     * @param key API密钥
     * @param signType 签名方式
     * @return 签名
     */
    public static String generateSignature(final Map<String,String> data, String key, WXPayConstants.SignType signType) throws Exception {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (k.equals(WXPayConstants.FIELD_SIGN)) {
                continue;
            }
            if (data.get(k).trim().length() > 0) {
                sb.append(k).append("=").append(data.get(k).trim()).append("&");
            }
        }
        sb.append("key=").append(key);
        if (WXPayConstants.SignType.MD5 == signType) {
            return MD5(sb.toString()).toUpperCase();
        }
        throw new Exception(String.format("Invalid sign_type: %s", signType));
    }

在做完这些操作以后,就可以在前端实现调起微信支付控件的逻辑了。在微信支付文档中给出了一种写法:

if (typeof WeixinJSBridge == "undefined"){
                       if( document.addEventListener ){
                           document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
                       }else if (document.attachEvent){
                           document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
                           document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
                       }
                    }else{
                       onBridgeReady(data);
                    }
function onBridgeReady(data){
    orderPage.orderParam.orderId = data.orderId;
    WeixinJSBridge.invoke(
        'getBrandWCPayRequest', {
        "appId": data.appId,     //公众号名称,由商户传入      
        "timeStamp": data.timeStamp, //时间戳,自1970年以来的秒数
        "nonceStr": data.nonceStr, //随机串     
        "package": data.package,     
        "signType": data.signType,         //微信签名方式:     
        "paySign": data.paySign //微信签名 
        },
        function(res){
            alert(res.err_msg + " " + res.err_code + " " + res.err_desc);
            if(res.err_msg == "get_brand_wcpay_request:ok"){
                orderPage.orderParam.status = "WAITSEND";
                orderPage.submitOrder();
            }else if(res.err_msg == "get_brand_wcpay_request:fail"){
                alert("调用微信支付失败");
            }else if(res.err_msg == "get_brand_wcpay_request:cancel"){
                alert("已取消支付");
            }
        }
    ); 
}

在上面所使用到的参数都是服务端微信支付请求成功后获取的参数。完成这些之后,微信支付就可以使用了。
但是我们开发的过程中,如果没有相关的项目经验,难免会遇到很多坑。这里我就列举出我在开发中遇到的问题。

  1. 参数缺失:缺少openid,在微信公众号内嵌网页中调用微信支付需要添加用户的openid。
  2. 参数形式错误:在前端调起微信支付控件时,将package参数传错,package参数的正确格式为:“prepay_id=XXXXXXXXX”,而我忘了加入“prepay_id=”,这个错误着实让我找了好久(都是不仔细阅读文档的问题)。
  3. 签名失败:这个签名失败是在前端提示。造成的原因是我在微信支付请求成功之后,直接使用了服务端申请微信支付请求生成的签名,而正确的应该是在申请支付权限成功之后,需要**将前端用到的参数拿过来重新生成一次签名才对。**这个错误卡了我大半天才搞定,需要注意。
  4. get_wcpay_branch_request:fail,这个错误的排查顺序是:首先查看返回参数中request_code,result_code的返回值,如果都为SUCCESS,那么说明服务端请求微信支付权限已经成功,错误就来自于前端,或者参数错误(参考3)。

微信支付的调试:
由于开发微信支付需要调用第三方接口,所以在调试的时候会遇到诸多不便。这里我们就需要使用一些工具来帮助我们完成。
1.微信web开发者工具,我们可以使用这个工具进行调试,直接输入链接地址,然后在这里可以断点调试也可以查看相关错误信息。
这里写图片描述
2。打印log。在前端我们可以打印出关键信息进行错误排查。比如说,在调用微信支付控件时,输出err_msg,err_code,err_desc,进行查看。
这里写图片描述

最后说两句

在做完微信支付以后,其实你会发现并没有太大难度,就是在开发的过程中我们需要善于发现问题。还有就是要仔细阅读文档,我遇到的一些错误有很多都是文档中所提到的,但是没有仔细看所以就花费了很多时间去排查错误,而这些都是可以避免的。

最后一张,微信支付的目录结构(仅供参考):
这里写图片描述

UE4打包为Framework库嵌入iOS原生工程 阅读详情

相关推荐

频偏估计技术:从原理到5G应用的实战解析

本文深入解析了5G通信中的频偏问题及其核心技术。频偏如同调不准的旋钮,会导致信号失真与载波间干扰。文章详细拆解了整数倍与小数倍频偏估计两大核心方法,重点剖析了基于循环前缀和基于同步信号块的算法原理与优劣,并结合eMBB、mMTC、URLLC三大5G应用场景,提供了实战算法选择策略与参数调优避坑指南。

weixin_29218963的博客 262

微信支付 总提示get_brand_wcpay_request:fail 也不跳转支付页面 的解决方案

28行是我后面加进去的,主要用来查看返回的详细信息,信息提示我是我当前域名没有在微信支付配置中授权,登录微信公众号平台,在微信支付中配置下授权目录,在这里,将提示信息中的目录添加到该目录下,过几分钟就OK了.。

coldriversnow的专栏 1689

别再死记硬背了!一张图搞懂无刷电机半桥与全桥驱动的核心差异(附避坑指南)

本文深入解析无刷直流电机的半桥与全桥驱动方式的核心差异,提供直观对比与选型指南。半桥驱动结构简单、成本低,适合低要求场景;全桥驱动性能优越但复杂,适用于高精度控制。文章还包含实战避坑指南,帮助工程师优化驱动方案选择与应用。

weixin_29290947的博客 319

微信公众号支付开发(一):前期准备

微信公众号(服务号)认证准备工作

Desire染指年华 650

Android 导出aar 用于Unity 百度语音唤醒

AndroidStudio版本下载地址Android Studio Arctic Fox Unity版本2021.3.26f1c1 新建AndroidStudio工程 新建module 这里注意一下,网上很多教程说要注意包名要和unity一样,但是测试下来,不一样也可以的 在新建的module里添加这两个jar包,并点击右键add as library 导入jniLibs 右键创建这几个package 代码就安装这个大佬的写参考代码 需要注意的的是在WakeupListener脚本里U

weixin_38777563的博客 633

AS7341光谱传感器实战:如何用STM32F103精准测量环境色温(附完整代码)

本文详细介绍了如何使用STM32F103驱动AS7341光谱传感器实现环境色温的精准测量。从硬件连接到驱动开发,再到色温计算算法的实现,提供了完整的代码示例和优化建议,帮助开发者在智能照明、农业监测等领域快速应用AS7341进行高精度色温检测。

weixin_30352645的博客 478

微信服务号开发-整合微信支付

最近的项目在对接微信支付,所以抽出一些时间,将方法总结一下:欢迎加群交流:724225958官方开发文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=1_1;文档中分别对支付账户(参数)、接口规则、支付业务场景,流程、API做了详细介绍,并提供了SDK以及DEMO ,大部分有一定基础的开发或研发,均可参照文档及其demo,一步一...

Soongp的博客 3530

HFSS/ADS仿真实操:手把手调优一个2.4GHz SAW滤波器的IDT结构

本文详细介绍了使用HFSS和ADS仿真工具优化2.4GHz表面声波滤波器(SAW)的IDT结构。从材料参数设置到IDT建模,再到参数化扫描与频率调谐,提供了实用的操作步骤和优化技巧,帮助工程师快速掌握SAW滤波器的设计方案与性能调优方法。

weixin_29197835的博客 531

微信支付(一)统一下单接口注意事项

开发背景 WXPaySdk 3.0.9 Java 注意事项 使用SDK中的requestWithoutCert方法发送下单请求时传入的data是xml格式的,不是json格式。可以使用 WXPayUtil.mapToXml(jsonObject); 因为这个版本的WXPayConfig中的方法仅同包可以实现,所以我这里把它copy到工程中进行实现,在实现其getWXPayDomain方法时需要返回一个IWXPayDomain接口的实现类,注意实现getDomain方法时DomainInfo

Nio的博客 1307

IAP板卡远程升级(串口网口都可)+Ymodem+AES对bin文件加密+pc软件+板卡相互烧录

还是决定记录一下,毕竟这个东西我也搞了挺久的,遇到一些棘手的,或者是因为我很粗心遇到的问题也和大家分享一下,。 板卡核心是 STM32F103RCT6,256kflash 前言 开始看这个远程升级的时候,我是一头雾水的,原子哥的教程里面也有说到过iap,有了一个大概的了解,我想不明白的是,通过串口下载的方式把hex文件下载到flash,和把bin文件下载到flash难道不是拉一根线,下载一个文件嘛,(初入职场的我并没有考虑到安全这个问题)如果直接将hex文件给到客户那边,风险是非常大...

那可真是太开心了的博客 5371

【鼠标在不点击的情况下,直接移动到QT控件上不显示提示信息】

有时明明已经调用了setToolTips方法,鼠标移动到QT控件上仍然不会有提示信息,这时候就需要具体分析下。重点就是标红的这段话,大概意思就是。.h文件中加入鼠标移动事件的定义。.cpp文件中实现该事件。

ZTH_G的博客 2423

微信支付

微信支付目录 文章目录微信支付目录前言一、微信支付简介支付场景支付的流程基本流程二、使用步骤1.引入库2.下载完成之后总结 前言 随着科技的进步,越来越多的人开始使用移动支付作为支付手段,所有掌握主流的移动支付也变得很重要了 一、微信支付 简介 再很多场合大家用的都是微信支付,它方便了大家,改善了人们的生活。 支付场景 支付的流程 基本流程 在微信公众平台获取商户号 在微信商户平台关联商户 二、使用步骤 1.引入库 到官网选取合适的sdk下载,很多东西官方都给你写好了,地址在下边 2.

qq_44688861的博客 368

编写python脚本调用ordinals以及BRC20的接口

1、钱包地址生成walletreceive,对应ord命令:ord wallet receive。6、测试手动出块generate,这个只在regtest链节点用得上。所有接口都是post请求,采用postman进行测试。4、测试bitcoin转币sendtoaddress。7、测试其他的wallet方法wallet。2、钱包币种铭刻inscription,对应bitcoin-cli命令。对应bitcoin-cli命令。对应bitcoin-cli命令。fee.json文本模板。还可以加很多根据需要加减。

云深海阔专栏 1048

阿里正式发布《Java开发手册》终极版!

点击上方“终端研发部”,选择“星标”回复“资源”,领取全网最火的Java核心知识总结~前言别人都说我们是码农,但我们知道,自己是个艺术家。也许我们不过多在意自己的外表和穿着,但我们不羁的...

这个时代,作为程序员可能要学习小程序 1418

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Oracle 官方定调:JVM 未来 3 大趋势(附可运行代码 + 落地时间表 + 避坑手册)

结合 10 余年 Java 底层实战经验与 Oracle《JVM 技术路线白皮书(2024-2027)》,拆解 JVM 三大未来趋势:2025 年 WASM 跨语言(附 Java 调用 Rust 可运行代码,延迟降 60%)、JDK 23 云原生动态内存(K8s 配置示例,解决 OOM)、2026 年 JDK 24 内置安全审计(对接 OpenTelemetry 代码,性能损耗<5%),所有技术点附 Oracle 官方链接、生产案例(电商 / 支付 / 银行)及避坑要点,读者可直接复用落地。

开源架构师的博客 1095

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

微信公众号支付的开发经历 2016年java版

最近做了微信公众号支付的开发,开发过程中使用官方的手册还是遇到了很多问题,在百度的过程中发现大家遇到的问题根本原因都类似,但是很杂乱,最终还是解决了。把自己遇到的一些经验记录下来,希望能够对大家有所帮助,之所以写2016年版,是因为网上的资料很多是旧的,大家都是相互复制粘贴。 前言:首先要说的一点:我看见有些人的页面里使用WeixinJSBridge,这个已经过时了,新开发的情况下不要用这个

774

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

【软件开发规范篇】JAVA后端开发编程安全规范

现在的软件项目都是团队多人合作一起开发,软件架构的复杂性也需要协同开发完成,如何高效地协同呢?无规矩不成方圆,无规范难以协同。对软件来说,适当的规范和标准绝不是消灭代码内容的创造性、优雅性,而是限制过度个性化,以一种普遍认可的统一方式一起做事,提升协作效率,降低沟通成本。本文介绍一下JAVA后端开发,关于编程安全方面,可以遵循的一些技术规范。以上介绍了JAVA后端开发,关于编程安全方面,可以遵循的一些技术规范。编程安全无小事,若出现安全问题,被黑客恶意攻击,轻则出现服务器故障。

分享是一种境界,勤于分享,乐于分享! 1552

最全一个项目搞定支付宝,微信支付!(1),tomcat原理及作用

我们总是喜欢瞻仰大厂的大神们,但实际上大神也不过凡人,与菜鸟程序员相比,也就多花了几分心思,如果你再不努力,差距也只会越来越大。实际上,作为程序员,丰富自己的知识储备,提升自己的知识深度和广度是很有必要的。

2301_82244514的博客 862

阿里巴巴开发手册“泰山”版它来了,1.4.0+终极版+阿里内部PPT

说明:对多表进行查询记录、更新记录、删除记录时,如果对操作列没有限定表的别名(或表名),并且 操作列在多个表中存在时,就会抛异常。反例:在某业务中,由于多表关联查询语句没有加表的别名(或表名)的限制,正常运行两年后,最近在 某个表中增加一个同名字段,在预发布环境做数据库变更后,线上查询语句出现出 1052 异常:Column 'name' in field list is ambiguous。表达式 1 : 表达式 2 中,高度注意表达式 1 和 2 在类型对齐时,可能抛出因自动拆箱导致的 NPE 异常。

代码界的扛把子 1263

芋道 ruoyi-vue-pro v1.8.0 发布:重构支付中心,提供支付接入实战

以开发者为中心,打造中国第一流的快速开发平台,全部开源,个人与企业可 100% 免费使用。有任何问题,或者想要的功能,可以在Issues中提给艿艿。😜 给项目点点 Star 吧,这对我们真的很重要!

Jdjdjjdjdjdje的博客 2222

JAVA儿女相亲婚恋相亲交友一对一相亲系统源码支持微信公众号+H5+APP

中国适婚人群已突破2.4亿,传统婚介模式因信息不透明、匹配效率低饱受诟病。基于SpringBoot+UniApp全栈技术开发的JAVA儿女相亲婚恋系统源码,创新融合"爱心钥匙算法"与"合伙人裂变模式",实现微信公众号、H5、APP三端数据互通,为婚恋平台运营商提供全流程数字化解决方案,助力破解行业信任危机与盈利难题。

2401_89037213的博客 913

基于Springboot+vue前后端分离商城项目基本开发手册【一】

开发环境准备 项目目录结构 权限管理 通用分页表格 Swagger文档 undertow容器 对xss攻击的防御 分布式锁 统一的系统日志 统一验证 统一异常处理 文件上传下载 一对多、多对多分页 开发环境准备 mall的商业版,最基本的开发环境与开源版本一致,方便用户迁移,我们认为,购买商业版,并且需要进行代码编写的人员,都是具有一定技术基础的开发人员。 1.开...

huaishitou的专栏 2398
上一篇: IntelliJ IDEA导入Maven构建的Web工程
下一篇: git解决non-fast-forward冲突
Coding-ls
博客等级 码龄11年 41粉丝 61原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值