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

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

微信支付有官方提供的SDK,但要自己处理的东西比较多。我使用的是一个别人封装过的SDK https://github.com/Wechat-Group/WxJava (同事推荐我用的)。
要如何使用呢,首先引入依赖。

     <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@ConditionalOnMissingBeanpublic 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: #小程序APPIDmchId: #商户号IDmchKey: #商户号秘钥subAppId: #服务商模式下的子商户公众账号IDsubMchId: #服务商模式下的子商户号#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.qq.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.qq.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();//内部订单记录IDString wxTransactionId = payResult.getTransactionId();//商户号订单IDBigDecimal 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    支付宝支付:2stOrderPayMapper.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());}}

Java微信小程序支付篇相关推荐

  1. java微信小程序支付-回调(Jsapi-APIv3)

    一.接入前准备,按照这个文档准备 准备: 接入前准备-小程序支付 | 微信支付商户平台文档中心 准备好了就可以获得(第二点里需要的参数):         参数1 商户号 merchantId:xxx ...

  2. java微信小程序支付V2版本(亲测有效)

    首先微信支付需要以下的字段,关于如何去获取微信支付的字段,网上一大把,注意(像商户号等重要字段不要泄露不要泄露) MCHID(商户号) 就是商户注册之后,微信支付给你的唯一的数字 APPID(小程序的 ...

  3. java微信小程序支付退款_微信小程序-微信自动退款(Java后台)

    packagecom.bodi.repository;importjava.security.MessageDigest;public classMD5Util {/*** 十六进制下数字到字符的映射 ...

  4. 微信小程序支付-付款(Java后台)

    微信小程序支付-付款(Java后台) 一.概述 接触微信小程序支付有一段时间,趁着项目上线空闲期,来总结一下付款.退款.提现到银行卡.查询流水等步骤过程,涉及到的知识,以及编程过程中需要注意的问题. ...

  5. java微信小程序调用支付接口

    简介:微信小程序支付这里的坑还是有的,所以提醒各位在编写的一定要注意!!! 1.首先呢,你需要准备openid,appid,还有申请微信支付后要设置一个32位的密钥,需要先生成一个sign,得到pre ...

  6. 微信小程序支付java服务端集成采坑总结

    先上个微信小程序支付官方文档地址: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_7&index=8 重点看 ...

  7. 微信小程序支付流程(Java后端)

    微信小程序支付(Java后端) 一.小程序支付的交互图如下 按住ctrl点击 微信支付平台开发文档 二.准备工作 第一步:在pom文件中导入微信支付SDK 有可能自动下载不了,可以到微信支付平台下载手 ...

  8. 微信小程序支付(java后端)

    微信支付文档传送门:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3 1.开发工具: idea+springclou ...

  9. java实现微信小程序支付功能

    微信支付-开发者文档: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_1.shtml 生成订单 /*** 生成订单*/@User@A ...

最新文章

  1. ubuntu samba重启 mount命令
  2. 5月23日任务 LAMP架构介绍、MySQL、MariaDB介绍、 MySQL安装
  3. 【完结】12篇文章带你逛遍主流分割网络
  4. 网易云信联合浙江大学信电学院成立创新与实践基地,探索音视频前沿技术
  5. Latex+Texstudio+Texlive 2020 windows10 安装教程
  6. 命名参数_告别编码5分钟,命名2小时!史上最全的Java命名规范参考!
  7. 关于framework4.5的相关介绍
  8. minetest Window编译运行
  9. Python 进阶——重访 list
  10. js获取url传递参数
  11. 论文翻译|疾病自动编码|Clinical-Coder: Assigning Interpretable ICD-10 Codes to Chinese Clinical Notes
  12. [状压dp] 玉米田(状压dp)
  13. PR快节奏短视频转场预设 时尚新款照片展示PR免费转场预设
  14. it人才计算机知识题,Excel试题_电脑基础知识_IT/计算机_专业资料
  15. TWINCAT2安装问题
  16. 搜索引擎使用技巧之高级搜索
  17. Pubg九月十六日服务器维护,绝地求生9月16日更新维护到几点?绝地求生9月16日更新时间公告...
  18. 江苏大学的计算机,毛启容-江苏大学计算机科学与通信工程学院
  19. insmod: error inserting './scull.ko': -1 Unknown symbol in module
  20. Effective JavaScript Item 23 永远不要修改arguments对象

热门文章

  1. Android中 简洁优秀的AgentWeb框架基本使用
  2. 【Redis】(二)Redis命令大全(速记)
  3. 算法:NP问题,NP完全问题(NPC),NPhard问题
  4. ESP32:用了七天我终于把环境搭建好了
  5. Java 20 超神版正式发布,展示了 Java 技术的最新进展
  6. python语句list range 13执行结果为_python练习题-答案
  7. 什么是着色器/Threejs如何使用着色器/Threejs使用着色器实现平面网格的动态效果案例
  8. 吸顶那个叫什么_吸顶空调吊顶区别到底是什么
  9. 中兴5G解决方案打造新体验,构建新生态
  10. 5、zookeeper四字监控命令/配置属性