mirror of
https://github.com/dromara/payment-spring-boot.git
synced 2026-03-13 21:33:41 +08:00
重启批次接口 营销回调接口
This commit is contained in:
@@ -60,14 +60,26 @@ public class WechatPayConfiguration {
|
||||
* Wechat pay v3 api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay v 3 client
|
||||
* @param wechatMetaBean the wechat meta bean
|
||||
* @param wechatMetaBean the wechat meta bean
|
||||
* @return the wechat pay v 3 api
|
||||
*/
|
||||
@Bean
|
||||
public WechatPayApi wechatPayApi(WechatPayClient wechatPayClient, WechatMetaBean wechatMetaBean) {
|
||||
return new WechatPayApi(wechatPayClient,wechatMetaBean);
|
||||
return new WechatPayApi(wechatPayClient, wechatMetaBean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wechat pay callback.
|
||||
*
|
||||
* @param signatureProvider the signature provider
|
||||
* @return the wechat pay callback
|
||||
*/
|
||||
@Bean
|
||||
public WechatPayCallback wechatPayCallback(SignatureProvider signatureProvider) {
|
||||
return new WechatPayCallback(signatureProvider);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 公众号授权工具用于获取用户openId,需要配置{@link WechatPayProperties.Mp}.
|
||||
*
|
||||
@@ -76,7 +88,7 @@ public class WechatPayConfiguration {
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "wechat.pay", name = "v3.mp.app-id")
|
||||
public OAuth2AuthorizationRequestRedirectProvider oAuth2Provider(WechatPayProperties wechatPayProperties){
|
||||
public OAuth2AuthorizationRequestRedirectProvider oAuth2Provider(WechatPayProperties wechatPayProperties) {
|
||||
WechatPayProperties.Mp mp = wechatPayProperties.getV3().getMp();
|
||||
return new OAuth2AuthorizationRequestRedirectProvider(mp.getAppId(), mp.getAppSecret());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.enongm.dianji.payment.wechat.enumeration;
|
||||
|
||||
/**
|
||||
* The enum Coupon status.
|
||||
*
|
||||
* @author Dax
|
||||
* @since 10 :57
|
||||
*/
|
||||
public enum CouponStatus {
|
||||
/**
|
||||
* 可用.
|
||||
*/
|
||||
SENDED,
|
||||
/**
|
||||
* 已实扣.
|
||||
*/
|
||||
USED,
|
||||
/**
|
||||
* 已过期.
|
||||
*/
|
||||
EXPIRED
|
||||
}
|
||||
@@ -43,6 +43,10 @@ public enum WechatPayV3Type {
|
||||
* 激活代金券批次API.
|
||||
*/
|
||||
MARKETING_FAVOR_STOCKS_START(HttpMethod.POST,"%s/v3/marketing/favor/stocks/{stock_id}/start"),
|
||||
/**
|
||||
* 重启代金券
|
||||
*/
|
||||
MARKETING_FAVOR_STOCKS_RESTART(HttpMethod.POST,"%s/v3/marketing/favor/stocks/{stock_id}/restart"),
|
||||
/**
|
||||
* 发放代金券API & 根据商户号查用户的券.
|
||||
*/
|
||||
@@ -62,7 +66,11 @@ public enum WechatPayV3Type {
|
||||
/**
|
||||
* 营销图片上传API.
|
||||
*/
|
||||
MARKETING_IMAGE_UPLOAD(HttpMethod.POST, "%s/v3/marketing/favor/media/image-upload");
|
||||
MARKETING_IMAGE_UPLOAD(HttpMethod.POST, "%s/v3/marketing/favor/media/image-upload"),
|
||||
/**
|
||||
* 设置核销回调通知API.
|
||||
*/
|
||||
MARKETING_FAVOR_CALLBACKS(HttpMethod.POST, "%s/v3/marketing/favor/callbacks");
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ package com.enongm.dianji.payment.wechat.oauth2;
|
||||
import com.enongm.dianji.payment.PayException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -11,10 +12,11 @@ import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestOperations;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -48,14 +50,17 @@ public class OAuth2AuthorizationRequestRedirectProvider {
|
||||
* @param redirectUri the redirect uri
|
||||
* @return uri components
|
||||
*/
|
||||
public UriComponents redirect(String phoneNumber, String redirectUri) {
|
||||
@SneakyThrows
|
||||
public String redirect(String phoneNumber, String redirectUri) {
|
||||
Assert.hasText(redirectUri, "redirectUri is required");
|
||||
String encode = URLEncoder.encode(redirectUri, StandardCharsets.UTF_8.name());
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
queryParams.add("appid", appId);
|
||||
queryParams.add("redirect_uri", redirectUri);
|
||||
queryParams.add("redirect_uri", encode);
|
||||
queryParams.add("response_type", "code");
|
||||
queryParams.add("scope", "snsapi_base");
|
||||
queryParams.add("state", phoneNumber);
|
||||
return UriComponentsBuilder.fromHttpUrl(AUTHORIZATION_URI).queryParams(queryParams).build();
|
||||
return UriComponentsBuilder.fromHttpUrl(AUTHORIZATION_URI).queryParams(queryParams).build().toUriString() + "#wechat_redirect";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@ package com.enongm.dianji.payment.wechat.v3;
|
||||
|
||||
|
||||
import com.enongm.dianji.payment.PayException;
|
||||
import com.enongm.dianji.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import com.enongm.dianji.payment.wechat.enumeration.WeChatServer;
|
||||
import com.enongm.dianji.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import com.enongm.dianji.payment.wechat.v3.model.ResponseSignVerifyParams;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
@@ -107,27 +108,24 @@ public class SignatureProvider {
|
||||
/**
|
||||
* 我方对响应验签,和应答签名做比较,使用微信平台证书.
|
||||
*
|
||||
* @param wechatpaySerial response.headers['Wechatpay-Serial'] 当前使用的微信平台证书序列号
|
||||
* @param wechatpaySignature response.headers['Wechatpay-Signature'] 微信平台签名
|
||||
* @param wechatpayTimestamp response.headers['Wechatpay-Timestamp'] 微信服务器的时间戳
|
||||
* @param wechatpayNonce response.headers['Wechatpay-Nonce'] 微信服务器提供的随机串
|
||||
* @param body response.body 微信服务器的响应体
|
||||
* @param params the params
|
||||
* @return the boolean
|
||||
*/
|
||||
@SneakyThrows
|
||||
public boolean responseSignVerify(String wechatpaySerial, String wechatpaySignature, String wechatpayTimestamp, String wechatpayNonce, String body) {
|
||||
public boolean responseSignVerify(ResponseSignVerifyParams params) {
|
||||
|
||||
String wechatpaySerial = params.getWechatpaySerial();
|
||||
if (CERTIFICATE_MAP.isEmpty() || !CERTIFICATE_MAP.containsKey(wechatpaySerial)) {
|
||||
refreshCertificate();
|
||||
}
|
||||
Certificate certificate = CERTIFICATE_MAP.get(wechatpaySerial);
|
||||
|
||||
final String signatureStr = createSign(wechatpayTimestamp, wechatpayNonce, body);
|
||||
final String signatureStr = createSign(params.getWechatpayTimestamp(), params.getWechatpayNonce(), params.getBody());
|
||||
Signature signer = Signature.getInstance("SHA256withRSA");
|
||||
signer.initVerify(certificate);
|
||||
signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
return signer.verify(Base64Utils.decodeFromString(wechatpaySignature));
|
||||
return signer.verify(Base64Utils.decodeFromString(params.getWechatpaySignature()));
|
||||
}
|
||||
|
||||
|
||||
@@ -207,7 +205,6 @@ public class SignatureProvider {
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, spec);
|
||||
cipher.updateAAD(associatedData.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
|
||||
byte[] bytes;
|
||||
try {
|
||||
bytes = cipher.doFinal(Base64Utils.decodeFromString(ciphertext));
|
||||
@@ -221,6 +218,11 @@ public class SignatureProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets wechat meta bean.
|
||||
*
|
||||
* @return the wechat meta bean
|
||||
*/
|
||||
public WechatMetaBean getWechatMetaBean() {
|
||||
return wechatMetaBean;
|
||||
}
|
||||
|
||||
@@ -79,13 +79,7 @@ public class WechatPayApi {
|
||||
String httpUrl = type.uri(WeChatServer.CHINA);
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(httpUrl).build().toUri();
|
||||
params.setBelongMerchant(mchId);
|
||||
try {
|
||||
return RequestEntity.post(uri)
|
||||
.body(MAPPER.writeValueAsString(params));
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new PayException("wechat app pay json failed");
|
||||
return postRequestEntity(uri, params);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,27 +91,35 @@ public class WechatPayApi {
|
||||
public WechatResponseEntity<ObjectNode> startStock(String stockId) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
wechatPayClient.withType(WechatPayV3Type.MARKETING_FAVOR_STOCKS_START, stockId)
|
||||
.function(this::startStockFunction)
|
||||
.function(this::startAndRestartStockFunction)
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
private RequestEntity<?> startStockFunction(WechatPayV3Type type, String stockId) {
|
||||
/**
|
||||
* 重启代金券批次API.
|
||||
*
|
||||
* @param stockId the stock id
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> restartStock(String stockId) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
wechatPayClient.withType(WechatPayV3Type.MARKETING_FAVOR_STOCKS_RESTART, stockId)
|
||||
.function(this::startAndRestartStockFunction)
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
private RequestEntity<?> startAndRestartStockFunction(WechatPayV3Type type, String stockId) {
|
||||
WechatPayProperties.V3 v3 = wechatMetaBean.getWechatPayProperties().getV3();
|
||||
String mchId = v3.getMchId();
|
||||
Map<String, String> body = new HashMap<>();
|
||||
body.put("stock_creator_mchid", mchId);
|
||||
String httpUrl = type.uri(WeChatServer.CHINA);
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(httpUrl).build().expand(stockId).toUri();
|
||||
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("stock_creator_mchid", mchId);
|
||||
try {
|
||||
return RequestEntity.post(uri)
|
||||
.body(MAPPER.writeValueAsString(map));
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new PayException("wechat app pay json failed");
|
||||
return postRequestEntity(uri, body);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,13 +249,34 @@ public class WechatPayApi {
|
||||
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");
|
||||
return postRequestEntity(uri, params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 代金券核销回调通知.
|
||||
*
|
||||
* @param notifyUrl the notify url
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> marketingFavorCallback(String notifyUrl) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
wechatPayClient.withType(WechatPayV3Type.MARKETING_FAVOR_CALLBACKS, notifyUrl)
|
||||
.function(this::marketingFavorCallbackFunction)
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
private RequestEntity<?> marketingFavorCallbackFunction(WechatPayV3Type type, String notifyUrl) {
|
||||
WechatPayProperties.V3 v3 = wechatMetaBean.getWechatPayProperties().getV3();
|
||||
Map<String, Object> body = new HashMap<>(3);
|
||||
body.put("mchid", v3.getMchId());
|
||||
body.put("notify_url", notifyUrl);
|
||||
body.put("switch", true);
|
||||
String httpUrl = type.uri(WeChatServer.CHINA);
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(httpUrl).build().toUri();
|
||||
return postRequestEntity(uri, body);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -277,13 +300,19 @@ public class WechatPayApi {
|
||||
payParams.setMchid(v3.getMchId());
|
||||
String httpUrl = type.uri(WeChatServer.CHINA);
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(httpUrl).build().toUri();
|
||||
return postRequestEntity(uri, payParams);
|
||||
}
|
||||
|
||||
|
||||
private static RequestEntity<?> postRequestEntity(URI uri, Object params) {
|
||||
try {
|
||||
return RequestEntity.post(uri)
|
||||
.body(MAPPER.writeValueAsString(payParams));
|
||||
.body(MAPPER.writeValueAsString(params));
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new PayException("wechat app pay json failed");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.enongm.dianji.payment.wechat.v3;
|
||||
|
||||
import com.enongm.dianji.payment.PayException;
|
||||
import com.enongm.dianji.payment.wechat.v3.model.CallbackParams;
|
||||
import com.enongm.dianji.payment.wechat.v3.model.CouponConsumeData;
|
||||
import com.enongm.dianji.payment.wechat.v3.model.ResponseSignVerifyParams;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Dax
|
||||
* @since 10:21
|
||||
*/
|
||||
public class WechatPayCallback {
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
private final SignatureProvider signatureProvider;
|
||||
|
||||
static {
|
||||
MAPPER.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
|
||||
MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
}
|
||||
|
||||
public WechatPayCallback(SignatureProvider signatureProvider) {
|
||||
this.signatureProvider = signatureProvider;
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public CouponConsumeData wechatPayCouponCallback(ResponseSignVerifyParams params) {
|
||||
|
||||
if (signatureProvider.responseSignVerify(params)) {
|
||||
CallbackParams callbackParams = MAPPER.readValue(params.getBody(), CallbackParams.class);
|
||||
|
||||
CallbackParams.Resource resource = callbackParams.getResource();
|
||||
String associatedData = resource.getAssociatedData();
|
||||
String nonce = resource.getNonce();
|
||||
String ciphertext = resource.getCiphertext();
|
||||
String data = signatureProvider.decryptResponseBody(associatedData, nonce, ciphertext);
|
||||
Assert.hasText(data, "decryptData is required");
|
||||
return MAPPER.readValue(data, CouponConsumeData.class);
|
||||
}
|
||||
throw new PayException("invalid wechat pay coupon callback");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ package com.enongm.dianji.payment.wechat.v3;
|
||||
import com.enongm.dianji.payment.PayException;
|
||||
import com.enongm.dianji.payment.wechat.WechatPayResponseErrorHandler;
|
||||
import com.enongm.dianji.payment.wechat.enumeration.WechatPayV3Type;
|
||||
import com.enongm.dianji.payment.wechat.v3.model.ResponseSignVerifyParams;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.http.*;
|
||||
@@ -97,7 +98,7 @@ public class WechatPayClient {
|
||||
/**
|
||||
* Function executor.
|
||||
*
|
||||
* @param requestEntityBiFunction the request entity bi function
|
||||
* @param requestEntityBiFunction the request entity bifunction
|
||||
* @return the executor
|
||||
*/
|
||||
public Executor<M> function(BiFunction<WechatPayV3Type, M, RequestEntity<?>> requestEntityBiFunction) {
|
||||
@@ -170,26 +171,28 @@ public class WechatPayClient {
|
||||
ResponseEntity<ObjectNode> responseEntity = restOperations.exchange(requestEntity, ObjectNode.class);
|
||||
HttpHeaders headers = responseEntity.getHeaders();
|
||||
ObjectNode body = responseEntity.getBody();
|
||||
|
||||
if (!responseEntity.getStatusCode().is2xxSuccessful()) {
|
||||
throw new PayException("wechat pay server error,result : " + body);
|
||||
}
|
||||
if (Objects.isNull(body)) {
|
||||
throw new IllegalStateException("cant obtain response body");
|
||||
}
|
||||
|
||||
|
||||
ResponseSignVerifyParams params = new ResponseSignVerifyParams();
|
||||
// 微信请求回调id
|
||||
// String RequestId = response.header("Request-ID");
|
||||
// 微信平台证书序列号 用来取微信平台证书
|
||||
String wechatpaySerial = headers.getFirst("Wechatpay-Serial");
|
||||
params.setWechatpaySerial(headers.getFirst("Wechatpay-Serial"));
|
||||
//获取应答签名
|
||||
String wechatpaySignature = headers.getFirst("Wechatpay-Signature");
|
||||
params.setWechatpaySignature(headers.getFirst("Wechatpay-Signature"));
|
||||
//构造验签名串
|
||||
String wechatpayTimestamp = headers.getFirst("Wechatpay-Timestamp");
|
||||
String wechatpayNonce = headers.getFirst("Wechatpay-Nonce");
|
||||
params.setWechatpayTimestamp(headers.getFirst("Wechatpay-Timestamp"));
|
||||
params.setWechatpayNonce(headers.getFirst("Wechatpay-Nonce"));
|
||||
params.setBody(body.toString());
|
||||
|
||||
// 验证微信服务器签名
|
||||
if (signatureProvider.responseSignVerify(wechatpaySerial,
|
||||
wechatpaySignature,
|
||||
wechatpayTimestamp,
|
||||
wechatpayNonce,
|
||||
body.toString())) {
|
||||
if (signatureProvider.responseSignVerify(params)) {
|
||||
Consumer<ResponseEntity<ObjectNode>> responseConsumer = requestEntity.getResponseBodyConsumer();
|
||||
if (Objects.nonNull(responseConsumer)) {
|
||||
// 验证通过消费
|
||||
|
||||
@@ -31,7 +31,10 @@ public class WechatResponseEntity<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean successful() {
|
||||
return this.httpStatus == HttpStatus.OK.value();
|
||||
public boolean is2xxSuccessful() {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("wechat httpStatus {}", this.httpStatus);
|
||||
}
|
||||
return HttpStatus.valueOf(this.httpStatus).is2xxSuccessful();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.enongm.dianji.payment.wechat.v3.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author Dax
|
||||
* @since 10:13
|
||||
*/
|
||||
@Data
|
||||
public class CallbackParams {
|
||||
private String id;
|
||||
private String createTime;
|
||||
private String eventType;
|
||||
private String resourceType;
|
||||
private String summary;
|
||||
private Resource resource;
|
||||
|
||||
|
||||
@Data
|
||||
public static class Resource {
|
||||
private String algorithm;
|
||||
private String ciphertext;
|
||||
private String associatedData;
|
||||
private String nonce;
|
||||
private String originalType;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
package com.enongm.dianji.payment.wechat.v3.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 已实扣代金券信息
|
||||
*/
|
||||
@Data
|
||||
public class ConsumeInformation {
|
||||
|
||||
private String consumeMchid;
|
||||
|
||||
private String consumeTime;
|
||||
|
||||
private List<GoodsDetail> goodsDetail;
|
||||
|
||||
private String transactionId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
package com.enongm.dianji.payment.wechat.v3.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 微信代金券核销通知参数
|
||||
*/
|
||||
@Data
|
||||
public class CouponConsumeData {
|
||||
|
||||
|
||||
private String availableBeginTime;
|
||||
private String availableEndTime;
|
||||
private ConsumeInformation consumeInformation;
|
||||
private String couponId;
|
||||
private String couponName;
|
||||
private String couponType;
|
||||
private String createTime;
|
||||
private String description;
|
||||
private DiscountTo discountTo;
|
||||
private boolean noCash;
|
||||
private NormalCouponInformation normalCouponInformation;
|
||||
private boolean singleitem;
|
||||
private SingleitemDiscountOff singleitemDiscountOff;
|
||||
private String status;
|
||||
private String stockCreatorMchid;
|
||||
private String stockId;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
package com.enongm.dianji.payment.wechat.v3.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 减至优惠限定字段,仅减至优惠场景有返回
|
||||
*/
|
||||
@Data
|
||||
public class DiscountTo {
|
||||
|
||||
private Long cutToPrice;
|
||||
private Long maxPrice;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
package com.enongm.dianji.payment.wechat.v3.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 商户下单接口传的单品信息
|
||||
*/
|
||||
@Data
|
||||
public class GoodsDetail {
|
||||
|
||||
private Long discountAmount;
|
||||
private String goodsId;
|
||||
private Long price;
|
||||
private Long quantity;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
package com.enongm.dianji.payment.wechat.v3.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 普通满减券面额、门槛信息
|
||||
*/
|
||||
@Data
|
||||
public class NormalCouponInformation {
|
||||
|
||||
private Long couponAmount;
|
||||
private Long transactionMinimum;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.enongm.dianji.payment.wechat.v3.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 微信的响应签名校验参数
|
||||
*
|
||||
* @author Dax
|
||||
* @see com.enongm.dianji.payment.wechat.v3.SignatureProvider#responseSignVerify(String, String, String, String, String)
|
||||
* @since 16:32
|
||||
*/
|
||||
@Data
|
||||
public class ResponseSignVerifyParams {
|
||||
/**
|
||||
* response.headers['Wechatpay-Serial'] 当前使用的微信平台证书序列号
|
||||
*/
|
||||
private String wechatpaySerial;
|
||||
/**
|
||||
* response.headers['Wechatpay-Signature'] 微信平台签名
|
||||
*/
|
||||
private String wechatpaySignature;
|
||||
/**
|
||||
* response.headers['Wechatpay-Timestamp'] 微信服务器的时间戳
|
||||
*/
|
||||
private String wechatpayTimestamp;
|
||||
/**
|
||||
* response.headers['Wechatpay-Nonce'] 微信服务器提供的随机串
|
||||
*/
|
||||
private String wechatpayNonce;
|
||||
/**
|
||||
* response.body 微信服务器的响应体
|
||||
*/
|
||||
private String body;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
package com.enongm.dianji.payment.wechat.v3.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 单品优惠特定信息
|
||||
*/
|
||||
@Data
|
||||
public class SingleitemDiscountOff {
|
||||
|
||||
private Long singlePriceMax;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user