微信支付API v3接口使用应用篇

article/2025/8/19 9:07:12

目录

    • 前言
    • 版本
    • 应用
      • 基础配置
        • 1.申请商户API证书
        • 2.设置接口密钥
        • 3.下载平台证书
      • 接口实测
        • 微信支付API官方客户端
        • 1.客户端
        • 2.支付调起参数签名
        • 3.回调通知
    • 参考资料

前言

最近新项目中有涉及到微信支付相关接口业务的交互,毕竟原先开发接触过支付这块,轻车熟路。打开微信支付官方文档,好家伙,微信支付API 升级至v3版本了,心中一万匹草泥马奔涌而来,根据以往对微信开发文档的认识,赶紧倒杯水,喝一喝,压压惊。
喝完之后,开启了微信支付API v3的对接之路。

版本

jdk:1.8
wechatpay-apache-httpclient:0.2.2

应用

笔者以微信小程序支付接口为例展开说明,至于小程序注册、认证、微信支付注册本文概不说明。

基础配置

1.申请商户API证书

登录微信支付后台,进入账户中心,API安全设置,如下图
在这里插入图片描述
申请商户证书,如下图
在这里插入图片描述
点击“申请证书”按钮后,弹出生成API证书申请框,如下图
在这里插入图片描述
根据提示下载证书工具,当前页面不要关闭,下载证书工具后打开,如下图
在这里插入图片描述

点击“申请证书”按钮后,进入填写商户信息界面,商户信息经测试是自动填充的,如下图
在这里插入图片描述
点击“下一步”,进入复制请求串界面,如下图
在这里插入图片描述
将证书请求串进行复制,复制后回到上述微信支付后台申请API证书页面,将请求串进行复制,经测试自动帮你完成复制粘贴,请求串复制后点击“下一步”操作,进入复制证书串步骤,如下图
在这里插入图片描述
点击“复制证书串”,将复制的证书串粘贴至证书工具中,如下图
在这里插入图片描述
点击“下一步”完成商户证书的申请,如下图
在这里插入图片描述
商户API证书已生成,点击查看证书文件夹,即可查看证书信息,如下图
在这里插入图片描述
在微信支付商户后台可获取商户API证书序列号及证书有效期,如下图
在这里插入图片描述

2.设置接口密钥

设置API密钥,现阶段由于微信支付原先老接口并未全部升级至API v3版,涉及新老接口共存的情况,所以API密钥及APIV3密钥都需进行设置,新老接口请查阅微信支付开发文档
在这里插入图片描述
API v2老版本密钥设置
在这里插入图片描述
API v3密钥设置
在这里插入图片描述

3.下载平台证书

微信平台证书下载,查阅开发文档,微信已提供证书下载工具 如下图
在这里插入图片描述

关注本文末尾微信公众号,回复“666”获取常用开发工具包,内含常用开发组件及微信证书下载工具,节省翻墙下载时间。

下载平台证书至本地,执行命令

必需参数有:商户的私钥文件,即 -f (商户API证书中apiclient_key.pem文件路径)
证书解密的密钥,即 -k (微信支付后台设置的APIv3密钥)
商户号,即 -m (微信支付商户号,可在微信支付后台查阅)
保存证书的路径,即 -o (微信平台证书保存路径)
商户证书的序列号,即 -s (商户API证书,即上述第一步申请商户API证书序列号)
非必需参数有:微信支付证书,用于验签,即 -c完整命令如下java -jar CertificateDownloader-1.1.jar -k ${apiV3key} -m ${mchId} -f ${mchPrivateKeyFilePath} -s ${mchSerialNo} -o ${outputFilePath}

至此基础配置参数已准备就绪

接口实测

在请求接口之前先了解下接口中一些参数概念,首次接触最容易搞混的就是商户API证书和平台证书,如下图
在这里插入图片描述

微信支付API官方客户端

以往老吐槽微信支付接口文档不友好,没有sdk,现在API v3版本给你提供了一个客户端,这点还是可以点赞的,对于开发人员来说,demo代码直接拿过来,更改下配置参数就可以跑通,那简直是对程序员莫大的关怀,这方面阿里相对做的比较好

talk is cheap, show me the code

1.客户端

以post请求方式说明,get请求类似

private static String basePostRequest(String requestUrl,String requestJson) {CloseableHttpClient httpClient = null;CloseableHttpResponse response = null;HttpEntity entity = null;try {PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));X509Certificate wechatpayCertificate = PemUtil.loadCertificate(new ByteArrayInputStream(certificate.getBytes("utf-8")));ArrayList<X509Certificate> listCertificates = new ArrayList<>();listCertificates.add(wechatpayCertificate);httpClient = WechatPayHttpClientBuilder.create().withMerchant(mchId, mchSerialNo, merchantPrivateKey).withWechatpay(listCertificates).build();HttpPost httpPost = new HttpPost(requestUrl);// NOTE: 建议指定charset=utf-8。低于4.4.6版本的HttpCore,不能正确的设置字符集,可能导致签名错误StringEntity reqEntity = new StringEntity(requestJson, ContentType.create("application/json", "utf-8"));httpPost.setEntity(reqEntity);httpPost.addHeader("Accept", "application/json");response = httpClient.execute(httpPost);entity = response.getEntity();return EntityUtils.toString(entity);} catch (Exception e) {e.printStackTrace();} finally {// 关闭流}return null;}

方法中涉及参数说明

参数名说明
privateKey商户私钥(商户API证书apiclient_key.pem文件内容)
certificate平台证书(通过CertificateDownloader下载的证书文件内容)
mchId微信支付商户号
mchSerialNo商户API证书序列号

PemUtil.java类为com.wechat.pay.contrib.apache.httpclient.util.PemUtil

请求签名及应答签名校验该客户端均已帮你处理好,心中对微信支付开发文档有了一点点好感。根据具体接口方法传入接口地址及相应接口参数JSON数据即可完成接口联调测试。

2.支付调起参数签名

以小程序调起支付接口为例,简单说明参数签名方式,先看下文档中签名是怎么说的,如下图
在这里插入图片描述

 /*** 微信支付-前端唤起支付参数* prepay_id=wx201410272009395522657a690389285100* @param packageStr 预下单接口返回数据 预支付交易会话标识	prepay_id* @return*/public static Map<String,Object> createPayParams(String packageStr) {Map<String,Object> resultMap = new HashMap<>();String nonceStr = StringUtil.getUUID();Long timestamp = System.currentTimeMillis() / 1000;String message = buildMessage(timestamp, nonceStr, packageStr);String signature = null;try {signature = sign(message.getBytes("utf-8"));} catch (UnsupportedEncodingException e) {e.printStackTrace();}resultMap.put("appId", appId);resultMap.put("timeStamp",timestamp.toString());resultMap.put("nonceStr",nonceStr);resultMap.put("package",packageStr);resultMap.put("signType","RSA");resultMap.put("paySign",signature);return resultMap;}/*** 微信支付-前端唤起支付参数-签名* @param message 签名数据* @return*/public static String sign(byte[] message) {try{Signature sign = Signature.getInstance("SHA256withRSA");sign.initSign(getPrivateKey(keyFilePath));sign.update(message);return Base64.getEncoder().encodeToString(sign.sign());} catch(Exception e) {e.printStackTrace();}return null;}/*** 微信支付-前端唤起支付参数-构建签名参数* @param nonceStr 签名数据* @return*/public static String buildMessage(long timestamp, String nonceStr, String packageStr) {return appId + "\n"+ timestamp + "\n"+ nonceStr + "\n"+ packageStr + "\n";}/*** 微信支付-前端唤起支付参数-获取商户私钥** @param filename 私钥文件路径  (required)* @return 私钥对象*/public static PrivateKey getPrivateKey(String filename) throws IOException {String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8");try {String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").replaceAll("\\s+", "");KeyFactory kf = KeyFactory.getInstance("RSA");return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));} catch (NoSuchAlgorithmException e) {throw new RuntimeException("当前Java环境不支持RSA", e);} catch (InvalidKeySpecException e) {throw new RuntimeException("无效的密钥格式");}}

方法中涉及参数说明

参数名说明
appId小程序appid
keyFilePath商户API证书apiclient_key.pem路径

3.回调通知

回调通知涉及验签及解密

回调数据获取

String body = request.getReader().lines().collect(Collectors.joining());

验签

/*** 回调验签* https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml* @param wechatpaySerial 回调head头部* @param wechatpaySignature 回调head头部* @param wechatpayTimestamp 回调head头部* @param wechatpayNonce 回调head头部* @param body 请求数据* @return*/public static boolean  responseSignVerify(String wechatpaySerial, String wechatpaySignature, String wechatpayTimestamp, String wechatpayNonce, String body) {FileInputStream fileInputStream = null;try {String signatureStr = buildMessage(wechatpayTimestamp, wechatpayNonce, body);Signature signer = Signature.getInstance("SHA256withRSA");fileInputStream = new FileInputStream(weixin_platform_cert_path);X509Certificate receivedCertificate = loadCertificate(fileInputStream);signer.initVerify(receivedCertificate);signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));return signer.verify(Base64.getDecoder().decode(wechatpaySignature));} catch (Exception e ) {e.printStackTrace();} finally {if (fileInputStream != null) {try {fileInputStream.close();} catch (IOException e) {e.printStackTrace();}}}return false;}/*** 回调验签-加载微信平台证书* @param inputStream* @return*/public static X509Certificate loadCertificate(InputStream inputStream) {try {CertificateFactory cf = CertificateFactory.getInstance("X509");X509Certificate cert = (X509Certificate) cf.generateCertificate(inputStream);cert.checkValidity();return cert;} catch (CertificateExpiredException e) {throw new RuntimeException("证书已过期", e);} catch (CertificateNotYetValidException e) {throw new RuntimeException("证书尚未生效", e);} catch (CertificateException e) {throw new RuntimeException("无效的证书", e);}}/*** 回调验签-构建签名数据* @param * @return*/public static String buildMessage(String wechatpayTimestamp, String wechatpayNonce, String body) {return wechatpayTimestamp + "\n"+ wechatpayNonce + "\n"+ body + "\n";}

方法中涉及参数说明

参数名说明
weixin_platform_cert_path微信平台证书路径

解密

// https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml
AesUtil wxAesUtil = new AesUtil(apiv3.getBytes());
String jsonStr = wxAesUtil.decryptToString("associated_data".getBytes(),"nonce".getBytes(),"ciphertext");

方法中涉及参数说明

参数名说明
apiv3商户API v3密钥
associated_data附加数据 (微信回调通知数据中resource对象)
noncenonce (微信回调通知数据中resource对象)
ciphertext数据密文 (微信回调通知数据中resource对象)
jsonStr对resource对象进行解密后,得到的资源对象数据

参考资料

微信支付开发文档

平台证书下载工具

微信支付API v3文档介绍

微信支付API客户端

在这里插入图片描述


http://chatgpt.dhexx.cn/article/9cRG8yE4.shtml

相关文章

Java对接微信、支付宝、银联第三方支付

一、微信支付 1、业务平台介绍&#xff1a; &#xff08;1&#xff09;微信公众平台 微信公众平台是微信公众账号申请入口和管理后台。商户可以在公众平台提交基本资料、业务资料、财务资料申请开通微信支付功能。 &#xff08;2&#xff09; 微信开放平台 微信开放平台是商…

php微信支付宝第三方接口开发平台,帝国CMS第三方个人支付接口微信支付宝免签约即时到账api_帝国网站管理系统插件...

帝国CMS网站管理系统是一个高效的网站解决方案,本文将给出开发好的帝国CMS第三方个人免签约支付接口插件(支持支付宝/微信扫码即时到账支付),可用于帝国系统收款使用,供有需求的用户参考或快速接入。本代码无加密完全开源,欢迎参考/使用。 概述 环境 本接口插件基于帝国CMS…

第三方支付接口之微信扫码支付

此篇文章是为了记录学习如何编写第三方支付接口&#xff0c;熟悉这个流程。使用的是威富通第三方支付平台https://open.swiftpass.cn/ 对接的是微信扫码和公总号支付 基本成员&#xff1a;用户&#xff0c;商户&#xff0c;第三方支付方 扫码支付业务流程&#xff1a; 接口…

第三方支付接口有哪些?怎么申请?

第三方支付接口有哪些&#xff1f; 目前中国国内的第三方支付产品主要有支付宝&#xff08;阿里巴巴旗下&#xff09;、微信&#xff08;腾讯公司&#xff09;、QQ钱包&#xff08;财付通公司&#xff09;、云闪付&#xff08;中国银联旗下&#xff09;等。其中最用户数量最大…

调用微信和支付宝第三方接口方法总结

最近项目上用到了调用微信和支付宝的第三方支付接口&#xff0c;因为以前没用过&#xff0c;所以这次用到了之后总结一下分享给大家&#xff0c;这里介绍两种支付方式&#xff0c;即app支付和扫码支付方式。 一、app支付&#xff08;这里只介绍java端调用支付&#xff0c;安卓…

第三方支付:微信公众号接入支付宝支付开发

第三方支付&#xff1a;微信公众号接入支付宝支付开发 引言 这篇文章使用一些简单的代码例子来解释微信接入支付宝支付功能的操作步骤&#xff0c;即使新手也可以轻松参透的。 第三方支付是指具备一定实力和信誉保障的独立机构&#xff0c;采用与各大银行签约的方式&#xff…

第三方支付接入(微信,支付宝)

写在最前面 以下内容关于微信相关的&#xff0c;除了binarywang&#xff0c;个人认为都不要再用了。相比较王大哥的封装&#xff0c;我自己写的真是连弟弟都不如。 支付宝相关的&#xff0c;好久不用了&#xff0c;不知道还能不能工作。建议找创建时间比较新的文章来看。 关…

微信第三方支付接口java调用详细文档

1.显示支付二维码 支付流程 首先用户选好商品后 跳到结算页面 在点击支付提交时应先将表单的数据保存到数据库(一般都会有订单表一二级) 经过后台保存数据后再转发到前台(二维码是后台调用微信生成的) 看到扫码页面 当用户扫码成功后 更改订单状态为已支付(一般情况 根据业务…

微信支付接口配置教程(下)

微信第三方平台微信支付接口配置教程&#xff08;下&#xff09; 上传微信支付证书 登录后台系统&#xff0c;在后台微信商城里&#xff0c;点击微信支付证书。这一步我们需要上传对应的微信支付证书&#xff0c;这个证书就是文章《微信第三方平台微信支付接口配置教程&#…

聊一聊对“事务”的理解

什么是事务 事务即英文Transaction&#xff0c;在软件开发过程中&#xff0c;难免需要考虑处理事务。从微观层面看亦或者从成员最早了解到这个词汇看&#xff0c;事务通常指多条写入数据库的语句需要并发成功执行&#xff0c;从宏观层面看得话则是客户端发出的并发请求需要一致…

聊一聊wifi6

引言 8.11&#xff0c;小米十周年&#xff0c;雷军即将召开发布会&#xff0c;相信又是are you ok 放大招的时候了。作为小米各种产品的使用者&#xff08;包括但不限于手机&#xff0c;路由器&#xff0c;音响&#xff0c;手环&#xff0c;中性笔… &#xff09;&#xff0c;…

聊一聊我对测试开发的看法

前言 在一线大厂&#xff0c;没有测试这个岗位&#xff0c;只有测开这个岗位 即使是做业务测试&#xff0c;那么你的title也是测开 所以想聊一聊测开的看法 但不代表这是正确的看法&#xff0c;仅供参考 还没来阿里之前&#xff0c;我对测开的看法 一直以为专职做自动化测…

聊一聊,我对DDD的关键理解

作者&#xff1a;闵大为 阿里业务平台解决方案团队 当我们在学习DDD的过程中&#xff0c;感觉学而不得的时候&#xff0c;可能会问&#xff1a;我们还要学么&#xff1f;这的确引人深思。本文基于工作经验&#xff0c;尝试谈谈对DDD的一些理解。 一、序 《阿甘正传》中&#xf…

聊一聊Kotlin的泛型

Kotlin的泛型 简介 与java一样&#xff0c;kotlin也支持泛型&#xff0c;用法和java泛型差别不大&#xff0c;kotlin特色是型变支持。 基本用法&#xff1a; 定义类&#xff1a; 跟java相同&#xff0c;定义在类后面的尖括号&#xff1a; open class Basket<T>{}定…

聊一聊学习方法

聊一聊学习方法 为什么学习没效果&#xff1f;你只是看起来很努力自知与不自知&#xff0c;真的不是一字之差什么时候真的能出效果&#xff1f;学习方法一&#xff08;拍照式记忆&#xff09;学习方法二&#xff08;殊途同归&#xff09;学习方法三&#xff08;精细化管理&…

聊一聊ThreadLocal内存泄漏的问题

回答任何一个问题的时候应该要遵循&#xff1a;明确题意-->深入浅出-->举例说明-->总结&#xff0c;这四个步骤很重要&#xff0c;可以让你沉着冷静&#xff0c;思路清晰&#xff0c;避免尴尬。 01 — 明确题意 明确题意的意思就是先明确一下面试官的题目&#xff0…

聊一聊Https

前言 https协议是一种在http的基础上进行加密的协议&#xff0c;在http协议传输过程中&#xff0c;传输的数据都是已明文的方式进行传输&#xff0c;那我们的信息就有可能被他人进行捕获篡改&#xff08;比如你给女神表白却被程序员情敌发现并修改了你的消息&#xff0c;然后你…

SLAM基础——聊一聊信息矩阵

文章目录 前言1 :book: 信息矩阵1-1 :bookmark: 信息矩阵是什么&#xff1f;有什么作用&#xff1f;1-2 :bookmark: 信息矩阵与Hessian矩阵的关系1-2-1 Hessian矩阵和H矩阵的关系1-2-2 Hessian或H矩阵和信息矩阵的关系 2 :book: 信息矩阵与最小二乘的关联2-1 :bookmark: 先谈一…

聊一聊SpringCloud的五大组件

聊一聊SpringCloud的五大组件 1.初始SpringCloud 微服务是一种架构方式&#xff0c;最终肯定需要技术架构去实施。 微服务的实现方式很多&#xff0c;但是最火的莫过于Spring Cloud了。为什么&#xff1f; 后台硬&#xff1a;作为Spring家族的一员&#xff0c;有整个Spring全…

聊一聊Serverless

聊一聊Serverless Serverless是什么云计算发展过程Serverless的优势Serverless的不足云函数冷启动热启动函数实例不同语言冷启动时长排名首次调用超时性能优化 SFFBaaS再会推荐阅读 Serverless是什么 从单词角度理解,server译为服务&#xff0c;less译为少&#xff0c;Serverl…