mirror of
https://github.com/dromara/payment-spring-boot.git
synced 2026-03-14 05:43:46 +08:00
Merge remote-tracking branch 'origin/1.0.10.SNAPSHOT' into 1.0.10.SNAPSHOT
This commit is contained in:
@@ -0,0 +1,247 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2021 felord.cn
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Website:
|
||||||
|
* https://felord.cn
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cn.felord.payment.wechat.v2;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.WechatPayProperties;
|
||||||
|
import cn.felord.payment.wechat.v2.model.allocation.*;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付分账
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class WechatAllocationApi {
|
||||||
|
/**
|
||||||
|
* The constant MAPPER.
|
||||||
|
*/
|
||||||
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
|
static {
|
||||||
|
MAPPER.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
|
||||||
|
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
||||||
|
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||||
|
.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
|
||||||
|
.registerModule(new JavaTimeModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
private final WechatV2Client wechatV2Client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new Wechat allocation api.
|
||||||
|
*
|
||||||
|
* @param wechatV2Client the wechat v 2 client
|
||||||
|
*/
|
||||||
|
public WechatAllocationApi(WechatV2Client wechatV2Client) {
|
||||||
|
this.wechatV2Client = wechatV2Client;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求单次分账
|
||||||
|
*
|
||||||
|
* @param profitSharingModel the profit sharing model
|
||||||
|
* @return json node
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public JsonNode profitSharing(ProfitSharingModel profitSharingModel) {
|
||||||
|
ProfitSharingSModel profitSharingSModel = new ProfitSharingSModel();
|
||||||
|
List<Receiver> receivers = profitSharingModel.getReceivers();
|
||||||
|
profitSharingSModel.setReceivers(MAPPER.writeValueAsString(receivers));
|
||||||
|
|
||||||
|
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||||
|
profitSharingSModel.setAppid(v3.getAppId());
|
||||||
|
profitSharingSModel.setMchId(v3.getMchId());
|
||||||
|
|
||||||
|
profitSharingSModel.setTransactionId(profitSharingModel.getTransactionId());
|
||||||
|
profitSharingSModel.setOutOrderNo(profitSharingModel.getOutOrderNo());
|
||||||
|
|
||||||
|
profitSharingSModel.certPath(v3.getCertPath());
|
||||||
|
profitSharingSModel.signType("HMAC-SHA256");
|
||||||
|
return wechatV2Client.wechatPayRequest(profitSharingSModel,
|
||||||
|
HttpMethod.POST,
|
||||||
|
"https://api.mch.weixin.qq.com/secapi/pay/profitsharing");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求单次分账
|
||||||
|
*
|
||||||
|
* @param multiProfitSharingModel the multi profit sharing model
|
||||||
|
* @return json node
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public JsonNode multiProfitSharing(MultiProfitSharingModel multiProfitSharingModel) {
|
||||||
|
MultiProfitSharingSModel multiProfitSharingSModel = new MultiProfitSharingSModel();
|
||||||
|
List<Receiver> receivers = multiProfitSharingModel.getReceivers();
|
||||||
|
multiProfitSharingSModel.setReceivers(MAPPER.writeValueAsString(receivers));
|
||||||
|
|
||||||
|
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||||
|
multiProfitSharingSModel.setAppid(v3.getAppId());
|
||||||
|
multiProfitSharingSModel.setMchId(v3.getMchId());
|
||||||
|
|
||||||
|
multiProfitSharingSModel.setTransactionId(multiProfitSharingModel.getTransactionId());
|
||||||
|
multiProfitSharingSModel.setOutOrderNo(multiProfitSharingModel.getOutOrderNo());
|
||||||
|
|
||||||
|
multiProfitSharingSModel.certPath(v3.getCertPath());
|
||||||
|
multiProfitSharingSModel.signType("HMAC-SHA256");
|
||||||
|
return wechatV2Client.wechatPayRequest(multiProfitSharingSModel,
|
||||||
|
HttpMethod.POST,
|
||||||
|
"https://api.mch.weixin.qq.com/secapi/pay/multiprofitsharing");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询分账结果
|
||||||
|
*
|
||||||
|
* @param profitSharingQueryModel the profit sharing query model
|
||||||
|
* @return json node
|
||||||
|
*/
|
||||||
|
public JsonNode profitSharingQuery(ProfitSharingQueryModel profitSharingQueryModel) {
|
||||||
|
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||||
|
profitSharingQueryModel.setMchId(v3.getMchId());
|
||||||
|
profitSharingQueryModel.certPath(v3.getCertPath());
|
||||||
|
profitSharingQueryModel.signType("HMAC-SHA256");
|
||||||
|
return wechatV2Client.wechatPayRequest(profitSharingQueryModel,
|
||||||
|
HttpMethod.POST,
|
||||||
|
"https://api.mch.weixin.qq.com/pay/profitsharingquery");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加分账接收方
|
||||||
|
*
|
||||||
|
* @param profitSharingAddReceiverModel the profit sharing add receiver model
|
||||||
|
* @return json node
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public JsonNode profitSharingAddReceiver(ProfitSharingAddReceiverModel profitSharingAddReceiverModel) {
|
||||||
|
ProfitSharingAddReceiverSModel profitSharingAddReceiverSModel = new ProfitSharingAddReceiverSModel();
|
||||||
|
ProfitSharingAddReceiverModel.Receiver receiver = profitSharingAddReceiverModel.getReceiver();
|
||||||
|
profitSharingAddReceiverSModel.setReceiver(MAPPER.writeValueAsString(receiver));
|
||||||
|
|
||||||
|
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||||
|
profitSharingAddReceiverSModel.setAppid(v3.getAppId());
|
||||||
|
profitSharingAddReceiverSModel.setMchId(v3.getMchId());
|
||||||
|
|
||||||
|
profitSharingAddReceiverSModel.certPath(v3.getCertPath());
|
||||||
|
profitSharingAddReceiverSModel.signType("HMAC-SHA256");
|
||||||
|
return wechatV2Client.wechatPayRequest(profitSharingAddReceiverSModel,
|
||||||
|
HttpMethod.POST,
|
||||||
|
"https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除分账接收方
|
||||||
|
*
|
||||||
|
* @param profitSharingRemoveReceiverModel the profit sharing remove receiver model
|
||||||
|
* @return json node
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public JsonNode profitSharingRemoveReceiver(ProfitSharingRemoveReceiverModel profitSharingRemoveReceiverModel) {
|
||||||
|
ProfitSharingRemoveReceiverSModel profitSharingRemoveReceiverSModel = new ProfitSharingRemoveReceiverSModel();
|
||||||
|
ProfitSharingRemoveReceiverModel.Receiver receiver = profitSharingRemoveReceiverModel.getReceiver();
|
||||||
|
profitSharingRemoveReceiverSModel.setReceiver(MAPPER.writeValueAsString(receiver));
|
||||||
|
|
||||||
|
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||||
|
profitSharingRemoveReceiverSModel.setAppid(v3.getAppId());
|
||||||
|
profitSharingRemoveReceiverSModel.setMchId(v3.getMchId());
|
||||||
|
|
||||||
|
profitSharingRemoveReceiverSModel.certPath(v3.getCertPath());
|
||||||
|
profitSharingRemoveReceiverSModel.signType("HMAC-SHA256");
|
||||||
|
return wechatV2Client.wechatPayRequest(profitSharingRemoveReceiverSModel,
|
||||||
|
HttpMethod.POST,
|
||||||
|
"https://api.mch.weixin.qq.com/pay/profitsharingremovereceiver");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 完结分账
|
||||||
|
*
|
||||||
|
* @param profitSharingFinishModel the profit sharing finish model
|
||||||
|
* @return json node
|
||||||
|
*/
|
||||||
|
public JsonNode profitSharingFinish(ProfitSharingFinishModel profitSharingFinishModel) {
|
||||||
|
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||||
|
profitSharingFinishModel.setAppid(v3.getAppId());
|
||||||
|
profitSharingFinishModel.setMchId(v3.getMchId());
|
||||||
|
profitSharingFinishModel.certPath(v3.getCertPath());
|
||||||
|
profitSharingFinishModel.signType("HMAC-SHA256");
|
||||||
|
return wechatV2Client.wechatPayRequest(profitSharingFinishModel,
|
||||||
|
HttpMethod.POST,
|
||||||
|
"https://api.mch.weixin.qq.com/secapi/pay/profitsharingfinish");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询订单待分账金额
|
||||||
|
*
|
||||||
|
* @param profitSharingOrderAmountQueryModel the profit sharing order amount query model
|
||||||
|
* @return json node
|
||||||
|
*/
|
||||||
|
public JsonNode profitSharingOrderAmountQuery(ProfitSharingOrderAmountQueryModel profitSharingOrderAmountQueryModel) {
|
||||||
|
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||||
|
profitSharingOrderAmountQueryModel.setMchId(v3.getMchId());
|
||||||
|
profitSharingOrderAmountQueryModel.certPath(v3.getCertPath());
|
||||||
|
profitSharingOrderAmountQueryModel.signType("HMAC-SHA256");
|
||||||
|
return wechatV2Client.wechatPayRequest(profitSharingOrderAmountQueryModel,
|
||||||
|
HttpMethod.POST,
|
||||||
|
"https://api.mch.weixin.qq.com/pay/profitsharingorderamountquery");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账回退
|
||||||
|
*
|
||||||
|
* @param profitSharingReturnModel the profit sharing return model
|
||||||
|
* @return json node
|
||||||
|
*/
|
||||||
|
public JsonNode profitSharingReturn(ProfitSharingReturnModel profitSharingReturnModel) {
|
||||||
|
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||||
|
profitSharingReturnModel.setAppid(v3.getAppId());
|
||||||
|
profitSharingReturnModel.setMchId(v3.getMchId());
|
||||||
|
profitSharingReturnModel.certPath(v3.getCertPath());
|
||||||
|
profitSharingReturnModel.signType("HMAC-SHA256");
|
||||||
|
return wechatV2Client.wechatPayRequest(profitSharingReturnModel,
|
||||||
|
HttpMethod.POST,
|
||||||
|
"https://api.mch.weixin.qq.com/secapi/pay/profitsharingreturn");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回退结果查询
|
||||||
|
*
|
||||||
|
* @param profitSharingReturnQueryModel the profit sharing return query model
|
||||||
|
* @return json node
|
||||||
|
*/
|
||||||
|
public JsonNode profitSharingReturnQuery(ProfitSharingReturnQueryModel profitSharingReturnQueryModel) {
|
||||||
|
WechatPayProperties.V3 v3 = wechatV2Client.getWechatMetaBean().getV3();
|
||||||
|
profitSharingReturnQueryModel.setAppid(v3.getAppId());
|
||||||
|
profitSharingReturnQueryModel.setMchId(v3.getMchId());
|
||||||
|
profitSharingReturnQueryModel.certPath(v3.getCertPath());
|
||||||
|
profitSharingReturnQueryModel.signType("HMAC-SHA256");
|
||||||
|
return wechatV2Client.wechatPayRequest(profitSharingReturnQueryModel,
|
||||||
|
HttpMethod.POST,
|
||||||
|
"https://api.mch.weixin.qq.com/pay/profitsharingreturnquery");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -48,6 +48,8 @@ import org.springframework.util.IdGenerator;
|
|||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import javax.net.ssl.HostnameVerifier;
|
import javax.net.ssl.HostnameVerifier;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -84,13 +86,27 @@ public abstract class BaseModel {
|
|||||||
private String sign;
|
private String sign;
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private String appSecret;
|
private String appSecret;
|
||||||
|
@JsonIgnore
|
||||||
|
private String certPath;
|
||||||
|
@JsonIgnore
|
||||||
|
private String signType;
|
||||||
|
|
||||||
public BaseModel appSecret(String appSecret) {
|
public BaseModel appSecret(String appSecret) {
|
||||||
this.appSecret = appSecret;
|
this.appSecret = appSecret;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BaseModel certPath(String certPath) {
|
||||||
|
this.certPath = certPath;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public BaseModel signType(String signType) {
|
||||||
|
this.signType = signType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Xml string.
|
* Xml string.
|
||||||
*
|
*
|
||||||
@@ -99,7 +115,11 @@ public abstract class BaseModel {
|
|||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
private String xml() {
|
private String xml() {
|
||||||
String link = link(this);
|
String link = link(this);
|
||||||
this.sign = this.md5(link);
|
if ("HMAC-SHA256".equals(signType)) {
|
||||||
|
this.sign = this.hmacSha256(link);
|
||||||
|
} else {
|
||||||
|
this.sign = this.md5(link);
|
||||||
|
}
|
||||||
return XML_MAPPER.writer()
|
return XML_MAPPER.writer()
|
||||||
.withRootName("xml")
|
.withRootName("xml")
|
||||||
.writeValueAsString(this);
|
.writeValueAsString(this);
|
||||||
@@ -120,6 +140,21 @@ public abstract class BaseModel {
|
|||||||
return Hex.toHexString(md5Bytes).toUpperCase();
|
return Hex.toHexString(md5Bytes).toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hmacSha256.
|
||||||
|
*
|
||||||
|
* @param src the src
|
||||||
|
* @return the string
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
private String hmacSha256(String src) {
|
||||||
|
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
|
||||||
|
SecretKeySpec secret_key = new SecretKeySpec(appSecret.getBytes(),"HmacSHA256");
|
||||||
|
sha256_HMAC.init(secret_key);
|
||||||
|
byte[] bytes = sha256_HMAC.doFinal(src.getBytes(StandardCharsets.UTF_8));
|
||||||
|
return Hex.toHexString(bytes).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按照格式拼接参数以生成签名
|
* 按照格式拼接参数以生成签名
|
||||||
*
|
*
|
||||||
@@ -130,14 +165,13 @@ public abstract class BaseModel {
|
|||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
private <T> String link(T t) {
|
private <T> String link(T t) {
|
||||||
Assert.hasText(appSecret, "wechat pay appSecret is required");
|
Assert.hasText(appSecret, "wechat pay appSecret is required");
|
||||||
return OBJECT_MAPPER
|
String link = OBJECT_MAPPER
|
||||||
.writer()
|
.writer()
|
||||||
.writeValueAsString(t)
|
.writeValueAsString(t)
|
||||||
.replaceAll("\":\"", "=")
|
.replaceAll("\":\"", "=")
|
||||||
.replaceAll("\",\"", "&")
|
.replaceAll("\",\"", "&")
|
||||||
.replaceAll("\\{\"", "")
|
.replaceAll("\\\\\"", "\"");
|
||||||
.replaceAll("\"}", "")
|
return link.substring(2, link.length() - 2).concat("&key=").concat(this.appSecret);
|
||||||
.concat("&key=").concat(this.appSecret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -164,7 +198,7 @@ public abstract class BaseModel {
|
|||||||
private RestTemplate getRestTemplateClientAuthentication(String mchId)
|
private RestTemplate getRestTemplateClientAuthentication(String mchId)
|
||||||
throws IOException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException,
|
throws IOException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException,
|
||||||
KeyStoreException, KeyManagementException {
|
KeyStoreException, KeyManagementException {
|
||||||
ClassPathResource resource = new ClassPathResource("wechat/apiclient_cert.p12");
|
ClassPathResource resource = new ClassPathResource(certPath == null ? "wechat/apiclient_cert.p12" : certPath);
|
||||||
|
|
||||||
char[] pem = mchId.toCharArray();
|
char[] pem = mchId.toCharArray();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class BaseProfitSharingModel extends BaseModel {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户号.
|
||||||
|
* <p>
|
||||||
|
* 微信支付分配的商户号
|
||||||
|
*/
|
||||||
|
private String mchId;
|
||||||
|
private String appid;
|
||||||
|
private String transactionId;
|
||||||
|
private String outOrderNo;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class BaseProfitSharingReceiverModel extends BaseModel {
|
||||||
|
/**
|
||||||
|
* 商户号.
|
||||||
|
* <p>
|
||||||
|
* 微信支付分配的商户号
|
||||||
|
*/
|
||||||
|
private String mchId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众账号ID.
|
||||||
|
* <p>
|
||||||
|
* 微信分配的公众账号ID
|
||||||
|
*/
|
||||||
|
private String appid;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
public class MultiProfitSharingModel extends ProfitSharingModel {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
public class MultiProfitSharingSModel extends ProfitSharingSModel {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class ProfitSharingAddReceiverModel extends BaseProfitSharingReceiverModel {
|
||||||
|
|
||||||
|
private Receiver receiver;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Receiver {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账接收方类型.
|
||||||
|
* <p>
|
||||||
|
* MERCHANT_ID:商户号(mch_id或者sub_mch_id)
|
||||||
|
* PERSONAL_OPENID:个人openid
|
||||||
|
*/
|
||||||
|
private Type type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账接收方帐号.
|
||||||
|
* <p>
|
||||||
|
* 类型是MERCHANT_ID时,是商户号(mch_id或者sub_mch_id)
|
||||||
|
* 类型是PERSONAL_OPENID时,是个人openid
|
||||||
|
*/
|
||||||
|
private String account;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账接收方全称.
|
||||||
|
* <p>
|
||||||
|
* 分账接收方类型是MERCHANT_ID时,是商户全称(必传),当商户是小微商户或个体户时,是开户人姓名
|
||||||
|
* 分账接收方类型是PERSONAL_OPENID时,是个人姓名(选传,传则校验)
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与分账方的关系类型.
|
||||||
|
* <p>
|
||||||
|
* 子商户与接收方的关系。
|
||||||
|
* 本字段值为枚举:
|
||||||
|
* SERVICE_PROVIDER:服务商
|
||||||
|
* STORE:门店
|
||||||
|
* STAFF:员工
|
||||||
|
* STORE_OWNER:店主
|
||||||
|
* PARTNER:合作伙伴
|
||||||
|
* HEADQUARTER:总部
|
||||||
|
* BRAND:品牌方
|
||||||
|
* DISTRIBUTOR:分销商
|
||||||
|
* USER:用户
|
||||||
|
* SUPPLIER:供应商
|
||||||
|
* CUSTOM:自定义
|
||||||
|
*/
|
||||||
|
private RelationType relationType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义的分账关系.
|
||||||
|
* <p>
|
||||||
|
* 子商户与接收方具体的关系,本字段最多10个字。
|
||||||
|
* 当字段relation_type的值为CUSTOM时,本字段必填
|
||||||
|
* 当字段relation_type的值不为CUSTOM时,本字段无需填写
|
||||||
|
*/
|
||||||
|
private String customRelation;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class ProfitSharingAddReceiverSModel extends BaseProfitSharingReceiverModel {
|
||||||
|
|
||||||
|
private String receiver;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class ProfitSharingFinishModel extends BaseModel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户号.
|
||||||
|
* <p>
|
||||||
|
* 微信支付分配的商户号
|
||||||
|
*/
|
||||||
|
private String mchId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众账号ID.
|
||||||
|
* <p>
|
||||||
|
* 微信分配的公众账号ID
|
||||||
|
*/
|
||||||
|
private String appid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信订单号.
|
||||||
|
* <p>
|
||||||
|
* 微信支付订单号
|
||||||
|
*/
|
||||||
|
private String transactionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户分账单号.
|
||||||
|
* <p>
|
||||||
|
* 查询分账结果,输入申请分账时的商户分账单号; 查询分账完结执行的结果,输入发起分账完结时的商户分账单号
|
||||||
|
*/
|
||||||
|
private String outOrderNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账完结描述.
|
||||||
|
* <p>
|
||||||
|
* 分账完结的原因描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单次分账请求按照传入的分账接收方账号和资金进行分账,同时会将订单剩余的待分账金额解冻给本商户。
|
||||||
|
* 故操作成功后,订单不能再进行分账,也不能进行分账完结。
|
||||||
|
*
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class ProfitSharingModel extends BaseProfitSharingModel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账接收方列表,不超过50个json对象,不能设置分账方作为分账接受方
|
||||||
|
*/
|
||||||
|
private List<Receiver> receivers;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class ProfitSharingOrderAmountQueryModel extends BaseModel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户号.
|
||||||
|
* <p>
|
||||||
|
* 微信支付分配的商户号
|
||||||
|
*/
|
||||||
|
private String mchId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信订单号.
|
||||||
|
* <p>
|
||||||
|
* 微信支付订单号
|
||||||
|
*/
|
||||||
|
private String transactionId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class ProfitSharingQueryModel extends BaseModel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户号.
|
||||||
|
* <p>
|
||||||
|
* 微信支付分配的商户号
|
||||||
|
*/
|
||||||
|
private String mchId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信订单号.
|
||||||
|
* <p>
|
||||||
|
* 微信支付订单号
|
||||||
|
*/
|
||||||
|
private String transactionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户分账单号.
|
||||||
|
* <p>
|
||||||
|
* 查询分账结果,输入申请分账时的商户分账单号; 查询分账完结执行的结果,输入发起分账完结时的商户分账单号
|
||||||
|
*/
|
||||||
|
private String outOrderNo;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class ProfitSharingRemoveReceiverModel extends BaseProfitSharingReceiverModel {
|
||||||
|
|
||||||
|
private Receiver receiver;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Receiver {
|
||||||
|
|
||||||
|
private Type type;
|
||||||
|
private String account;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class ProfitSharingRemoveReceiverSModel extends BaseProfitSharingReceiverModel {
|
||||||
|
|
||||||
|
private String receiver;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class ProfitSharingReturnModel extends BaseModel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户号.
|
||||||
|
* <p>
|
||||||
|
* 微信支付分配的商户号
|
||||||
|
*/
|
||||||
|
private String mchId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众账号ID.
|
||||||
|
* <p>
|
||||||
|
* 微信分配的公众账号ID
|
||||||
|
*/
|
||||||
|
private String appid;
|
||||||
|
private String orderId;
|
||||||
|
private String outOrderNo;
|
||||||
|
private String outReturnNo;
|
||||||
|
private String returnAccountType;
|
||||||
|
private String returnAccount;
|
||||||
|
private String returnAmount;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.v2.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class ProfitSharingReturnQueryModel extends BaseModel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户号.
|
||||||
|
* <p>
|
||||||
|
* 微信支付分配的商户号
|
||||||
|
*/
|
||||||
|
private String mchId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众账号ID.
|
||||||
|
* <p>
|
||||||
|
* 微信分配的公众账号ID
|
||||||
|
*/
|
||||||
|
private String appid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信分账订单号.
|
||||||
|
* <p>
|
||||||
|
* 原发起分账请求时,微信返回的微信分账单号,与商户分账单号一一对应。
|
||||||
|
* 微信分账单号与商户分账单号二选一填写
|
||||||
|
*/
|
||||||
|
private String orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户分账单号.
|
||||||
|
* <p>
|
||||||
|
* 原发起分账请求时使用的商户系统内部的分账单号。
|
||||||
|
* 微信分账单号与商户分账单号二选一填写
|
||||||
|
*/
|
||||||
|
private String outOrderNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户回退单号.
|
||||||
|
* <p>
|
||||||
|
* 调用回退接口提供的商户系统内部的回退单号
|
||||||
|
*/
|
||||||
|
private String outReturnNo;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class ProfitSharingSModel extends BaseProfitSharingModel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账接收方列表,不超过50个json对象,不能设置分账方作为分账接受方。
|
||||||
|
*/
|
||||||
|
private String receivers;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Receiver {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账接收方类型.
|
||||||
|
* <p>
|
||||||
|
* MERCHANT_ID:商户号(mch_id或者sub_mch_id)
|
||||||
|
* PERSONAL_OPENID:个人openid
|
||||||
|
*/
|
||||||
|
private Type type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账接收方帐号.
|
||||||
|
* <p>
|
||||||
|
* 类型是MERCHANT_ID时,是商户号(mch_id或者sub_mch_id)
|
||||||
|
* 类型是PERSONAL_OPENID时,是个人openid
|
||||||
|
*/
|
||||||
|
private String account;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账金额.
|
||||||
|
* <p>
|
||||||
|
* 单位为分,只能为整数,不能超过原订单支付金额及最大分账比例金额
|
||||||
|
*/
|
||||||
|
private Integer amount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账描述.
|
||||||
|
* <p>
|
||||||
|
* 分账的原因描述,分账账单中需要体现
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账个人接收方姓名.
|
||||||
|
* <p>
|
||||||
|
* 可选项,在接收方类型为个人的时可选填,若有值,会检查与 name 是否实名匹配,不匹配会拒绝分账请求.
|
||||||
|
* 1、分账接收方类型是PERSONAL_OPENID时,是个人姓名(选传,传则校验)
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
public enum RelationType {
|
||||||
|
|
||||||
|
SERVICE_PROVIDER,
|
||||||
|
STORE,
|
||||||
|
STAFF,
|
||||||
|
STORE_OWNER,
|
||||||
|
PARTNER,
|
||||||
|
HEADQUARTER,
|
||||||
|
BRAND,
|
||||||
|
DISTRIBUTOR,
|
||||||
|
USER,
|
||||||
|
SUPPLIER,
|
||||||
|
CUSTOM
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package cn.felord.payment.wechat.v2.model.allocation;
|
||||||
|
|
||||||
|
public enum Type {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户号(mch_id或者sub_mch_id)
|
||||||
|
*/
|
||||||
|
MERCHANT_ID,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 个人openid
|
||||||
|
*/
|
||||||
|
PERSONAL_OPENID;
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package cn.felord.payment.wechat.v3;
|
package cn.felord.payment.wechat.v3;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.v2.WechatAllocationApi;
|
||||||
import cn.felord.payment.wechat.v2.WechatPayRedpackApi;
|
import cn.felord.payment.wechat.v2.WechatPayRedpackApi;
|
||||||
import cn.felord.payment.wechat.v2.WechatPayTransfersApi;
|
import cn.felord.payment.wechat.v2.WechatPayTransfersApi;
|
||||||
import cn.felord.payment.wechat.v2.WechatV2Client;
|
import cn.felord.payment.wechat.v2.WechatV2Client;
|
||||||
@@ -177,4 +178,19 @@ public class WechatApiProvider {
|
|||||||
return new WechatPayTransfersApi(wechatV2Client);
|
return new WechatPayTransfersApi(wechatV2Client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付分账,基于V2
|
||||||
|
*
|
||||||
|
* @param tenantId the tenant id
|
||||||
|
* @return wechat allocation api
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
public WechatAllocationApi allocationApi(String tenantId) {
|
||||||
|
WechatMetaBean wechatMeta = wechatPayClient.signatureProvider()
|
||||||
|
.wechatMetaContainer()
|
||||||
|
.getWechatMeta(tenantId);
|
||||||
|
WechatV2Client wechatV2Client = new WechatV2Client(wechatMeta);
|
||||||
|
return new WechatAllocationApi(wechatV2Client);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,27 @@ public class WechatPayCallback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付分账回调.
|
||||||
|
*
|
||||||
|
* @param params the params
|
||||||
|
* @param consumeDataConsumer the consume data consumer
|
||||||
|
* @return the map
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public Map<String, ?> profitSharingCallback(ResponseSignVerifyParams params, Consumer<ProfitSharingConsumeData> consumeDataConsumer) {
|
||||||
|
String data = this.callback(params, EventType.COUPON_USE);
|
||||||
|
ProfitSharingConsumeData consumeData = MAPPER.readValue(data, ProfitSharingConsumeData.class);
|
||||||
|
consumeDataConsumer.accept(consumeData);
|
||||||
|
Map<String, Object> responseBody = new HashMap<>(2);
|
||||||
|
responseBody.put("code", 200);
|
||||||
|
responseBody.put("message", "SUCCESS");
|
||||||
|
return responseBody;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信支付代金券核销回调.
|
* 微信支付代金券核销回调.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2019-2020 felord.cn
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Website:
|
||||||
|
* https://felord.cn
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package cn.felord.payment.wechat.v3.model;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.v2.model.allocation.Receiver;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付分账通知参数
|
||||||
|
*
|
||||||
|
* @since 1.0.10.RELEASE
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ProfitSharingConsumeData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直连商户号.
|
||||||
|
* <p>
|
||||||
|
* 直连模式分账发起和出资商户
|
||||||
|
*/
|
||||||
|
private String mchid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信订单号.
|
||||||
|
* <p>
|
||||||
|
* 微信支付订单号
|
||||||
|
*/
|
||||||
|
private String transactionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信分账/回退单号.
|
||||||
|
*/
|
||||||
|
private String orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户分账/回退单号.
|
||||||
|
* <p>
|
||||||
|
* 分账方系统内部的分账/回退单号
|
||||||
|
*/
|
||||||
|
private String outOrderNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分账接收方.
|
||||||
|
* <p>
|
||||||
|
* 分账接收方对象
|
||||||
|
*/
|
||||||
|
private Receiver receiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成功时间.
|
||||||
|
* <p>
|
||||||
|
* Rfc3339标准
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "GMT+8")
|
||||||
|
private OffsetDateTime successTime;
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user