🆕 #1706 微信支付增加特约商户进件相关接口

* 实现特约商户进件相关接口
This commit is contained in:
叶枫
2020-08-07 17:39:38 +08:00
committed by GitHub
parent e7f2378f49
commit edf8e18c5b
22 changed files with 1755 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
package com.github.binarywang.wxpay.service;
import com.github.binarywang.wxpay.bean.applyment.*;
import com.github.binarywang.wxpay.exception.WxPayException;
/**
* 特约商户进件
* 产品介绍https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment4sub/chapter1_1.shtml
*
* @author zhouyongshen
*/
public interface Applyment4SubService {
/**
* 提交申请单API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment4sub/chapter3_1.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/
*
* @param request 请求对象
* @return WxPayApplymentCreateResult 响应结果
* @throws WxPayException the wx pay exception
*/
WxPayApplymentCreateResult createApply(WxPayApplyment4SubCreateRequest request) throws WxPayException;
/**
* 通过业务申请编号查询申请状态
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment4sub/chapter3_2.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/business_code/{business_code}
*
* @param businessCode 业务申请编号
* 1、只能由数字、字母或下划线组成建议前缀为服务商商户号。
* 2、服务商自定义的唯一编号。
* 3、每个编号对应一个申请单每个申请单审核通过后生成一个微信支付商户号。
* 4、若申请单被驳回可填写相同的“业务申请编号”即可覆盖修改原申请单信息。
* 示例值1900013511_10000
*/
ApplymentStateQueryResult queryApplyStatusByBusinessCode(String businessCode) throws WxPayException;
/**
* 通过申请单号查询申请状态
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment4sub/chapter3_2.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/applyment_id/{applyment_id}
*
* @param applymentId 微信支付分的申请单号。示例值2000001234567890
*/
ApplymentStateQueryResult queryApplyStatusByApplymentId(String applymentId) throws WxPayException;
/**
* 通过申请单号查询申请状态
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment4sub/chapter3_4.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/{sub_mchid}/settlement
*
* @param subMchid 本服务商进件、已签约的特约商户号。
*/
SettlementInfoResult querySettlementBySubMchid(String subMchid) throws WxPayException;
/**
* 修改结算帐号
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment4sub/chapter3_3.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/{sub_mchid}/modify-settlement
* @param subMchid 特约商户号
* @param request 修改结算账户请求对象信息
*/
void modifySettlement(String subMchid,ModifySettlementRequest request) throws WxPayException;
}

View File

@@ -66,6 +66,18 @@ public interface WxPayService {
*/
String postV3(String url, String requestStr) throws WxPayException;
/**
* 发送post请求得到响应字符串.
*
* 部分字段会包含敏感信息,所以在提交前需要在请求头中会包含"Wechatpay-Serial"信息
*
* @param url 请求地址
* @param requestStr 请求信息
* @return 返回请求结果字符串 string
* @throws WxPayException the wx pay exception
*/
String postV3WithWechatpaySerial(String url, String requestStr) throws WxPayException;
/**
* 发送post请求得到响应字符串.
*

View File

@@ -0,0 +1,68 @@
package com.github.binarywang.wxpay.service.impl;
import com.github.binarywang.wxpay.bean.applyment.*;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.Applyment4SubService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.net.URI;
import java.security.cert.X509Certificate;
@Slf4j
@RequiredArgsConstructor
public class Applyment4SubServiceImpl implements Applyment4SubService {
private static final Gson GSON = new GsonBuilder().create();
private final WxPayService payService;
private void encryptFiled(Object request) throws WxPayException {
X509Certificate validCertificate = payService.getConfig().getVerifier().getValidCertificate();
RsaCryptoUtil.encryptFields(request, validCertificate);
}
@Override
public WxPayApplymentCreateResult createApply(WxPayApplyment4SubCreateRequest request) throws WxPayException {
String url = String.format("%s/v3/applyment4sub/applyment/", this.payService.getPayBaseUrl());
encryptFiled(request);
String result = payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(result, WxPayApplymentCreateResult.class);
}
@Override
public ApplymentStateQueryResult queryApplyStatusByBusinessCode(String businessCode) throws WxPayException {
String url = String.format("%s/v3/applyment4sub/applyment/business_code/%s", this.payService.getPayBaseUrl(), businessCode);
String result = payService.getV3(URI.create(url));
return GSON.fromJson(result, ApplymentStateQueryResult.class);
}
@Override
public ApplymentStateQueryResult queryApplyStatusByApplymentId(String applymentId) throws WxPayException {
String url = String.format("%s/v3/applyment4sub/applyment/applyment_id/%s", this.payService.getPayBaseUrl(), applymentId);
String result = payService.getV3(URI.create(url));
return GSON.fromJson(result, ApplymentStateQueryResult.class);
}
@Override
public SettlementInfoResult querySettlementBySubMchid(String subMchid) throws WxPayException {
String url = String.format("%s/v3/apply4sub/sub_merchants/%s/settlement", this.payService.getPayBaseUrl(), subMchid);
String result = payService.getV3(URI.create(url));
return GSON.fromJson(result, SettlementInfoResult.class);
}
@Override
public void modifySettlement(String subMchid,ModifySettlementRequest request) throws WxPayException {
String url = String.format("%s/v3/apply4sub/sub_merchants/%s/modify-settlement", this.payService.getPayBaseUrl(), subMchid);
encryptFiled(request);
String result = payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
}
}

View File

@@ -6,6 +6,7 @@ import com.google.gson.JsonObject;
import jodd.util.Base64;
import me.chanjar.weixin.common.util.json.GsonParser;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
@@ -26,6 +27,7 @@ import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import java.math.BigInteger;
import java.net.URI;
import java.nio.charset.StandardCharsets;
@@ -116,6 +118,40 @@ public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl {
}
@Override
public String postV3WithWechatpaySerial(String url, String requestStr) throws WxPayException {
CloseableHttpClient httpClient = this.createApiV3HttpClient();
HttpPost httpPost = this.createHttpPost(url, requestStr);
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Content-Type", "application/json");
String serialNumber = getConfig().getVerifier().getValidCertificate().getSerialNumber().toString(16).toUpperCase();
httpPost.addHeader("Wechatpay-Serial", serialNumber);
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
//v3已经改为通过状态码判断200 204 成功
int statusCode = response.getStatusLine().getStatusCode();
String responseString="{}";
HttpEntity entity = response.getEntity();
if(entity!=null){
responseString= EntityUtils.toString(entity, StandardCharsets.UTF_8);
}
if (HttpStatus.SC_OK == statusCode || HttpStatus.SC_NO_CONTENT == statusCode) {
this.log.info("\n【请求地址】{}\n【请求数据】{}\n【响应数据】{}", url, requestStr, responseString);
return responseString;
} else {
//有错误提示信息返回
JsonObject jsonObject = GsonParser.parse(responseString);
throw new WxPayException(jsonObject.get("message").getAsString());
}
} catch (Exception e) {
this.log.error("\n【请求地址】{}\n【请求数据】{}\n【异常信息】{}", url, requestStr, e.getMessage());
e.printStackTrace();
throw new WxPayException(e.getMessage(), e);
} finally {
httpPost.releaseConnection();
}
}
@Override
public String postV3(String url, HttpPost httpPost) throws WxPayException {

View File

@@ -66,6 +66,11 @@ public class WxPayServiceJoddHttpImpl extends BaseWxPayServiceImpl {
return null;
}
@Override
public String postV3WithWechatpaySerial(String url, String requestStr) throws WxPayException {
return null;
}
@Override
public String postV3(String url, HttpPost httpPost) throws WxPayException {
return null;