本人刚入这行最近项目要对接app版支付宝和微信支付,网上教程不是要钱,就是乱废话不多说开始上代码!
## 前期准备这方面我不会细说大概过一下,不知道的自行百度**你要对接支付必须要了解整个流程的**!如果文章反响大的话我会后面出教程1.首先你要有微信的商户号这个必须要有相关的营业执照具体申请地址:    https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2F设置V3密钥参数用![在这里插入图片描述](https://img-blog.csdnimg.cn/d0fde85abd8d41998f24ea08845c1364.jpg?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pGp5p-v5peg6YeP,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)2.登录开放平台申请相关APP应用需要300大洋话不多说上代码本项目采用的是Springboot多模块搭建

Maven配置

  <!--微信支付需要的依赖[BEGIN]--><dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-apache-httpclient</artifactId><version>0.2.2</version></dependency><!--json和对象的互转--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency>

常量工具类

package com.xqt.pay_wechat.utils;/*** @Description :  通用支付常量类* @Author : HaoZheng* @Date: 2021/9/28 17:59*/
public interface PayConstants {String NOTIFY_URL=" ";   //支付成功回调地址String MCH_ID=" ";       //商户号String MCH_SERIAL_NO=" ";    //商户证书序列号String API_V3KEY=" ";    //api密钥String APP_ID=" ";   //appidString PACKAGE="Sign=WXPay";  //签名固定字符串(微信要求的)//商户私钥String  PRIVATE_KEY="  ";
#### 验签及密钥解析类
package com.xqt.pay_wechat.utils;import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import com.xqt.base.config.ResultJson;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.PrivateKey;public class callback {//属于回调 验证签名是否正确 请求头:serial 验签的报文内容:message  自动更新验证器:signaturepublic static boolean signVerify(String serial,String message,String signature) {AutoUpdateCertificatesVerifier verifier=null;try {// 加载商户私钥(privateKey:私钥字符串)PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(PayConstants.PRIVATE_KEY.getBytes("utf-8")));//传入商户私钥//使用自动更新的签名验证器,不需要传入证书 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)verifier = new AutoUpdateCertificatesVerifier(new WechatPay2Credentials(PayConstants.MCH_ID, new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)),PayConstants.API_V3KEY.getBytes("utf-8"));return verifier.verify(serial, message.getBytes("utf-8"), signature);} catch (UnsupportedEncodingException e) {e.printStackTrace();}return false;}//回调解密详情看开发文档"通知数据"https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_2_5.shtmlpublic static String decryptOrder(String body){try {//通过调用微信工具类进行解密AesUtil aesUtil = new AesUtil(PayConstants.API_V3KEY.getBytes("utf-8"));//将相应的数据转化为JsonNodeObjectMapper objectMapper=new ObjectMapper();JsonNode node=objectMapper.readTree(body);//从JsonNode拿到通知数据resourceJsonNode resource=node.get("resource");//取出微信返回的各项数据,数据密文并进行转换为StringString ciphertext=resource.get("ciphertext").textValue();//附加数据String associated_data=resource.get("associated_data").textValue();//随机串String nonce=resource.get("nonce").textValue();return aesUtil.decryptToString(associated_data.getBytes("utf-8"),nonce.getBytes("utf-8"),ciphertext);} catch (UnsupportedEncodingException e) {e.printStackTrace();}catch (Exception e){e.printStackTrace();}return null;}//关单 如果用户长时间不支付就需要关闭预支付订单  商户订单号outTradeNopublic static ResultJson closeOrder(String outTradeNo){// 加载商户私钥(privateKey:私钥字符串)PrivateKey merchantPrivateKey = null;//传入商户私钥//使用自动更新的签名验证器,不需要传入证书 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)AutoUpdateCertificatesVerifier verifier = null;try {merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(PayConstants.PRIVATE_KEY.getBytes("utf-8")));verifier = new AutoUpdateCertificatesVerifier(new WechatPay2Credentials(PayConstants.MCH_ID, new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)),PayConstants.API_V3KEY.getBytes("utf-8"));} catch (UnsupportedEncodingException e) {e.printStackTrace();}catch (Exception e){e.printStackTrace();}// 初始化httpClientCloseableHttpClient httpClient = WechatPayHttpClientBuilder.create().withMerchant(PayConstants.MCH_ID, PayConstants.MCH_SERIAL_NO, merchantPrivateKey).withValidator(new WechatPay2Validator(verifier)).build();//关单url地址直接发送动态订单号HttpPost httpPost=new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/"+outTradeNo+"/close");httpPost.addHeader("Accept","application/json");httpPost.addHeader("Content-type","application/json; charset=utf-8");ByteArrayOutputStream bos=new ByteArrayOutputStream();ObjectMapper objectMapper=new ObjectMapper();ObjectNode rootNode=objectMapper.createObjectNode();rootNode.put("mchid",PayConstants.MCH_ID);try {objectMapper.writeValue(bos,rootNode);httpPost.setEntity(new StringEntity(bos.toString("UTF-8"),"UTF-8"));CloseableHttpResponse response=httpClient.execute(httpPost);//读取微信返回的状态码System.out.println(response.getStatusLine().getStatusCode());if (response.getStatusLine().getStatusCode()==204){return  ResultJson.ok("关闭订单成功!",response.getStatusLine().getStatusCode());}return ResultJson.err(response.getStatusLine().getStatusCode(),"关闭订单失败!");
//          String bodyAsString=EntityUtils.toString(response.getEntity());
//          System.out.println(bodyAsString);} catch (IOException e) {e.printStackTrace();}return ResultJson.err(500,"系统错误!请联系开发人员!");}
}

注意!注意!注意!
##这个类就是你需要进行进行支付调用的方法支付的话直接调用下边的方法一个是微信预支的一个回调的方法只需要调用方法传入

package com.xqt.pay_wechat.api;import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import com.wechat.pay.contrib.apache.httpclient.util.RsaCryptoUtil;
import com.xqt.base.config.ResultJson;
import com.xqt.base.entity.Order;
import com.xqt.pay_wechat.utils.PayConstants;
import com.xqt.pay_wechat.utils.callback;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.security.PrivateKey;
import java.util.HashMap;
import java.util.Map;
/*** @Description :  预支付下单* @Author : HaoZheng* @Date: 2021/9/29 13:57*/
@Slf4j
public class WeChatPayAPI {//预支付下单(订单id(id),金额(amount),描述(desc),回调地址(PayConstants.NOTIFY_URL))public static ResultJson wechatPay(String id,String ticketType,Integer amount) throws Exception{System.out.println("订单号:"+id);// 加载商户私钥(privateKey:私钥字符串)PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(PayConstants.PRIVATE_KEY.getBytes("utf-8")));//传入商户私钥//使用自动更新的签名验证器,不需要传入证书 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(new WechatPay2Credentials(PayConstants.MCH_ID, new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)),PayConstants.API_V3KEY.getBytes("utf-8"));// 初始化httpClientCloseableHttpClient httpClient = WechatPayHttpClientBuilder.create().withMerchant(PayConstants.MCH_ID, PayConstants.MCH_SERIAL_NO, merchantPrivateKey).withValidator(new WechatPay2Validator(verifier)).build();//定义预支付请求地址为post及支付的数据格式HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/app");  //统一下单接口httpPost.addHeader("Accept", "application/json");   //json格式数据传输httpPost.addHeader("Content-type","application/json; charset=utf-8");ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectMapper objectMapper = new ObjectMapper();//调用此方法生成jsonObjectNode rootNode = objectMapper.createObjectNode();rootNode.put("mchid", PayConstants.MCH_ID)      //商户订单号.put("appid", PayConstants.APP_ID)    //appid.put("notify_url",PayConstants.NOTIFY_URL)   //回调地址.put("description", ticketType)    //商品描述.put("out_trade_no", id);  //商品订单号//金额设置为分rootNode.putObject("amount").put("total", amount);//直接将传入的对象序列化为json,并且返回给客户端objectMapper.writeValue(bos, rootNode);httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));//接收返回参数CloseableHttpResponse response = httpClient.execute(httpPost);//取出prepay_id预支付订单idString bodyAsString = EntityUtils.toString(response.getEntity());System.out.println(bodyAsString+"接口里的预支付id!!!");JSONObject json = new JSONObject(bodyAsString);String prepay_id= (String) json.get("prepay_id");System.out.println(prepay_id);//根据微信文档必填参数进行加签//生成时间戳String timestamp=System.currentTimeMillis()+"";//调用hutool工具类生成随机字符串为不低于32位String nonce= RandomUtil.randomString(32);//拼接微信需要的参数使用进行加密.append方法拼接参数appid,时间戳,随机字符串,预支付idStringBuffer builder=new StringBuffer();//应用idbuilder.append(PayConstants.APP_ID).append("\n");//时间戳builder.append(timestamp).append("\n");//随机字符串后台支付idbuilder.append(nonce).append("\n");//预支付会话id通过调用此方法转换为数字JsonNode node=objectMapper.readTree(bodyAsString);builder.append(node.get("prepay_id")).append("\n");//通过微信pom依赖引入RsaCryptoUtil.encryptOAEP()方法进行加密   .decryptOAEP()解密String ciphertext = RsaCryptoUtil.encryptOAEP(builder.toString(), verifier.getValidCertificate());System.out.println("加密签名是:"+ciphertext);//封装为map返回Map map=new HashMap();map.put("appid",PayConstants.APP_ID);map.put("noncestr",nonce);map.put("package",PayConstants.PACKAGE);map.put("mch_id",PayConstants.MCH_ID);map.put("timestamp",timestamp);map.put("sign",ciphertext);map.put("prepay_id",prepay_id);map.put("money",amount);map.put("orderId",id);return ResultJson.ok("微信预支付成功!",map);}//微信回调请求解析public static Map callbackFunction(HttpServletRequest request) {//微信相关文档:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml//取出请求头部时间戳System.out.println("Wechatpay-Timestamp:" + request.getHeader("Wechatpay-Timestamp"));//HTTP头Wechatpay-Nonce 中的应答随机串System.out.println("Wechatpay-Nonce:" + request.getHeader("Wechatpay-Nonce"));//获取应答签名//微信支付的应答签名通过HTTP头Wechatpay-Signature传递。System.out.println("Wechatpay-Signature:" + request.getHeader("Wechatpay-Signature"));//因为微信支付后台会存一个最新的微信证书序列号用此来判断本地证书是否是最新的来验证本地的序列号(签名是由最新证书生成每次的生成都不一样)System.out.println("Wechatpay-Serial:" + request.getHeader("Wechatpay-Serial"));//这是返回微信的数据Map result = new HashMap();//验证签名主要是否是,微信回调的try {//首先验证签名是否正确StringBuilder signStr = new StringBuilder();//应答时间戳\n 添加signStrsignStr.append(request.getHeader("Wechatpay-Timestamp")).append("\n");//应答随机串\n 添加signStrsignStr.append(request.getHeader("Wechatpay-Nonce")).append("\n");/***  应答主体报文(response Body),需要按照接口返回的顺序进行验签,错误的顺序将导致验签失败。*  然后,请按照以下规则构造应答的验签名串。签名串共有三行,行尾以\n 结束,包括最后一行。\n为换行符*  (ASCII编码值为0x0A)。若应答报文主体为空(如HTTP状态码为204 No Content),最后一行仅为一个\n换行符。*///request.getReader()方法来获取请求内容值BufferedReader br = request.getReader();String str = null;StringBuilder builder = new StringBuilder();//一次读一行(\n),读入null时文件结束while ((str = br.readLine()) != null) {builder.append(str);}System.out.println(builder + "正在调用");//应答主体报文\n 添加signStrsignStr.append(builder.toString()).append("\n");//调用PayUtil类里的方法进行验签if (!callback.signVerify(request.getHeader("Wechatpay-Serial"),signStr.toString(), request.getHeader("Wechatpay-Signature"))) {//如果验签失败返回给微信接口错误码result.put("msg", "sign error");return result;}//解密密文String wxOrder = callback.decryptOrder(builder.toString());System.out.println(callback.decryptOrder(builder.toString()));//验证订单//调用数据库验证订单号是否存在out_trade_noJSONObject json = new JSONObject(wxOrder);String out_trade_no = (String) json.get("out_trade_no");String transaction_id = (String) json.get("transaction_id");//取出微信回调的订单号result.put("out_trade_no",out_trade_no);//取出微信生成的订单号result.put("transaction_id",transaction_id);result.put("msg","验签成功");return result;} catch (IOException e) {e.printStackTrace();}result.put("msg","验签失败请联系管理员!");return result;}
}

如有不足还请大佬多多指教!回调牵扯内网穿透明天在更新!

java后端AppV3版本微信支付CV大法2021-11-12相关推荐

  1. 微信支付采坑记录(java后端 一:微信支付调用从哪一步开始)

    普通商户模式微信支付之APP支付统一下单: 前言: 最近项目开发到微信支付的模块,经过一周的不懈努力,虽然微信支付流程跑通了,但当时的那些坑是真的烦,为了避免自己以后犯同样的错误,当然还有各位新接触微 ...

  2. java+uniapp对接app微信支付

    java+uniapp对接app微信支付 1.准备工作 注册app APP接入微信支付,需要先将商户APP在微信开放平台进行注册,登记APP开发参数以生成APPID.具体操作步骤如下: 一.登录微信开 ...

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

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

  4. JAVA使用Springboot+MP+VUE+Swagger前后端分离进行微信支付

    1.微信支付流程图 官方文档流程图 这里根据自己的理解画的图 2.后端代码 2.1依赖的引入 springboot工程创建 这里我创建的是springboot工程导入的工具类有Lombok.Sprin ...

  5. java 红包接口_微信支付中微信红包的接口测试,Java版本

    文档中普通红包有关于所有的讲解,调用必须有商户平台的证书: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=1 ...

  6. java后端+uniapp 对接微信app支付 报错-1

    问题描述: 原因分析: 上面两张图片完美的呈现了对接微信APP支付所能遇见的问题 排查流程: 检测自己的app是否 以及注册到微信开放平台 并且填写了与APP中的包名相对应的 检测自己的App是否开通 ...

  7. 微信java版_JAVA版微信支付V3-完全版

    本人做的是微信V3版本的微信支付,也是目前最新的微信支付接口.官方文档下载地址 微信支付成功后  你的邮件会有以下信息: 1. 信息包括:商户ID(mch_id).申请编号.登录帐号.登录密码.商户A ...

  8. java后台提供ios微信支付接口

    提供微信支付接口,需要先在微信开放平台(https://open.weixin.qq.com/)申请账号,进行开发者资格认证通过后创建应用. 创建成功后会有对应应用的AppID和AppSecret这个 ...

  9. java 解析p12_java引用微信支付的p12证书文件

    最近对接微信支付的退款功能,其中涉及到引用证书文件. 1. 绝对路径: //windows: public static String PATH1 = "E:\\project_ceshi\ ...

  10. PHP版本微信支付开发----电脑网站扫码支付(native)(心得、总结)

    早就听说微信支付比支付宝支付的坑多,但还得得该填的填,该绕的绕, 最终我们网站的微信支付功能成功上线啦♪(^ ∇ ^*) 首先自报家门,我的PHP版本是7,微信demo用的是php_sdk_v3.0. ...

最新文章

  1. Ubuntu 14.04 64bit上编译安装simple-rtmp-server(srs)服务器
  2. 疯狂Spring Cloud连载(5)Eureka集群搭建
  3. oralce中级OCP考试时间和题量以及通过率
  4. python 16进制加法_在python中追加2个十六进制值
  5. 贝壳集团IPO背后,风投协议之外还要面临何时盈利的问题
  6. Git复习(一)之简介、安装、集中式和分布式
  7. TensorFlow 2.X中的动手NLP深度学习模型准备
  8. ASP.NET Core Blazor 初探之 Blazor Server
  9. matlab drawnow连成曲线,precision recall曲线Matlab实现
  10. java1.8.0,jdk1.8.0版本
  11. JavaEE基础(02):Servlet核心API用法详解
  12. keilc error C183: unmodifiable lvalue (编程时要注意啦)
  13. opencv将图像转换成二维数组再将数组数据传给新图像
  14. python 内置变量
  15. spring boot 教程(四) 统一异常处理
  16. 构建基本脚本(转)*****好文章*****
  17. flow time 是什么
  18. 小甲鱼Python第二十八讲(文件)
  19. 在LaTeX中使用Python highlighting in LaTeX让python代码高亮
  20. DllMain 用法

热门文章

  1. 12个国外免费DNS服务
  2. Windows系统使用SSH连接远程服务器
  3. IoT协议LwM2M MQTT与CoAP
  4. IC卡防复制 设备联网 动态密钥方案说明 一卡通 门禁卡防破解Mifare卡低成本动态加密实现思路
  5. 华为主题包hwt下载_hwtTool-hwtTool(华为主题开发工具)下载 v9.1.3.302官方版--pc6下载站...
  6. inode客户端linux 怎样运行,H3C_iNode智能客户端安装指导(Linux)
  7. 儿童机器人编程语言_机器人十大流行编程语言的介绍
  8. 安装SAS可能遇到的各种问题
  9. laravel使用irazasyed/laravel-gamp集成google analytics
  10. java网页内容不能复制_win7系统禁用Java小程序脚本网页内容复制不了的解决方法...