商户Native支付下单接口,微信后台系统返回链接参数code_url,商户后台系统将code_url值生成二维码图片,用户使用微信客户端扫码后发起支付。
文档地址:微信支付-开发者文档
目录
一、Native下单接口简介
请求URL:https://api.mch.weixin.qq.com/v3/pay/transactions/native
请求方式:POST
请求参数:
-
-
{
-
"mchid":
"1900006XXX",
-
"out_trade_no":
"native12177525012014070332333",
-
"appid":
"wxdace645e0bc2cXXX",
-
"description":
"Image形象店-深圳腾大-QQ公仔",
-
"notify_url":
"https://weixin.qq.com/",
-
"amount": {
-
"total":
1,
-
"currency":
"CNY"
-
}
-
}
参数说明:
mchid 商户号 :在微信商户平台(微信支付 - 中国领先的第三方支付平台 | 微信支付提供安全快捷的支付方式)中获取
out_trade_no 商户订单号:自己生成的业务订单编号(只能是数字、大小写字母,且在同一个商户号下唯一)
description:商品描述信息
notify_url:回调通知地址(通知URL必须为直接可访问的URL,不允许携带其他参数,要求必须为https地址,本地可以借助于内网穿透工具来完成测试。)
amount :订单金额信息,注意total单位是分,不是元,这个跟支付宝接口有点不同,支付宝接口的单位是元,微信支付接口的单位是分 ,currency在国内使用的话,直接默认值CNY就行。
appid:使用公众号APPID(微信公众号需要先进行实名认证缴费300元)
然后让公众号和商户进行关联
业务流程时序图
二、如何正确调通接口
(1) 测试调用接口
首先拿到接口地址和请求参数去postman中测试一下
接口返回返回提示告诉我们:Http头Authorization值格式错误,请参考《微信支付商户REST API签名规则》,也就是说这个接口需要进行签名验证。
(2)签名生成规则
签名生成规则文档地址:签名生成-接口规则 | 微信支付商户平台文档中心
在进行签名过程中,会用到这几个参数
① 商户API证书
证书获取流程:什么是商户API证书?如何获取商户API证书?
② 商户证书序列号
API证书添加成功之后,点击管理就能看到商户证书序列号。
三、下单支付JAVA核心代码
(1)获取接口签名方法
getToken方法的作用是获取接口签名,具体参数解释
method:GET/POST
url:接口url地址
body:获取请求中的请求报文主体,
请求方法为GET时,报文主体为空。
当请求方法为POST或PUT时,请使用真实发送的JSON报文
signatureType :签名类型字符串常量:WECHATPAY2-SHA256-RSA2048
nonceStr :随机字符串,可以固定值。
-
public
static String
getToken
(String method, HttpUrl url, String body)
throws IOException, NoSuchAlgorithmException, SignatureException, InvalidKeyException {
-
String
nonceStr
=
"593BEC0C930BF1AFEB40B4A08C8FB242";
-
long
timestamp
= System.currentTimeMillis() /
1000;
-
String
message
= buildMessage(method, url, timestamp, nonceStr, body);
-
String
signature
= sign(message.getBytes(
"utf-8"));
-
-
return signatureType +
" mchid=\"" + mchid +
"\","
-
+
"nonce_str=\"" + nonceStr +
"\","
-
+
"timestamp=\"" + timestamp +
"\","
-
+
"serial_no=\"" + merchantSerialNumber +
"\","
-
+
"signature=\"" + signature +
"\"";
-
}
(2)获取私钥对象方法
参数说明:private_key的值来源于证书文件apiclient_key.pem文件类的所有内容。
-
/**
-
* 获取私钥。
-
*
-
* @return 私钥对象
-
*/
-
public
static PrivateKey
getPrivateKey
()
throws IOException {
-
try {
-
String
privateKey
= private_key.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(
"无效的密钥格式");
-
}
-
}
(3)接口签名加密方法
-
public
static String
sign
(byte[] message)
throws NoSuchAlgorithmException, IOException, InvalidKeyException, SignatureException {
-
Signature
sign
= Signature.getInstance(
"SHA256withRSA");
-
sign.initSign(getPrivateKey());
-
sign.update(message);
-
return Base64.getEncoder().encodeToString(sign.sign());
-
}
(4)构建加密信息字符串
-
public
static String
buildMessage
(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
-
String
canonicalUrl
= url.encodedPath();
-
if (url.encodedQuery() !=
null) {
-
canonicalUrl +=
"?" + url.encodedQuery();
-
}
-
return method +
"\n"
-
+ canonicalUrl +
"\n"
-
+ timestamp +
"\n"
-
+ nonceStr +
"\n"
-
+ body +
"\n";
-
}
(5)构建下单支付请求报文
-
/**
-
* 构建下单支付请求JSON字符串
-
*
-
* @return
-
*/
-
public
static String
buildNativePayJson
(Double total_amount, String out_trade_no) {
-
-
JSONObject
jsonObject
=
new
JSONObject();
-
// 应用ID
-
jsonObject.put(
"appid", appid);
-
// 商户号
-
jsonObject.put(
"mchid", mchid);
-
// 商户订单号
-
jsonObject.put(
"out_trade_no", out_trade_no);
-
// 商品描述
-
jsonObject.put(
"description",
"易微帮在线充值" + total_amount +
"元");
-
// 回调通知URL
-
jsonObject.put(
"notify_url", notify_url);
-
JSONObject
amount
=
new
JSONObject();
-
// 单位:分
-
amount.put(
"total", Convert.toInt(total_amount *
100));
-
//货币类型
-
amount.put(
"currency",
"CNY");
-
jsonObject.put(
"amount", amount);
-
return jsonObject.toJSONString();
-
}
(6)调用下单支付接口
-
//商户订单号
-
String
out_trade_no
= PayUtil.getOrderNum();
-
String
body
= WxPayUtil.buildNativePayJson(amount, out_trade_no);
-
String
url
=
"https://api.mch.weixin.qq.com/v3/pay/transactions/native";
-
HttpUrl
httpurl
= HttpUrl.parse(url);
-
String
sign
= WxPayUtil.getToken(
"POST", httpurl, body);
-
-
String
response
= HttpUtil.createPost(url)
-
.header(
"Authorization", sign)
-
.body(body)
-
.execute().body();
下单支付接口调用成功之后,response字符串的格式如下。
-
{
-
"code_url":
"weixin://wxpay/bizpayurl?pr=p4lpSuKzz"
-
}
后续使用,将code_url的值生成二维码,展现给用户扫码即可。
可以来我的个人网站参考一下应用场景。
页面地址:易微帮-专业IT技术协助平台
四、需要用到的部分依赖包
-
-
<!--微信支付v3接口-->
-
<dependency>
-
<groupId>com.github.wechatpay-apiv3
</groupId>
-
<artifactId>wechatpay-java
</artifactId>
-
<version>0.2.5
</version>
-
</dependency>
-
-
<!-- hutool工具包 -->
-
<dependency>
-
<groupId>cn.hutool
</groupId>
-
<artifactId>hutool-all
</artifactId>
-
<version>5.8.12
</version>
-
</dependency>
转载:https://blog.csdn.net/qq_19309473/article/details/129094700