微信支付先享后付java实现(持续更新中)
由于网上资料少,而且微信的文档我知道的就有4-5个版本,各个不一样,所以做这个的时候还是挺坑的,还好已经实现了,特此记录一下,让后来人,有个参考
一.先注册微信商户平台,那一堆乱七八糟的,就不说了,自行配置吧
二.开始开发
1.商户预授权
public String getApplyPermissionsToken(String authorization_code) throws IOException {//构造 ClientString token = CacheManager.get("token");if(token!=null && !token.equals("")){System.out.println("商户预授权缓存中有token");return token;}else {System.out.println("商户预授权缓存中没token");PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(PayParam.privateKey.getBytes("utf-8")));HttpClient httpClient = WechatPayHttpClientBuilder.create().withMerchant(PayParam.mchId, PayParam.mchSerialNo, merchantPrivateKey).withValidator(response -> true).build();Yushouquan models = new Yushouquan();models.setAppid(PayParam.appid);models.setService_id(PayParam.service_id);models.setAuthorization_code(authorization_code);models.setNotify_url("这里写你的回调地址");String url = "https://api.mch.weixin.qq.com/v3/payscore/permissions";HttpPost httpPost = new HttpPost(url);StringEntity reqEntity = new StringEntity(JSONObject.toJSONString(models), ContentType.create("application/json", "utf-8"));httpPost.setEntity(reqEntity);httpPost.addHeader("Accept", "application/json");httpPost.addHeader("Content-Type", "application/json");CloseableHttpResponse response = (CloseableHttpResponse) httpClient.execute(httpPost);System.out.println(httpPost);try {if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {String result = EntityUtils.toString(response.getEntity());// 返回json格式:
// log.info("微信支付V3 url={} result={} ",url,result);JSONObject jsons = JSONObject.parseObject(result);token = (String) jsons.get("apply_permissions_token");System.out.println("获取到了预授权的token:"+token);CacheManager.set("token", token, 3590 * 1000);} else {String result = EntityUtils.toString(response.getEntity());// 返回json格式:
// log.info("微信支付V3 url={} result={} response.getEntity()={}",url,result,JSON.toJSONString(response.getEntity()));System.out.println("获取预授权token失败了:"+result);}} catch (Exception e) {
// log.error("微信支付V3 请求url={} 参数={} 异常 e={}",url, JSON.toJSONString(json),e.getMessage());System.out.println(e.getMessage());} finally {response.close();}}return token;}
这个apply_permissions_token,你要返回给小程序端,用来拉起微信支付分授权,然后在回调接口你会收到微信的返回结果,结果做了加密处理,需要进行解密,然后拿到自己需要的参数做自己的逻辑处理
注意一下有个坑就是如果在商户平台没有配置api v3密钥的话,回调是不会被调用的,其次如果这个用户已经授权了,没有解除授权的话也是不会被回调的,解除的话在微信钱包支付分,服务管理中可以取消商户的授权就可以了。
下面是回调接口代码
/**商户预授权接口回调*/@RequestMapping(value = "CallBack", method = RequestMethod.POST)@ResponseBodypublic HashMap<String,Object> CallBack(HttpServletRequest request) throws Exception {HashMap<String,Object> resultjson = new HashMap<String,Object>();BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));String bodyContent = IOUtils.read(reader);String apiv3Key = PayParam.apiv3SecretKey;AesUtil aesu = new AesUtil(apiv3Key.getBytes("utf-8"));if(bodyContent == null || bodyContent.length() == 0){resultjson.put("code","UNSUCCESS");resultjson.put("message","body内容为空");System.out.println("body内容为空");return resultjson;}//byte[] associatedData, byte[] nonce, String ciphertextJSONObject jsonObject = JSONObject.parseObject(bodyContent);if(!jsonObject.containsKey("resource")){resultjson.put("code","UNSUCCESS");resultjson.put("message","resource不存在");System.out.println("resource不存在");return resultjson;}else{JSONObject resource = jsonObject.getJSONObject("resource");System.out.println("resource解密前内容是:"+resource);String associated_data = (String) resource.get("associated_data");String nonce = (String) resource.get("nonce");String ciphertext = (String) resource.get("ciphertext");System.out.println("开始解密--------------------");String result = aesu.decryptToString(associated_data.getBytes("utf-8"),nonce.getBytes("utf-8"),ciphertext);System.out.println("解密后的数据是:"+result);// 自己的逻辑代码.......resultjson.put("code","SUCCESS");System.out.println("授权回调成功-------------");return resultjson;}}
创建支付分订单代码,下单
public String payOrder(String out_order_no,String pointinfo,String openid) throws IOException {//创建先享后付订单String service_order_url = "https://api.mch.weixin.qq.com/v3/payscore/serviceorder";TimeRange tr = new TimeRange();SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");long currentTime = System.currentTimeMillis() + 2 * 60 * 1000;tr.setStart_time(sdf.format(new Date(currentTime)));RiskFund rf = new RiskFund();rf.setName("ESTIMATE_ORDER_COST");rf.setAmount(100);PayOrderModel pom = new PayOrderModel();pom.setOut_order_no(out_order_no);pom.setAppid(PayParam.appid);pom.setService_id(PayParam.service_id);pom.setService_introduction(pointinfo);pom.setNotify_url("此处写你的回调地址");pom.setOpenid(openid);pom.setNeed_user_confirm(false);pom.setTime_range(tr);pom.setRisk_fund(rf);//构造 ClientPrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(PayParam.privateKey.getBytes("utf-8")));HttpClient httpClient = WechatPayHttpClientBuilder.create().withMerchant(PayParam.mchId, PayParam.mchSerialNo, merchantPrivateKey).withValidator(response -> true).build();//请求支付分HttpPost httpPost = new HttpPost(service_order_url);StringEntity reqEntity = new StringEntity(JSONObject.toJSONString(pom), ContentType.create("application/json", "utf-8"));httpPost.setEntity(reqEntity);httpPost.addHeader("Accept", "application/json");httpPost.addHeader("Content-Type", "application/json");CloseableHttpResponse response = (CloseableHttpResponse) httpClient.execute(httpPost);try {if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){String result = EntityUtils.toString(response.getEntity());// 返回json格式:
// log.info("微信支付V3 url={} result={} ",url,result);
// return JSONObject.parseObject(result);System.out.println("创建支付分订单成功返回:"+result);return result;}else {String result = EntityUtils.toString(response.getEntity());// 返回json格式:
// log.info("微信支付V3 url={} result={} response.getEntity()={}",url,result,JSON.toJSONString(response.getEntity()));System.out.println(result);System.out.println("创建支付分订单失败返回"+result+"-------------");return result;}} catch (Exception e) {
// log.error("微信支付V3 请求url={} 参数={} 异常 e={}",url, JSON.toJSONString(json),e.getMessage());System.out.println(e.getMessage());return e.getMessage();}finally {response.close();}}
下单的回调代码,跟预授权的回调一样,配置了回调地址之后,在回调中去解密数据,做自己的逻辑处理
最近有点忙,先写到这里,基本上后面的做法都一样,有时间会持续完善帖子
如果任何疑问,请搜索公众号"老秦的快乐生活"获取我的联系方式
附微信官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/payscore/chapter5_1.shtml
微信支付先享后付java实现(持续更新中)相关推荐
- 史上最具体Android集成QQ,微信,微博分享(不用第三方)持续更新中
QQ 下载sdk并执行demo 各种配置 IUiListener 分享图片 分享到QQ 分享到QZONE Sina微博 配置 选择集成sdk方式 分享图片 微信 朋友 朋友圈 如今项目中用个第三方登录 ...
- 史上最详细Android集成QQ,微信,微博分享(不用第三方)持续更新中
QQ 下载sdk并运行demo 各种配置 IUiListener 分享图片 分享到QQ 分享到QZONE Sina微博 配置 选择集成sdk方式 分享图片 微信 朋友 朋友圈 现在项目中用个第三方登录 ...
- android qq分享自动弹出,史上最详细Android集成QQ,微信,微博分享(不要第三方)持续更新中...
QQ1 下载sdk并运行demo 2 各种配置 IUiListener 4 分享图片41 分享到QQ 41 分享到QZONE Sina微博配置 选择集成sdk方式 分享图片 现在项目中用个第三方登录, ...
- 大数据集群某节点彻底损毁后重装系统恢复(持续更新中)
如果某个节点彻底损毁,重装系统,那么需要的步骤如下: 目的 操作步骤 节点之间配置文件是否完全一致 需要各个节点分别启动 Hadoop修复 mkdir -p ~/dfs/name hadoop nam ...
- 剑指offer没有java版吗_剑指Offer(Java版) 持续更新中
面试题2 单例(之前有整理,略) 面试题3 二维数组中的查找 public boolean find(int target, int [][] array) { boolean found = fal ...
- 微信支付分(先享后付)对接记录:
微信支付分(先享后付)对接记录: 微信支付分对接步骤 填写开通支付分的申请表格 此步骤大概需要审核 1-3 个工作日; (模板-服务信息配置表-[先享后付免确认]-[商户名].xls) 填写商户信息 ...
- 微信支付首创“先享后付”保险模式 司乘没交钱就可享受高速保险服务
侯维科技 7月11日消息,微信今日宣布,微信支付正式提供"开微信代扣,享高速保障"能力,推动行业首创"先享后付"的保险模式.这意味着,车辆从高速收费站" ...
- 第三方移动支付类产品竞品分析:支付宝VS微信支付VS云闪付
第三方移动支付类产品竞品分析:支付宝VS微信支付VS云闪付 文章目录 第三方移动支付类产品竞品分析:支付宝VS微信支付VS云闪付 一.分析背景与竞品选择 1.竞品分析目的 2.行业研究与市场趋势分析 ...
- “先享后付”风靡深圳 “买鸭”618交易额增3倍助线下消费复苏
618当天,深圳南山益田假日广场,消费者李先生选中一台科沃斯扫地机器人后,没有立刻付全款,而是选择用"买鸭pay"小程序支付,原价3499元的机器仅付600余元就可带回家.同一天, ...
最新文章
- 细说接口性能优化的11个小技巧
- java泛型数组替代方案_Kotlin泛型Array T导致“不能将T用作具体类型参数 . 使用类代替“但List T不会...
- 深度linux腾讯视频,在UOS/Deepin 20/Ubuntu 18.04下安装腾讯视频Linux版的方法
- c语言多线程 视频教程,如何用C语言实现多线程
- Lockdown Wheelie项目
- layui数据表格循环数据给特殊行变颜色遇到的bug
- 干货:4个小技巧助你搞定缺失、混乱的数据(附实例代码)
- java时间戳格式_Java时间戳转化为今天、昨天、明天(字符串格式)
- 【算法导论】贪心算法,递归算法,动态规划算法总结
- vm虚拟机做为pxe服务器,vm esxi创建的虚拟机怎么通过pxe启动
- 【动手学深度学习】01 Windows下安装环境
- SPSS作业-一元线性回归
- label confusion learning to enhance text classification models
- Thinkpad 禁用触摸板
- 毕业5年决定人的一生(大家有空一定要看看)
- SpringBoot配置websocket
- 人工智能数学基础:利用导数判断函数单调性、凹凸性、极值、最值和描绘函数图形
- 2021年了你还不了解新式类与经典类?
- TIA西门子博途下载HMI程序后,画面中文字体显示乱码的处理对策
- 放假只能打游戏?不如自己做个简单又有趣的推箱子小游戏
热门文章
- Ubuntu输入法的使用
- thinkPHP+easyWeChat开发微信公众号支付,企业付款,红包
- C/C++音视频开发技术要点与学习路线
- YOLO 3/4/5/6/7/x、Efficient、MaskRcnn、FasterRcnn、FCOS、SSD、M2Det、Retina、CenterNet、PicoDet等系列数据模型汇总持续更新中
- 你的网站有【智能名片】吗?快来领取带名片功能的网站吧!
- [Spring Cloud] Hystrix三大特性--降级,熔断,隔离
- 键盘方向键移动某个元素
- matlab用while循环编写程序,MATLAB程序设计
- pil 获取图像尺寸_从命令行获取图像尺寸
- Vue3.x 设置浏览器动态 Title 方法