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 0f6659e..2653956 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 @@ -34,6 +34,11 @@ public enum WechatPayV3Type { */ APP(HttpMethod.POST, "%s/v3/pay/transactions/app"), + /** + * 合单下单-APP支付API. + */ + COMBINE_APP(HttpMethod.POST, "%s/v3/combine-transactions/app"), + /** * H5支付. */ @@ -111,11 +116,21 @@ public enum WechatPayV3Type { MARKETING_FAVOR_CALLBACKS(HttpMethod.POST, "%s/v3/marketing/favor/callbacks"); - - + /** + * The Pattern. + */ private final String pattern; + /** + * The Method. + */ private final HttpMethod method; + /** + * Instantiates a new Wechat pay v 3 type. + * + * @param method the method + * @param pattern the pattern + */ WechatPayV3Type(HttpMethod method, String pattern) { this.method = method; this.pattern = pattern; diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatCombinePayApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatCombinePayApi.java new file mode 100644 index 0000000..bf13f97 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatCombinePayApi.java @@ -0,0 +1,71 @@ +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.combine.CombinePayParams; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.springframework.http.RequestEntity; +import org.springframework.web.util.UriComponentsBuilder; + +import java.net.URI; + +/** + * 微信合单支付. + * + * @author felord.cn + * @since 1.0.0.RELEASE + */ +public class WechatCombinePayApi extends AbstractApi{ + /** + * Instantiates a new Abstract api. + * + * @param wechatPayClient the wechat pay client + * @param tenantId the tenant id + */ + public WechatCombinePayApi(WechatPayClient wechatPayClient, String tenantId) { + super(wechatPayClient, tenantId); + } + + /** + * 合单下单-APP支付API + *

+ * 使用合单支付接口,用户只输入一次密码,即可完成多个订单的支付。目前最多一次可支持50笔订单进行合单支付。 + *

+ * 注意: + * • 订单如果需要进行抽佣等,需要在合单中指定需要进行分账(profit_sharing为true);指定后,交易资金进入二级商户账户,处于冻结状态,可在后续使用分账接口进行分账,利用分账完结进行资金解冻,实现抽佣和对二级商户的账期。 + * + * @param combinePayParams the combine pay params + * @return the wechat response entity + */ + public WechatResponseEntity appPay(CombinePayParams combinePayParams) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.APP, combinePayParams) + .function(this::combinePayFunction) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + + /** + * Combine pay function request entity. + * + * @param type the type + * @param params the params + * @return the request entity + */ + private RequestEntity combinePayFunction(WechatPayV3Type type, CombinePayParams params) { + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + params.setCombineAppid(v3.getAppId()); + params.setCombineMchid(v3.getMchId()); + + String notifyUrl = v3.getDomain().concat(params.getNotifyUrl()); + params.setNotifyUrl(notifyUrl); + URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) + .build() + .toUri(); + return Post(uri, params); + } + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombineAmount.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombineAmount.java new file mode 100644 index 0000000..ab9e9fe --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombineAmount.java @@ -0,0 +1,25 @@ + +package cn.felord.payment.wechat.v3.model.combine; + + +import lombok.Data; + +/** + * 合单支付订单金额信息. + * + * @author felord.cn + * @since 1.0.0.RELEASE + */ +@Data +public class CombineAmount { + /** + * 符合ISO 4217标准的三位字母代码,必填,人民币:CNY 。 + */ + private String currency = "CNY"; + /** + * 子单金额,单位为分,必填 + *

+ * 境外场景下,标价金额要超过商户结算币种的最小单位金额,例如结算币种为美元,则标价金额必须大于1美分 + */ + private Long totalAmount; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombinePayParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombinePayParams.java new file mode 100644 index 0000000..ec0d6e2 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombinePayParams.java @@ -0,0 +1,62 @@ + +package cn.felord.payment.wechat.v3.model.combine; + +import cn.felord.payment.wechat.v3.model.SettleInfo; +import lombok.Data; + +import java.time.OffsetDateTime; +import java.util.List; + +/** + * 合单支付参数. + * + * @author felord.cn + * @since 1.0.0.RELEASE + */ +@Data +public class CombinePayParams { + + /** + * 合单商户appid,必填 + */ + private String combineAppid; + /** + * 合单商户号,必填 + */ + private String combineMchid; + /** + * 合单商户订单号,必填,商户侧需要保证同一商户下唯一 + */ + private String combineOutTradeNo; + /** + * 合单支付者信息,选填 + */ + private CombinePayerInfo combinePayerInfo; + /** + * 通知地址,必填,接收微信支付异步通知回调地址,通知url必须为直接可访问的URL,不能携带参数。 + *

+ * 合单支付需要独立的通知地址。 + */ + private String notifyUrl; + /** + * 合单支付场景信息描述,选填 + */ + private CombineSceneInfo sceneInfo; + /** + * 子单信息,必填,最多50单 + */ + private List subOrders; + /** + * 结算信息,选填 + */ + private SettleInfo settleInfo; + /** + * 交易起始时间,选填 + */ + private OffsetDateTime timeStart; + /** + * 交易结束时间,选填 + */ + private OffsetDateTime timeExpire; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombinePayerInfo.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombinePayerInfo.java new file mode 100644 index 0000000..90bee19 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombinePayerInfo.java @@ -0,0 +1,19 @@ + +package cn.felord.payment.wechat.v3.model.combine; + + +import lombok.Data; + +/** + * 合单支付,支付者信息. + * + * @author felord.cn + * @since 1.0.0.RELEASE + */ +@Data +public class CombinePayerInfo { + /** + * 使用合单appid获取的对应用户openid。是用户在商户appid下的唯一标识。 + */ + private String openid; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombineSceneInfo.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombineSceneInfo.java new file mode 100644 index 0000000..d32258f --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombineSceneInfo.java @@ -0,0 +1,22 @@ + +package cn.felord.payment.wechat.v3.model.combine; + +import lombok.Data; + +/** + * 合单支付场景信息. + * + * @author felord.cn + * @since 1.0.0.RELEASE + */ +@Data +public class CombineSceneInfo { + /** + * 商户设备号,选填。 + */ + private String deviceId; + /** + * 用户终端ip,必填。 + */ + private String payerClientIp; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/SubOrder.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/SubOrder.java new file mode 100644 index 0000000..ccd2a7b --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/SubOrder.java @@ -0,0 +1,49 @@ + +package cn.felord.payment.wechat.v3.model.combine; + +import lombok.Data; + +/** + * 子单信息,最多50单. + * + * @author felord.cn + * @since 1.0.0.RELEASE + */ +@Data +public class SubOrder { + /** + * 合单支付订单金额信息,必填。 + */ + private CombineAmount amount; + + /** + * 附加数据,必填,在查询API和支付通知中原样返回,可作为自定义参数使用。 + */ + private String attach; + + /** + * 商品描述,必填,需传入应用市场上的APP名字-实际商品名称,例如:天天爱消除-游戏充值。 + */ + private String description; + + /** + * 子单发起方商户号,必填,必须与发起方appid有绑定关系。 + */ + private String mchid; + + /** + * 子单商户订单号,必填,商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。 + */ + private String outTradeNo; + + /** + * 二级商户商户号,由微信支付生成并下发。 + *

+ * 服务商子商户的商户号,被合单方。 + *

+ * 直连商户不用传二级商户号。 + */ + private String subMchid; + + +}