软件编程
位置:首页>> 软件编程>> java编程>> Java后台实现微信支付和微信退款

Java后台实现微信支付和微信退款

作者:桐桐桐汀灬  发布时间:2023-09-06 13:44:00 

标签:Java,微信支付,微信退款

微信支付流程

都是我自己工作中开发的,亲测可用,不喜勿喷。

controller中我是这么写的,你们需要根据自己的业务需求改动。ResponseBean是我自己封装的,你们可以改成你们想要的形式。


/**
  * 微信统一下单接口
  * @return
  */
 @RequestMapping(value = "/doUnifiedOrder", method = RequestMethod.POST)
 public ResponseBean doUnifiedOrder(@RequestBody Map<String,Object> req) {
   Map resultMap=new HashMap();
   String openid = (String) req.get("openId");

WXPay wxpay =null;

try {
     //初始化证书
     myConfig.initCert();
     wxpay= new WXPay(myConfig);
   } catch (Exception e) {
     e.printStackTrace();
   }
   //生成的随机字符串
   String nonce_str = WXPayUtil.generateNonceStr();
   //获取客户端的ip地址
   //获取本机的ip地址
   InetAddress addr = null;
   try {
     addr = InetAddress.getLocalHost();
   } catch (UnknownHostException e) {
     e.printStackTrace();
   }
   //支付金额,需要转成字符串类型,否则后面的签名会失败
   String payOutMoney = WxMoney.changeY2F(String.valueOf(req.get("money")));
   String tradeName = (String) req.get("tradeName");
   if(tradeName!=null&&tradeName.length()>0){

}else{
     tradeName = "课程支付";
   }
   String body = tradeName;
   //商户订单号
   String out_trade_no= WXPayUtil.generateNonceStr();
   //统一下单接口参数
   HashMap<String, String> data = new HashMap<String, String>();
   data.put("appid", 你的appid);
   data.put("mch_id", 商户id);
   data.put("nonce_str", nonce_str);
   data.put("body", body);
   data.put("out_trade_no",out_trade_no);
   data.put("total_fee", payOutMoney);
   data.put("spbill_create_ip", "127.0.0.1");
   data.put("notify_url", 回调地址);
   data.put("trade_type","JSAPI");
   data.put("openid", openid);
   try {
     Map<String, String> rMap = wxpay.unifiedOrder(data);
     String return_code = (String) rMap.get("return_code");
     String result_code = (String) rMap.get("result_code");
     String nonceStr = WXPayUtil.generateNonceStr();
     resultMap.put("nonceStr", nonceStr);
     Long timeStamp = System.currentTimeMillis() / 1000;
     if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) {
         String prepayid = rMap.get("prepay_id");
         resultMap.put("package", "prepay_id="+prepayid);
         resultMap.put("signType", "MD5");
         //这边要将返回的时间戳转化成字符串,不然小程序端调用wx.requestPayment方法会报签名错误
         resultMap.put("timeStamp", timeStamp + "");
         //再次签名,这个签名用于小程序端调用wx.requesetPayment方法
         resultMap.put("appId",myConfig.getAppID());
         String sign = WXPayUtil.generateSignature(resultMap, myConfig.getKey());
         resultMap.put("paySign", sign);
         resultMap.put("out_trade_no",out_trade_no);
         ResponseBean responseBean = new ResponseBean(HttpStatus.OK.value(),"微信支付",resultMap);
         return responseBean;

}else{
       ResponseBean responseBean = new ResponseBean(HttpStatus.OK.value(),"微信支付失败","微信支付失败");
       return responseBean;
     }
   } catch (Exception e) {
     ResponseBean responseBean = new ResponseBean(HttpStatus.OK.value(),"微信支付失败","微信支付失败");
     e.printStackTrace();
     return responseBean;
   }
 }

微信退款代码(需要传退款的订单id)


 public ResponseBean refund(Map<String, Object> req) {
   Map resultMap=new HashMap();
   String buyId = (String) req.get("buyId");
   WXPay wxpay =null;
   try {
     myConfig.initCert();//初始化证书
     wxpay= new WXPay(myConfig);
   } catch (Exception e) {
     e.printStackTrace();
   }
   //生成的随机字符串
   String nonce_str = WXPayUtil.generateNonceStr();
   //获取客户端的ip地址
   //获取本机的ip地址
   InetAddress addr = null;
   try {
     addr = InetAddress.getLocalHost();
   } catch (UnknownHostException e) {
     e.printStackTrace();
   }
   //支付金额,需要转成字符串类型,否则后面的签名会失败
//    int total_fee= (int) req.get("money");
   String payOutMoney = WxMoney.changeY2F(String.valueOf(req.get("money")));

//    String body = (String) req.get("z");
   //商户订单号
   String out_trade_no= WXPayUtil.generateNonceStr();
   //统一下单接口参数
   HashMap<String, String> data = new HashMap<String, String>();

try {
     data.put("appid", myConfig.getAppID());
     data.put("mch_id", myConfig.getMchID());
     data.put("nonce_str", nonce_str);
     data.put("sign_type", "MD5");
     data.put("out_trade_no",buyId);//微信订单号
     data.put("out_refund_no", out_trade_no);//商户退款单号
     data.put("total_fee",payOutMoney);//支付金额,微信支付提交的金额是不能带小数点的,且是以分为单位,这边需要转成字符串类型,否则后面的签名会失败
     data.put("refund_fee",payOutMoney);//退款总金额,订单总金额,单位为分,只能为整数
     //MD5运算生成签名,这里是第一次签名,用于调用统一下单接口
     String sign = WXPayUtil.generateSignature(data, myConfig.getKey());
     data.put("sign", sign);

Map<String, String> rMap = wxpay.refund(data);
     String return_code = (String) rMap.get("return_code");
     String result_code = (String) rMap.get("result_code");

Long timeStamp = System.currentTimeMillis() / 1000;
     if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) {

ResponseBean responseBean = new ResponseBean(HttpStatus.OK.value(),"微信退款成功",rMap);
       return responseBean;

}else{
       ResponseBean responseBean = new ResponseBean(HttpStatus.OK.value(),"微信退款失败","微信支付失败");
       return responseBean;
     }

} catch (Exception e) {
     ResponseBean responseBean = new ResponseBean(HttpStatus.OK.value(),"微信退款失败","微信支付失败");
     e.printStackTrace();
     return responseBean;
   }
 }

需要用到的工具类

Java后台实现微信支付和微信退款

然后在MyConfig中配置一下你们的小程序参数就行了,如果需要添加退款功能必须配置商户证书(对应在你项目中的位置)。不需要的话就把initCert方法去掉。


public class MyConfig extends WXPayConfig {
 @Value("${res.imgPath}")
 public String imgPath;

private byte[] certData;

@Override
 public String getAppID() {
   return "你的小程序id";
 }

@Override
 public String getMchID() {
   return "商户id";
 }

@Override
 public String getKey() {
   return "商户秘钥";
 }

@Override
 public InputStream getCertStream() {
   ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
   return certBis;
 }

@Override
 public int getHttpConnectTimeoutMs() {
   return 8000;
 }

@Override
 public int getHttpReadTimeoutMs() {
   return 10000;
 }

@Override
 IWXPayDomain getWXPayDomain() {
   return new IWXPayDomain() {
     @Override
     public void report(String domain, long elapsedTimeMillis, Exception ex) {
     }

@Override
     public DomainInfo getDomain(WXPayConfig config) {
       return new DomainInfo("api.mch.weixin.qq.com", false);
     }
   };
 }

@Override
 public void initCert() throws Exception {
   String certPath = this.imgPath+"/upload/cert/"+"apiclient_cert.p12";//从微信商户平台下载的安全证书存放的目录
   System.out.println(certPath);
   File file = new File(certPath);
   InputStream certStream = new FileInputStream(file);
   this.certData = new byte[(int) file.length()];
   certStream.read(this.certData);
   certStream.close();
 }
}

来源:https://blog.csdn.net/weixin_44045144/article/details/104884298

0
投稿

猜你喜欢

  • 将Android项目导出为Library1.修改build.gradle中的Module:app文件最终如下:2. 进入到项目文件夹目录,保
  • 什么是 Spring Boot 插件?Spring Boot 插件是一种扩展机制,它提供了一种简单的方式来扩展 Spring Boot 的功
  • 1.基本思路①.创建已加锁应用的数据库(字段:_id,packagename),如果应用已加锁,将加锁应用的包名维护到数据库中②.已加锁+未
  •   大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加
  • 上了这么多年学,我发现一个问题,好象老师都很喜欢点名,甚至点名都成了某些老师的嗜好,一日不点名,就饭吃不香,觉睡不好似的,我就觉得很奇怪,你
  •        Fragment一般是宿主Activity UI的一部分或一种行为
  • 先看看效果图:中间的圆形头像和光环波形讲解请看:https://www.jb51.net/article/96508.htm周围的气泡布局,
  • 在正式的进入主题之前,我们先来了解下深拷贝和前拷贝的概念:浅拷贝:会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝,如果属性是基本
  • 本文实例为大家分享了C#实现银行家算法的具体代码,供大家参考,具体内容如下1.死锁死锁,顾名思义,是一种锁住不可自行解开的死局。在操作系统中
  • 任务,基于线程池。其使我们对并行编程变得更简单,且不用关心底层是怎么实现的。System.Threading.Tasks.Task类是Tas
  • 之前百度,google了很多,发现并没有介绍mongodb生产环境如何配置的文章, 当时想参考下都不行, 所以写篇文章,大家可以一块讨论下.
  • 本文实例讲述了Java TreeMap排序算法。分享给大家供大家参考,具体如下:TreeMap 和 HashMap 用法大致相同,但实际需求
  • 定义:用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。特点:     1、它支持以不同的方式遍历一个
  • 本文实例为大家分享了Java实现简单员工管理系统的具体代码,供大家参考,具体内容如下代码如下:import java.util.*;publ
  • 实例如下:ServletRequestAttributes aRequestAttributes=(ServletRequestAttrib
  • 昨天写了一个关于Excel文件处理的脚本,在字符串匹配功能上总是出现多余不正确的匹配,debug调试之后,发现一个坑。------->
  • Java中使用也比较简单:1. 编译正则表达式的字面值得到对应的模式Pattern对象;2. 创建匹配给定输入与此模式的匹配器Matcher
  • 本文实例讲述了c#实现随鼠标移动窗体的方法,分享给大家供大家参考。具体实现方法如下:private void MainForm_Load(o
  • Interceptor讲到Interceptor,相信熟悉struts2的童鞋肯定不会陌生了,struts2可以自定义 * 进行自己想要的一
  • 1、局部变量在方法或语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。局部变量声明在方法、构造方
手机版 软件编程 asp之家 www.aspxhome.com