Java微信小程序支付篇

Java微信小程序支付篇在做完一个仿美团的应用 我将其中涉及到的一些技术点进行总结和整理 当下次遇到类似的问题就能省下不少时间 避免踩坑 一 微信小程序支付的使用微信支付有官方提供的 SDK 但要自己处理的东西比较多 我使用的是一个别人封装过的 SDKhttps github com Wechat Group WxJava 同事推荐我用的 要如何使用呢 首先引入依赖 dependency groupId com github binarywang groupId dependency

在做完一个仿美团的应用,我将其中涉及到的一些技术点进行总结和整理,当下次遇到类似的问题就能省下不少时间,避免踩坑。

一、微信小程序支付的使用

 <dependency> <groupId>com.github.binarywang 
     groupId> <artifactId>wx-java-pay-spring-boot-starter 
      artifactId> <version>4.0.0 
       version>  
        dependency> 

然后去 https://github.com/Wechat-Group/WxJava 下载一个demo,将demo中的 WxPayConfiguration.java、WxPayProperties.java 文件复制到自己的项目中

在这里插入图片描述
也可以直接复制我在下方提供的代码,是一模一样的
WxPayConfiguration.java




package com.cmzn.meigo.wx.pay.config; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; import lombok.AllArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; / * @author Binary Wang */ @Configuration @ConditionalOnClass(WxPayService.class) @EnableConfigurationProperties(WxPayProperties.class) @AllArgsConstructor public class WxPayConfiguration { 
    private WxPayProperties properties; @Bean @ConditionalOnMissingBean public WxPayService wxService() { 
    WxPayConfig payConfig = new WxPayConfig(); payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId())); payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId())); payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey())); payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getSubAppId())); payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId())); payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath())); // 可以指定是否使用沙箱环境 payConfig.setUseSandboxEnv(false); WxPayService wxPayService = new WxPayServiceImpl(); wxPayService.setConfig(payConfig); return wxPayService; } } 

WxPayProperties.java

import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; / * wxpay pay properties. * * @author Binary Wang */ @Data @ConfigurationProperties(prefix = "wx.pay") public class WxPayProperties { 
    / * 设置微信公众号或者小程序等的appid */ private String appId; / * 微信支付商户号 */ private String mchId; / * 微信支付商户密钥 */ private String mchKey; / * 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除 */ private String subAppId; / * 服务商模式下的子商户号,普通模式请不要配置,最好是请在配置文件中将对应项删除 */ private String subMchId; / * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定 */ private String keyPath; } 

然后在application.yml中配置参数,支付用不到证书,可以注释掉,我的也不是服务商模式,不用理subAppId和subMchId

wx: pay: appId: #小程序APPID mchId: #商户号ID mchKey: #商户号秘钥 subAppId: #服务商模式下的子商户公众账号ID subMchId: #服务商模式下的子商户号 #keyPath: classpath:/wx/apiclient_cert.p12 # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头) secret: #小程序秘钥 

二、唤起微信支付窗口

写一个简单的下单流程,业务逻辑代码我给他省略了

 private HttpResult order(OrderRequest orderRequest, String gkId) throws WxPayException{ 
    /* * 业务代码省略 */ wxPayMpOrderResult = myWxPayService.createDdzqOrder(ddzqOrder); //调用唤起窗口方法 if(wxPayMpOrderResult == null){ 
    throw new RuntimeException("创建订单异常"); }else{ 
    return HttpResult.ok(wxPayMpOrderResult); } } 

唤起微信小程序支付窗口 参数可以按自己需要进行增加 https://pay.weixin..com/wiki/doc/api/jsapi_sl.php?chapter=9_1 参考微信支付开发文档

public WxPayMpOrderResult createDdzqOrder(DdzqOrder ddzqOrder)throws WxPayException { 
    String endPayMoney = ddzqOrder.getEndPayMoney().multiply(BigDecimal.valueOf(100)).stripTrailingZeros().toPlainString(); //将金额转换为分 WxPayUnifiedOrderRequest.WxPayUnifiedOrderRequestBuilder builder = WxPayUnifiedOrderRequest.newBuilder(); WxPayUnifiedOrderRequest wxOrder = builder .body("") //商品描述 .openid("") //用户openid .outTradeNo(ddzqOrder.getMasterId()) //商户订单号 .spbillCreateIp("0.0.0.0") //终端IP .totalFee(endPayMoney) // 支付收款金额 100分 注意:单位(分) //.totalFee(1) 测试时可以设置一分钱 .timeStart(DateTimeUtils.yyyyMMddHHmmssDateTime(0)) //交易起始时间 .timeExpire(DateTimeUtils.yyyyMMddHHmmssDateTime(2)) //交易结束时间  .tradeType(WxPayConstants.TradeType.JSAPI).build(); wxOrder.setSignType("MD5"); //wxOrder.setNotifyUrl("https://微信支付成功回调地址*/pay/ddzqOrder"); //不测试时需要放开注释  return wxPayService.createOrder(wxOrder); } 

三、微信支付成功回调

https://pay.weixin..com/wiki/doc/api/jsapi.php?chapter=9_7&index=8
在这里插入图片描述意思就是支付成功后,微信会调用我们之前设置的 微信支付成功回调地址

wxOrder.setNotifyUrl("https://微信支付成功回调地址*/pay/ddzqOrder"); 
@Api("微信支付") @RestController @RequestMapping("/pay") @AllArgsConstructor public class WxPayController { 
    //监听到店自取下单的支付成功回调 @PostMapping("/ddzqOrder") public String ddzqOrderPay(HttpServletRequest request, HttpServletResponse response) throws WxPayException { 
    return myWxPayService.ddzqOrder(request); } } 

那微信那边重复请求我们应该怎么处理呢,其实这里有个小技巧,我们可以通过数据库锁避免同一条数据被重复操作。

update st_order set pay_status = #{ 
   payStatus } where pay_status = 0 

通过 where pay_status = 0 这个条件,那么这条订单数据只会被修改一次,以下就是我处理订单成功回调的方法

 public String ddzqOrder(HttpServletRequest request) { 
    try { 
    String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding()); WxPayOrderNotifyResult payResult = wxPayService.parseOrderNotifyResult(xmlResult); String masterOrderId = payResult.getOutTradeNo();//内部订单记录ID String wxTransactionId = payResult.getTransactionId();//商户号订单ID BigDecimal wxRealPayAmount = new BigDecimal(BaseWxPayResult.fenToYuan(payResult.getTotalFee()));//微信真实支付金额 StOrder stOrder = stOrderMapper.selectByEOrderId(masterOrderId); Date nowTime = new Date(); if(stOrder.getPayStatus() == 1){ 
    //下一个进程进来的时候,上一个进程已经修改了订单支付状态 return WxPayNotifyResponse.success("处理成功!"); } StOrder orderRequest = new StOrder(); orderRequest.setPayStatus(1);//标记已支付 orderRequest.setMasterOrderId(masterOrderId); orderRequest.setPaymentTime(nowTime); orderRequest.setStoreReceiveTime(nowTime); orderRequest.setOrderStatus(10); //等待顾客取货 stOrderMapper.updateByMasterOrderIdSelective(orderRequest); StOrderPay stOrderPay = new StOrderPay(); stOrderPay.setMasterOrderId(masterOrderId); stOrderPay.setWxRealPayAmount(wxRealPayAmount); stOrderPay.setWxTransactionId(wxTransactionId); stOrderPay.setPayWay(1); //支付方式 微信支付:1 支付宝支付:2 stOrderPayMapper.insert(stOrderPay); / * 打印订单 */ List<StPrinter> stPrinterList = stPrinterMapper.selectPrintersByStoreId(stOrder.getStoreId()); for (StPrinter stPrinter:stPrinterList) { 
    stPrinterService.printOrder(stOrder.getEOrderId(),stOrder.getStoreId(),stPrinter.getOkPrinterSn()); } return WxPayNotifyResponse.success("处理成功!"); } catch (Exception e) { 
    e.printStackTrace(); return WxPayNotifyResponse.fail(e.getMessage()); } } 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/223477.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午2:07
下一篇 2026年3月17日 下午2:07


相关推荐

  • bmp格式说明

    bmp格式说明bmp24 位位图格式创建 bmp24 位位图格式的图片打开 Windows 系统自带的画面软件 如下 点击 文件 gt 另存为 在弹出的界面中有 4 种 bmp 格式可以选择 如下 不知道 bmp 格式是不是只有上面的 4 种 还是有更多 我也懒得了解 这里我们只了解 24 位位图 的 bmp 格式 因为这个格式比较简单 所以 在保存图片的时候要选择 24 位位图的 bmp 格式 不要选错了 bmp24 位位图格式说明重新调整大小 如下 如上图 点击 重新调整大小 然后在出现的界面中设置大小为 2×3 这样的话我们的

    2026年3月18日
    2
  • 文件包含漏洞

    0x00前言在我们文件上传的时候,如果是白名单通常会配合到文件包含和解析漏洞来getshell,那么这里先来说说文件包含。0x01 文件包含漏洞在php当中的文件包含的内容都会被当作php

    2021年12月11日
    47
  • mysql存储过程菜鸟教程_mysql存储过程是什么

    mysql存储过程菜鸟教程_mysql存储过程是什么本文介绍关于在MySQL存储过程游标使用实例,包括简单游标使用与游标循环跳出等方法例1、一个简单存储过程游标实例DELIMITER$$DROPPROCEDUREIFEXISTSgetUserInfo$$CREATEPROCEDUREgetUserInfo(indate_daydatetime)—-实例–存储过程名为:getUserInfo–参数为:date_day…

    2022年10月1日
    5
  • Quartz表达式详解

    Quartz表达式详解1 字符代表所有可能的值因此 在子表达式 月 里表示每个月的含义 在子表达式 天 星期 表示星期的每一天 月的每一周 2 字符用来指定数值的增量 example 在子表达式 分钟 里的 0 15 表示从第 0 分钟开始 每 15 分钟 nbsp nbsp nbsp 在子表达式 分钟 里的 3 20 表示从第 3 分钟开始 每 20 分钟 它和 3 23 43

    2026年3月18日
    2
  • Flink教程(5)-Flink常用API

    Flink教程(5)-Flink常用APIFlink 教程 FlinkAPI 讲解 Flink 是一个同时具备流数据处理和批数据处理的分布式计算框架 Flink 代码主要是由 Java 实现 部分代码由 Scala 实现 Flink 既可以处理有界的批量数据集 也可以处理无界的实时数据集 Flink 处理的主要场景是流式数据 Flink 称得上是一款真正的流 批统一的大数据计算框架

    2026年3月17日
    2
  • 错误: 在类中找不到 main 方法, 请将 main 方法定义为:public static void main(String[] args)否则 JavaFX 应用程序类必须扩展javafx.ap

    错误: 在类中找不到 main 方法, 请将 main 方法定义为:public static void main(String[] args)否则 JavaFX 应用程序类必须扩展javafx.ap最近在使用eclipse编写java程序时遇到这样一个问题:错误在类中找不到main方法,请将main方法定义为publicstaticvoidmain(String[]args)否则JavaFX应用程序类必须扩展javafx.application.Application看到这样的问题让我一头雾水,因为main方法已经写出解决这个问题可以点开eclipse-&amp;gt…

    2022年5月31日
    42

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号