From a3b595a8dd0a0c660617433dd9dd82d14cc07118 Mon Sep 17 00:00:00 2001 From: xiafang Date: Tue, 15 Dec 2020 19:20:46 +0800 Subject: [PATCH] wechat pay score api --- .../wechat/enumeration/WechatPayV3Type.java | 56 ++++++++ .../payment/wechat/v3/SignatureProvider.java | 29 ++-- .../payment/wechat/v3/WechatPayCallback.java | 2 +- .../payment/wechat/v3/WechatPayScoreApi.java | 135 +++++++++++++++++- .../payscore/CompleteServiceOrderParams.java | 94 ++++++++++++ .../payscore/ModifyServiceOrderParams.java | 53 +++++++ .../model/payscore/PayServiceOrderParams.java | 30 ++++ .../v3/model/payscore/PostDiscount.java | 5 + .../wechat/v3/model/payscore/PostPayment.java | 4 +- .../wechat/v3/model/payscore/RiskFund.java | 2 +- .../payscore/SyncServiceOrderParams.java | 64 +++++++++ ...arams.java => UserServiceOrderParams.java} | 2 +- 12 files changed, 447 insertions(+), 29 deletions(-) create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/CompleteServiceOrderParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ModifyServiceOrderParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayServiceOrderParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/SyncServiceOrderParams.java rename payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/{UserPayScoreOrderParams.java => UserServiceOrderParams.java} (98%) 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 6131821..7017f02 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 @@ -109,12 +109,44 @@ 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_QUEERY_PERMISSIONS_AUTHORIZATION_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"), + /** + * 查询与用户授权记录(openid)API. + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_PERMISSIONS_OPENID(HttpMethod.GET, "%s/v3/payscore/permissions/openid/{openid}"), + /** + * 解除用户授权关系(openid)API. + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_TERMINATE_PERMISSIONS_OPENID(HttpMethod.POST, "%s/v3/payscore/permissions/openid/{openid}/terminate"), /** * 查询用户授权状态API. * * @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 * @@ -133,6 +165,30 @@ public enum WechatPayV3Type { * @since 1.0.2.RELEASE */ PAY_SCORE_CANCEL_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder/{out_order_no}/cancel"), + /** + * 修改订单金额API + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_MODIFY_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder/{out_order_no}/modify"), + /** + * 完结支付分订单API + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_COMPLETE_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder/{out_order_no}/complete"), + /** + * 商户发起催收扣款API + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_PAY_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder/{out_order_no}/pay"), + /** + * 同步服务订单信息API + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_SYNC_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder/{out_order_no}/sync"), /** diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java index a3e9980..b69182e 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java @@ -86,7 +86,7 @@ public class SignatureProvider { /** - * 我方请求时加签,使用API证书. + * 我方请求前用 SHA256withRSA 加签,使用API证书. * * @param tenantId the properties key * @param method the method @@ -95,7 +95,7 @@ public class SignatureProvider { * @return the string */ @SneakyThrows - public String requestSign(String tenantId,String method, String canonicalUrl, String body) { + public String requestSign(String tenantId, String method, String canonicalUrl, String body) { Signature signer = Signature.getInstance("SHA256withRSA"); WechatMetaBean wechatMetaBean = wechatMetaContainer.getWechatMeta(tenantId); signer.initSign(wechatMetaBean.getKeyPair().getPrivate()); @@ -160,7 +160,7 @@ public class SignatureProvider { } // 签名 HttpMethod httpMethod = WechatPayV3Type.CERT.method(); - String authorization = requestSign(tenantId,httpMethod.name(), canonicalUrl, ""); + String authorization = requestSign(tenantId, httpMethod.name(), canonicalUrl, ""); HttpHeaders headers = new HttpHeaders(); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); @@ -177,30 +177,27 @@ public class SignatureProvider { ArrayNode certificates = bodyObjectNode.withArray("data"); if (certificates.isArray() && certificates.size() > 0) { CERTIFICATE_MAP.clear(); - final CertificateFactory cf = CertificateFactory.getInstance("X509"); + final CertificateFactory certificateFactory = CertificateFactory.getInstance("X509"); certificates.forEach(objectNode -> { JsonNode encryptCertificate = objectNode.get("encrypt_certificate"); String associatedData = encryptCertificate.get("associated_data").asText(); String nonce = encryptCertificate.get("nonce").asText(); String ciphertext = encryptCertificate.get("ciphertext").asText(); - String publicKey = decryptResponseBody(tenantId,associatedData, nonce, ciphertext); + String publicKey = decryptResponseBody(tenantId, associatedData, nonce, ciphertext); ByteArrayInputStream inputStream = new ByteArrayInputStream(publicKey.getBytes(StandardCharsets.UTF_8)); - Certificate certificate = null; + try { - certificate = cf.generateCertificate(inputStream); + Certificate certificate = certificateFactory.generateCertificate(inputStream); + String responseSerialNo = objectNode.get("serial_no").asText(); + CERTIFICATE_MAP.put(responseSerialNo, certificate); } catch (CertificateException e) { - e.printStackTrace(); + throw new PayException("An error occurred while generating the wechat v3 certificate, reason : " + e.getMessage()); } - String responseSerialNo = objectNode.get("serial_no").asText(); - CERTIFICATE_MAP.put(responseSerialNo, certificate); }); - } - } - /** * 解密响应体. * @@ -210,7 +207,7 @@ public class SignatureProvider { * @param ciphertext the ciphertext * @return the string */ - public String decryptResponseBody(String tenantId,String associatedData, String nonce, String ciphertext) { + public String decryptResponseBody(String tenantId, String associatedData, String nonce, String ciphertext) { try { Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); String apiV3Key = wechatMetaContainer.getWechatMeta(tenantId).getV3().getAppV3Secret(); @@ -233,7 +230,6 @@ public class SignatureProvider { } } - /** * Wechat meta container. * @@ -249,10 +245,9 @@ public class SignatureProvider { * @param components the components * @return string string */ - private String createSign(String... components) { + private static String createSign(String... components) { return Arrays.stream(components) .collect(Collectors.joining("\n", "", "\n")); } - } 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 f38b7e1..72bc8dc 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 @@ -19,7 +19,7 @@ import java.util.function.Consumer; * 微信支付回调工具. *

* 支付通知http应答码为200或204才会当作正常接收,当回调处理异常时,应答的HTTP状态码应为500,或者4xx。 - * + * TODO 微信支付分有三个回调通知 * @author felord.cn * @since 1.0.0.RELEASE */ 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 ce3017b..c541967 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 @@ -3,10 +3,7 @@ package cn.felord.payment.wechat.v3; import cn.felord.payment.wechat.WechatPayProperties; import cn.felord.payment.wechat.enumeration.WeChatServer; import cn.felord.payment.wechat.enumeration.WechatPayV3Type; -import cn.felord.payment.wechat.v3.model.payscore.CancelServiceOrderParams; -import cn.felord.payment.wechat.v3.model.payscore.QueryServiceOrderParams; -import cn.felord.payment.wechat.v3.model.payscore.UserPayScoreOrderParams; -import cn.felord.payment.wechat.v3.model.payscore.UserServiceStateParams; +import cn.felord.payment.wechat.v3.model.payscore.*; import com.fasterxml.jackson.databind.node.ObjectNode; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -72,7 +69,7 @@ public class WechatPayScoreApi extends AbstractApi { * @param params the params * @return the wechat response entity */ - public WechatResponseEntity createServiceOrder(UserPayScoreOrderParams params) { + public WechatResponseEntity createServiceOrder(UserServiceOrderParams params) { WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); this.client().withType(WechatPayV3Type.PAY_SCORE_CREATE_USER_SERVICE_ORDER, params) .function((wechatPayV3Type, orderParams) -> { @@ -147,16 +144,140 @@ public class WechatPayScoreApi extends AbstractApi { WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); this.client().withType(WechatPayV3Type.PAY_SCORE_CANCEL_USER_SERVICE_ORDER, params) .function((wechatPayV3Type, orderParams) -> { - URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) .build() .expand(orderParams.getOutOrderNo()) .toUri(); - orderParams.setOutOrderNo(null); WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); orderParams.setAppid(v3.getAppId()); + orderParams.setOutOrderNo(null); + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + /** + * 修改订单金额API + *

+ * 完结订单总金额与实际金额不符时,可通过该接口修改订单金额。 + * 例如:充电宝场景,由于机器计费问题导致商户完结订单时扣除用户99元,用户客诉成功后,商户需要按照实际的消费金额(如10元)扣费,当服务订单支付状态处于“待支付”时,商户可使用此能力修改订单金额。 + *

+ * 注意: + * • 若此笔订单已收款成功,商户直接使用退款能力,将差价退回用户即可。 + *

+ * • 修改次数>=1,第n次修改后金额 <第n-1次修改后金额 + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity modifyServiceOrder(ModifyServiceOrderParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_MODIFY_USER_SERVICE_ORDER, params) + .function((wechatPayV3Type, orderParams) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .expand(orderParams.getOutOrderNo()) + .toUri(); + + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + orderParams.setAppid(v3.getAppId()); + orderParams.setOutOrderNo(null); + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 完结支付分订单API + *

+ * 前置条件:服务订单状态为“进行中”且订单状态说明需为[USER_CONFIRM:用户确认] + *

+ * 完结微信支付分订单。用户使用服务完成后,商户可通过此接口完结订单。 + *

+ * 特别说明: + * • 完结接口调用成功后,微信支付将自动发起免密代扣。 若扣款失败,微信支付将自动再次发起免密代扣(按照一定频次),直到扣成功为止。 + * + * @param params the params + * @return wechat response entity + */ + public WechatResponseEntity completeServiceOrder(CompleteServiceOrderParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_COMPLETE_USER_SERVICE_ORDER, params) + .function((wechatPayV3Type, orderParams) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .expand(orderParams.getOutOrderNo()) + .toUri(); + + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + orderParams.setAppid(v3.getAppId()); + orderParams.setOutOrderNo(null); + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 商户发起催收扣款API + *

+ * 前置条件:服务订单支付状态处于“待支付”状态 + *

+ * 当微信支付分订单支付状态处于“待支付”时,商户可使用该接口向用户发起收款。 + *

+ * 注意: + * • 此能力不影响微信支付分代商户向用户发起收款的策略。 + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity payServiceOrder(PayServiceOrderParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_PAY_USER_SERVICE_ORDER, params) + .function((wechatPayV3Type, orderParams) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .expand(orderParams.getOutOrderNo()) + .toUri(); + + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + orderParams.setAppid(v3.getAppId()); + orderParams.setOutOrderNo(null); + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 同步服务订单信息API + *

+ * 前提条件:同步商户渠道收款成功信息时,即场景类型=“Order_Paid”,订单的状态需为[MCH_COMPLETE:商户完结订单] + *

+ * 由于收款商户进行的某些“线下操作”会导致微信支付侧的订单状态与实际情况不符。例如,用户通过线下付款的方式已经完成支付,而微信支付侧并未支付成功,此时可能导致用户重复支付。因此商户需要通过订单同步接口将订单状态同步给微信支付,修改订单在微信支付系统中的状态。 + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity syncServiceOrder(SyncServiceOrderParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_SYNC_USER_SERVICE_ORDER, params) + .function((wechatPayV3Type, orderParams) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .expand(orderParams.getOutOrderNo()) + .toUri(); + + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + orderParams.setAppid(v3.getAppId()); + orderParams.setOutOrderNo(null); return Post(uri, orderParams); }) .consumer(wechatResponseEntity::convert) diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/CompleteServiceOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/CompleteServiceOrderParams.java new file mode 100644 index 0000000..93380bd --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/CompleteServiceOrderParams.java @@ -0,0 +1,94 @@ +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 CompleteServiceOrderParams { + + /** + * 商户服务订单号,必填 + *

+ * 商户系统内部服务订单号(不是交易单号),要求此参数只能由数字、大小写字母_-|*组成,且在同一个商户号下唯一。详见[商户订单号]。 + */ + private String outOrderNo; + /** + * 与传入的商户号建立了支付绑定关系的appid,必填 + */ + private String appid; + /** + * 服务ID,必填 + *

+ * 该服务ID有本接口对应产品的权限。 + */ + private String serviceId; + /** + * 后付费项目,必填 + */ + private List postPayments; + /** + * 后付费商户优惠,选填 + */ + private List postDiscounts; + /** + * 总金额,单位分,必填 + *

+ * 不能超过完结订单时候的总金额,只能为整数,详见 支付金额。此参数需满足:总金额 =(修改后付费项目1…+修改后完结付费项目n)-(修改 后付费商户优惠项目1…+修改后付费商户优惠项目n) + */ + private Long totalAmount; + /** + * 服务时间段,条件选填 + *

+ * 服务时间范围,创建订单未填写服务结束时间,则完结的时候,服务结束时间必填 + * 如果传入,用户侧则显示此参数。 + */ + private TimeRange timeRange; + /** + * 服务位置,选填 + */ + private CompleteLocation location; + /** + * 微信支付服务分账标记,选填 + *

+ * 完结订单分账接口标记。分账开通流程,详见 分账 + * false:不分账,默认:false + * true:分账。 + */ + private Boolean profitSharing = Boolean.TRUE; + /** + * 订单优惠标记,选填 + *

+ * 代金券或立减金优惠的参数,说明详见代金券或立减金优惠 + */ + private String goods_tag; + + + /** + * 服务位置信息 + *

+ * 如果传入,用户侧则显示此参数。 + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ + @Data + public static class CompleteLocation { + + /** + * 预计服务结束地点,条件选填。 + *

+ * 结束使用服务的地点,不超过50个字符,超出报错处理 。 创建订单传入了【服务开始地点】,此项才能填写 + * 【建议】 + * 1、预计结束地点为空时,实际结束地点与开始地点相同,不填写 + * 2、预计结束地点不为空时,实际结束地点与预计结束地点相同,不填写 + */ + private String endLocation; + } +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ModifyServiceOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ModifyServiceOrderParams.java new file mode 100644 index 0000000..f7b3816 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ModifyServiceOrderParams.java @@ -0,0 +1,53 @@ + +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 ModifyServiceOrderParams { + + /** + * 商户服务订单号,必填 + *

+ * 商户系统内部服务订单号(不是交易单号),要求此参数只能由数字、大小写字母_-|*组成,且在同一个商户号下唯一。详见[商户订单号]。 + */ + private String outOrderNo; + /** + * 与传入的商户号建立了支付绑定关系的appid,必填 + */ + private String appid; + /** + * 服务ID,必填 + *

+ * 该服务ID有本接口对应产品的权限。需要与创建订单时保持一致。 + */ + private String serviceId; + /** + * 后付费项目,必填 + */ + private List postPayments; + /** + * 后付费商户优惠,选填 + */ + private List postDiscounts; + /** + * 总金额,单位分,必填 + * + * 不能超过完结订单时候的总金额,只能为整数,详见 支付金额。此参数需满足:总金额 =(修改后付费项目1…+修改后完结付费项目n)-(修改 后付费商户优惠项目1…+修改后付费商户优惠项目n) + */ + private Long totalAmount; + /** + * 取消原因,最长50个字符,必填 + */ + private String reason; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayServiceOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayServiceOrderParams.java new file mode 100644 index 0000000..ce472a3 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayServiceOrderParams.java @@ -0,0 +1,30 @@ +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 商户发起催收扣款请求参数. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class PayServiceOrderParams { + + /** + * 商户服务订单号,必填 + *

+ * 商户系统内部服务订单号(不是交易单号),要求此参数只能由数字、大小写字母_-|*组成,且在同一个商户号下唯一。详见[商户订单号]。 + */ + private String outOrderNo; + /** + * 与传入的商户号建立了支付绑定关系的appid,必填 + */ + private String appid; + /** + * 服务ID,必填 + *

+ * 该服务ID有本接口对应产品的权限。 + */ + private String serviceId; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java index 803deb0..7b253b4 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java @@ -26,6 +26,11 @@ public class PostDiscount { * 优惠使用条件说明。{@link PostDiscount#name}若填写,则必须同时填写。 */ private String description; + /** + * 总金额,单位分,必填 + * todo 新增没有此字段,修改必填,感觉不太符合常理 + */ + private Long amount; /** * 优惠数量,选填。 *

diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java index 51502e0..ededb85 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java @@ -14,13 +14,13 @@ import lombok.Data; @Data public class PostPayment { /** - * 付费项目名称,选填。 + * 付费项目名称,选填。 修改订单必填 *

* 相同订单号下不能出现相同的付费项目名称,当参数长度超过20个字符时,报错处理。 */ private String name; /** - * 金额,条件选填。 + * 金额,条件选填。修改订单必填 *

* 此付费项目总金额,大于等于0,单位为分,等于0时代表不需要扣费,只能为整数,详见支付金额。如果填写了“付费项目名称”,则amount或description必须填写其一,或都填。 */ diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java index 746a624..31da2de 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java @@ -22,7 +22,7 @@ public class RiskFund { * 1、数字,必须>0(单位分)。 * 2、风险金额≤每个服务ID的风险金额上限。 * 3、当商户优惠字段为空时,付费项目总金额≤服务ID的风险金额上限 (未填写金额的付费项目,视为该付费项目金额为0)。 - * 4、完结金额可大于、小于或等于风险金额。详细可见QA 关于订单风险金额问题 + * 4、完结金额可大于、小于或等于风险金额。详细可见QA 关于订单风险金额问题 */ private Long amount; /** diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/SyncServiceOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/SyncServiceOrderParams.java new file mode 100644 index 0000000..7764199 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/SyncServiceOrderParams.java @@ -0,0 +1,64 @@ +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 同步服务订单信息请求参数. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class SyncServiceOrderParams { + + /** + * 商户服务订单号,必填 + *

+ * 商户系统内部服务订单号(不是交易单号),要求此参数只能由数字、大小写字母_-|*组成,且在同一个商户号下唯一。详见[商户订单号]。 + */ + private String outOrderNo; + /** + * 与传入的商户号建立了支付绑定关系的appid,必填 + */ + private String appid; + /** + * 服务ID,必填 + *

+ * 该服务ID有本接口对应产品的权限。与订单要保持一致。 + */ + private String serviceId; + /** + * 场景类型,必填,场景类型为“Order_Paid”,字符串表示“订单收款成功” 。 + */ + private String type = "Order_Paid"; + + /** + * 内容信息详情,场景类型为Order_Paid时,为必填项。 + */ + private SyncDetail detail; + + + /** + * 内容信息详情 + */ + @Data + public static class SyncDetail{ + /** + * 收款成功时间 + *

+ * 支付成功时间,支持两种格式:yyyyMMddHHmmss和yyyyMMdd + * ● 传入20091225091010表示2009年12月25日9点10分10秒。 + * ● 传入20091225默认认为时间为2009年12月25日0点0分0秒。 + * 用户通过其他方式付款成功的实际时间需满足条件:服务开始时间<调用商户完结订单接口的时间<用户通过其他方式付款成功的实际时间≤商户调用支付分订单同步接口的时间。 + * 【服务开始时间】 + * 1、当完结订单有填写【实际服务开始时间】时,【服务开始时间】=完结订单【实际服务开始时间】。 + * 2、当完结订单未填写【实际服务开始时间】时,【服务开始时间】=创建订单【服务开始时间】 + * 场景类型为Order_Paid时,必填。 + * 支持两种格式:yyyyMMddHHmmss和yyyyMMdd + * ● 传入20091225091010表示2009年12月25日9点10分10秒。 + * ● 传入20091225表示时间为2009年12月25日23点59分59秒。 + * 注意:微信支付分会根据此时间更新用户侧的守约记录、负面记录信息;因此请务必如实填写用户实际付款成功时间,以免造成不必要的客诉。 + */ + private String paidTime; + } +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserPayScoreOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserServiceOrderParams.java similarity index 98% rename from payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserPayScoreOrderParams.java rename to payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserServiceOrderParams.java index dba2540..5b5e612 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserPayScoreOrderParams.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserServiceOrderParams.java @@ -13,7 +13,7 @@ import java.util.List; * @since 1.0.2.RELEASE */ @Data -public class UserPayScoreOrderParams { +public class UserServiceOrderParams { /** * 商户服务订单号,必填