mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2026-03-10 00:13:40 +08:00
🆕 #2022 【微信支付】增加智慧商圈相关接口和解析支付营销代金券核销回调消息的方法
* 增加解析支付营销代金券核销回调消息解析 * 增加微信支付智慧商圈接口和回调解析 Co-authored-by: 黄星 <huang.xing@aquilaflycloud.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
package com.github.binarywang.wxpay.service;
|
||||
|
||||
import com.github.binarywang.wxpay.bean.businesscircle.BusinessCircleNotifyData;
|
||||
import com.github.binarywang.wxpay.bean.businesscircle.PaidResult;
|
||||
import com.github.binarywang.wxpay.bean.businesscircle.PointsNotifyRequest;
|
||||
import com.github.binarywang.wxpay.bean.businesscircle.RefundResult;
|
||||
import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader;
|
||||
import com.github.binarywang.wxpay.exception.WxPayException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 微信支付智慧商圈API
|
||||
* </pre>
|
||||
*
|
||||
* @author thinsstar
|
||||
*/
|
||||
public interface BusinessCircleService {
|
||||
/**
|
||||
* <pre>
|
||||
* 智慧商圈接口-商圈积分同步API
|
||||
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/businesscircle/chapter3_2.shtml
|
||||
* 接口链接:https://api.mch.weixin.qq.com/v3/businesscircle/points/notify
|
||||
* </pre>
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
void notifyPoints(PointsNotifyRequest request) throws WxPayException;
|
||||
|
||||
BusinessCircleNotifyData parseNotifyData(String data, SignatureHeader header) throws WxPayException;
|
||||
|
||||
PaidResult decryptPaidNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException;
|
||||
|
||||
RefundResult decryptRefundNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.binarywang.wxpay.service;
|
||||
|
||||
import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader;
|
||||
import com.github.binarywang.wxpay.bean.marketing.*;
|
||||
import com.github.binarywang.wxpay.exception.WxPayException;
|
||||
|
||||
@@ -172,13 +173,39 @@ public interface MarketingFavorService {
|
||||
* 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/callbacks
|
||||
* </pre>
|
||||
*
|
||||
* @param request 批次号
|
||||
* @param request 请求对象
|
||||
* @return FavorCallbacksSaveResult 微信返回的结果信息。
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
FavorCallbacksSaveResult saveFavorCallbacksV3(FavorCallbacksSaveRequest request) throws WxPayException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 代金券接口-暂停代金券批次API
|
||||
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_13.shtml
|
||||
* 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}/pause
|
||||
* </pre>
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @return FavorCallbacksSaveResult 微信返回的结果信息。
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
FavorStocksStartResult pauseFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 代金券接口-重启代金券批次API
|
||||
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_14.shtml
|
||||
* 接口链接:https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}/restart
|
||||
* </pre>
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @return FavorCallbacksSaveResult 微信返回的结果信息。
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
FavorStocksStartResult restartFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException;
|
||||
|
||||
UseNotifyData parseNotifyData(String data, SignatureHeader header) throws WxPayException;
|
||||
|
||||
FavorCouponsUseResult decryptNotifyDataResource(UseNotifyData data) throws WxPayException;
|
||||
}
|
||||
|
||||
@@ -153,6 +153,13 @@ public interface WxPayService {
|
||||
*/
|
||||
EcommerceService getEcommerceService();
|
||||
|
||||
/**
|
||||
* 获取微信支付智慧商圈服务类
|
||||
*
|
||||
* @return the business circle service
|
||||
*/
|
||||
BusinessCircleService getBusinessCircleService();
|
||||
|
||||
/**
|
||||
* 获取微信支付通用媒体服务类
|
||||
*
|
||||
|
||||
@@ -60,6 +60,7 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
|
||||
private final RedpackService redpackService = new RedpackServiceImpl(this);
|
||||
private final PayScoreService payScoreService = new PayScoreServiceImpl(this);
|
||||
private final EcommerceService ecommerceService = new EcommerceServiceImpl(this);
|
||||
private final BusinessCircleService businessCircleService = new BusinessCircleServiceImpl(this);
|
||||
private final MerchantMediaService merchantMediaService = new MerchantMediaServiceImpl(this);
|
||||
private final MarketingMediaService marketingMediaService = new MarketingMediaServiceImpl(this);
|
||||
private final MarketingFavorService marketingFavorService = new MarketingFavorServiceImpl(this);
|
||||
@@ -91,6 +92,11 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
|
||||
return ecommerceService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BusinessCircleService getBusinessCircleService() {
|
||||
return this.businessCircleService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MerchantMediaService getMerchantMediaService() {
|
||||
return this.merchantMediaService;
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.github.binarywang.wxpay.service.impl;
|
||||
|
||||
import com.github.binarywang.wxpay.bean.businesscircle.BusinessCircleNotifyData;
|
||||
import com.github.binarywang.wxpay.bean.businesscircle.PaidResult;
|
||||
import com.github.binarywang.wxpay.bean.businesscircle.PointsNotifyRequest;
|
||||
import com.github.binarywang.wxpay.bean.businesscircle.RefundResult;
|
||||
import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader;
|
||||
import com.github.binarywang.wxpay.exception.WxPayException;
|
||||
import com.github.binarywang.wxpay.service.BusinessCircleService;
|
||||
import com.github.binarywang.wxpay.service.WxPayService;
|
||||
import com.github.binarywang.wxpay.v3.util.AesUtils;
|
||||
import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 微信支付-微信支付智慧商圈service
|
||||
*
|
||||
* @author thinsstar
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class BusinessCircleServiceImpl implements BusinessCircleService {
|
||||
private static final Gson GSON = new GsonBuilder().create();
|
||||
private final WxPayService payService;
|
||||
|
||||
@Override
|
||||
public void notifyPoints(PointsNotifyRequest request) throws WxPayException {
|
||||
String url = String.format("%s/v3/businesscircle/points/notify", this.payService.getPayBaseUrl());
|
||||
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
|
||||
this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验通知签名
|
||||
*
|
||||
* @param header 通知头信息
|
||||
* @param data 通知数据
|
||||
* @return true:校验通过 false:校验不通过
|
||||
*/
|
||||
private boolean verifyNotifySign(SignatureHeader header, String data) {
|
||||
String beforeSign = String.format("%s%n%s%n%s%n", header.getTimeStamp(), header.getNonce(), data);
|
||||
return payService.getConfig().getVerifier().verify(header.getSerialNo(),
|
||||
beforeSign.getBytes(StandardCharsets.UTF_8), header.getSigned());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BusinessCircleNotifyData parseNotifyData(String data, SignatureHeader header) throws WxPayException {
|
||||
if (Objects.nonNull(header) && !this.verifyNotifySign(header, data)) {
|
||||
throw new WxPayException("非法请求,头部信息验证失败");
|
||||
}
|
||||
return GSON.fromJson(data, BusinessCircleNotifyData.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaidResult decryptPaidNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException {
|
||||
BusinessCircleNotifyData.Resource resource = data.getResource();
|
||||
String cipherText = resource.getCipherText();
|
||||
String associatedData = resource.getAssociatedData();
|
||||
String nonce = resource.getNonce();
|
||||
String apiV3Key = this.payService.getConfig().getApiV3Key();
|
||||
try {
|
||||
return GSON.fromJson(AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key), PaidResult.class);
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
throw new WxPayException("解析报文异常!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefundResult decryptRefundNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException {
|
||||
BusinessCircleNotifyData.Resource resource = data.getResource();
|
||||
String cipherText = resource.getCipherText();
|
||||
String associatedData = resource.getAssociatedData();
|
||||
String nonce = resource.getNonce();
|
||||
String apiV3Key = this.payService.getConfig().getApiV3Key();
|
||||
try {
|
||||
return GSON.fromJson(AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key), RefundResult.class);
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
throw new WxPayException("解析报文异常!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.github.binarywang.wxpay.service.impl;
|
||||
|
||||
import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader;
|
||||
import com.github.binarywang.wxpay.bean.marketing.*;
|
||||
import com.github.binarywang.wxpay.exception.WxPayException;
|
||||
import com.github.binarywang.wxpay.service.MarketingFavorService;
|
||||
import com.github.binarywang.wxpay.service.WxPayService;
|
||||
import com.github.binarywang.wxpay.v3.util.AesUtils;
|
||||
import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
@@ -11,6 +13,11 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 微信支付-营销代金券接口
|
||||
*
|
||||
@@ -161,4 +168,39 @@ public class MarketingFavorServiceImpl implements MarketingFavorService {
|
||||
String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
|
||||
return GSON.fromJson(result, FavorStocksStartResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验通知签名
|
||||
*
|
||||
* @param header 通知头信息
|
||||
* @param data 通知数据
|
||||
* @return true:校验通过 false:校验不通过
|
||||
*/
|
||||
private boolean verifyNotifySign(SignatureHeader header, String data) {
|
||||
String beforeSign = String.format("%s%n%s%n%s%n", header.getTimeStamp(), header.getNonce(), data);
|
||||
return payService.getConfig().getVerifier().verify(header.getSerialNo(),
|
||||
beforeSign.getBytes(StandardCharsets.UTF_8), header.getSigned());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UseNotifyData parseNotifyData(String data, SignatureHeader header) throws WxPayException {
|
||||
if (Objects.nonNull(header) && !this.verifyNotifySign(header, data)) {
|
||||
throw new WxPayException("非法请求,头部信息验证失败");
|
||||
}
|
||||
return GSON.fromJson(data, UseNotifyData.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FavorCouponsUseResult decryptNotifyDataResource(UseNotifyData data) throws WxPayException {
|
||||
UseNotifyData.Resource resource = data.getResource();
|
||||
String cipherText = resource.getCipherText();
|
||||
String associatedData = resource.getAssociatedData();
|
||||
String nonce = resource.getNonce();
|
||||
String apiV3Key = this.payService.getConfig().getApiV3Key();
|
||||
try {
|
||||
return GSON.fromJson(AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key), FavorCouponsUseResult.class);
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
throw new WxPayException("解析报文异常!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user