mirror of
https://github.com/dromara/payment-spring-boot.git
synced 2026-03-13 21:33:41 +08:00
发放优惠券
This commit is contained in:
@@ -8,7 +8,7 @@ import org.springframework.http.HttpMethod;
|
|||||||
* @author Dax
|
* @author Dax
|
||||||
* @since 14 :25
|
* @since 14 :25
|
||||||
*/
|
*/
|
||||||
public enum V3PayType {
|
public enum WechatPayV3Type {
|
||||||
/**
|
/**
|
||||||
* 获取证书.
|
* 获取证书.
|
||||||
*/
|
*/
|
||||||
@@ -39,6 +39,10 @@ public enum V3PayType {
|
|||||||
* 激活代金券批次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.
|
||||||
|
*/
|
||||||
|
MARKETING_FAVOR_USERS_COUPONS(HttpMethod.POST,"%s/v3/marketing/favor/users/{openid}/coupons"),
|
||||||
/**
|
/**
|
||||||
* 查询代金券可用商户
|
* 查询代金券可用商户
|
||||||
*/
|
*/
|
||||||
@@ -50,7 +54,7 @@ public enum V3PayType {
|
|||||||
private final String pattern;
|
private final String pattern;
|
||||||
private final HttpMethod method;
|
private final HttpMethod method;
|
||||||
|
|
||||||
V3PayType(HttpMethod method, String pattern) {
|
WechatPayV3Type(HttpMethod method, String pattern) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@ package com.enongm.dianji.payment.wechat.v3;
|
|||||||
|
|
||||||
|
|
||||||
import com.enongm.dianji.payment.PayException;
|
import com.enongm.dianji.payment.PayException;
|
||||||
import com.enongm.dianji.payment.wechat.enumeration.V3PayType;
|
import com.enongm.dianji.payment.wechat.enumeration.WechatPayV3Type;
|
||||||
import com.enongm.dianji.payment.wechat.enumeration.WeChatServer;
|
import com.enongm.dianji.payment.wechat.enumeration.WeChatServer;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
@@ -136,7 +136,7 @@ public class SignatureProvider {
|
|||||||
*/
|
*/
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
private synchronized void refreshCertificate() {
|
private synchronized void refreshCertificate() {
|
||||||
String url = V3PayType.CERT.uri(WeChatServer.CHINA);
|
String url = WechatPayV3Type.CERT.uri(WeChatServer.CHINA);
|
||||||
|
|
||||||
UriComponents uri = UriComponentsBuilder.fromHttpUrl(url).build();
|
UriComponents uri = UriComponentsBuilder.fromHttpUrl(url).build();
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ public class SignatureProvider {
|
|||||||
canonicalUrl += "?" + encodedQuery;
|
canonicalUrl += "?" + encodedQuery;
|
||||||
}
|
}
|
||||||
// 签名
|
// 签名
|
||||||
HttpMethod httpMethod = V3PayType.CERT.method();
|
HttpMethod httpMethod = WechatPayV3Type.CERT.method();
|
||||||
String authorization = requestSign(httpMethod.name(), canonicalUrl, "");
|
String authorization = requestSign(httpMethod.name(), canonicalUrl, "");
|
||||||
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ package com.enongm.dianji.payment.wechat.v3;
|
|||||||
|
|
||||||
import com.enongm.dianji.payment.PayException;
|
import com.enongm.dianji.payment.PayException;
|
||||||
import com.enongm.dianji.payment.wechat.WechatPayProperties;
|
import com.enongm.dianji.payment.wechat.WechatPayProperties;
|
||||||
import com.enongm.dianji.payment.wechat.enumeration.V3PayType;
|
|
||||||
import com.enongm.dianji.payment.wechat.enumeration.WeChatServer;
|
import com.enongm.dianji.payment.wechat.enumeration.WeChatServer;
|
||||||
|
import com.enongm.dianji.payment.wechat.enumeration.WechatPayV3Type;
|
||||||
import com.enongm.dianji.payment.wechat.v3.model.AppPayParams;
|
import com.enongm.dianji.payment.wechat.v3.model.AppPayParams;
|
||||||
import com.enongm.dianji.payment.wechat.v3.model.StocksMchQueryParams;
|
import com.enongm.dianji.payment.wechat.v3.model.StocksMchQueryParams;
|
||||||
|
import com.enongm.dianji.payment.wechat.v3.model.StocksSendParams;
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
@@ -53,17 +54,19 @@ public class WechatPayV3Api {
|
|||||||
* 激活代金券批次API
|
* 激活代金券批次API
|
||||||
*
|
*
|
||||||
* @param stockId the stock id
|
* @param stockId the stock id
|
||||||
|
* @return the wechat response entity
|
||||||
*/
|
*/
|
||||||
public WechatResponseEntity<?> startStocks(String stockId) {
|
public WechatResponseEntity<ObjectNode> startStocks(String stockId) {
|
||||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||||
wechatPayV3Client.withType(V3PayType.MARKETING_FAVOR_STOCKS_START, stockId)
|
wechatPayV3Client.withType(WechatPayV3Type.MARKETING_FAVOR_STOCKS_START, stockId)
|
||||||
.function(this::startStocksFunction)
|
.function(this::startStocksFunction)
|
||||||
.consumer(wechatResponseEntity::convert)
|
.consumer(wechatResponseEntity::convert)
|
||||||
.request();
|
.request();
|
||||||
return wechatResponseEntity;
|
return wechatResponseEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RequestEntity<?> startStocksFunction(V3PayType type, String stockId) {
|
|
||||||
|
private RequestEntity<?> startStocksFunction(WechatPayV3Type type, String stockId) {
|
||||||
WechatPayProperties.V3 v3 = wechatMetaBean.getWechatPayProperties().getV3();
|
WechatPayProperties.V3 v3 = wechatMetaBean.getWechatPayProperties().getV3();
|
||||||
String mchId = v3.getMchId();
|
String mchId = v3.getMchId();
|
||||||
String httpUrl = type.uri(WeChatServer.CHINA);
|
String httpUrl = type.uri(WeChatServer.CHINA);
|
||||||
@@ -85,10 +88,11 @@ public class WechatPayV3Api {
|
|||||||
* 查询代金券可用商户API
|
* 查询代金券可用商户API
|
||||||
*
|
*
|
||||||
* @param params the params
|
* @param params the params
|
||||||
|
* @return the wechat response entity
|
||||||
*/
|
*/
|
||||||
public WechatResponseEntity<?> queryMerchantsByStockId(StocksMchQueryParams params) {
|
public WechatResponseEntity<ObjectNode> queryMerchantsByStockId(StocksMchQueryParams params) {
|
||||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||||
wechatPayV3Client.withType(V3PayType.MARKETING_FAVOR_STOCKS_MERCHANTS, params)
|
wechatPayV3Client.withType(WechatPayV3Type.MARKETING_FAVOR_STOCKS_MERCHANTS, params)
|
||||||
.function(this::queryMerchantsFunction)
|
.function(this::queryMerchantsFunction)
|
||||||
.consumer(wechatResponseEntity::convert)
|
.consumer(wechatResponseEntity::convert)
|
||||||
.request();
|
.request();
|
||||||
@@ -98,7 +102,7 @@ public class WechatPayV3Api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private RequestEntity<?> queryMerchantsFunction(V3PayType type, StocksMchQueryParams params) {
|
private RequestEntity<?> queryMerchantsFunction(WechatPayV3Type type, StocksMchQueryParams params) {
|
||||||
|
|
||||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||||
queryParams.add("offset", String.valueOf(params.getOffset()));
|
queryParams.add("offset", String.valueOf(params.getOffset()));
|
||||||
@@ -114,21 +118,53 @@ public class WechatPayV3Api {
|
|||||||
return RequestEntity.get(uri).build();
|
return RequestEntity.get(uri).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发放代金券API.
|
||||||
|
*
|
||||||
|
* @param params the params
|
||||||
|
* @return the wechat response entity
|
||||||
|
*/
|
||||||
|
public WechatResponseEntity<ObjectNode> sendStocks(StocksSendParams params) {
|
||||||
|
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||||
|
wechatPayV3Client.withType(WechatPayV3Type.MARKETING_FAVOR_USERS_COUPONS, params)
|
||||||
|
.function(this::sendStocksFunction)
|
||||||
|
.consumer(wechatResponseEntity::convert)
|
||||||
|
.request();
|
||||||
|
return wechatResponseEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private RequestEntity<?> sendStocksFunction(WechatPayV3Type type,StocksSendParams params){
|
||||||
|
|
||||||
|
String httpUrl = type.uri(WeChatServer.CHINA);
|
||||||
|
URI uri = UriComponentsBuilder.fromHttpUrl(httpUrl).build().expand(params.getOpenid()).toUri();
|
||||||
|
params.setOpenid(null);
|
||||||
|
try {
|
||||||
|
return RequestEntity.post(uri)
|
||||||
|
.body(MAPPER.writeValueAsString(params));
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
throw new PayException("wechat app pay json failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APP下单API.
|
* APP下单API.
|
||||||
*
|
*
|
||||||
* @param payParams the pay params
|
* @param payParams the pay params
|
||||||
|
* @return the wechat response entity
|
||||||
*/
|
*/
|
||||||
public WechatResponseEntity<?> appPay(AppPayParams payParams) {
|
public WechatResponseEntity<ObjectNode> appPay(AppPayParams payParams) {
|
||||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||||
wechatPayV3Client.withType(V3PayType.APP, payParams)
|
wechatPayV3Client.withType(WechatPayV3Type.APP, payParams)
|
||||||
.function(this::appPayFunction)
|
.function(this::appPayFunction)
|
||||||
.consumer(wechatResponseEntity::convert)
|
.consumer(wechatResponseEntity::convert)
|
||||||
.request();
|
.request();
|
||||||
return wechatResponseEntity;
|
return wechatResponseEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RequestEntity<?> appPayFunction(V3PayType type, AppPayParams payParams) {
|
private RequestEntity<?> appPayFunction(WechatPayV3Type type, AppPayParams payParams) {
|
||||||
WechatPayProperties.V3 v3 = wechatMetaBean.getWechatPayProperties().getV3();
|
WechatPayProperties.V3 v3 = wechatMetaBean.getWechatPayProperties().getV3();
|
||||||
payParams.setAppid(v3.getAppId());
|
payParams.setAppid(v3.getAppId());
|
||||||
payParams.setMchid(v3.getMchId());
|
payParams.setMchid(v3.getMchId());
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.enongm.dianji.payment.wechat.v3;
|
package com.enongm.dianji.payment.wechat.v3;
|
||||||
|
|
||||||
|
|
||||||
import com.enongm.dianji.payment.wechat.enumeration.V3PayType;
|
import com.enongm.dianji.payment.wechat.enumeration.WechatPayV3Type;
|
||||||
import com.enongm.dianji.payment.wechat.v3.filter.HeaderFilter;
|
import com.enongm.dianji.payment.wechat.v3.filter.HeaderFilter;
|
||||||
import com.enongm.dianji.payment.wechat.v3.filter.HttpRequestFilter;
|
import com.enongm.dianji.payment.wechat.v3.filter.HttpRequestFilter;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
@@ -39,12 +39,12 @@ public class WechatPayV3Client {
|
|||||||
* 构造 {@link WechatRequestEntity}.
|
* 构造 {@link WechatRequestEntity}.
|
||||||
*
|
*
|
||||||
* @param <M> the type parameter
|
* @param <M> the type parameter
|
||||||
* @param v3PayType the v 3 pay type
|
* @param wechatPayV3Type the v 3 pay type
|
||||||
* @param m the m
|
* @param m the m
|
||||||
* @return the executor
|
* @return the executor
|
||||||
*/
|
*/
|
||||||
public <M> Executor<M> withType(V3PayType v3PayType, M m) {
|
public <M> Executor<M> withType(WechatPayV3Type wechatPayV3Type, M m) {
|
||||||
return new Executor<>(v3PayType,m ,this.payFilterChain);
|
return new Executor<>(wechatPayV3Type,m ,this.payFilterChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ public class WechatPayV3Client {
|
|||||||
/**
|
/**
|
||||||
* The V 3 pay type.
|
* The V 3 pay type.
|
||||||
*/
|
*/
|
||||||
private final V3PayType v3PayType;
|
private final WechatPayV3Type wechatPayV3Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Pay filter chain.
|
* The Pay filter chain.
|
||||||
@@ -68,7 +68,7 @@ public class WechatPayV3Client {
|
|||||||
/**
|
/**
|
||||||
* The Request entity bi function.
|
* The Request entity bi function.
|
||||||
*/
|
*/
|
||||||
private BiFunction<V3PayType, M, RequestEntity<?>> requestEntityBiFunction;
|
private BiFunction<WechatPayV3Type, M, RequestEntity<?>> requestEntityBiFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Response body consumer.
|
* The Response body consumer.
|
||||||
@@ -78,14 +78,14 @@ public class WechatPayV3Client {
|
|||||||
/**
|
/**
|
||||||
* Instantiates a new Executor.
|
* Instantiates a new Executor.
|
||||||
*
|
*
|
||||||
* @param v3PayType the v 3 pay type
|
* @param wechatPayV3Type the v 3 pay type
|
||||||
* @param model the model
|
* @param model the model
|
||||||
* @param payFilterChain the pay filter chain
|
* @param payFilterChain the pay filter chain
|
||||||
*/
|
*/
|
||||||
public Executor(V3PayType v3PayType,
|
public Executor(WechatPayV3Type wechatPayV3Type,
|
||||||
M model,
|
M model,
|
||||||
PayFilterChain payFilterChain) {
|
PayFilterChain payFilterChain) {
|
||||||
this.v3PayType = v3PayType;
|
this.wechatPayV3Type = wechatPayV3Type;
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.payFilterChain = payFilterChain;
|
this.payFilterChain = payFilterChain;
|
||||||
}
|
}
|
||||||
@@ -96,7 +96,7 @@ public class WechatPayV3Client {
|
|||||||
* @param requestEntityBiFunction the request entity bi function
|
* @param requestEntityBiFunction the request entity bi function
|
||||||
* @return the executor
|
* @return the executor
|
||||||
*/
|
*/
|
||||||
public Executor<M> function(BiFunction<V3PayType, M, RequestEntity<?>> requestEntityBiFunction) {
|
public Executor<M> function(BiFunction<WechatPayV3Type, M, RequestEntity<?>> requestEntityBiFunction) {
|
||||||
this.requestEntityBiFunction = requestEntityBiFunction;
|
this.requestEntityBiFunction = requestEntityBiFunction;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ public class WechatPayV3Client {
|
|||||||
*/
|
*/
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void request() {
|
public void request() {
|
||||||
RequestEntity<?> requestEntity = this.requestEntityBiFunction.apply(this.v3PayType, this.model);
|
RequestEntity<?> requestEntity = this.requestEntityBiFunction.apply(this.wechatPayV3Type, this.model);
|
||||||
payFilterChain.doChain(WechatRequestEntity.of(requestEntity, this.responseBodyConsumer));
|
payFilterChain.doChain(WechatRequestEntity.of(requestEntity, this.responseBodyConsumer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.enongm.dianji.payment.wechat.v3.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class StocksSendParams {
|
||||||
|
/**
|
||||||
|
* 批次号 必须为代金券(全场券或单品券)批次号,不支持立减与折扣。
|
||||||
|
*/
|
||||||
|
private String stockId;
|
||||||
|
/**
|
||||||
|
* 用户openid 该openid需要与接口传入中的appid有对应关系。
|
||||||
|
*/
|
||||||
|
private String openid;
|
||||||
|
/**
|
||||||
|
* 商户单据号
|
||||||
|
*/
|
||||||
|
private String outRequestNo;
|
||||||
|
/**
|
||||||
|
* 公众账号ID
|
||||||
|
*/
|
||||||
|
private String appid;
|
||||||
|
/**
|
||||||
|
* 创建批次的商户号
|
||||||
|
*/
|
||||||
|
private String stockCreatorMchid;
|
||||||
|
/**
|
||||||
|
* 指定面额发券,面额
|
||||||
|
*/
|
||||||
|
private String couponValue;
|
||||||
|
/**
|
||||||
|
* 指定面额发券,券门槛
|
||||||
|
*/
|
||||||
|
private String couponMinimum;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user