发放优惠券

This commit is contained in:
felord.cn
2020-11-21 22:28:36 +08:00
parent 7b58dbb17b
commit c51488af18
5 changed files with 101 additions and 26 deletions

View File

@@ -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;
} }

View File

@@ -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();

View File

@@ -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());

View File

@@ -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));
} }
} }

View File

@@ -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;
}