diff --git a/docs/README.md b/docs/README.md
index 8134f5e..8ad18f7 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -44,4 +44,4 @@
## **免责声明**
-**本项目涉及到资金交易,开发者需要经严格测试后方能用于生产环境,本项目不对使用者的行为负责。**
\ No newline at end of file
+**本项目涉及到资金交易开发,开发者需要经严格测试后方能用于生产环境,本项目不对使用者的行为负责。**
\ No newline at end of file
diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java
index 7017f02..35c0c11 100644
--- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java
+++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java
@@ -10,6 +10,9 @@ import org.springframework.http.HttpMethod;
* @since 1.0.0.RELEASE
*/
public enum WechatPayV3Type {
+
+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
/**
* 获取证书.
*
@@ -24,6 +27,8 @@ public enum WechatPayV3Type {
*/
FILE_DOWNLOAD(HttpMethod.GET, "%s/v3/billdownload/file"),
+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
/**
* 微信公众号支付或者小程序支付.
*
@@ -70,6 +75,8 @@ public enum WechatPayV3Type {
*/
TRANSACTION_OUT_TRADE_NO(HttpMethod.GET, "%s/v3/pay/transactions/out-trade-no/{out_trade_no}"),
+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
/**
* 合单下单-APP支付API.
*
@@ -109,24 +116,32 @@ public enum WechatPayV3Type {
*/
COMBINE_CLOSE(HttpMethod.POST, "%s/v3/combine-transactions/out-trade-no/{combine_out_trade_no}/close"),
+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
/**
* 商户预授权API.
*
* @since 1.0.2.RELEASE
*/
PAY_SCORE_PERMISSIONS(HttpMethod.POST, "%s/v3/payscore/permissions"),
+ /**
+ * 创单结单合并API.
+ *
+ * @since 1.0.2.RELEASE
+ */
+ PAY_SCORE_DIRECT_COMPLETE(HttpMethod.POST, "%s/payscore/serviceorder/direct-complete"),
/**
* 查询与用户授权记录(授权协议号)API.
*
* @since 1.0.2.RELEASE
*/
- PAY_SCORE_QUEERY_PERMISSIONS_AUTHORIZATION_CODE(HttpMethod.GET, "%s/v3/payscore/permissions/authorization-code/{authorization_code}"),
+ PAY_SCORE_PERMISSIONS_AUTH_CODE(HttpMethod.GET, "%s/v3/payscore/permissions/authorization-code/{authorization_code}"),
/**
* 解除用户授权关系(授权协议号)API.
*
* @since 1.0.2.RELEASE
*/
- PAY_SCORE_TERMINATE_PERMISSIONS_AUTHORIZATION_CODE(HttpMethod.POST, "%s/v3/payscore/permissions/authorization-code/{authorization_code}/terminate"),
+ PAY_SCORE_TERMINATE_PERMISSIONS_AUTH_CODE(HttpMethod.POST, "%s/v3/payscore/permissions/authorization-code/{authorization_code}/terminate"),
/**
* 查询与用户授权记录(openid)API.
*
@@ -145,8 +160,6 @@ public enum WechatPayV3Type {
* @since 1.0.2.RELEASE
*/
PAY_SCORE_USER_SERVICE_STATE(HttpMethod.GET, "%s/v3/payscore/user-service-state?service_id={service_id}&appid={appid}&openid={openid}"),
-
-
/**
* 创建支付分订单API
*
@@ -190,6 +203,7 @@ public enum WechatPayV3Type {
*/
PAY_SCORE_SYNC_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder/{out_order_no}/sync"),
+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* 创建代金券批次API.
diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java
index 72bc8dc..2a15fb0 100644
--- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java
+++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java
@@ -2,7 +2,10 @@ package cn.felord.payment.wechat.v3;
import cn.felord.payment.PayException;
import cn.felord.payment.wechat.v3.model.*;
+import cn.felord.payment.wechat.v3.model.payscore.PayScoreUserConfirmConsumeData;
+import cn.felord.payment.wechat.v3.model.payscore.PayScoreUserPaidConsumeData;
import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import lombok.SneakyThrows;
@@ -19,7 +22,7 @@ import java.util.function.Consumer;
* 微信支付回调工具.
*
* 支付通知http应答码为200或204才会当作正常接收,当回调处理异常时,应答的HTTP状态码应为500,或者4xx。
- * TODO 微信支付分有三个回调通知
+ *
* @author felord.cn
* @since 1.0.0.RELEASE
*/
@@ -59,15 +62,16 @@ public class WechatPayCallback {
/**
* 微信支付代金券核销回调.
*
- * @param params the params
- * @param couponConsumeDataConsumer the coupon consume data consumer
+ * @param params the params
+ * @param consumeDataConsumer the consume data consumer
* @return the map
+ * @since 1.0.0.RELEASE
*/
@SneakyThrows
- public Map couponCallback(ResponseSignVerifyParams params, Consumer couponConsumeDataConsumer) {
- String data = callback(params, EventType.COUPON);
+ public Map couponCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) {
+ String data = this.callback(params, EventType.COUPON);
CouponConsumeData couponConsumeData = MAPPER.readValue(data, CouponConsumeData.class);
- couponConsumeDataConsumer.accept(couponConsumeData);
+ consumeDataConsumer.accept(couponConsumeData);
Map responseBody = new HashMap<>();
responseBody.put("code", 200);
responseBody.put("message", "SUCCESS");
@@ -80,15 +84,16 @@ public class WechatPayCallback {
*
* 无需开发者判断,只有扣款成功微信才会回调此接口
*
- * @param params the params
- * @param transactionConsumeDataConsumer the transaction consume data consumer
+ * @param params the params
+ * @param consumeDataConsumer the consume data consumer
* @return the map
+ * @since 1.0.0.RELEASE
*/
@SneakyThrows
- public Map transactionCallback(ResponseSignVerifyParams params, Consumer transactionConsumeDataConsumer) {
- String data = callback(params, EventType.TRANSACTION);
+ public Map transactionCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) {
+ String data = this.callback(params, EventType.TRANSACTION);
TransactionConsumeData transactionConsumeData = MAPPER.readValue(data, TransactionConsumeData.class);
- transactionConsumeDataConsumer.accept(transactionConsumeData);
+ consumeDataConsumer.accept(transactionConsumeData);
return Collections.singletonMap("code", "SUCCESS");
}
@@ -98,21 +103,74 @@ public class WechatPayCallback {
*
* 无需开发者判断,只有扣款成功微信才会回调此接口
*
- * @param params the params
- * @param combineTransactionConsumeDataConsumer the combine transaction consume data consumer
+ * @param params the params
+ * @param consumeDataConsumer the consume data consumer
* @return the map
+ * @since 1.0.0.RELEASE
*/
@SneakyThrows
- public Map combineTransactionCallback(ResponseSignVerifyParams params, Consumer combineTransactionConsumeDataConsumer) {
- String data = callback(params, EventType.TRANSACTION);
+ public Map combineTransactionCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) {
+ String data = this.callback(params, EventType.TRANSACTION);
CombineTransactionConsumeData combineTransactionConsumeData = MAPPER.readValue(data, CombineTransactionConsumeData.class);
- combineTransactionConsumeDataConsumer.accept(combineTransactionConsumeData);
+ consumeDataConsumer.accept(combineTransactionConsumeData);
return Collections.singletonMap("code", "SUCCESS");
}
+
/**
- * Callback string.
+ * 微信支付分确认订单回调通知.
+ *
+ * 该链接是通过商户[创建支付分订单]提交notify_url参数,必须为https协议。如果链接无法访问,商户将无法接收到微信通知。 通知url必须为直接可访问的url,不能携带参数。示例: “https://pay.weixin.qq.com/wxpay/pay.action”
+ *
+ * @param params the params
+ * @param consumeDataConsumer the consume data consumer
+ * @return the map
+ * @since 1.0.2.RELEASE
+ */
+ @SneakyThrows
+ public Map payscoreUserConfirmCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) {
+ String data = this.callback(params, EventType.PAYSCORE_USER_CONFIRM);
+ PayScoreUserConfirmConsumeData payScoreUserConfirmConsumeData = MAPPER.readValue(data, PayScoreUserConfirmConsumeData.class);
+ consumeDataConsumer.accept(payScoreUserConfirmConsumeData);
+ return Collections.singletonMap("code", "SUCCESS");
+ }
+
+ /**
+ * 微信支付分支付成功回调通知API.
+ *
+ * 请求URL:该链接是通过商户[创建支付分订单]提交notify_url参数,必须为https协议。如果链接无法访问,商户将无法接收到微信通知。 通知url必须为直接可访问的url,不能携带参数。示例: “https://pay.weixin.qq.com/wxpay/pay.action”
+ *
+ * @param params the params
+ * @param consumeDataConsumer the consume data consumer
+ * @return the map
+ * @since 1.0.2.RELEASE
+ */
+ @SneakyThrows
+ public Map payscoreUserPaidCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) {
+ String data = this.callback(params, EventType.PAYSCORE_USER_PAID);
+ PayScoreUserPaidConsumeData payScoreUserPaidConsumeData = MAPPER.readValue(data, PayScoreUserPaidConsumeData.class);
+ consumeDataConsumer.accept(payScoreUserPaidConsumeData);
+ return Collections.singletonMap("code", "SUCCESS");
+ }
+
+ /**
+ * Permission callback map.
+ *
+ * @param params the params
+ * @param consumeDataConsumer the consume data consumer
+ * @return the map
+ */
+ @SneakyThrows
+ public Map permissionCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) {
+
+
+ return Collections.singletonMap("code", "SUCCESS");
+ }
+
+
+ /**
+ * Callback.
*
* @param params the params
* @param eventType the event type
@@ -120,24 +178,48 @@ public class WechatPayCallback {
*/
@SneakyThrows
private String callback(ResponseSignVerifyParams params, EventType eventType) {
- if (signatureProvider.responseSignVerify(params)) {
- CallbackParams callbackParams = MAPPER.readValue(params.getBody(), CallbackParams.class);
+ CallbackParams callbackParams = resolve(params);
- if (!Objects.equals(callbackParams.getEventType(), eventType.event)) {
- log.error("wechat pay event type is not matched, callbackParams {}", callbackParams);
- throw new PayException(" wechat pay event type is not matched");
- }
- CallbackParams.Resource resource = callbackParams.getResource();
- String associatedData = resource.getAssociatedData();
- String nonce = resource.getNonce();
- String ciphertext = resource.getCiphertext();
- String data = signatureProvider.decryptResponseBody(tenantId, associatedData, nonce, ciphertext);
- Assert.hasText(data, "decryptData is required");
- return data;
+ if (!Objects.equals(callbackParams.getEventType(), eventType.event)) {
+ log.error("wechat pay event type is not matched, callbackParams {}", callbackParams);
+ throw new PayException(" wechat pay event type is not matched");
+ }
+ return decrypt(callbackParams);
+ }
+
+ /**
+ * Resolve callback params.
+ *
+ * @param params the params
+ * @return the callback params
+ * @throws JsonProcessingException the json processing exception
+ * @since 1.0.2.RELEASE
+ */
+ private CallbackParams resolve(ResponseSignVerifyParams params) throws JsonProcessingException {
+ if (signatureProvider.responseSignVerify(params)) {
+ return MAPPER.readValue(params.getBody(), CallbackParams.class);
}
throw new PayException("invalid wechat pay callback");
}
+ /**
+ * Decrypt.
+ *
+ * @param callbackParams the callback params
+ * @return the string
+ * @since 1.0.2.RELEASE
+ */
+ private String decrypt(CallbackParams callbackParams) {
+ CallbackParams.Resource resource = callbackParams.getResource();
+ String associatedData = resource.getAssociatedData();
+ String nonce = resource.getNonce();
+ String ciphertext = resource.getCiphertext();
+ String data = signatureProvider.decryptResponseBody(tenantId, associatedData, nonce, ciphertext);
+ Assert.hasText(data, "decryptData is required");
+ return data;
+ }
+
+
/**
* 事件类型用于处理回调.
*
@@ -145,12 +227,41 @@ public class WechatPayCallback {
* @since 1.0.0.RELEASE
*/
enum EventType {
+
+ /**
+ * 微信支付分确认订单事件.
+ *
+ * @since 1.0.2.RELEASE
+ */
+ PAYSCORE_USER_CONFIRM("PAYSCORE.USER_CONFIRM"),
+ /**
+ * 微信支付分用户支付成功订单事件.
+ *
+ * @since 1.0.2.RELEASE
+ */
+ PAYSCORE_USER_PAID("PAYSCORE.USER_PAID"),
+ /**
+ * 微信支付分授权事件.
+ *
+ * @since 1.0.2.RELEASE
+ */
+ PAYSCORE_USER_OPEN("PAYSCORE.USER_CLOSE_SERVICE"),
+ /**
+ * 微信支付分解除授权事件.
+ *
+ * @since 1.0.2.RELEASE
+ */
+ PAYSCORE_USER_CLOSE("PAYSCORE.USER_CLOSE_SERVICE"),
/**
* 优惠券核销事件.
+ *
+ * @since 1.0.0.RELEASE
*/
COUPON("COUPON.USE"),
/**
* 支付成功事件.
+ *
+ * @since 1.0.0.RELEASE
*/
TRANSACTION("TRANSACTION.SUCCESS");
diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java
index c541967..325ed31 100644
--- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java
+++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java
@@ -284,4 +284,168 @@ public class WechatPayScoreApi extends AbstractApi {
.request();
return wechatResponseEntity;
}
+
+ /**
+ * 创单结单合并API
+ *
+ * 相对需确认模式,免确认模式减少了用户确认授权这步操作,因此在免确认模式下商户无法获取用户的授权状态,为了解决商户的困扰,我们为免确认模式特别提供了查询授权状态和调起授权页面的api接口,这些接口仅在免确认模式下需要调用,且必须调用。
+ *
+ *
+ * 该接口适用于无需微信支付分做订单风控判断的业务场景,在服务完成后,通过该接口对用户进行免密代扣。
+ *
+ * 注意:
+ * • 限制条件:【免确认订单模式】,用户已授权状态下,可调用该接口。
+ *
+ *
+ * 特别提醒:创单结单合并接口暂未对外开放,如有需要请咨询对接的微信支付运营人员,申请开通调用权限。
+ *
+ * @param params the params
+ * @return the wechat response entity
+ */
+ public WechatResponseEntity directCompleteServiceOrder(DirectCompleteServiceOrderParams params) {
+ WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>();
+ this.client().withType(WechatPayV3Type.PAY_SCORE_DIRECT_COMPLETE, params)
+ .function((wechatPayV3Type, orderParams) -> {
+ URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
+ .build()
+ .toUri();
+
+ WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
+ orderParams.setAppid(v3.getAppId());
+ String notifyUrl = orderParams.getNotifyUrl();
+ if (StringUtils.hasText(notifyUrl)) {
+ orderParams.setNotifyUrl(v3.getDomain().concat(notifyUrl));
+ }
+ return Post(uri, orderParams);
+ })
+ .consumer(wechatResponseEntity::convert)
+ .request();
+ return wechatResponseEntity;
+ }
+
+ /**
+ * 商户预授权API
+ *
+ * @param params the params
+ * @return the wechat response entity
+ */
+ public WechatResponseEntity permissions(ServiceOrderPermissionParams params) {
+ WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>();
+ this.client().withType(WechatPayV3Type.PAY_SCORE_PERMISSIONS, params)
+ .function((wechatPayV3Type, orderParams) -> {
+ URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
+ .build()
+ .toUri();
+
+ WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
+ String notifyUrl = orderParams.getNotifyUrl();
+ orderParams.setAppid(v3.getAppId());
+ if (StringUtils.hasText(notifyUrl)) {
+ orderParams.setNotifyUrl(v3.getDomain().concat(notifyUrl));
+ }
+ return Post(uri, orderParams);
+ })
+ .consumer(wechatResponseEntity::convert)
+ .request();
+ return wechatResponseEntity;
+ }
+
+
+ /**
+ * 查询与用户授权记录(授权协议号)API
+ *
+ * 通过authorization_code,商户查询与用户授权关系
+ *
+ * @param params the params
+ * @return the wechat response entity
+ */
+ public WechatResponseEntity queryPermissionsByAuthCode(PermissionsAuthCodeParams params) {
+ WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>();
+ this.client().withType(WechatPayV3Type.PAY_SCORE_PERMISSIONS_AUTH_CODE, params)
+ .function((wechatPayV3Type, orderParams) -> {
+ URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
+ .queryParam("service_id", orderParams.getServiceId())
+ .build()
+ .expand(orderParams.getAuthorizationCode())
+ .toUri();
+
+ return Get(uri);
+ })
+ .consumer(wechatResponseEntity::convert)
+ .request();
+ return wechatResponseEntity;
+ }
+
+ /**
+ * 解除用户授权关系(授权协议号)API
+ *
+ * 通过authorization_code,商户解除用户授权关系
+ *
+ * @param params the params
+ * @return the wechat response entity
+ */
+ public WechatResponseEntity terminatePermissionsByAuthCode(PermissionsAuthCodeParams params) {
+ WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>();
+ this.client().withType(WechatPayV3Type.PAY_SCORE_TERMINATE_PERMISSIONS_AUTH_CODE, params)
+ .function((wechatPayV3Type, orderParams) -> {
+ URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
+ .build()
+ .expand(orderParams.getAuthorizationCode())
+ .toUri();
+ orderParams.setAuthorizationCode(null);
+ return Post(uri, orderParams);
+ })
+ .consumer(wechatResponseEntity::convert)
+ .request();
+ return wechatResponseEntity;
+ }
+
+ /**
+ * 查询与用户授权记录(openid)API
+ *
+ * @param params the params
+ * @return the wechat response entity
+ */
+ public WechatResponseEntity queryPermissionsByOpenId(PermissionsOpenIdParams params) {
+ WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>();
+ this.client().withType(WechatPayV3Type.PAY_SCORE_PERMISSIONS_OPENID, params)
+ .function((wechatPayV3Type, orderParams) -> {
+ WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
+ URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
+ .queryParam("appid", v3.getAppId())
+ .queryParam("service_id", orderParams.getServiceId())
+ .build()
+ .expand(orderParams.getOpenid())
+ .toUri();
+ return Get(uri);
+ })
+ .consumer(wechatResponseEntity::convert)
+ .request();
+ return wechatResponseEntity;
+ }
+
+ /**
+ * 解除用户授权关系(openid)API
+ *
+ * @param params the params
+ * @return the wechat response entity
+ */
+ public WechatResponseEntity terminatePermissionsByOpenId(PermissionsOpenIdParams params) {
+ WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>();
+ this.client().withType(WechatPayV3Type.PAY_SCORE_PERMISSIONS_OPENID, params)
+ .function((wechatPayV3Type, orderParams) -> {
+
+ URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
+ .build()
+ .expand(orderParams.getOpenid())
+ .toUri();
+ WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
+ orderParams.setAppid(v3.getAppId());
+ orderParams.setOpenid(null);
+ return Post(uri, orderParams);
+ })
+ .consumer(wechatResponseEntity::convert)
+ .request();
+ return wechatResponseEntity;
+ }
}
diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/DirectCompleteServiceOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/DirectCompleteServiceOrderParams.java
new file mode 100644
index 0000000..94f2613
--- /dev/null
+++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/DirectCompleteServiceOrderParams.java
@@ -0,0 +1,71 @@
+package cn.felord.payment.wechat.v3.model.payscore;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 创单结单合并API请求参数
+ *
+ * @author felord.cn
+ * @since 1.0.2.RELEASE
+ */
+@Data
+public class DirectCompleteServiceOrderParams {
+ /**
+ * The Appid.
+ */
+ private String appid;
+ /**
+ * The Attach.
+ */
+ private String attach;
+ /**
+ * The Goods tag.
+ */
+ private String goodsTag;
+ /**
+ * The Location.
+ */
+ private Location location;
+ /**
+ * The Notify url.
+ */
+ private String notifyUrl;
+ /**
+ * The Openid.
+ */
+ private String openid;
+ /**
+ * The Out order no.
+ */
+ private String outOrderNo;
+ /**
+ * The Post discounts.
+ */
+ private List postDiscounts;
+ /**
+ * The Post payments.
+ */
+ private List postPayments;
+ /**
+ * The Profit sharing.
+ */
+ private Boolean profitSharing;
+ /**
+ * The Service id.
+ */
+ private String serviceId;
+ /**
+ * The Service introduction.
+ */
+ private String serviceIntroduction;
+ /**
+ * The Time range.
+ */
+ private TimeRange timeRange;
+ /**
+ * The Total amount.
+ */
+ private Long totalAmount;
+}
diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserConfirmConsumeData.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserConfirmConsumeData.java
new file mode 100644
index 0000000..56625fb
--- /dev/null
+++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserConfirmConsumeData.java
@@ -0,0 +1,80 @@
+package cn.felord.payment.wechat.v3.model.payscore;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 微信支付分用户确认订单回调解密.
+ *
+ * @author felord.cn
+ * @since 1.0.2.RELEASE
+ */
+@Data
+public class PayScoreUserConfirmConsumeData {
+
+ /**
+ * The Appid.
+ */
+ private String appid;
+ /**
+ * The Attach.
+ */
+ private String attach;
+ /**
+ * The Location.
+ */
+ private Location location;
+ /**
+ * The Mchid.
+ */
+ private String mchid;
+ /**
+ * The Openid.
+ */
+ private String openid;
+ /**
+ * The Order id.
+ */
+ private String orderId;
+ /**
+ * The Out order no.
+ */
+ private String outOrderNo;
+ /**
+ * The Post discounts.
+ */
+ private List postDiscounts;
+ /**
+ * The Post payments.
+ */
+ private List postPayments;
+ /**
+ * The Risk fund.
+ */
+ private RiskFund riskFund;
+ /**
+ * The Service id.
+ */
+ private String serviceId;
+ /**
+ * The Service introduction.
+ */
+ private String serviceIntroduction;
+ /**
+ * The State.
+ */
+ private String state;
+ /**
+ * The State description.
+ */
+ private String stateDescription;
+ /**
+ * The Time range.
+ */
+ private TimeRange timeRange;
+ /**
+ * The Total amount.
+ */
+ private String totalAmount;
+}
diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserPaidConsumeData.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserPaidConsumeData.java
new file mode 100644
index 0000000..9f6e6d1
--- /dev/null
+++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserPaidConsumeData.java
@@ -0,0 +1,87 @@
+package cn.felord.payment.wechat.v3.model.payscore;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 微信支付分支付成功回调解密
+ *
+ * @author felord.cn
+ * @since 1.0.2.RELEASE
+ */
+@Data
+public class PayScoreUserPaidConsumeData {
+ /**
+ * The Appid.
+ */
+ private String appid;
+ /**
+ * The Attach.
+ */
+ private String attach;
+ /**
+ * The Collection.
+ */
+ private PaymentCollection collection;
+ /**
+ * The Location.
+ */
+ private Location location;
+ /**
+ * The Mchid.
+ */
+ private String mchid;
+ /**
+ * The Need collection.
+ */
+ private Boolean needCollection;
+ /**
+ * The Notify url.
+ */
+ private String notifyUrl;
+ /**
+ * The Openid.
+ */
+ private String openid;
+ /**
+ * The Order id.
+ */
+ private String orderId;
+ /**
+ * The Out order no.
+ */
+ private String outOrderNo;
+ /**
+ * The Post discounts.
+ */
+ private List postDiscounts;
+ /**
+ * The Post payments.
+ */
+ private List postPayments;
+ /**
+ * The Risk fund.
+ */
+ private RiskFund riskFund;
+ /**
+ * The Service id.
+ */
+ private String serviceId;
+ /**
+ * The Service introduction.
+ */
+ private String serviceIntroduction;
+ /**
+ * The State.
+ */
+ private String state;
+ /**
+ * The Time range.
+ */
+ private TimeRange timeRange;
+ /**
+ * The Total amount.
+ */
+ private String totalAmount;
+}
diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PaymentCollection.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PaymentCollection.java
new file mode 100644
index 0000000..924ae7f
--- /dev/null
+++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PaymentCollection.java
@@ -0,0 +1,74 @@
+
+package cn.felord.payment.wechat.v3.model.payscore;
+
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 微信支付分支付成功回调,收款信息,非0元完结后返回
+ *
+ * @author felord.cn
+ * @since 1.0.2.RELEASE
+ */
+@Data
+public class PaymentCollection {
+
+ /**
+ * The Details.
+ */
+ private List details;
+ /**
+ * The Paid amount.
+ */
+ private Long paidAmount;
+ /**
+ * The Paying amount.
+ */
+ private Long payingAmount;
+ /**
+ * The State.
+ */
+ private String state;
+ /**
+ * The Total amount.
+ */
+ private Long totalAmount;
+
+ /**
+ * 收款明细列表
+ *
+ * @author felord.cn
+ * @since 1.0.2.RELEASE
+ */
+ @Data
+ public static class Detail {
+
+ /**
+ * The Amount.
+ */
+ private Long amount;
+ /**
+ * The Paid time.
+ */
+ private String paidTime;
+ /**
+ * The Paid type.
+ */
+ private String paidType;
+ /**
+ * The Promotion detail.
+ */
+ private List promotionDetail;
+ /**
+ * The Seq.
+ */
+ private Long seq;
+ /**
+ * The Transaction id.
+ */
+ private String transactionId;
+
+ }
+}
diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsAuthCodeParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsAuthCodeParams.java
new file mode 100644
index 0000000..e531903
--- /dev/null
+++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsAuthCodeParams.java
@@ -0,0 +1,29 @@
+package cn.felord.payment.wechat.v3.model.payscore;
+
+import lombok.Data;
+
+/**
+ * 适用于以下API:
+ *
+ * 查询与用户授权记录(授权协议号)API
+ *
+ * 解除用户授权关系(授权协议号)API
+ *
+ * @author felord.cn
+ * @since 1.0.2.RELEASE
+ */
+@Data
+public class PermissionsAuthCodeParams {
+ /**
+ * 服务ID,必填
+ */
+ private String serviceId;
+ /**
+ * 授权协议号,必填
+ */
+ private String authorizationCode;
+ /**
+ * 仅仅适用于解除用户授权关系(授权协议号)API
+ */
+ private String reason;
+}
diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsOpenIdParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsOpenIdParams.java
new file mode 100644
index 0000000..2497484
--- /dev/null
+++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsOpenIdParams.java
@@ -0,0 +1,35 @@
+package cn.felord.payment.wechat.v3.model.payscore;
+
+import lombok.Data;
+
+/**
+ * 适用于以下API:
+ *
+ * 查询与用户授权记录(openid)API
+ *
+ * 解除用户授权关系(openid)API
+ *
+ * @author felord.cn
+ * @since 1.0.2.RELEASE
+ */
+@Data
+public class PermissionsOpenIdParams {
+ /**
+ * openid,必填
+ */
+ private String openid;
+ /**
+ * 仅仅适用于解除用户授权关系(openid)API
+ */
+ private String appid;
+ /**
+ * 服务ID,必填
+ *
+ * 该服务ID有本接口对应产品的权限。
+ */
+ private String serviceId;
+ /**
+ * 仅仅适用于解除用户授权关系(openid)API
+ */
+ private String reason;
+}
diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PromotionDetail.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PromotionDetail.java
new file mode 100644
index 0000000..c513ed7
--- /dev/null
+++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PromotionDetail.java
@@ -0,0 +1,93 @@
+
+package cn.felord.payment.wechat.v3.model.payscore;
+
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 微信支付分支付成功回调,优惠功能
+ *
+ * 注:针对2020年5月27日10:00:00以后完结的订单生效
+ *
+ * @author felord.cn
+ * @since 1.0.2.RELEASE
+ */
+@Data
+public class PromotionDetail {
+
+ /**
+ * The Amount.
+ */
+ private Long amount;
+ /**
+ * The Coupon id.
+ */
+ private String couponId;
+ /**
+ * The Currency.
+ */
+ private String currency;
+ /**
+ * The Goods detail.
+ */
+ private List goodsDetail;
+ /**
+ * The Merchant contribute.
+ */
+ private Long merchantContribute;
+ /**
+ * The Name.
+ */
+ private String name;
+ /**
+ * The Other contribute.
+ */
+ private Long otherContribute;
+ /**
+ * The Scope.
+ */
+ private String scope;
+ /**
+ * The Stock id.
+ */
+ private String stockId;
+ /**
+ * The Type.
+ */
+ private String type;
+ /**
+ * The Wechatpay contribute.
+ */
+ private Long wechatpayContribute;
+
+ /**
+ * The type Goods detail.
+ */
+ @Data
+ public static class GoodsDetail {
+
+ /**
+ * The Discount amount.
+ */
+ private Long discountAmount;
+ /**
+ * The Goods id.
+ */
+ private String goodsId;
+ /**
+ * The Goods remark.
+ */
+ private String goodsRemark;
+ /**
+ * The Quantity.
+ */
+ private Long quantity;
+ /**
+ * The Unit price.
+ */
+ private Long unitPrice;
+
+ }
+}
diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ServiceOrderPermissionParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ServiceOrderPermissionParams.java
new file mode 100644
index 0000000..c6d9e96
--- /dev/null
+++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ServiceOrderPermissionParams.java
@@ -0,0 +1,34 @@
+
+package cn.felord.payment.wechat.v3.model.payscore;
+
+import lombok.Data;
+
+/**
+ * 商户预授权API请求参数
+ *
+ * @author felord.cn
+ * @since 1.0.2.RELEASE
+ */
+@Data
+public class ServiceOrderPermissionParams {
+
+ /**
+ * 服务id,必填
+ */
+ private String serviceId;
+ /**
+ * 服务商申请的公众号或移动应用APPID,必填
+ */
+ private String appid;
+ /**
+ * 授权协议号,必填
+ *
+ * 预授权成功时的授权协议号,要求此参数只能由数字、大小写字母_-*组成,且在同一个商户号下唯一。详见[商户订单号]。
+ */
+ private String authorizationCode;
+ /**
+ * 商户接收授权回调通知的地址,选填
+ */
+ private String notifyUrl;
+
+}