🆕 #2018 【微信支付】增加营销代金券接口和营销专用图片上传接口

Co-authored-by: 黄星 <huang.xing@aquilaflycloud.com>
This commit is contained in:
thinsstar
2021-02-26 22:10:38 +08:00
committed by GitHub
parent 52c33e207c
commit bac1b679b4
29 changed files with 3079 additions and 1 deletions

View File

@@ -0,0 +1,184 @@
package com.github.binarywang.wxpay.service;
import com.github.binarywang.wxpay.bean.marketing.*;
import com.github.binarywang.wxpay.exception.WxPayException;
/**
* <pre>
* 微信支付营销代金券接口
* </pre>
*
* @author thinsstar
*/
public interface MarketingFavorService {
/**
* <pre>
* 代金券接口-创建代金券批次API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_1.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/coupon-stocks
* </pre>
*
* @param request 请求对象
* @return FavorStocksResult 微信返回的批次号信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksCreateResult createFavorStocksV3(FavorStocksCreateRequest request) throws WxPayException;
/**
* <pre>
* 代金券接口-发放代金券API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_2.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/users/{openid}/coupons
* </pre>
*
* @param openid 用户openid
* @param request 请求对象
* @return FavorStocksResult 微信返回的发放结果信息。
* @throws WxPayException the wx pay exception
*/
FavorCouponsCreateResult createFavorCouponsV3(String openid, FavorCouponsCreateRequest request) throws WxPayException;
/**
* <pre>
* 代金券接口-激活代金券批次API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_3.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}/start
* </pre>
*
* @param stockId 批次号
* @param request 请求对象
* @return FavorStocksStartResult 微信返回的激活信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksStartResult startFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException;
/**
* <pre>
* 代金券接口-条件查询代金券批次列表API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_4.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/stocks
* </pre>
*
* @param request 请求对象
* @return FavorStocksQueryResult 微信返回的批次列表信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksQueryResult queryFavorStocksV3(FavorStocksQueryRequest request) throws WxPayException;
/**
* <pre>
* 代金券接口-查询批次详情API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_5.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}
* </pre>
*
* @param stockId 批次号
* @param stockCreatorMchid 创建批次的商户号
* @return FavorStocksQueryResult 微信返回的批次详情信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksGetResult getFavorStocksV3(String stockId, String stockCreatorMchid) throws WxPayException;
/**
* <pre>
* 代金券接口-查询代金券详情API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_6.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/users/{openid}/coupons/{coupon_id}
* </pre>
*
* @param couponId 代金券id
* @param appid 公众账号ID
* @param openid 用户openid
* @return FavorCouponsGetResult 微信返回的代金券详情信息。
* @throws WxPayException the wx pay exception
*/
FavorCouponsGetResult getFavorCouponsV3(String couponId, String appid, String openid) throws WxPayException;
/**
* <pre>
* 代金券接口-查询代金券可用商户API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_7.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}/merchants
* </pre>
*
* @param stockId 批次号
* @param stockCreatorMchid 创建批次的商户号
* @param offset 分页大小
* @param limit 创建批次的商户号
* @return FavorStocksMerchantsGetResult 微信返回的代金券可用商户信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksMerchantsGetResult getFavorStocksMerchantsV3(String stockId, String stockCreatorMchid, Integer offset, Integer limit) throws WxPayException;
/**
* <pre>
* 代金券接口-查询代金券可用单品API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_8.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}/items
* </pre>
*
* @param stockId 批次号
* @param stockCreatorMchid 创建批次的商户号
* @param offset 分页大小
* @param limit 创建批次的商户号
* @return FavorStocksItemsGetResult 微信返回的代金券可用单品信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksItemsGetResult getFavorStocksItemsV3(String stockId, String stockCreatorMchid, Integer offset, Integer limit) throws WxPayException;
/**
* <pre>
* 代金券接口-根据商户号查用户的券API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_9.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/users/{openid}/coupons
* </pre>
*
* @param request 请求对象
* @return FavorCouponsQueryResult 微信返回的用户的券信息。
* @throws WxPayException the wx pay exception
*/
FavorCouponsQueryResult queryFavorCouponsV3(FavorCouponsQueryRequest request) throws WxPayException;
/**
* <pre>
* 代金券接口-下载批次核销明细API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_10.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}/use-flow
* </pre>
*
* @param stockId 批次号
* @return FavorStocksFlowGetResult 微信返回的下载信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksFlowGetResult getFavorStocksUseFlowV3(String stockId) throws WxPayException;
/**
* <pre>
* 代金券接口-下载批次退款明细API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_11.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{stock_id}/refund-flow
* </pre>
*
* @param stockId 批次号
* @return FavorStocksFlowGetResult 微信返回的下载信息。
* @throws WxPayException the wx pay exception
*/
FavorStocksFlowGetResult getFavorStocksRefundFlowV3(String stockId) throws WxPayException;
/**
* <pre>
* 代金券接口-设置消息通知地址API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/marketing/convention/chapter3_12.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/callbacks
* </pre>
*
* @param request 批次号
* @return FavorCallbacksSaveResult 微信返回的结果信息。
* @throws WxPayException the wx pay exception
*/
FavorCallbacksSaveResult saveFavorCallbacksV3(FavorCallbacksSaveRequest request) throws WxPayException;
FavorStocksStartResult pauseFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException;
FavorStocksStartResult restartFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException;
}

View File

@@ -0,0 +1,46 @@
package com.github.binarywang.wxpay.service;
import com.github.binarywang.wxpay.bean.media.MarketingImageUploadResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
* <pre>
* 微信支付营销专用媒体接口.
* </pre>
*
* @author thinsstar
*/
public interface MarketingMediaService {
/**
* <pre>
* 营销专用接口-图片上传API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter9_0_1.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/media/image-upload
* </pre>
*
* @param imageFile 需要上传的图片文件
* @return ImageUploadResult 微信返回的媒体文件标识Id。示例值6uqyGjGrCf2GtyXP8bxrbuH9-aAoTjH-rKeSl3Lf4_So6kdkQu4w8BYVP3bzLtvR38lxt4PjtCDXsQpzqge_hQEovHzOhsLleGFQVRF-U_0
* @throws WxPayException the wx pay exception
*/
MarketingImageUploadResult imageUploadV3(File imageFile) throws WxPayException, IOException;
/**
* <pre>
* 营销专用接口-图片上传API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter9_0_1.shtml
* 接口链接https://api.mch.weixin.qq.com/v3/marketing/favor/media/image-upload
* </pre>
*
* @param inputStream 需要上传的图片文件流
* @param fileName 需要上传的图片文件名
* @return ImageUploadResult 微信返回的媒体文件标识Id。示例值6uqyGjGrCf2GtyXP8bxrbuH9-aAoTjH-rKeSl3Lf4_So6kdkQu4w8BYVP3bzLtvR38lxt4PjtCDXsQpzqge_hQEovHzOhsLleGFQVRF-U_0
* @throws WxPayException the wx pay exception
*/
MarketingImageUploadResult imageUploadV3(InputStream inputStream, String fileName) throws WxPayException, IOException;
}

View File

@@ -15,7 +15,6 @@ import org.apache.http.client.methods.HttpRequestBase;
import java.io.File;
import java.io.InputStream;
import java.net.URI;
import java.util.Date;
import java.util.Map;
@@ -161,6 +160,20 @@ public interface WxPayService {
*/
MerchantMediaService getMerchantMediaService();
/**
* 获取微信支付营销媒体服务类
*
* @return the marketing media service
*/
MarketingMediaService getMarketingMediaService();
/**
* 获取微信支付营销代金券服务类
*
* @return the marketing favor service
*/
MarketingFavorService getMarketingFavorService();
/**
* 设置企业付款服务类,允许开发者自定义实现类.
*

View File

@@ -61,6 +61,8 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
private final PayScoreService payScoreService = new PayScoreServiceImpl(this);
private final EcommerceService ecommerceService = new EcommerceServiceImpl(this);
private final MerchantMediaService merchantMediaService = new MerchantMediaServiceImpl(this);
private final MarketingMediaService marketingMediaService = new MarketingMediaServiceImpl(this);
private final MarketingFavorService marketingFavorService = new MarketingFavorServiceImpl(this);
protected WxPayConfig config;
@@ -94,6 +96,16 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
return this.merchantMediaService;
}
@Override
public MarketingMediaService getMarketingMediaService() {
return this.marketingMediaService;
}
@Override
public MarketingFavorService getMarketingFavorService() {
return this.marketingFavorService;
}
@Override
public void setEntPayService(EntPayService entPayService) {
this.entPayService = entPayService;

View File

@@ -0,0 +1,164 @@
package com.github.binarywang.wxpay.service.impl;
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.RsaCryptoUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
/**
* 微信支付-营销代金券接口
*
* @author thinsstar
*/
@Slf4j
@RequiredArgsConstructor
public class MarketingFavorServiceImpl implements MarketingFavorService {
private static final Gson GSON = new GsonBuilder().create();
private final WxPayService payService;
@Override
public FavorStocksCreateResult createFavorStocksV3(FavorStocksCreateRequest request) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/coupon-stocks", this.payService.getPayBaseUrl());
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(result, FavorStocksCreateResult.class);
}
@Override
public FavorCouponsCreateResult createFavorCouponsV3(String openid, FavorCouponsCreateRequest request) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/users/%s/coupons", this.payService.getPayBaseUrl(), openid);
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(result, FavorCouponsCreateResult.class);
}
@Override
public FavorStocksStartResult startFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/stocks/%s/start", this.payService.getPayBaseUrl(), stockId);
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(result, FavorStocksStartResult.class);
}
@Override
public FavorStocksQueryResult queryFavorStocksV3(FavorStocksQueryRequest request) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/stocks", this.payService.getPayBaseUrl());
String query = String.format("?offset=%s&limit=%s&stock_creator_mchid=%s", request.getOffset(), request.getLimit(), request.getStockCreatorMchid());
if (StringUtils.isNotBlank(request.getCreateStartTime())) {
query += "&create_start_time=" + request.getCreateStartTime();
}
if (StringUtils.isNotBlank(request.getCreateEndTime())) {
query += "&create_end_time=" + request.getCreateEndTime();
}
if (StringUtils.isNotBlank(request.getStatus())) {
query += "&status=" + request.getStatus();
}
String result = this.payService.getV3(url + query);
return GSON.fromJson(result, FavorStocksQueryResult.class);
}
@Override
public FavorStocksGetResult getFavorStocksV3(String stockId, String stockCreatorMchid) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/stocks/%s", this.payService.getPayBaseUrl(), stockId);
String query = String.format("?stock_creator_mchid=%s", stockCreatorMchid);
String result = this.payService.getV3(url + query);
return GSON.fromJson(result, FavorStocksGetResult.class);
}
@Override
public FavorCouponsGetResult getFavorCouponsV3(String couponId, String appid, String openid) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/users/%s/coupons/%s", this.payService.getPayBaseUrl(), openid, couponId);
String query = String.format("?appid=%s", appid);
String result = this.payService.getV3(url + query);
return GSON.fromJson(result, FavorCouponsGetResult.class);
}
@Override
public FavorStocksMerchantsGetResult getFavorStocksMerchantsV3(String stockId, String stockCreatorMchid, Integer offset, Integer limit) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/stocks/%s/merchants", this.payService.getPayBaseUrl(), stockId);
String query = String.format("?stock_creator_mchid=%s&offset=%s&limit=%s", stockCreatorMchid, offset, limit);
String result = this.payService.getV3(url + query);
return GSON.fromJson(result, FavorStocksMerchantsGetResult.class);
}
@Override
public FavorStocksItemsGetResult getFavorStocksItemsV3(String stockId, String stockCreatorMchid, Integer offset, Integer limit) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/stocks/%s/items", this.payService.getPayBaseUrl(), stockId);
String query = String.format("?stock_creator_mchid=%s&offset=%s&limit=%s", stockCreatorMchid, offset, limit);
String result = this.payService.getV3(url + query);
return GSON.fromJson(result, FavorStocksItemsGetResult.class);
}
@Override
public FavorCouponsQueryResult queryFavorCouponsV3(FavorCouponsQueryRequest request) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/users/%s/coupons", this.payService.getPayBaseUrl(), request.getOpenid());
String query = String.format("?appid=%s", request.getAppid());
if (StringUtils.isNotBlank(request.getStockId())) {
query += "&stock_id=" + request.getStockId();
}
if (StringUtils.isNotBlank(request.getStatus())) {
query += "&status=" + request.getStatus();
}
if (StringUtils.isNotBlank(request.getCreatorMchid())) {
query += "&creator_mchid=" + request.getCreatorMchid();
}
if (StringUtils.isNotBlank(request.getSenderMchid())) {
query += "&sender_mchid=" + request.getSenderMchid();
}
if (StringUtils.isNotBlank(request.getAvailableMchid())) {
query += "&available_mchid=" + request.getAvailableMchid();
}
if (request.getOffset() != null) {
query += "&offset=" + request.getOffset();
}
if (request.getLimit() != null) {
query += "&limit=" + request.getLimit();
}
String result = this.payService.getV3(url + query);
return GSON.fromJson(result, FavorCouponsQueryResult.class);
}
@Override
public FavorStocksFlowGetResult getFavorStocksUseFlowV3(String stockId) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/stocks/%s/use-flow", this.payService.getPayBaseUrl(), stockId);
String result = this.payService.getV3(url);
return GSON.fromJson(result, FavorStocksFlowGetResult.class);
}
@Override
public FavorStocksFlowGetResult getFavorStocksRefundFlowV3(String stockId) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/stocks/%s/refund-flow", this.payService.getPayBaseUrl(), stockId);
String result = this.payService.getV3(url);
return GSON.fromJson(result, FavorStocksFlowGetResult.class);
}
@Override
public FavorCallbacksSaveResult saveFavorCallbacksV3(FavorCallbacksSaveRequest request) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/callbacks", this.payService.getPayBaseUrl());
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(result, FavorCallbacksSaveResult.class);
}
@Override
public FavorStocksStartResult pauseFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/stocks/%s/start", this.payService.getPayBaseUrl(), stockId);
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(result, FavorStocksStartResult.class);
}
@Override
public FavorStocksStartResult restartFavorStocksV3(String stockId, FavorStocksSetRequest request) throws WxPayException {
String url = String.format("%s/v3/marketing/favor/stocks/%s/start", this.payService.getPayBaseUrl(), stockId);
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(result, FavorStocksStartResult.class);
}
}

View File

@@ -0,0 +1,60 @@
package com.github.binarywang.wxpay.service.impl;
import com.github.binarywang.wxpay.bean.media.MarketingImageUploadResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.MarketingMediaService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.v3.WechatPayUploadHttpPost;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import java.io.*;
import java.net.URI;
/**
* 微信支付-营销专用媒体文件上传service
*
* @author thinsstar
*/
@Slf4j
@RequiredArgsConstructor
public class MarketingMediaServiceImpl implements MarketingMediaService {
private final WxPayService payService;
@Override
public MarketingImageUploadResult imageUploadV3(File imageFile) throws WxPayException, IOException {
String url = String.format("%s/v3/marketing/favor/media/image-upload", this.payService.getPayBaseUrl());
try (FileInputStream s1 = new FileInputStream(imageFile)) {
String sha256 = DigestUtils.sha256Hex(s1);
try (InputStream s2 = new FileInputStream(imageFile)) {
WechatPayUploadHttpPost request = new WechatPayUploadHttpPost.Builder(URI.create(url))
.withImage(imageFile.getName(), sha256, s2)
.build();
String result = this.payService.postV3(url, request);
return MarketingImageUploadResult.fromJson(result);
}
}
}
@Override
public MarketingImageUploadResult imageUploadV3(InputStream inputStream, String fileName) throws WxPayException, IOException {
String url = String.format("%s/v3/marketing/favor/media/image-upload", this.payService.getPayBaseUrl());
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
byte[] buffer = new byte[2048];
int len;
while ((len = inputStream.read(buffer)) > -1) {
bos.write(buffer, 0, len);
}
bos.flush();
byte[] data = bos.toByteArray();
String sha256 = DigestUtils.sha256Hex(data);
WechatPayUploadHttpPost request = new WechatPayUploadHttpPost.Builder(URI.create(url))
.withImage(fileName, sha256, new ByteArrayInputStream(data))
.build();
String result = this.payService.postV3(url, request);
return MarketingImageUploadResult.fromJson(result);
}
}
}