spring boot微信jsapi支付

  • 话不多说,撸起袖子就是干,下面上源码
    • pom.xml
    • 配置文件 resources/wx.properties
    • 配置类
    • service(WechatPayService)
    • 上impl(WechatPayServiceImpl)之前还是先上一个获取IP的工具类和返回工具类( ResResult)
      • ResResult
      • GetRealyIp
    • impl(WechatPayServiceImpl)
    • controller(WeichatPayController )
    • 前端(我这里是没有前后端分离,引擎使用的是thymeleaf)
      • 终于到最后一步了html,新建一个pay.html
    • spring boot微信支付到此结束!

话不多说,撸起袖子就是干,下面上源码

pom.xml

<dependency><groupId>com.github.wxpay</groupId><artifactId>wxpay-sdk</artifactId><version>0.0.3</version>
</dependency>

配置文件 resources/wx.properties

#未知是否再支付的时候必传
pay.appSecret=你自己的appSecret
pay.appID=你自己的appID
#必传
pay.mchID=你自己的mchID
#必传,但不参与签名
pay.key=自己的key
#随机数 必传
pay.nonceStr=
#必传,支付成功后的通知地址,通知url必须为外网可访问的url,不能携带参数。
pay.notifyUrl=http://***********/pay/hasOrder
#必传,终端IP支持IPV4和IPV6两种格式的IP地址。用户的客户端IP,这里测试就写死
pay.spbillCreateIp= 127.0.0.1
#支付方式
pay.tradeType=JSAPI
#设备信息,非必须
pay.deviceInfo=WEB
#JSAPI方式必传,只是这里用测试测试就写死
pay.openid=oPgg30mSXJTvd372-pgnyb1M9aEI
#HTTP(S) 连接超时时间,单位毫秒
pay.httpConnectTimeoutMs=180000
#HTTP(S) 读数据超时时间,单位毫秒
pay.httpReadTimeoutMs=180000
#证书路径 非必传
pay.certPath=E:/******

配置类

import com.github.wxpay.sdk.WXPayConfig;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;@Data
@Component
@PropertySource(value = "classpath:wx.properties")
@ConfigurationProperties(prefix = "pay")
public class Pay  implements WXPayConfig{private String appSecret;// 公众账号IDprivate String appID;// 商户号private String mchID;// 设备号private String deviceInfo;// 商户的key【API密匙】private String key;// api请求地址//private String url;// 服务器异步通知页面路径private String notifyUrl;private String spbillCreateIp;private String tradeType;private String openid;/*** HTTP(S) 连接超时时间,单位毫秒*/private int httpConnectTimeoutMs;/*** HTTP(S) 读数据超时时间,单位毫秒*/private int httpReadTimeoutMs;/*** API证书绝对路径*/private String certPath;private String weChatRedirectUrl;@Overridepublic InputStream getCertStream() {File certFile = new File(certPath);InputStream inputStream = null;try {inputStream = new FileInputStream(certFile);} catch (FileNotFoundException e) {e.printStackTrace();}return inputStream;}@Overridepublic String getKey() {
//        if (useSandbox) {
//            return sandboxKey;
//        }return key;}}

service(WechatPayService)

public interface WechatPayService {ResResult goWeChatPay(String money,String des, HttpServletRequest request) throws Exception;String reply(HttpServletRequest request, HttpServletResponse response) throws IOException;
}

上impl(WechatPayServiceImpl)之前还是先上一个获取IP的工具类和返回工具类( ResResult)

ResResult

@Data
public  class ResResult {private int code=200;private Object data;private String description="请求成功!";public  ResResult() {}public  ResResult ok(){return this;}public ResResult data(Object data){this.data=data;return this;}public ResResult err(int code,Object data,String des){this.code=code;this.data=data;this.description=des;return this;}public ResResult err(int code,Object data){this.code=code;this.data=data;this.description="请求失败!";return this;}public ResResult err(Object data,String des){this.code=500;this.data=data;this.description=des;return this;}static class Nei{private static ResResult resResult=new ResResult();}
}

GetRealyIp


import javax.servlet.http.HttpServletRequest;public class GetRealyIp {public static String getIPAddress(HttpServletRequest request) {String ip = null;//X-Forwarded-For:Squid 服务代理String ipAddresses = request.getHeader("X-Forwarded-For");if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {//Proxy-Client-IP:apache 服务代理ipAddresses = request.getHeader("Proxy-Client-IP");}if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {//WL-Proxy-Client-IP:weblogic 服务代理ipAddresses = request.getHeader("WL-Proxy-Client-IP");}if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {//HTTP_CLIENT_IP:有些代理服务器ipAddresses = request.getHeader("HTTP_CLIENT_IP");}if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {//X-Real-IP:nginx服务代理ipAddresses = request.getHeader("X-Real-IP");}//有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IPif (ipAddresses != null && ipAddresses.length() != 0) {ip = ipAddresses.split(",")[0];}//还是不能获取到,最后再通过request.getRemoteAddr();获取if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {ip = request.getRemoteAddr();}return ip;}
}

impl(WechatPayServiceImpl)


@Service
public class WechatPayServiceImpl implements WechatPayService {@Autowiredprivate Pay pay;//这个是你你们本地的订单service,你们可以删除@Autowiredprivate Orderservice orderservice;//这个是你你们本地的订单service,你们可以删除@Autowiredprivate CoreUserService userService;public ResResult goWeChatPay(String money,String des, HttpServletRequest request) throws Exception {//new一个微信支付,实际开发中最好使用单例模式WXPay wxPay = new WXPay(pay);//订单实体,和你们的不同,你们自己换,我使用的是jpa,id是uaa自增长,我这样写的目的是//在下边能使用订单的id做一些事Orders order=new Orders();order.setCoreUser(user);order=orderservice.save(order);String outTradeNo= order.getId().replaceAll("-","0").substring(5);LocalDateTime time_start= LocalDateTime.now();String substring = time_start.toString().substring(0, time_start.toString().lastIndexOf("."));substring=substring.replaceAll("-","").replaceAll("T","").replaceAll(":","").substring(0,14);Map<String, String> params = new HashMap<String, String>();params.put("notify_url", pay.getNotifyUrl());params.put("device_info",pay.getDeviceInfo());params.put("total_fee", String.valueOf(money));params.put("trade_type",pay.getTradeType());params.put("body", des);//商品描述params.put("openid", user.getOpenId());params.put("out_trade_no", outTradeNo);params.put("spbill_create_ip", GetRealyIp.getIPAddress(request));params.put("time_start",String.valueOf(Long.parseLong(substring)));//加上下边这个东西好像报错,报一个啥啥一分钟,啥啥其他不能低于5分钟,忘记了,你们自行研究,//这里我是没搞好的,你们谁搞好了帮忙通知一哈我(微信:gdc1997i),谢谢
//        long expire = Long.parseLong(substring)+240;
//        params.put("time_expire", String.valueOf(expire));//这下边也是我的订单实体的,你们自己换成你们自己的order.setWxOutTradeNo(outTradeNo);order.setOrderName(des);orderservice.save(order);System.out.println("out_trade_no:"+ outTradeNo);System.out.println("time_start:"+Long.parseLong(substring));Map<String, String> resultMap = null;try {resultMap = wxPay.unifiedOrder(params);} catch (Exception e) {e.printStackTrace();}System.out.println("--------------------------------------------------------------------------------");System.out.println("return_code:"+resultMap.get("result_code"));System.out.println("result_code:"+resultMap.get("result_code"));System.out.println("appid:"+resultMap.get("appid"));System.out.println("mch_id:"+resultMap.get("mch_id"));System.out.println("device_info:"+resultMap.get("device_info"));System.out.println("nonce_str:"+resultMap.get("nonce_str"));System.out.println("sign:"+resultMap.get("sign"));System.out.println("err_code:"+resultMap.get("err_code"));System.out.println("err_code_des:"+resultMap.get("err_code_des"));System.out.println("--------------------------------------------------------------------------------");if ("FAIL".equals(resultMap.get("return_code"))) {//这里,我是如果预下单不成功,就删除刚才新建的orderorderservice.delete(order);System.out.println("FAIL");return new ResResult().err(500,resultMap);}else if ("SUCCESS".equals(resultMap.get("result_code"))) {System.out.println("trade_type:"+resultMap.get("trade_type"));System.out.println("prepay_id:"+resultMap.get("prepay_id"));System.out.println("code_url:"+resultMap.get("code_url"));Map<String,String> map=new HashMap<>();map.put("appId",resultMap.get("appid"));//微信那边要求时间戳只能是十位,我这样干估计有问题,但现在还没遇到,哈哈哈!String time = String.valueOf(System.currentTimeMillis()).substring(0,10);System.out.println("timeStamp:"+time);map.put("timeStamp",new Date().toString());map.put("nonceStr",WXPayUtil.generateNonceStr());map.put("package","prepay_id="+resultMap.get("prepay_id"));//加密方式和之前预下单的一样,预下单没看见传这个是因为它封装好了的,//可以从下单的那个方法跟着代码就能看见map.put("signType","MD5");String sing=WXPayUtil.generateSignature(map,pay.getKey());map.put("paySign",sing);//这里返回给前端return new ResResult().ok().data(map);}return null;}//这个支付成功是返回通知@Overridepublic String reply(HttpServletRequest request, HttpServletResponse response) throws IOException {String res = "";InputStream inputStream = request.getInputStream();BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, UTF8));StringBuffer stringBuffer = new StringBuffer();String line = null;while((line = bufferedReader.readLine()) != null) {stringBuffer.append(line);}String xml = stringBuffer.toString();//System.out.println("微信支付成功,微信发送的callback信息,请注意修改订单信息");InputStream is = null;try {is = request.getInputStream();//获取请求的流信息(这里是微信发的xml格式所有只能使用流来读)String RETURN_CODE = "return_code";Map<String, String> notifyMap = WXPayUtil.xmlToMap(xml);//将微信发的xml转mapif(notifyMap.get("return_code").equals("SUCCESS")){if(notifyMap.get("result_code").equals("SUCCESS")){//商户订单号String ordersSn = notifyMap.get("out_trade_no");//实际支付的订单金额:单位 分String amountpaid = notifyMap.get("total_fee");//将分转换成元-实际支付金额:元BigDecimal amountPay = (new BigDecimal(amountpaid).divide(new BigDecimal("100"))).setScale(2);//如果有需要可以获取String openid = notifyMap.get("openid");String trade_type = notifyMap.get("trade_type");/*以下是自己的业务处理------仅做参考* 更新order对应字段/已支付金额/状态码*/}}//告诉微信服务器收到信息了,不要在调用回调action了//========这里很重要回复微信服务器信息用流发送一个xml即可res= "<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>";response.getWriter().write(res);is.close();} catch (Exception e) {e.printStackTrace();}return res;}
}

controller(WeichatPayController )

@RestController
@RequestMapping("pay")
public class WeichatPayController {@Autowiredprivate WechatPayService wechatPayService;@RequestMapping("/wechatpay")public ResResult wxUnifiedorder(@RequestParam("money") String money,@RequestParam("des") String des, HttpServletRequest request) throws Exception {return wechatPayService.goWeChatPay(money,des, request) ;}@RequestMapping("hasOrder")public String  reply(HttpServletRequest request,HttpServletResponse response) throws Exception {response.getWriter().write( wechatPayService.reply(request, response));return "<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>";}
}

前端(我这里是没有前后端分离,引擎使用的是thymeleaf)

终于到最后一步了html,新建一个pay.html

pay.html的位置不必和我的一样,但方式一定一样,内容我就不全写了,把重要的部分干出来
immediateRecharge()这个函数就是你点击需要支付产品的时候出发的函数,它就会调起微信的h5支付页面

//这个必须要加载你的html那<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js" type="text/javascript"></script><script type="text/javascript">function addMoney(money) {$("#money").text(money);}var appId,timeStamp,nonceStr,package,signType,paySign;function immediateRecharge(){//money=9990不能是小数必须是整数,它那边还要化成元,基本单位是分,这个只是题外的话,不管他了var url="/pay/wechatpay?money=9990&des=佐良科技-会员"$.get(url,function(result) {if (result.data.code==200){appId = result.data.appId;timeStamp = result.data.timeStamp;nonceStr = result.data.nonceStr;package = result.data.package;signType = result.data.signType;paySign = result.data.paySign;if (typeof WeixinJSBridge == "undefined") {if (document.addEventListener) {document.addEventListener('WeixinJSBridgeReady',onBridgeReady, false);} else if (document.attachEvent) {document.attachEvent('WeixinJSBridgeReady',onBridgeReady);document.attachEvent('onWeixinJSBridgeReady',onBridgeReady);}} else {onBridgeReady();}}else {alert("服务器错误")}});}function onBridgeReady(){WeixinJSBridge.invoke( 'getBrandWCPayRequest', {"appId":appId, //公众号名称,由商户传入"timeStamp":timeStamp, //时间戳,自1970年以来的秒数"nonceStr":nonceStr, //随机串"package":package,"signType":signType, //微信签名方式:"paySign":paySign //微信签名},function(res){if(res.err_msg == "get_brand_wcpay_request:ok" ) {console.log('支付成功');//支付成功后跳转的页面}else if(res.err_msg == "get_brand_wcpay_request:cancel"){console.log('支付取消');}else if(res.err_msg == "get_brand_wcpay_request:fail"){console.log('支付失败');WeixinJSBridge.call('closeWindow');}//使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。});}
</script>

spring boot微信支付到此结束!

我也是第一次写这个csdn论坛的文章,

Java 微信jsapi支付相关推荐

  1. JAVA+微信JSAPI支付

    JAVA+微信JSAPI支付 引入依赖 获取请求ip 组装微信支付请求 回调处理 引入依赖 <dependency><groupId>com.github.binarywang ...

  2. 微信JSAPI支付对接流程及支付接口设计

    文章目录 前言 一.JSAPI支付场景及逻辑 二.开发步骤 1.设置支付目录 2.设置授权域名 3.业务流程 三.代码设计 1. 支付页面 2. Controller 3. JS调起支付 4. 工具类 ...

  3. php微信jsapi支付小结,ThinkPHP接入微信支付 - JSAPI支付

    一.支付准备 二.获取用户openid 首先,到微信公众平台后台 - 设置 - 网页授权域名(别忘了添加开发者) // 在头部引入WechatPubService.php文件,见附录一 use app ...

  4. 微信JSAPI支付 跟 所遇到的那些坑

    首先介绍一下我在调用微信支付接口使用的是 weixin.senparc SDK,非常方便好用开源的一个微信开发SDK. weixin.senparc SDK 官网:http://weixin.senp ...

  5. 微信JSApi支付~订单号和微信交易号

    返回目录 谈谈transactionId和out_trade_no 前一篇微信JSApi支付~坑和如何填坑文章反映不错,所以又写了个后篇,呵呵. 每个第三方在线支付系统中都会有至少两类订单号,其一为支 ...

  6. 关于微信JSAPI支付成功后,点击完成后没有返回值并且页面被自动关闭问题

    微信JSAPI支付成功后,点击完成后没有返回值并且页面被自动关闭 简介 解决方式 错误的处理方式 总结 简介 最近很多人可能都遇到一个问题,在使用微信JSAPI支付成功后,不走成功的回调方法,只有支付 ...

  7. php接入微信JSAPI支付,微信内拉起支付,基于thinkPHP框架 WeChatDeveloper支付类包

    文章:php接入微信支付,扫码支付和H5支付(非微信浏览器),基于thinkPHP框架 WeChatDeveloper支付类包 踩坑指南 文章:php快速接入支付宝即时支付,PC网站支付和手机网站支付 ...

  8. php 微信统一下单接口,微信JSAPI支付,统一下单接口

    微信JSAPI支付,统一下单接口 今天小编给大家分享一下微信支付的统一下单接口,其实微信官网上也有SDK和DEMO下载了,但是不太好理解,小编就自己整理一份容易理解的代码,看不懂官方的,就来看看小编这 ...

  9. C# .NETMVC 微信JSAPI支付

    C# .NET MVC微信JSAPI支付 经过本人不断翻找资料和百度终于结合一些大佬的经验和思路弄出来一个MVC的微信支付了. 再弄微信支付之前我们需要先有一个商户号,并且开通了微信支付的JSAPI支 ...

最新文章

  1. PyTorch笔记: GPU上训练的模型加载到CPU/错误处理Attempting to deserialize object on a CUDA device but torch.cuda.is_a
  2. 10个常用的Python图像处理工具,建议收藏!
  3. latex 1图加标题_使用VsCode编译latex心得
  4. LeetCode 1668. 最大重复子字符串
  5. Pocket Gem OA: Path Finder
  6. 双系统ubuntu无法进入_win10下安装ubuntu双系统
  7. linux apache
  8. 【MySQL】mysql中any,in,some,all的区别
  9. OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x000001faf3e50000
  10. Python编程的例子----股票数据接口
  11. 开发人员学习文档下载地址
  12. em算法 c语言,EM算法原理与应用(附代码)
  13. php mysql知识总结_Mysql数据库知识总结(看资料总结出来的)
  14. 服务器上的光信号出现红点怎么办,光纤猫光信号闪红灯无法上网怎么办
  15. ACSII,GB2312,GBK,GB18030,Unicode,UTF8,UTF16,UTF32,BOM区别与转换——字符编码最全总结
  16. Excel的单元格设置下拉选项并填充颜色
  17. 小程序各个文件夹的作用分类
  18. 给CheckBox换样式
  19. 周鸿祎:ChatGPT可能两三年内产生自我意识;字节加入大模型之战;Ubuntu下一版本默认不再支持Flatpak| 极客头条
  20. plsql 客户端字符集_plsql查看数据库字符集

热门文章

  1. 3DMax烘焙CompleteMap贴图导入进Unity3D
  2. 一文带你了解android的root原理
  3. Windows安装Nginx反向代理访问IIS网站
  4. 机器学习-朴素贝叶斯分类器
  5. 苹果7和8的区别_★苹果cms常见问题有哪些?100个常见问题的解决方法
  6. 信用卡评分模型(R语言)(转载)
  7. 爱尔兰,这里是全世界离婚率最低的国家,你知道吗?
  8. Java获取文档页数_java准确读取word文件页数
  9. 组织:阿米巴-事业部-成员公司
  10. java模拟器野人岛2,生存战争独闯野人岛2