Java对接微信支付V3流程及示例代码

2024-09-05 17:12

本文主要是介绍Java对接微信支付V3流程及示例代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

微信支付V3对接流程如下:

  1. 创建商户平台账号:在微信支付商户平台(pay.weixin.qq.com)上注册并创建商户平台账号。

  2. 开通微信支付功能:在商户平台上完成实名认证,并申请开通微信支付功能。

  3. 获取API证书:在商户平台上下载API证书,并将证书保存在安全的地方。

  4. 配置回调接口:在商户自己的服务器上配置一个用于接收微信支付结果通知的回调接口,并确保能够正确处理通知。

  5. 获取接口调用凭证:在商户平台上获取接口调用凭证(API秘钥),用于后续API的调用。

  6. 调用API接口:使用接口调用凭证,调用相应的API接口,完成支付相关的操作,如生成支付订单、查询订单状态等。

  7. 处理支付结果:在接收到微信支付结果通知后,根据通知内容进行相应的处理,如更新订单状态、发货等。

  8. 进行退款操作:根据需要,可以调用退款接口进行退款操作。

  9. 审核接入资质:在支付成功后,根据微信支付的规定,需要将商户的接入资质进行审核。

  10. 上线测试:完成以上步骤后,可以进行上线测试,确保支付功能正常。

以上是微信支付V3对接的基本流程,具体流程可能还会根据具体需求有所差异。建议在对接前仔细阅读微信支付官方文档,参考下面的接口调用示例进行对接。

微信支付 V3 对接流程简要如下:

  1. 注册微信支付商户号,并获取到商户号和商户密钥。
  2. 在微信商户平台生成 API v3 密钥,并下载证书。
  3. 配置证书,并设置商户号和商户密钥。
  4. 构建请求参数,包括接口地址、请求方法、请求头、请求体等。
  5. 生成签名,将签名添加到请求头中。
  6. 发送请求,获取响应。
  7. 解析响应,获取支付结果等相关信息。

下面是一个示例代码,基于 Java 实现微信支付 V3 对接:

import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.*;
import javax.net.ssl.*;
import org.apache.commons.codec.binary.Base64;
import com.google.gson.Gson;
import com.google.gson.JsonObject;public class WechatPayV3Demo {private static final String MCH_ID = "your_mch_id";private static final String MCH_KEY = "your_mch_key";private static final String API_V3_KEY_PATH = "your_api_v3_key_path";private static final String CERT_PATH = "your_cert_path";private static final String CERT_PASSWORD = "your_cert_password";private static final String API_BASE_URL = "https://api.mch.weixin.qq.com/v3";private static final String PAY_URL = API_BASE_URL + "/pay/transactions/native";public static void main(String[] args) throws Exception {String amount = "100";String description = "test payment";String outTradeNo = "your_out_trade_no";// 构建请求参数JsonObject request = new JsonObject();request.addProperty("mchid", MCH_ID);request.addProperty("out_trade_no", outTradeNo);request.addProperty("description", description);request.addProperty("amount", amount);request.addProperty("notify_url", "your_notify_url");// 发送请求String response = sendPostRequest(PAY_URL, request.toString());// 解析响应JsonObject jsonResponse = new Gson().fromJson(response, JsonObject.class);String codeUrl = jsonResponse.get("code_url").getAsString();System.out.println("Payment QR Code URL: " + codeUrl);}private static String sendPostRequest(String url, String requestBody) throws Exception {// 加载证书KeyStore keyStore = KeyStore.getInstance("PKCS12");keyStore.load(new FileInputStream(CERT_PATH), CERT_PASSWORD.toCharArray());// 创建 SSL 上下文SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keyStore, CERT_PASSWORD.toCharArray()).build();// 创建 SSL 连接工厂SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,new String[]{"TLSv1.2"}, null, new DefaultHostnameVerifier());// 创建默认的请求配置RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build();// 创建 HttpClientCloseableHttpClient httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslConnectionSocketFactory).setDefaultRequestConfig(requestConfig).build();// 构造请求HttpPost httpPost = new HttpPost(url);httpPost.setHeader("Accept", "application/json");httpPost.setHeader("Content-Type", "application/json; charset=utf-8");httpPost.setHeader("User-Agent", "Mozilla/5.0");httpPost.setHeader("Authorization", "WECHATPAY2-SHA256-RSA2048 " + generateAuthorizationHeader(httpPost, requestBody));// 设置请求体httpPost.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));// 发送请求CloseableHttpResponse httpResponse = httpClient.execute(httpPost);int statusCode = httpResponse.getStatusLine().getStatusCode();String response = EntityUtils.toString(httpResponse.getEntity(), StandardCharsets.UTF_8);// 关闭连接httpClient.close();httpResponse.close();// 检查响应状态码if (statusCode != HttpURLConnection.HTTP_OK) {throw new Exception("HTTPPOST Failed with Error Code: " + statusCode + ", Response Body: " + response);}return response;}private static String generateAuthorizationHeader(HttpPost httpPost, String requestBody) throws Exception {String method = httpPost.getMethod();String url = httpPost.getURI().getPath();String timestamp = String.valueOf(System.currentTimeMillis() / 1000);// 生成签名String signature = generateSignature(method, url, timestamp, requestBody);// 生成 Authorization headerreturn "mchid=\"" + MCH_ID + "\","+ "nonce_str=\"" + getRandomString(32) + "\","+ "timestamp=\"" + timestamp + "\","+ "serial_no=\"" + getCertificateSerialNumber() + "\","+ "signature=\"" + signature + "\"";}private static String generateSignature(String method, String url, String timestamp, String requestBody) throws Exception {String message = method + "\n"+ url + "\n"+ timestamp + "\n"+ getCanonicalRequestHeaders() + "\n"+ getSHA256Hash(requestBody) + "\n";// 从 API V3 密钥中加载私钥KeyFactory keyFactory = KeyFactory.getInstance("RSA");PrivateKey privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(readFile(API_V3_KEY_PATH)));// 使用私钥对消息进行签名Signature signature = Signature.getInstance("SHA256withRSA");signature.initSign(privateKey);signature.update(message.getBytes(StandardCharsets.UTF_8));byte[] signatureBytes = signature.sign();// 返回 Base64 编码的签名值return Base64.encodeBase64String(signatureBytes);}private static String getCanonicalRequestHeaders() {return "accept:application/json\n"+ "content-type:application/json; charset=utf-8\n"+ "user-agent:Mozilla/5.0\n";}private static String getSHA256Hash(String input) throws Exception {MessageDigest digest = MessageDigest.getInstance("SHA-256");byte[] hashBytes = digest.digest(input.getBytes(StandardCharsets.UTF_8));StringBuilder hexString = new StringBuilder();for (byte hashByte : hashBytes) {String hex = Integer.toHexString(0xFF & hashByte);if (hex.length() == 1) {hexString.append('0');}hexString.append(hex);}return hexString.toString();}private static String getRandomString(int length) {String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";StringBuilder randomString = new StringBuilder();SecureRandom secureRandom = new SecureRandom();for (int i = 0; i < length; i++) {randomString.append(characters.charAt(secureRandom.nextInt(characters.length())));}return randomString.toString();}private static String getCertificateSerialNumber() throws Exception {X509Certificate certificate = (X509Certificate) CertificateFactory.getInstance("X509").generateCertificate(new FileInputStream(CERT_PATH));return certificate.getSerialNumber().toString(16).toUpperCase();}private static byte[] readFile(String filePath) throws IOException {ByteArrayOutputStream outputStream = new ByteArrayOutputStream();try (InputStream inputStream = new FileInputStream(filePath)) {byte[] buffer = new byte[2048];int length;while ((length = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, length);}}return outputStream.toByteArray();}
}

以上就是微信支付 V3 对接流程及代码的示例,你可以根据自己的实际情况进行修改和扩展。请注意,示例中的 your_mch_idyour_mch_keyyour_api_v3_key_pathyour_cert_pathyour_cert_passwordyour_out_trade_noyour_notify_url 都需要替换为真实的值。

这篇关于Java对接微信支付V3流程及示例代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1139571

相关文章

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑