Skip to content

Commit 3b8d0a8

Browse files
authored
🆕 #3814 【微信支付】增加实名验证的接口
1 parent c8cdfb5 commit 3b8d0a8

File tree

8 files changed

+432
-0
lines changed

8 files changed

+432
-0
lines changed

weixin-java-pay/REAL_NAME_USAGE.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# 微信支付实名验证接口使用说明
2+
3+
## 概述
4+
5+
微信支付实名验证接口允许商户查询用户的实名认证状态,如果用户未实名认证,接口会返回引导用户进行实名认证的URL。
6+
7+
## 官方文档
8+
9+
https://pay.wechatpay.cn/doc/v2/merchant/4011987607
10+
11+
## 接口说明
12+
13+
### 查询用户实名认证信息
14+
15+
- **接口地址**`https://api.mch.weixin.qq.com/userinfo/realnameauth/query`
16+
- **请求方式**:POST(需要使用商户证书)
17+
- **请求参数**
18+
- `appid`:公众账号ID(自动填充)
19+
- `mch_id`:商户号(自动填充)
20+
- `openid`:用户在商户appid下的唯一标识
21+
- `nonce_str`:随机字符串(自动生成)
22+
- `sign`:签名(自动生成)
23+
24+
- **返回参数**
25+
- `return_code`:返回状态码
26+
- `return_msg`:返回信息
27+
- `result_code`:业务结果
28+
- `openid`:用户标识
29+
- `is_certified`:实名认证状态(Y-已实名认证,N-未实名认证)
30+
- `cert_info`:实名认证信息(加密,仅已实名时返回)
31+
- `guide_url`:引导用户进行实名认证的URL(仅未实名时返回)
32+
33+
## 使用示例
34+
35+
### 1. 获取实名验证服务
36+
37+
```java
38+
// 获取WxPayService实例
39+
WxPayService wxPayService = ... // 根据你的配置初始化
40+
41+
// 获取实名验证服务
42+
RealNameService realNameService = wxPayService.getRealNameService();
43+
```
44+
45+
### 2. 查询用户实名认证状态(完整方式)
46+
47+
```java
48+
import com.github.binarywang.wxpay.bean.realname.RealNameRequest;
49+
import com.github.binarywang.wxpay.bean.realname.RealNameResult;
50+
import com.github.binarywang.wxpay.exception.WxPayException;
51+
52+
try {
53+
// 构建请求对象
54+
RealNameRequest request = RealNameRequest.newBuilder()
55+
.openid("oUpF8uMuAJO_M2pxb1Q9zNjWeS6o") // 用户的openid
56+
.build();
57+
58+
// 调用查询接口
59+
RealNameResult result = realNameService.queryRealName(request);
60+
61+
// 处理返回结果
62+
if ("Y".equals(result.getIsCertified())) {
63+
System.out.println("用户已实名认证");
64+
System.out.println("认证信息:" + result.getCertInfo());
65+
} else {
66+
System.out.println("用户未实名认证");
67+
System.out.println("引导链接:" + result.getGuideUrl());
68+
// 可以将guide_url提供给用户,引导其完成实名认证
69+
}
70+
} catch (WxPayException e) {
71+
System.err.println("查询失败:" + e.getMessage());
72+
}
73+
```
74+
75+
### 3. 查询用户实名认证状态(简化方式)
76+
77+
```java
78+
import com.github.binarywang.wxpay.bean.realname.RealNameResult;
79+
import com.github.binarywang.wxpay.exception.WxPayException;
80+
81+
try {
82+
// 直接传入openid进行查询
83+
RealNameResult result = realNameService.queryRealName("oUpF8uMuAJO_M2pxb1Q9zNjWeS6o");
84+
85+
// 处理返回结果
86+
if ("Y".equals(result.getIsCertified())) {
87+
System.out.println("用户已实名认证");
88+
} else {
89+
System.out.println("用户未实名认证,引导链接:" + result.getGuideUrl());
90+
}
91+
} catch (WxPayException e) {
92+
System.err.println("查询失败:" + e.getMessage());
93+
}
94+
```
95+
96+
## 注意事项
97+
98+
1. **证书要求**:本接口需要使用商户证书进行请求,请确保已正确配置商户证书。
99+
100+
2. **OPENID获取**:openid是用户在商户appid下的唯一标识,需要通过微信公众平台或小程序获取。
101+
102+
3. **认证信息**`cert_info`字段返回的信息是加密的,需要使用相应的解密方法才能获取明文信息。
103+
104+
4. **引导链接**:当用户未实名时,返回的`guide_url`可以用于引导用户完成实名认证,建议在小程序或H5页面中使用。
105+
106+
5. **频率限制**:请注意接口调用频率限制,避免频繁查询同一用户的实名状态。
107+
108+
## 业务场景
109+
110+
- **转账前校验**:在进行企业付款到零钱等操作前,可以先查询用户的实名认证状态
111+
- **风控审核**:作为业务风控的一部分,确认用户已完成实名认证
112+
- **用户引导**:发现用户未实名时,引导用户完成实名认证以使用相关功能
113+
114+
## 错误处理
115+
116+
```java
117+
try {
118+
RealNameResult result = realNameService.queryRealName(openid);
119+
// 处理结果...
120+
} catch (WxPayException e) {
121+
// 处理异常
122+
String errorCode = e.getErrCode();
123+
String errorMsg = e.getErrCodeDes();
124+
125+
// 根据错误码进行相应处理
126+
switch (errorCode) {
127+
case "SYSTEMERROR":
128+
// 系统错误,建议稍后重试
129+
break;
130+
case "PARAM_ERROR":
131+
// 参数错误,检查openid是否正确
132+
break;
133+
default:
134+
// 其他错误
135+
break;
136+
}
137+
}
138+
```
139+
140+
## 相关链接
141+
142+
- [微信支付官方文档](https://pay.wechatpay.cn/doc/v2/merchant/4011987607)
143+
- [WxJava项目主页](https://github.com/binarywang/WxJava)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.github.binarywang.wxpay.bean.realname;
2+
3+
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
4+
import com.thoughtworks.xstream.annotations.XStreamAlias;
5+
import lombok.*;
6+
import me.chanjar.weixin.common.annotation.Required;
7+
8+
import java.util.Map;
9+
10+
/**
11+
* <pre>
12+
* 微信支付实名验证请求对象.
13+
* 详见文档:https://pay.wechatpay.cn/doc/v2/merchant/4011987607
14+
* </pre>
15+
*
16+
* @author <a href="https://github.com/binarywang">Binary Wang</a>
17+
*/
18+
@Data
19+
@EqualsAndHashCode(callSuper = true)
20+
@Builder(builderMethodName = "newBuilder")
21+
@NoArgsConstructor
22+
@AllArgsConstructor
23+
@XStreamAlias("xml")
24+
public class RealNameRequest extends BaseWxPayRequest {
25+
private static final long serialVersionUID = 1L;
26+
27+
/**
28+
* <pre>
29+
* 字段名:用户标识
30+
* 变量名:openid
31+
* 是否必填:是
32+
* 类型:String(128)
33+
* 示例值:oUpF8uMuAJO_M2pxb1Q9zNjWeS6o
34+
* 描述:用户在商户appid下的唯一标识
35+
* </pre>
36+
*/
37+
@Required
38+
@XStreamAlias("openid")
39+
private String openid;
40+
41+
@Override
42+
protected void checkConstraints() {
43+
//do nothing
44+
}
45+
46+
@Override
47+
protected void storeMap(Map<String, String> map) {
48+
map.put("openid", openid);
49+
}
50+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package com.github.binarywang.wxpay.bean.realname;
2+
3+
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
4+
import com.thoughtworks.xstream.annotations.XStreamAlias;
5+
import lombok.Data;
6+
import lombok.EqualsAndHashCode;
7+
import lombok.NoArgsConstructor;
8+
import org.w3c.dom.Document;
9+
10+
import java.io.Serializable;
11+
12+
/**
13+
* <pre>
14+
* 微信支付实名验证返回结果.
15+
* 详见文档:https://pay.wechatpay.cn/doc/v2/merchant/4011987607
16+
* </pre>
17+
*
18+
* @author <a href="https://github.com/binarywang">Binary Wang</a>
19+
*/
20+
@Data
21+
@EqualsAndHashCode(callSuper = true)
22+
@NoArgsConstructor
23+
@XStreamAlias("xml")
24+
public class RealNameResult extends BaseWxPayResult implements Serializable {
25+
private static final long serialVersionUID = 1L;
26+
27+
/**
28+
* <pre>
29+
* 字段名:用户标识
30+
* 变量名:openid
31+
* 是否必填:否
32+
* 类型:String(128)
33+
* 示例值:oUpF8uMuAJO_M2pxb1Q9zNjWeS6o
34+
* 描述:用户在商户appid下的唯一标识
35+
* </pre>
36+
*/
37+
@XStreamAlias("openid")
38+
private String openid;
39+
40+
/**
41+
* <pre>
42+
* 字段名:实名认证状态
43+
* 变量名:is_certified
44+
* 是否必填:是
45+
* 类型:String(1)
46+
* 示例值:Y
47+
* 描述:Y-已实名认证 N-未实名认证
48+
* </pre>
49+
*/
50+
@XStreamAlias("is_certified")
51+
private String isCertified;
52+
53+
/**
54+
* <pre>
55+
* 字段名:实名认证信息
56+
* 变量名:cert_info
57+
* 是否必填:否
58+
* 类型:String(256)
59+
* 示例值:
60+
* 描述:实名认证的相关信息,如姓名等(加密)
61+
* </pre>
62+
*/
63+
@XStreamAlias("cert_info")
64+
private String certInfo;
65+
66+
/**
67+
* <pre>
68+
* 字段名:引导链接
69+
* 变量名:guide_url
70+
* 是否必填:否
71+
* 类型:String(256)
72+
* 示例值:
73+
* 描述:未实名时,引导用户进行实名认证的URL
74+
* </pre>
75+
*/
76+
@XStreamAlias("guide_url")
77+
private String guideUrl;
78+
79+
/**
80+
* 从XML结构中加载额外的属性
81+
*
82+
* @param d Document
83+
*/
84+
@Override
85+
protected void loadXml(Document d) {
86+
openid = readXmlString(d, "openid");
87+
isCertified = readXmlString(d, "is_certified");
88+
certInfo = readXmlString(d, "cert_info");
89+
guideUrl = readXmlString(d, "guide_url");
90+
}
91+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.github.binarywang.wxpay.service;
2+
3+
import com.github.binarywang.wxpay.bean.realname.RealNameRequest;
4+
import com.github.binarywang.wxpay.bean.realname.RealNameResult;
5+
import com.github.binarywang.wxpay.exception.WxPayException;
6+
7+
/**
8+
* <pre>
9+
* 微信支付实名验证相关服务类.
10+
* 详见文档:https://pay.wechatpay.cn/doc/v2/merchant/4011987607
11+
* </pre>
12+
*
13+
* @author <a href="https://github.com/binarywang">Binary Wang</a>
14+
*/
15+
public interface RealNameService {
16+
/**
17+
* <pre>
18+
* 获取用户实名认证信息API.
19+
* 用于商户查询用户的实名认证状态,如果用户未实名认证,会返回引导用户实名认证的URL
20+
* 文档详见:https://pay.wechatpay.cn/doc/v2/merchant/4011987607
21+
* 接口链接:https://api.mch.weixin.qq.com/userinfo/realnameauth/query
22+
* </pre>
23+
*
24+
* @param request 请求对象
25+
* @return 实名认证查询结果
26+
* @throws WxPayException the wx pay exception
27+
*/
28+
RealNameResult queryRealName(RealNameRequest request) throws WxPayException;
29+
30+
/**
31+
* <pre>
32+
* 获取用户实名认证信息API(简化方法).
33+
* 用于商户查询用户的实名认证状态,如果用户未实名认证,会返回引导用户实名认证的URL
34+
* 文档详见:https://pay.wechatpay.cn/doc/v2/merchant/4011987607
35+
* 接口链接:https://api.mch.weixin.qq.com/userinfo/realnameauth/query
36+
* </pre>
37+
*
38+
* @param openid 用户openid
39+
* @return 实名认证查询结果
40+
* @throws WxPayException the wx pay exception
41+
*/
42+
RealNameResult queryRealName(String openid) throws WxPayException;
43+
}

weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,6 +1707,13 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
17071707
*/
17081708
PartnerPayScoreSignPlanService getPartnerPayScoreSignPlanService();
17091709

1710+
/**
1711+
* 获取实名验证服务类
1712+
*
1713+
* @return the real name service
1714+
*/
1715+
RealNameService getRealNameService();
1716+
17101717
/**
17111718
* 获取医保支付服务类
17121719
*

weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
137137
@Getter
138138
private final BusinessOperationTransferService businessOperationTransferService = new BusinessOperationTransferServiceImpl(this);
139139

140+
@Getter
141+
private final RealNameService realNameService = new RealNameServiceImpl(this);
142+
140143
@Getter
141144
private final MiPayService miPayService = new MiPayServiceImpl(this);
142145

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.github.binarywang.wxpay.service.impl;
2+
3+
import com.github.binarywang.wxpay.bean.realname.RealNameRequest;
4+
import com.github.binarywang.wxpay.bean.realname.RealNameResult;
5+
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
6+
import com.github.binarywang.wxpay.exception.WxPayException;
7+
import com.github.binarywang.wxpay.service.RealNameService;
8+
import com.github.binarywang.wxpay.service.WxPayService;
9+
import lombok.RequiredArgsConstructor;
10+
11+
/**
12+
* <pre>
13+
* 微信支付实名验证相关服务实现类.
14+
* 详见文档:https://pay.wechatpay.cn/doc/v2/merchant/4011987607
15+
* </pre>
16+
*
17+
* @author <a href="https://github.com/binarywang">Binary Wang</a>
18+
*/
19+
@RequiredArgsConstructor
20+
public class RealNameServiceImpl implements RealNameService {
21+
private final WxPayService payService;
22+
23+
@Override
24+
public RealNameResult queryRealName(RealNameRequest request) throws WxPayException {
25+
request.checkAndSign(this.payService.getConfig());
26+
String url = this.payService.getPayBaseUrl() + "/userinfo/realnameauth/query";
27+
28+
String responseContent = this.payService.post(url, request.toXML(), true);
29+
RealNameResult result = BaseWxPayResult.fromXML(responseContent, RealNameResult.class);
30+
result.checkResult(this.payService, request.getSignType(), true);
31+
return result;
32+
}
33+
34+
@Override
35+
public RealNameResult queryRealName(String openid) throws WxPayException {
36+
RealNameRequest request = RealNameRequest.newBuilder()
37+
.openid(openid)
38+
.build();
39+
return this.queryRealName(request);
40+
}
41+
}

0 commit comments

Comments
 (0)