mirror of
https://github.com/dromara/payment-spring-boot.git
synced 2026-03-13 21:33:41 +08:00
合单支付
This commit is contained in:
@@ -17,7 +17,7 @@ public enum WechatPayV3Type {
|
|||||||
/**
|
/**
|
||||||
* 文件下载
|
* 文件下载
|
||||||
*/
|
*/
|
||||||
FILE_DOWNLOAD(HttpMethod.GET,"%s/v3/billdownload/file"),
|
FILE_DOWNLOAD(HttpMethod.GET, "%s/v3/billdownload/file"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信公众号支付或者小程序支付.
|
* 微信公众号支付或者小程序支付.
|
||||||
@@ -34,11 +34,6 @@ public enum WechatPayV3Type {
|
|||||||
*/
|
*/
|
||||||
APP(HttpMethod.POST, "%s/v3/pay/transactions/app"),
|
APP(HttpMethod.POST, "%s/v3/pay/transactions/app"),
|
||||||
|
|
||||||
/**
|
|
||||||
* 合单下单-APP支付API.
|
|
||||||
*/
|
|
||||||
COMBINE_APP(HttpMethod.POST, "%s/v3/combine-transactions/app"),
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* H5支付.
|
* H5支付.
|
||||||
*/
|
*/
|
||||||
@@ -57,27 +52,55 @@ public enum WechatPayV3Type {
|
|||||||
TRANSACTION_OUT_TRADE_NO(HttpMethod.GET, "%s/v3/pay/transactions/out-trade-no/{out_trade_no}"),
|
TRANSACTION_OUT_TRADE_NO(HttpMethod.GET, "%s/v3/pay/transactions/out-trade-no/{out_trade_no}"),
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单下单-APP支付API.
|
||||||
|
*/
|
||||||
|
COMBINE_APP(HttpMethod.POST, "%s/v3/combine-transactions/app"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单下单-微信公众号支付或者小程序支付.
|
||||||
|
*/
|
||||||
|
COMBINE_JSAPI(HttpMethod.POST, "%s/v3/pay/combine-transactions/jsapi"),
|
||||||
|
/**
|
||||||
|
* 合单下单-H5支付API.
|
||||||
|
*/
|
||||||
|
COMBINE_MWEB(HttpMethod.POST, "%s/v3/pay/combine-transactions/h5"),
|
||||||
|
/**
|
||||||
|
* 合单下单-Native支付API. /v3/combine-transactions/out-trade-no/{combine_out_trade_no}
|
||||||
|
*/
|
||||||
|
COMBINE_NATIVE(HttpMethod.POST, "%s/v3/pay/combine-transactions/native"),
|
||||||
|
/**
|
||||||
|
* 合单查询订单API.
|
||||||
|
*/
|
||||||
|
COMBINE_TRANSACTION_OUT_TRADE_NO(HttpMethod.GET, "%s/v3/combine-transactions/out-trade-no/{combine_out_trade_no}"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单关闭订单API.
|
||||||
|
*/
|
||||||
|
COMBINE_CLOSE(HttpMethod.POST, "%s/v3/combine-transactions/out-trade-no/{combine_out_trade_no}/close"),
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建代金券批次API.
|
* 创建代金券批次API.
|
||||||
*/
|
*/
|
||||||
MARKETING_FAVOR_STOCKS_COUPON_STOCKS(HttpMethod.POST,"%s/v3/marketing/favor/coupon-stocks"),
|
MARKETING_FAVOR_STOCKS_COUPON_STOCKS(HttpMethod.POST, "%s/v3/marketing/favor/coupon-stocks"),
|
||||||
/**
|
/**
|
||||||
* 激活代金券批次API.
|
* 激活代金券批次API.
|
||||||
*/
|
*/
|
||||||
MARKETING_FAVOR_STOCKS_START(HttpMethod.POST,"%s/v3/marketing/favor/stocks/{stock_id}/start"),
|
MARKETING_FAVOR_STOCKS_START(HttpMethod.POST, "%s/v3/marketing/favor/stocks/{stock_id}/start"),
|
||||||
/**
|
/**
|
||||||
* 暂停代金券批次API.
|
* 暂停代金券批次API.
|
||||||
*/
|
*/
|
||||||
MARKETING_FAVOR_STOCKS_PAUSE(HttpMethod.POST,"%s/v3/marketing/favor/stocks/{stock_id}/pause"),
|
MARKETING_FAVOR_STOCKS_PAUSE(HttpMethod.POST, "%s/v3/marketing/favor/stocks/{stock_id}/pause"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发放代金券API、根据商户号查用户的券.
|
* 发放代金券API、根据商户号查用户的券.
|
||||||
*/
|
*/
|
||||||
MARKETING_FAVOR_USERS_COUPONS(HttpMethod.POST,"%s/v3/marketing/favor/users/{openid}/coupons"),
|
MARKETING_FAVOR_USERS_COUPONS(HttpMethod.POST, "%s/v3/marketing/favor/users/{openid}/coupons"),
|
||||||
/**
|
/**
|
||||||
* 重启代金券API.
|
* 重启代金券API.
|
||||||
*/
|
*/
|
||||||
MARKETING_FAVOR_STOCKS_RESTART(HttpMethod.POST,"%s/v3/marketing/favor/stocks/{stock_id}/restart"),
|
MARKETING_FAVOR_STOCKS_RESTART(HttpMethod.POST, "%s/v3/marketing/favor/stocks/{stock_id}/restart"),
|
||||||
/**
|
/**
|
||||||
* 条件查询批次列表API.
|
* 条件查询批次列表API.
|
||||||
*/
|
*/
|
||||||
@@ -162,7 +185,7 @@ public enum WechatPayV3Type {
|
|||||||
* @return the string
|
* @return the string
|
||||||
*/
|
*/
|
||||||
public String uri(WeChatServer weChatServer) {
|
public String uri(WeChatServer weChatServer) {
|
||||||
return String.format(this.pattern,weChatServer.domain());
|
return String.format(this.pattern, weChatServer.domain());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ package cn.felord.payment.wechat.v3;
|
|||||||
* @since 1.0.0.RELEASE
|
* @since 1.0.0.RELEASE
|
||||||
*/
|
*/
|
||||||
public class WechatApiProvider {
|
public class WechatApiProvider {
|
||||||
|
/**
|
||||||
|
* The Wechat pay client.
|
||||||
|
*/
|
||||||
private final WechatPayClient wechatPayClient;
|
private final WechatPayClient wechatPayClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,8 +27,8 @@ public class WechatApiProvider {
|
|||||||
* @param tenantId the tenant id
|
* @param tenantId the tenant id
|
||||||
* @return the wechat marketing favor api
|
* @return the wechat marketing favor api
|
||||||
*/
|
*/
|
||||||
public WechatMarketingFavorApi favorApi(String tenantId){
|
public WechatMarketingFavorApi favorApi(String tenantId) {
|
||||||
return new WechatMarketingFavorApi(this.wechatPayClient,tenantId);
|
return new WechatMarketingFavorApi(this.wechatPayClient, tenantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,8 +37,18 @@ public class WechatApiProvider {
|
|||||||
* @param tenantId the tenant id
|
* @param tenantId the tenant id
|
||||||
* @return the wechat pay api
|
* @return the wechat pay api
|
||||||
*/
|
*/
|
||||||
public WechatDirectPayApi directPayApi(String tenantId){
|
public WechatDirectPayApi directPayApi(String tenantId) {
|
||||||
return new WechatDirectPayApi(wechatPayClient,tenantId);
|
return new WechatDirectPayApi(wechatPayClient, tenantId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单支付.
|
||||||
|
*
|
||||||
|
* @param tenantId the tenant id
|
||||||
|
* @return the wechat combine pay api
|
||||||
|
*/
|
||||||
|
public WechatCombinePayApi combinePayApi(String tenantId) {
|
||||||
|
return new WechatCombinePayApi(wechatPayClient, tenantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,8 +57,8 @@ public class WechatApiProvider {
|
|||||||
* @param tenantId the tenant id
|
* @param tenantId the tenant id
|
||||||
* @return the wechat pay callback
|
* @return the wechat pay callback
|
||||||
*/
|
*/
|
||||||
public WechatPayCallback callback(String tenantId){
|
public WechatPayCallback callback(String tenantId) {
|
||||||
return new WechatPayCallback(wechatPayClient.signatureProvider(),tenantId);
|
return new WechatPayCallback(wechatPayClient.signatureProvider(), tenantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package cn.felord.payment.wechat.v3;
|
|||||||
import cn.felord.payment.wechat.WechatPayProperties;
|
import cn.felord.payment.wechat.WechatPayProperties;
|
||||||
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
import cn.felord.payment.wechat.enumeration.WeChatServer;
|
||||||
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
import cn.felord.payment.wechat.enumeration.WechatPayV3Type;
|
||||||
|
import cn.felord.payment.wechat.v3.model.combine.CombineCloseParams;
|
||||||
|
import cn.felord.payment.wechat.v3.model.combine.CombineH5PayParams;
|
||||||
import cn.felord.payment.wechat.v3.model.combine.CombinePayParams;
|
import cn.felord.payment.wechat.v3.model.combine.CombinePayParams;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import org.springframework.http.RequestEntity;
|
import org.springframework.http.RequestEntity;
|
||||||
@@ -40,7 +42,7 @@ public class WechatCombinePayApi extends AbstractApi{
|
|||||||
*/
|
*/
|
||||||
public WechatResponseEntity<ObjectNode> appPay(CombinePayParams combinePayParams) {
|
public WechatResponseEntity<ObjectNode> appPay(CombinePayParams combinePayParams) {
|
||||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||||
this.client().withType(WechatPayV3Type.APP, combinePayParams)
|
this.client().withType(WechatPayV3Type.COMBINE_APP, combinePayParams)
|
||||||
.function(this::combinePayFunction)
|
.function(this::combinePayFunction)
|
||||||
.consumer(wechatResponseEntity::convert)
|
.consumer(wechatResponseEntity::convert)
|
||||||
.request();
|
.request();
|
||||||
@@ -48,6 +50,26 @@ public class WechatCombinePayApi extends AbstractApi{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单下单-JSAPI支付/小程序支付API
|
||||||
|
* <p>
|
||||||
|
* 使用合单支付接口,用户只输入一次密码,即可完成多个订单的支付。目前最多一次可支持50笔订单进行合单支付。
|
||||||
|
* <p>
|
||||||
|
* 注意:
|
||||||
|
* • 订单如果需要进行抽佣等,需要在合单中指定需要进行分账(profit_sharing为true);指定后,交易资金进入二级商户账户,处于冻结状态,可在后续使用分账接口进行分账,利用分账完结进行资金解冻,实现抽佣和对二级商户的账期。
|
||||||
|
*
|
||||||
|
* @param combinePayParams the combine pay params
|
||||||
|
* @return wechat response entity
|
||||||
|
*/
|
||||||
|
public WechatResponseEntity<ObjectNode> jsPay(CombinePayParams combinePayParams) {
|
||||||
|
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||||
|
this.client().withType(WechatPayV3Type.COMBINE_JSAPI, combinePayParams)
|
||||||
|
.function(this::combinePayFunction)
|
||||||
|
.consumer(wechatResponseEntity::convert)
|
||||||
|
.request();
|
||||||
|
return wechatResponseEntity;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combine pay function request entity.
|
* Combine pay function request entity.
|
||||||
*
|
*
|
||||||
@@ -68,4 +90,107 @@ public class WechatCombinePayApi extends AbstractApi{
|
|||||||
return Post(uri, params);
|
return Post(uri, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单下单-H5支付API.
|
||||||
|
* <p>
|
||||||
|
* 使用合单支付接口,用户只输入一次密码,即可完成多个订单的支付。目前最多一次可支持50笔订单进行合单支付。
|
||||||
|
* <p>
|
||||||
|
* 注意:
|
||||||
|
* • 订单如果需要进行抽佣等,需要在合单中指定需要进行分账(profit_sharing为true);指定后,交易资金进入二级商户账户,处于冻结状态,可在后续使用分账接口进行分账,利用分账完结进行资金解冻,实现抽佣和对二级商户的账期。
|
||||||
|
*
|
||||||
|
* @param combineH5PayParams the combine h 5 pay params
|
||||||
|
* @return the wechat response entity
|
||||||
|
*/
|
||||||
|
public WechatResponseEntity<ObjectNode> h5Pay(CombineH5PayParams combineH5PayParams) {
|
||||||
|
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||||
|
this.client().withType(WechatPayV3Type.COMBINE_MWEB, combineH5PayParams)
|
||||||
|
.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, CombineH5PayParams 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单下单-Native支付API.
|
||||||
|
* <p>
|
||||||
|
* 使用合单支付接口,用户只输入一次密码,即可完成多个订单的支付。目前最多一次可支持50笔订单进行合单支付。
|
||||||
|
* <p>
|
||||||
|
* 注意:
|
||||||
|
* • 订单如果需要进行抽佣等,需要在合单中指定需要进行分账(profit_sharing为true);指定后,交易资金进入二级商户账户,处于冻结状态,可在后续使用分账接口进行分账,利用分账完结进行资金解冻,实现抽佣和对二级商户的账期。
|
||||||
|
*
|
||||||
|
* @param combinePayParams the combine pay params
|
||||||
|
* @return the wechat response entity
|
||||||
|
*/
|
||||||
|
public WechatResponseEntity<ObjectNode> nativePay(CombinePayParams combinePayParams) {
|
||||||
|
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||||
|
this.client().withType(WechatPayV3Type.COMBINE_NATIVE, combinePayParams)
|
||||||
|
.function(this::combinePayFunction)
|
||||||
|
.consumer(wechatResponseEntity::convert)
|
||||||
|
.request();
|
||||||
|
return wechatResponseEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单查询订单API.
|
||||||
|
*
|
||||||
|
* @param combineOutTradeNo the combine out trade no
|
||||||
|
* @return the wechat response entity
|
||||||
|
*/
|
||||||
|
public WechatResponseEntity<ObjectNode> queryTransactionByOutTradeNo(String combineOutTradeNo) {
|
||||||
|
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||||
|
this.client().withType(WechatPayV3Type.COMBINE_TRANSACTION_OUT_TRADE_NO, combineOutTradeNo)
|
||||||
|
.function((wechatPayV3Type, outTradeNo) -> {
|
||||||
|
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||||
|
.build()
|
||||||
|
.expand(outTradeNo)
|
||||||
|
.toUri();
|
||||||
|
return Get(uri);
|
||||||
|
})
|
||||||
|
.consumer(wechatResponseEntity::convert)
|
||||||
|
.request();
|
||||||
|
return wechatResponseEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单关闭订单API.
|
||||||
|
* <p>
|
||||||
|
* 合单支付订单只能使用此合单关单api完成关单。
|
||||||
|
*
|
||||||
|
* 微信服务器返回 204。
|
||||||
|
*
|
||||||
|
* @param combineCloseParams the combine close params
|
||||||
|
* @return the wechat response entity
|
||||||
|
*/
|
||||||
|
public WechatResponseEntity<ObjectNode> close(CombineCloseParams combineCloseParams) {
|
||||||
|
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||||
|
this.client().withType(WechatPayV3Type.COMBINE_NATIVE, combineCloseParams)
|
||||||
|
.function((wechatPayV3Type, params) -> {
|
||||||
|
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||||
|
.build().toUri();
|
||||||
|
return Post(uri,params);
|
||||||
|
})
|
||||||
|
.consumer(wechatResponseEntity::convert)
|
||||||
|
.request();
|
||||||
|
return wechatResponseEntity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
package cn.felord.payment.wechat.v3;
|
package cn.felord.payment.wechat.v3;
|
||||||
|
|
||||||
import cn.felord.payment.wechat.v3.model.CouponConsumeData;
|
|
||||||
import cn.felord.payment.wechat.v3.model.ResponseSignVerifyParams;
|
|
||||||
import cn.felord.payment.PayException;
|
import cn.felord.payment.PayException;
|
||||||
import cn.felord.payment.wechat.v3.model.CallbackParams;
|
import cn.felord.payment.wechat.v3.model.*;
|
||||||
import cn.felord.payment.wechat.v3.model.TransactionConsumeData;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||||
@@ -26,8 +23,17 @@ import java.util.function.Consumer;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class WechatPayCallback {
|
public class WechatPayCallback {
|
||||||
|
/**
|
||||||
|
* The constant MAPPER.
|
||||||
|
*/
|
||||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||||
|
/**
|
||||||
|
* The Signature provider.
|
||||||
|
*/
|
||||||
private final SignatureProvider signatureProvider;
|
private final SignatureProvider signatureProvider;
|
||||||
|
/**
|
||||||
|
* The Tenant id.
|
||||||
|
*/
|
||||||
private final String tenantId;
|
private final String tenantId;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@@ -72,20 +78,44 @@ public class WechatPayCallback {
|
|||||||
* <p>
|
* <p>
|
||||||
* 无需开发者判断,只有扣款成功微信才会回调此接口
|
* 无需开发者判断,只有扣款成功微信才会回调此接口
|
||||||
*
|
*
|
||||||
* @param params the params
|
* @param params the params
|
||||||
* @param couponConsumeDataConsumer the coupon consume data consumer
|
* @param transactionConsumeDataConsumer the transaction consume data consumer
|
||||||
* @return the map
|
* @return the map
|
||||||
*/
|
*/
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public Map<String, ?> transactionCallback(ResponseSignVerifyParams params, Consumer<TransactionConsumeData> couponConsumeDataConsumer) {
|
public Map<String, ?> transactionCallback(ResponseSignVerifyParams params, Consumer<TransactionConsumeData> transactionConsumeDataConsumer) {
|
||||||
String data = callback(params, EventType.TRANSACTION);
|
String data = callback(params, EventType.TRANSACTION);
|
||||||
TransactionConsumeData transactionConsumeData = MAPPER.readValue(data, TransactionConsumeData.class);
|
TransactionConsumeData transactionConsumeData = MAPPER.readValue(data, TransactionConsumeData.class);
|
||||||
couponConsumeDataConsumer.accept(transactionConsumeData);
|
transactionConsumeDataConsumer.accept(transactionConsumeData);
|
||||||
return Collections.singletonMap("code", "SUCCESS");
|
return Collections.singletonMap("code", "SUCCESS");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信合单支付成功回调.
|
||||||
|
* <p>
|
||||||
|
* 无需开发者判断,只有扣款成功微信才会回调此接口
|
||||||
|
*
|
||||||
|
* @param params the params
|
||||||
|
* @param combineTransactionConsumeDataConsumer the combine transaction consume data consumer
|
||||||
|
* @return the map
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public Map<String, ?> combineTransactionCallback(ResponseSignVerifyParams params, Consumer<CombineTransactionConsumeData> combineTransactionConsumeDataConsumer) {
|
||||||
|
String data = callback(params, EventType.TRANSACTION);
|
||||||
|
CombineTransactionConsumeData combineTransactionConsumeData = MAPPER.readValue(data, CombineTransactionConsumeData.class);
|
||||||
|
combineTransactionConsumeDataConsumer.accept(combineTransactionConsumeData);
|
||||||
|
return Collections.singletonMap("code", "SUCCESS");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback string.
|
||||||
|
*
|
||||||
|
* @param params the params
|
||||||
|
* @param eventType the event type
|
||||||
|
* @return the string
|
||||||
|
*/
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
private String callback(ResponseSignVerifyParams params, EventType eventType) {
|
private String callback(ResponseSignVerifyParams params, EventType eventType) {
|
||||||
if (signatureProvider.responseSignVerify(params)) {
|
if (signatureProvider.responseSignVerify(params)) {
|
||||||
@@ -122,8 +152,16 @@ public class WechatPayCallback {
|
|||||||
*/
|
*/
|
||||||
TRANSACTION("TRANSACTION.SUCCESS");
|
TRANSACTION("TRANSACTION.SUCCESS");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Event.
|
||||||
|
*/
|
||||||
private final String event;
|
private final String event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new Event type.
|
||||||
|
*
|
||||||
|
* @param event the event
|
||||||
|
*/
|
||||||
EventType(String event) {
|
EventType(String event) {
|
||||||
this.event = event;
|
this.event = event;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -219,10 +219,7 @@ public class WechatPayClient {
|
|||||||
ObjectNode body = responseEntity.getBody();
|
ObjectNode body = responseEntity.getBody();
|
||||||
HttpStatus statusCode = responseEntity.getStatusCode();
|
HttpStatus statusCode = responseEntity.getStatusCode();
|
||||||
if (!statusCode.is2xxSuccessful()) {
|
if (!statusCode.is2xxSuccessful()) {
|
||||||
throw new PayException("wechat pay server error,statusCode "+ statusCode +",result : " + body);
|
throw new PayException("wechat pay server error,statusCode " + statusCode + ",result : " + body);
|
||||||
}
|
|
||||||
if (Objects.isNull(body)) {
|
|
||||||
throw new PayException("cant obtain wechat response body");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseSignVerifyParams params = new ResponseSignVerifyParams();
|
ResponseSignVerifyParams params = new ResponseSignVerifyParams();
|
||||||
@@ -235,7 +232,9 @@ public class WechatPayClient {
|
|||||||
//构造验签名串
|
//构造验签名串
|
||||||
params.setWechatpayTimestamp(headers.getFirst("Wechatpay-Timestamp"));
|
params.setWechatpayTimestamp(headers.getFirst("Wechatpay-Timestamp"));
|
||||||
params.setWechatpayNonce(headers.getFirst("Wechatpay-Nonce"));
|
params.setWechatpayNonce(headers.getFirst("Wechatpay-Nonce"));
|
||||||
params.setBody(body.toString());
|
|
||||||
|
String content = Objects.isNull(body) ? "" : body.toString();
|
||||||
|
params.setBody(content);
|
||||||
|
|
||||||
// 验证微信服务器签名
|
// 验证微信服务器签名
|
||||||
if (signatureProvider.responseSignVerify(params)) {
|
if (signatureProvider.responseSignVerify(params)) {
|
||||||
@@ -263,12 +262,12 @@ public class WechatPayClient {
|
|||||||
String body = responseEntity.getBody();
|
String body = responseEntity.getBody();
|
||||||
HttpStatus statusCode = responseEntity.getStatusCode();
|
HttpStatus statusCode = responseEntity.getStatusCode();
|
||||||
if (!statusCode.is2xxSuccessful()) {
|
if (!statusCode.is2xxSuccessful()) {
|
||||||
throw new PayException("wechat pay server error,statusCode "+ statusCode +",result : " + body);
|
throw new PayException("wechat pay server error,statusCode " + statusCode + ",result : " + body);
|
||||||
}
|
}
|
||||||
if (Objects.isNull(body)) {
|
if (Objects.isNull(body)) {
|
||||||
throw new PayException("cant obtain wechat response body");
|
throw new PayException("cant obtain wechat response body");
|
||||||
}
|
}
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
|
||||||
|
package cn.felord.payment.wechat.v3.model;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.v3.model.combine.CombinePayerInfo;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单支付回调解密数据.
|
||||||
|
*
|
||||||
|
* @author felord.cn
|
||||||
|
* @since 1.0.0.RELEASE
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CombineTransactionConsumeData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单商户appid.
|
||||||
|
*/
|
||||||
|
private String combineAppid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单商户号.
|
||||||
|
*/
|
||||||
|
private String combineMchid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单商户订单号.
|
||||||
|
*/
|
||||||
|
private String combineOutTradeNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付者.
|
||||||
|
*/
|
||||||
|
private CombinePayerInfo combinePayerInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 场景信息,合单支付回调只返回device_id
|
||||||
|
*/
|
||||||
|
private SceneInfo sceneInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单支付回调子订单.
|
||||||
|
*/
|
||||||
|
private List<SubOrderCallback> subOrders;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单支付回调子订单.
|
||||||
|
*
|
||||||
|
* @author felord.cn
|
||||||
|
* @since 1.0.0.RELEASE
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class SubOrderCallback {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Amount.
|
||||||
|
*/
|
||||||
|
private CombineAmount amount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Attach.
|
||||||
|
*/
|
||||||
|
private String attach;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Bank type.
|
||||||
|
*/
|
||||||
|
private String bankType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Mchid.
|
||||||
|
*/
|
||||||
|
private String mchid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Out trade no.
|
||||||
|
*/
|
||||||
|
private String outTradeNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Sub mchid.
|
||||||
|
*/
|
||||||
|
private String subMchid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Success time.
|
||||||
|
*/
|
||||||
|
private String successTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Trade state.
|
||||||
|
*/
|
||||||
|
private String tradeState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Trade type.
|
||||||
|
*/
|
||||||
|
private String tradeType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Transaction id.
|
||||||
|
*/
|
||||||
|
private String transactionId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单金额信息.
|
||||||
|
*
|
||||||
|
* @author felord.cn
|
||||||
|
* @since 1.0.0.RELEASE
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class CombineAmount{
|
||||||
|
/**
|
||||||
|
* 标价金额,单位为分.
|
||||||
|
*/
|
||||||
|
private Long totalAmount;
|
||||||
|
/**
|
||||||
|
* 标价币种.
|
||||||
|
*/
|
||||||
|
private String currency;
|
||||||
|
/**
|
||||||
|
* 现金支付金额.
|
||||||
|
*/
|
||||||
|
private Long payerAmount;
|
||||||
|
/**
|
||||||
|
* 现金支付币种.
|
||||||
|
*/
|
||||||
|
private String payerCurrency;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package cn.felord.payment.wechat.v3.model.combine;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单支付 关单参数.
|
||||||
|
*
|
||||||
|
* @author felord.cn
|
||||||
|
* @since 1.0.0.RELEASE
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CombineCloseParams {
|
||||||
|
/**
|
||||||
|
* 合单商户appid,必填
|
||||||
|
*/
|
||||||
|
private String combineAppid;
|
||||||
|
/**
|
||||||
|
* 合单商户订单号,必填,商户侧需要保证同一商户下唯一
|
||||||
|
*/
|
||||||
|
private String combineOutTradeNo;
|
||||||
|
/**
|
||||||
|
* 子单信息,必填,最多50单
|
||||||
|
*/
|
||||||
|
private List<ClosingSubOrder> subOrders;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关单-子单信息,最多50单.
|
||||||
|
*
|
||||||
|
* @author felord.cn
|
||||||
|
* @since 1.0.0.RELEASE
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class ClosingSubOrder {
|
||||||
|
/**
|
||||||
|
* 子单发起方商户号,必填,必须与发起方appid有绑定关系。
|
||||||
|
*/
|
||||||
|
private String mchid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子单商户订单号,必填,商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。
|
||||||
|
*/
|
||||||
|
private String outTradeNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 二级商户商户号,由微信支付生成并下发。
|
||||||
|
* <p>
|
||||||
|
* 服务商子商户的商户号,被合单方。
|
||||||
|
* <p>
|
||||||
|
* 直连商户不用传二级商户号。
|
||||||
|
*/
|
||||||
|
private String subMchid;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
|
||||||
|
package cn.felord.payment.wechat.v3.model.combine;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单支付 H5支付参数.
|
||||||
|
*
|
||||||
|
* @author felord.cn
|
||||||
|
* @since 1.0.0.RELEASE
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CombineH5PayParams {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合单商户appid,必填
|
||||||
|
*/
|
||||||
|
private String combineAppid;
|
||||||
|
/**
|
||||||
|
* 合单商户号,必填
|
||||||
|
*/
|
||||||
|
private String combineMchid;
|
||||||
|
/**
|
||||||
|
* 合单商户订单号,必填,商户侧需要保证同一商户下唯一
|
||||||
|
*/
|
||||||
|
private String combineOutTradeNo;
|
||||||
|
/**
|
||||||
|
* 合单支付者信息,选填
|
||||||
|
*/
|
||||||
|
private CombinePayerInfo combinePayerInfo;
|
||||||
|
/**
|
||||||
|
* 通知地址,必填,接收微信支付异步通知回调地址,通知url必须为直接可访问的URL,不能携带参数。
|
||||||
|
* <p>
|
||||||
|
* <strong>合单支付需要独立的通知地址。</strong>
|
||||||
|
*/
|
||||||
|
private String notifyUrl;
|
||||||
|
/**
|
||||||
|
* 合单支付场景信息描述,选填
|
||||||
|
*/
|
||||||
|
private CombineH5SceneInfo sceneInfo;
|
||||||
|
/**
|
||||||
|
* 子单信息,必填,最多50单
|
||||||
|
*/
|
||||||
|
private List<SubOrder> subOrders;
|
||||||
|
/**
|
||||||
|
* 交易起始时间,选填
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8")
|
||||||
|
private OffsetDateTime timeStart;
|
||||||
|
/**
|
||||||
|
* 交易结束时间,选填
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8")
|
||||||
|
private OffsetDateTime timeExpire;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package cn.felord.payment.wechat.v3.model.combine;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.v3.model.H5Info;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class CombineH5SceneInfo extends CombineSceneInfo {
|
||||||
|
private H5Info h5Info;
|
||||||
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
|
|
||||||
package cn.felord.payment.wechat.v3.model.combine;
|
package cn.felord.payment.wechat.v3.model.combine;
|
||||||
|
|
||||||
import cn.felord.payment.wechat.v3.model.SettleInfo;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 合单支付参数.
|
* 合单支付 APP支付、JSAPI支付、小程序支付、Native支付参数.
|
||||||
*
|
*
|
||||||
* @author felord.cn
|
* @author felord.cn
|
||||||
* @since 1.0.0.RELEASE
|
* @since 1.0.0.RELEASE
|
||||||
@@ -46,17 +46,15 @@ public class CombinePayParams {
|
|||||||
* 子单信息,必填,最多50单
|
* 子单信息,必填,最多50单
|
||||||
*/
|
*/
|
||||||
private List<SubOrder> subOrders;
|
private List<SubOrder> subOrders;
|
||||||
/**
|
|
||||||
* 结算信息,选填
|
|
||||||
*/
|
|
||||||
private SettleInfo settleInfo;
|
|
||||||
/**
|
/**
|
||||||
* 交易起始时间,选填
|
* 交易起始时间,选填
|
||||||
*/
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8")
|
||||||
private OffsetDateTime timeStart;
|
private OffsetDateTime timeStart;
|
||||||
/**
|
/**
|
||||||
* 交易结束时间,选填
|
* 交易结束时间,选填
|
||||||
*/
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8")
|
||||||
private OffsetDateTime timeExpire;
|
private OffsetDateTime timeExpire;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
package cn.felord.payment.wechat.v3.model.combine;
|
package cn.felord.payment.wechat.v3.model.combine;
|
||||||
|
|
||||||
|
import cn.felord.payment.wechat.v3.model.SettleInfo;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,5 +46,9 @@ public class SubOrder {
|
|||||||
*/
|
*/
|
||||||
private String subMchid;
|
private String subMchid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结算信息,选填
|
||||||
|
*/
|
||||||
|
private SettleInfo settleInfo;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user