配置文件

build.gradle

// 注意 com.github.binarywang微信支付包版本应与微信其他包版本一致
compile 'com.github.binarywang:weixin-java-pay:4.1.0'

application.yml

wx:# 微信支付pay:# 小程序的appIDappid: appid# 商户号mchId: mchId# 商户密钥mchKey: mchKey# 证书路径keyPath: apiclient_cert.p12# 交易类型:JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付tradeType: JSAPI

微信支付商户基本信息配置信息

WeChatPayProperties.java

/*** 微信支付商户基本信息** @author developer_cw* @date 2021-10-26*/
@Data
@Component
@ConfigurationProperties(prefix = "wx.pay")
public class WeChatPayProperties {/*** appId*/private String appId;/*** 商户号*/private String mchId;/*** 商户密钥*/private String mchKey;/*** 证书*/private String keyPath;/*** 交易类型* JSAPI--公众号支付* NATIVE--原生扫码支付* APP--app支付*/private String tradeType;@Overridepublic String toString() {return ToStringBuilder.reflectionToString(this,ToStringStyle.MULTI_LINE_STYLE);}
}

微信支付信息注入bean中

WechatPayConfig.java

/*** @author developer_cw* @date 2021-10-26* 微信支付信息注入bean 中*/
@Component
public class WechatPayConfig {@Autowiredprivate WeChatPayProperties properties;@Bean@ConditionalOnMissingBeanpublic WxPayConfig payConfig() {WxPayConfig payConfig = new WxPayConfig();payConfig.setAppId(this.properties.getAppId());payConfig.setMchId(this.properties.getMchId());payConfig.setMchKey(this.properties.getMchKey());payConfig.setKeyPath(this.properties.getKeyPath());payConfig.setTradeType(this.properties.getTradeType());return payConfig;}@Beanpublic WxPayService wxPayService(WxPayConfig payConfig) {WxPayService wxPayService = new WxPayServiceImpl();wxPayService.setConfig(payConfig);return wxPayService;}
}

返回交给前端调起支付的信息

WxPayReturnInfoVO.java

/*** 返回交给前端调起支付的信息** @author developer_cw* @date 2021-10-26*/
@Data
public class WxPayReturnInfoVO {private String appId;private String timeStamp;private String nonceStr;private String prepayId;private String paySign;private String signType;
}

控制器

WeChatPayController.java

/*** 微信支付相关 控制器** @author developer_cw* @date 2021-10-26*/
@Slf4j
@RestController
public class WeChatPayController {@AutowiredWxPayService wxPayService;@AutowiredWeChatPayProperties weChatPayProperties;private static final String REFUND_SUCCESS = "SUCCESS";/*** 此处处理订单信息,构建订单数据。* 将构建好的支付参数返回到前端,前端调起微信支付*/public WxPayReturnInfoVO weChatPay() {/*** 系统内部业务逻辑*/// 构建支付参数final WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = WxPayUnifiedOrderRequest.newBuilder()//调起支付的人的 openId.openid("")//用户生成的唯一订单编号.outTradeNo("")//订单金额 单位分.totalFee(0)//商品描述.body("")//获取本地IP.spbillCreateIp(InetAddress.getLoopbackAddress().getHostAddress())//回调的 URL 地址.notifyUrl("").build();WxPayUnifiedOrderResult wxPayUnifiedOrderResult;try {wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest);} catch (WxPayException e) {e.printStackTrace();throw new Exception("微信支付调起失败!");}//组合参数构建支付Map<String, String> paySignInfo = new HashMap<>(5);String timeStamp = createTimestamp();String nonceStr = String.valueOf(System.currentTimeMillis());paySignInfo.put("appId", weChatPayProperties.getAppId());paySignInfo.put("nonceStr", nonceStr);paySignInfo.put("timeStamp", timeStamp);paySignInfo.put("signType", "MD5");paySignInfo.put("package", "prepay_id=" + wxPayUnifiedOrderResult.getPrepayId());String[] signInfo = new String[0];String paySign = SignUtils.createSign(paySignInfo, "MD5", weChatPayProperties.getMchKey(), signInfo);//组合支付参数WxPayReturnInfoVO returnPayInfoVO = new WxPayReturnInfoVO();returnPayInfoVO.setAppId(weChatPayProperties.getAppId());returnPayInfoVO.setNonceStr(nonceStr);returnPayInfoVO.setPaySign(paySign);returnPayInfoVO.setSignType("MD5");returnPayInfoVO.setPrepayId(wxPayUnifiedOrderResult.getPrepayId());returnPayInfoVO.setTimeStamp(timeStamp);return returnPayInfoVO;}/*** 微信支付回调* * @param xmlData 微信返回的流* @return String*/public String parseOrderNotifyResult(@RequestBody String xmlData) {try {final WxPayOrderNotifyResult notifyResult = this.wxPayService.parseOrderNotifyResult(xmlData);// 自身支付订单号notifyResult.getOutTradeNo();/*** 系统内部业务逻辑*/return WxPayNotifyResponse.success("回调成功!");} catch (WxPayException e) {e.printStackTrace();return WxPayNotifyResponse.fail("回调有误!");}}/*** 微信退款* * @return String*/public R refund() {/*** 系统内部业务逻辑*///申请退款WxPayRefundRequest refundInfo = WxPayRefundRequest.newBuilder()// 支付订单号.outTradeNo("")// 退款订单号.outRefundNo("")// 支付金额 单位分.totalFee(0)// 退款金额 单位分.refundFee(0)//todo 微信退款回调地址.notifyUrl("").build();WxPayRefundResult wxPayRefundResult;try {wxPayRefundResult = wxPayService.refund(refundInfo);//判断退款信息是否正确if (REFUND_SUCCESS.equals(wxPayRefundResult.getReturnCode())&& REFUND_SUCCESS.equals(wxPayRefundResult.getResultCode())) {/*** 系统内部业务逻辑*/return R.success("退款中");}} catch (WxPayException e) {log.error("微信退款接口错误信息= {}", e);System.out.println(e.getMessage());}return R.fail(400, "退款失败");}/*** 仅支持一次性退款,多次退款需要修改逻辑** @param xmlData 微信返回的流数据* @return String*/public String refundNotify(@RequestBody String xmlData) {WxPayRefundNotifyResult wxPayRefundNotifyResult;try {wxPayRefundNotifyResult = wxPayService.parseRefundNotifyResult(xmlData);} catch (WxPayException e) {log.error("退款失败,失败信息:{}", e);System.out.println(e.getMessage());return WxPayNotifyResponse.fail("退款失败");}//判断你返回状态信息是否正确if (REFUND_SUCCESS.equals(wxPayRefundNotifyResult.getReturnCode())) {WxPayRefundNotifyResult.ReqInfo reqInfo = wxPayRefundNotifyResult.getReqInfo();//判断退款状态if (REFUND_SUCCESS.equals(reqInfo.getRefundStatus())) {try {/*** 一、可能会重复回调,需要做防重判断* 二、处理我们系统内部业务,做修改订单状态,释放资源等!*/return WxPayNotifyResponse.success("退款成功!");} catch (Exception e) {e.printStackTrace();System.out.println(e.getMessage());}}}return WxPayNotifyResponse.fail("退款失败!");}/*** 企业付款到用户零钱*/public void entPay() {/*** 系统内部业务逻辑*/EntPayRequest wxEntPayRequest = new EntPayRequest();wxEntPayRequest.setAppid(weChatPayProperties.getAppId());wxEntPayRequest.setMchId(weChatPayProperties.getMchId());// 系统订单idwxEntPayRequest.setPartnerTradeNo("");// 付款用户的wxopenidwxEntPayRequest.setOpenid("");// 实名校验// NO_CHECK:不校验真实姓名// FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账)// OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)wxEntPayRequest.setCheckName("NO_CHECK");// 付款金额 单位分wxEntPayRequest.setAmount(0);// 描述wxEntPayRequest.setDescription("提现");// 调用接口的机器IP地址wxEntPayRequest.setSpbillCreateIp("");try {EntPayResult wxEntPayResult = wxPayService.getEntPayService().entPay(wxEntPayRequest);if (REFUND_SUCCESS.equals(wxEntPayResult.getResultCode())&& REFUND_SUCCESS.equals(wxEntPayResult.getReturnCode())) {log.info("企业对个人付款成功!\n付款信息:\n" + wxEntPayResult);System.out.println("企业对个人付款成功!\n付款信息:\n" + wxEntPayResult);/*** 系统内部业务逻辑*/} else {log.error("err_code: " + wxEntPayResult.getErrCode()+ "  err_code_des: " + wxEntPayResult.getErrCodeDes());System.out.println("提现失败! " + "err_code: " + wxEntPayResult.getErrCode() + "  err_code_des: " + wxEntPayResult.getErrCodeDes());/*** 系统内部业务逻辑*/}} catch (Exception e) {e.printStackTrace();System.out.println("提现失败! " + e.getMessage());}}/*** 企业付款到用户银行卡*/public void payBank() {/*** 系统内部业务逻辑*/EntPayBankRequest wxEntPayBankRequest = new EntPayBankRequest();wxEntPayBankRequest.setAppid(weChatPayProperties.getAppId());wxEntPayBankRequest.setMchId(weChatPayProperties.getMchId());// 系统订单编号(唯一)wxEntPayBankRequest.setPartnerTradeNo("");// 收款方银行卡号wxEntPayBankRequest.setEncBankNo("");// 收款方银行卡所属银行wxEntPayBankRequest.setBankCode("");// 付款金额 单位分wxEntPayBankRequest.setAmount(0);// 订单备注 100字以内wxEntPayBankRequest.setDescription("");try {EntPayBankResult wxEntPayBankResult = wxPayService.getEntPayService().payBank(wxEntPayBankRequest);if (REFUND_SUCCESS.equals(wxEntPayBankResult.getResultCode())&& REFUND_SUCCESS.equals(wxEntPayBankResult.getReturnCode())) {log.info("企业对银行卡付款成功!\n付款信息:\n" + wxEntPayBankResult);System.out.println("企业对银行卡付款成功!\n付款信息:\n" + wxEntPayBankResult);/*** 系统内部业务逻辑*/} else {log.error("err_code: " + wxEntPayBankResult.getErrCode()+ "  err_code_des: " + wxEntPayBankResult.getErrCodeDes());System.out.println("企业对银行卡付款失败! " + "err_code: " + wxEntPayBankResult.getErrCode() + "  err_code_des: " + wxEntPayBankResult.getErrCodeDes());/*** 系统内部业务逻辑*/}} catch (Exception e) {e.printStackTrace();System.out.println("企业对银行卡付款失败! " + e.getMessage());}}/*** 1 块钱转为 100 分* 元转分** @param bigDecimal 钱数目* @return 分*/private int yuanToFee(BigDecimal bigDecimal) {return bigDecimal.multiply(new BigDecimal(100)).intValue();}/*** 时间** @return 时间戳*/private String createTimestamp() {return Long.toString(System.currentTimeMillis() / 1000);}
}

Spring Boot 微信小程序用户支付、退款及企业付款到用户零钱、银行卡 -- 自用相关推荐

  1. Spring Boot+微信小程序_保存微信登录者的个人信息

    1. 前言 微信小程序开发平台,提供有一类 API,可以让开发者获取到微信登录用户的个人数据.这类 API 统称为开放接口. Tip:微信小程序开发平台,会把微信登录用户的个人信息分为明文数据和敏感数 ...

  2. 微信小程序的支付/退款

    官网 我的代码百度云盘: 链接:https://pan.baidu.com/s/1hs-1HScGBGy4NpaHVenZ1g 提取码:jhfv 验证签名是否成功的网址: 自己的经验 1.不要先去网上 ...

  3. Spring Boot + 微信小程序——登录凭证校验DEMO

    基本概念 微信小程序-登录凭证校验:通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程. 微信小程序API https://developers.weix ...

  4. 微信小程序调用支付接口支付(tp5、小程序)

    微信小程序调用支付接口支付 今天记录一下学习的小程序调用微信支付接口 一.先理清一下调起微信支付的整个流程. 1.就是先调用微信的支付统一下单api获取到prepay_id 2.然后后端再将这个pre ...

  5. ios微信小程序虚拟支付解决办法

    ios微信小程序虚拟支付整理介绍 目前iOS端暂不支持虚拟支付,微信小程序虚拟支付仅涉及到ios端,安卓端不受影响. 小程序支付规范 https://developers.weixin.qq.com/ ...

  6. 微信小程序配置支付(附完整代码)

    微信小程序配置支付 1. 微信支付官网配置项 2. 代码配置(登录.获取openId.拉起支付等) 3. 云开发示例 1. 微信支付官网配置项 初次接入,商户号管理是没有数据的,需要申请接入. 如果是 ...

  7. 微信小程序 iOS支付

    微信小程序运营支付规范 微信官方针对有虚拟支付功能的小程序下发了整改通知.截至5月8号,平台将对账号屏蔽iOS系统的支付接口调用.我去查了<<微信小程序运营规则>>,如上图.发 ...

  8. 微信小程序篇(微信小程序的支付)

    微信小程序的支付和微信公众号的支付是类似的,对比起来还比公众号支付简单了一些,我们只需要调用微信的统一下单接口获取prepay_id之后我们在调用微信的支付即可. 今天我们来封装一般node的支付接口 ...

  9. 微信小程序服务器支付sdk,微信小程序之支付后如何调用SDK的异步通知

    微信小程序之支付后如何调用SDK的异步通知 发布时间:2021-07-05 10:47:33 来源:亿速云 阅读:57 作者:小新 这篇文章主要介绍微信小程序之支付后如何调用SDK的异步通知,文中介绍 ...

最新文章

  1. 美国再出半导体新法案!1800亿谋求芯片制造振兴
  2. 对话框处理与登录测试
  3. 判断字符串数组中是否所有字符只出现了一次
  4. poj 3207 2-sat
  5. python如何使用字典_python字典怎么使用zip
  6. leetcode744. 寻找比目标字母大的最小字母(二分查找)
  7. 如何在计算机中找到桌面这个项,怎样找到“计算机管理”这项菜单?
  8. 夜神模拟器99%卡死打不开问题
  9. Java中的私有权限(private)
  10. 《Java JDK8学习笔记》读书笔记(3)
  11. PDF是什么格式?如何在电脑上编辑PDF文件
  12. 基于Python的基金数据汇总分析
  13. 两级分销加两级代理佣金计算工具
  14. 思科网络学院-网络互连ccna3-第九章
  15. zebra 的Thread机制
  16. lol8.18服务器不稳定,lol8月18日更新BUG修复一览 8月18日更新修复了哪些BUG
  17. Uniapp/Vue中引入使用阿里图标
  18. 企业数字化转型,为何 SaaS 模式如此重要?
  19. 中国汽车流通协会:解读2018中国二手车经销商百强排行榜
  20. 2021年国赛高教杯数学建模A题FAST主动反射面的形状调节解题全过程文档及程序

热门文章

  1. Linux内核TC工具链路带宽设计--HTB队列规定及简单的过滤器介绍
  2. 在WPF中使用Caliburn.Micro搭建MEF插件化开发框架
  3. 纯原生实现多张图片合成
  4. Android入门之ScrollView
  5. [Java开发之路](8)输入流和输出流
  6. [读书笔记]1980年代的爱情-野夫
  7. 【C语言】30行代码写出无限重启程序,室友太吵怎么办?
  8. 发现一个2k/xp/2003的补丁中心,直接下载!
  9. 一个c语言程序的开发环境,C语言入门(2)——安装VS2013开发环境并编写第一个C语言程序...
  10. java autorun_揭开AutoRun功能的神秘面纱