参考文章:SpringBoot + 小程序 整合微信支付和退款 V2版 - 码农教程

本文仅作记录

参考文章: UniApp + SpringBoot 实现微信支付和退款 - 奔跑的砖头 - 博客园

Springboot整合支付宝支付参考: UniApp + SpringBoot 实现支付宝支付和退款 - 奔跑的砖头 - 博客园

一、开发前提

  • 微信支付商户号接入微信支付
  • 商户号绑定对应的小程序
  • 获取对应的 信息
    • 开放平台: appId
    • 商户号: mchId
    • 商户秘钥: mchKey
    • p12证书:
    • apiclient_key.pem证书文件

官方网站: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

二、Springboot整合微信支付

2.1 导入基本的pom依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><!-- 微信支付坐标 start-->
<dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-pay</artifactId><version>4.2.5.B</version>
</dependency>
<!-- 退款用 -->
<dependency><groupId>org.jodd</groupId><artifactId>jodd-http</artifactId><version>6.0.8</version>
</dependency>
<!-- 微信支付坐标 end--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>

2.2 在 application.yml 中添加配置

回调地址 我这里使用 ngrok内网穿透 官网: ngrok - Online in One Line

# 服务启动端口
server:port: 8081# 微信pay相关
wxpay:# appIdappId: # 自己的appId# 商户idmchId:  # 自己的商户id# 商户秘钥mchKey: # 商户秘钥# p12证书文件的绝对路径或者以classpath:开头的类路径.keyPath: classpath:/wxpay_cert/apiclient_cert.p12privateKeyPath: classpath:/wxpay_cert/apiclient_key.pemprivateCertPath: classpath:/wxpay_cert/apiclient_cert.pem# 微信支付的异步通知接口# 我这里使用的ngrok内网穿透 notifyUrl: https://bfb3-221-237-148-6.ap.ngrok.io/wechat/pay/notify# 退款回调地址refundNotifyUrl: https://bfb3-221-237-148-6.ap.ngrok.io/wechat/pay/refund_notify

2.3 创建配置文件对应的 配置类

package com.system.system.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;@Data
@ConfigurationProperties(prefix = "wxpay")
public class WechatPayConfig {private String appId;private String mchId;private String mchKey;private String keyPath;private String privateKeyPath;private String privateCertPath;private String notifyUrl;
}

2.4 在service层 创建 BizWechatPayService类

package com.system.system.service.impl;import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;import java.net.InetAddress;/*** 微信支付*/
@Service
@ConditionalOnClass(WxPayService.class)
@EnableConfigurationProperties(WechatPayConfig.class)
@AllArgsConstructor
public class BizWechatPayService {private WechatPayConfig wechatPayConfig;public WxPayService wxPayService() {WxPayConfig payConfig = new WxPayConfig();payConfig.setAppId(wechatPayConfig.getAppId());payConfig.setMchId(wechatPayConfig.getMchId());payConfig.setMchKey(wechatPayConfig.getMchKey());payConfig.setKeyPath(wechatPayConfig.getKeyPath());payConfig.setPrivateKeyPath(wechatPayConfig.getPrivateKeyPath());payConfig.setPrivateCertPath(wechatPayConfig.getPrivateCertPath());// 可以指定是否使用沙箱环境payConfig.setUseSandboxEnv(false);payConfig.setSignType("MD5");WxPayService wxPayService = new WxPayServiceImpl();wxPayService.setConfig(payConfig);return wxPayService;}/*** 创建微信支付订单** @param productTitle 商品标题* @param outTradeNo   订单号* @param totalFee     总价* @param openId     openId* @return*/public Object createOrder(String productTitle, String outTradeNo, Integer totalFee, String openId) {try {WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();// 支付描述request.setBody(productTitle);// 订单号request.setOutTradeNo(outTradeNo);// 请按照分填写request.setTotalFee(totalFee);// 小程序需要传入 openidrequest.setOpenid(openId);// 回调链接request.setNotifyUrl(wechatPayConfig.getNotifyUrl());// 终端IP.request.setSpbillCreateIp(InetAddress.getLocalHost().getHostAddress());// 设置类型为JSAPIrequest.setTradeType(WxPayConstants.TradeType.JSAPI);// 一定要用 createOrder 不然得自己做二次校验Object order = wxPayService().createOrder(request);return order;} catch (Exception e) {return null;}}/*** 退款** @param tradeNo 订单号* @param totalFee 总价* @return*/public WxPayRefundResult refund(String tradeNo, Integer totalFee) {WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();wxPayRefundRequest.setTransactionId(tradeNo);wxPayRefundRequest.setOutRefundNo(String.valueOf(System.currentTimeMillis()));wxPayRefundRequest.setTotalFee(totalFee);wxPayRefundRequest.setRefundFee(totalFee);wxPayRefundRequest.setNotifyUrl(wechatPayConfig.getRefundNotifyUrl());try {WxPayRefundResult refund = wxPayService().refundV2(wxPayRefundRequest);if (refund.getReturnCode().equals("SUCCESS") && refund.getResultCode().equals("SUCCESS")) {return refund;}} catch (WxPayException e) {e.printStackTrace();}return null;}
}

2.5 创建Controller测试

package com.runbrick.paytest.controller;import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.runbrick.paytest.util.wxpay.BizWechatPayService;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/wechat/pay")
@AllArgsConstructor
public class WechatController {BizWechatPayService wechatPayService;private static Logger logger = LoggerFactory.getLogger(WechatController.class);/*** 创建微信订单** @return*/@RequestMapping(value = "/unified/request", method = RequestMethod.GET)public Object appPayUnifiedRequest() {// totalFee 必须要以分为单位Object createOrderResult = wechatPayService.createOrder("测试支付", String.valueOf(System.currentTimeMillis()), 1, "从前端传入的openIdopendId");logger.info("统一下单的生成的参数:{}", createOrderResult);return createOrderResult;}@RequestMapping(method = RequestMethod.POST, value = "notify")public String notify(@RequestBody String xmlData) {try {WxPayOrderNotifyResult result = wechatPayService.wxPayService().parseOrderNotifyResult(xmlData);// 支付返回信息if ("SUCCESS".equals(result.getReturnCode())) {// 可以实现自己的业务逻辑logger.info("来自微信支付的回调:{}", result);}return WxPayNotifyResponse.success("成功");} catch (WxPayException e) {logger.error(e.getMessage());return WxPayNotifyResponse.fail("失败");}}/*** 退款** @param transaction_id*/@RequestMapping(method = RequestMethod.POST, value = "refund")public void refund(String transaction_id) {// totalFee 必须要以分为单位,退款的价格可以这里只做的全部退款WxPayRefundResult refund = wechatPayService.refund(transaction_id, 1);// 实现自己的逻辑logger.info("退款本地回调:{}", refund);}/*** 退款回调** @param xmlData* @return*/@RequestMapping(method = RequestMethod.POST, value = "refund_notify")public String refundNotify(@RequestBody String xmlData) {// 实现自己的逻辑logger.info("退款远程回调:{}", xmlData);// 必须要返回 SUCCESS 不过有 WxPayNotifyResponse 给整合成了 xml了return WxPayNotifyResponse.success("成功");}}

三、前端代码

<template><view class="content"><view class="text-area"><text class="title">{{title}}</text></view><button type="default" @click="goPay()">点我前去支付</button></view>
</template><script>export default {data() {return {title: '跟我去支付'}},onLoad() {},methods: {goPay() {uni.request({url: "https://bfb3-221-237-148-6.ap.ngrok.io/wechat/pay/unified/request",success(res) {let obj = {appid: res.data.appId,noncestr: res.data.nonceStr,package: res.data.packageValue,partnerid: res.data.partnerId,prepayid: res.data.prepayId,timestamp: parseInt(res.data.timeStamp),sign: res.data.sign,};uni.requestPayment({provider: "wxpay",orderInfo: obj,success(res) {uni.showModal({content: "支付成功",showCancel: false})},fail(e) {uni.showModal({content: "支付失败,原因为: " + e.errMsg,showCancel: false})},complete() {console.log("啥也没干");}});}})}}}
</script><style>page {background-color: #ff5500;}.content {display: flex;flex-direction: column;align-items: center;justify-content: center;}.text-area {display: flex;justify-content: center;}.title {font-size: 36rpx;color: #8f8f94;}
</style>

待解决的问题

这段前端是怎么传值的,一直没有解决

@RequestMapping(method = RequestMethod.POST, value = "notify")public String notify(@RequestBody String xmlData) {try {WxPayOrderNotifyResult result = wechatPayService.wxPayService().parseOrderNotifyResult(xmlData);// 支付返回信息if ("SUCCESS".equals(result.getReturnCode())) {// 可以实现自己的业务逻辑logger.info("来自微信支付的回调:{}", result);}return WxPayNotifyResponse.success("成功");} catch (WxPayException e) {logger.error(e.getMessage());return WxPayNotifyResponse.fail("失败");}}

springboot 小程序微信支付相关推荐

  1. 调用支付jsapi缺少参数appid_服务商模式下的小程序微信支付

    最近,要做一个小程序商城的项目,需要在小程序中用到分账功能,也就是顾客购买商品支付的钱要给各个店铺,这就需要用到服务商模式. 在谈服务商模式下小程序微信支付之前,我们先要有一个服务商的商户号,这个商户 ...

  2. java 后台 小程序微信支付

    java 后台 小程序微信支付 步骤说明: 微信公众平台支付接口调试工具 #1.生成字符串: appid=appId&body=测试商品名称&mch_id=商户号&nonce_ ...

  3. 小程序微信支付开发流程记录

    我所在公司需要开发一款商城小程序,里面需要用到微信支付,我负责里面的下单功能,从小程序端到后台的支付流程都是我自己开发的,由于我们组没有人有开发微信支付的经验,只有我有开发过JSAPI的微信支付的经验 ...

  4. 微信小程序收款手续费_小程序微信支付收款流程

    大家都知道,小程序具备微信支付功能,但是,很多商家还不知道具体的收款流程是什么?用户在小程序下单支付的款项究竟到了哪里?或者找第三方公司开发担心资金安全问题? 今天给大家详细的讲解一下: 在实现微信小 ...

  5. PHP实现小程序微信支付V2获取prepay_id

    PS:本文旨在简单获取prepay_id,只是简单的介绍一下流程,并非完整的订单支付流程 小程序端JS代码: getxml(){var test = thiswx.getStorage({ //从缓存 ...

  6. laravel小程序微信支付

    php小程序微信支付类 laravel小程序微信支付分享地址http://www.xiaoshu168.com/php/232.html

  7. 微信小程序 微信支付代码实现流程

    微信小程序 微信支付是一个很简单的流程  微信开发文档 地址:wx.requestPayment(Object object) | 微信开放文档 微信公众平台申请支付功能 百度一大堆例举代码 官方文档 ...

  8. nodejs实现小程序微信支付

    最近做小程序时用到了微信支付很是开心,因为之前支付一直都没有做过,终于又可以学点东西了.于是很开心的去看了下微信小程序的支付接口,没想到,事情基本都是后端做的,前端只要调用wx.requestPaym ...

  9. 移动支付开发:小程序微信支付开发测试

    小程序推出邀请测试已经有一个多月,终于申请到一个内部账号,尝试了一把小程序上的微信支付.小程序虽然叫"小",但是个人感觉他的门槛并不低.(/www.zhaoweb.cn) 教育小程 ...

最新文章

  1. 和达摩院深度绑定,阿里云下一个十年,成为“云上的阿里巴巴”
  2. Matlab:利用Matlab编程实现模拟分子布朗运动的动画展示
  3. SAP One Order redesign里的WebUI advanced search重构
  4. 出门就背他了!可伸缩的背包,自由变大变小,还有防盗功能!
  5. (C++)浅谈using namespace std
  6. 分布式锁实现的几种方式(DB,Redis,Zookeeper)
  7. python-下拉框处理
  8. 全网首发:Undefined symbols for architecture x86_64: “std::__1::locale::use_facet(std::__1::locale::id)
  9. mysql 12_Navicat for MySQL12免费版
  10. java里美元符_Java语言标识符中可以使用美元符
  11. JavaScript 打开新页面
  12. HTML文本格式化标签(用来调整文本的格式和排版)
  13. vue自定义组件,ElementUi表单校验v-model不能即时生效的解决方法
  14. MOS管推挽电路设计及特性解析
  15. 【Noip模拟 20161004】局域网
  16. Regression 回归
  17. RISC-V CSR 相关指令集
  18. 艾伟:memcached全面剖析–2.理解memcached的内存存储
  19. 国内低代码平台有哪些?织信informat怎么样?
  20. 华为路由器、交换机、AC忘记密码,但是想保留配置怎么处理

热门文章

  1. 走进Linux操作系统世界
  2. 安排 , 2021新冠疫情防控指挥作战平台(视频+课件+代码+资料)
  3. baud rate - 波特率
  4. 【uiautomation】批量给微信好友/群聊发消息
  5. 多张CAD图纸需要转换PDF格式怎么样操作更快?
  6. xml 转换 --倾斜文本矩形框 (cx,cy,w,h,ang)到四个角坐标点(x1,y1,x2,y2,x3,y3,x4,y4)
  7. Spark SQL数据通用保存数据_大数据培训
  8. 计算机组装与维护学习网站,计算机组装与维护学习课件.ppt
  9. python求级数的值_如何在Numpy中计算Fourier级数?
  10. 入职新企业,被凉一边看代码的破局