步骤一:下载账单文件,得到账单文件密文ciphertext;
步骤二:使用商户证书私钥解密从接口获取的加密密钥(变量名:encrypt_key)得到密钥明文key;
步骤三:利用步骤一、二中得到的账单密文ciphertext,密钥key和接口返回的随机字符串nonce解密账单,得到账单明文。
步骤四:把明文数据以excel文件返回
*引入基础依赖
<!-- 微信支付SDK 商户平台模式-->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
<version>4.5.0</version>
</dependency>
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>0.2.12</version>
</dependency>
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.4.9</version>
</dependency>
<!-- 微信支付SDK END-->
* 下载方法代码
/**
* 申请二级商户资金账单
*/
@PostMapping("getAllSubMchFundFlowBill")
public void getAllSubMchFundFlowBill(@RequestBody TradeBillVo tradeBillVo, HttpServletResponse response) {
PmsApplicationServePay config = getConfig();
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
try {
FundBillRequest request = FundBillRequest.builder()
.billDate(tradeBillVo.getBillDate())
.accountType(tradeBillVo.getAccountType())
.algorithm(tradeBillVo.getAlgorithm()).build();
FundBillResult result = ecommerceService.applyFundBill(FundBillTypeEnum.SUB_FUND_FLOW_BILL, request);
if (result.getDownloadBillCount() > 0) {
JSONArray billList = new JSONArray(result.getDownloadBillList());
for (Object object : billList) {
JSONObject object1 = new JSONObject(object);
byte[] ciphertext = downloadUrl(object1.getStr("downloadUrl"));
String encryptKey = WxPayUtils.rsaDecryptOAEP(object1.getStr("encryptKey"), config.getPrivateKeyPath());
String notifyData = WxPayUtils.decryptToString("",
object1.getStr("nonce").getBytes(StandardCharsets.UTF_8),
ciphertext,
encryptKey.getBytes(StandardCharsets.UTF_8));
log.info(notifyData);
// TODO 导出为.csv文件
List<BillFlowInfoVo> infoVos = WxPayUtils.stringToCsvFile(notifyData);
String fileName = new Date().getTime() + ".xlsx";
response.setContentType(CONTENT_TYPE);
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
EasyExcel.write(response.getOutputStream(), BillFlowInfoVo.class).sheet().doWrite(infoVos);
}
}
}catch (ServiceException e) {
log.error(e.getMessage());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
*构建配置信息
private HttpClient httpClient;
public static final String CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
/**
* 构建配置
* @return
*/
public PmsApplicationServePay getConfig() {
PmsApplicationServePay servePay = iPmsApplicationServePayService.getServePayEntity();
Config config = new RSAAutoCertificateConfig.Builder()
.merchantId(servePay.getMchId())
.privateKeyFromPath(servePay.getPrivateKeyPath())
.merchantSerialNumber(servePay.getCertSerialNo())
.apiV3Key(servePay.getApiV3Key())
.build();
httpClient = new DefaultHttpClientBuilder().config(config).build();
return servePay;
}
/**
* 构建配置信息
*/
public WxPayService wxService() {
WxPayConfig payConfig = new WxPayConfig();
PmsApplicationServePay servePay = iPmsApplicationServePayService.getServePayEntity();
payConfig.setAppId(StringUtils.trimToNull(servePay.getAppId()));
payConfig.setMchId(StringUtils.trimToNull(servePay.getMchId()));
payConfig.setApiV3Key(StringUtils.trimToNull(servePay.getApiV3Key()));
payConfig.setCertSerialNo(StringUtils.trimToNull(servePay.getCertSerialNo()));
payConfig.setPrivateKeyPath(servePay.getPrivateKeyPath());
payConfig.setPrivateCertPath(servePay.getPrivateCertPath());
payConfig.setNotifyUrl(StringUtils.trimToNull(servePay.getNotifyUrl()));
payConfig.setTradeType("JSAPI");
payConfig.setSignType("MD5");
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(payConfig);
return wxPayService;
}
步骤一:下载账单文件,得到账单文件密文ciphertext;
/**
* 下载账单转成 byte[]
* @param downloadUrl
* @return
* @throws Exception
*/
private byte[] downloadUrl(String downloadUrl) throws Exception {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 下载账单
InputStream inputStream = ecommerceService.downloadBill(downloadUrl);
byte[] bytes = IOUtils.toByteArray(inputStream);
return bytes;
}
获取账单文件密文ciphertext
步骤二:使用商户证书私钥解密从接口获取的加密密钥(变量名:encrypt_key)得到密钥明文key;
/**
* 敏感信息解密
* @param message: 加密信息
* @param privateKeyPath:私钥地址
* @return
*/
public static String rsaDecryptOAEP(String message, String privateKeyPath) throws BadPaddingException, IOException {
try {
// 加载私钥
PrivateKey privateKey = getPrivateKey(privateKeyPath);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] data = Base64.getDecoder().decode(message);
return new String(cipher.doFinal(data), "utf-8");
} catch (NoSuchPaddingException | NoSuchAlgorithmException e) {
throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e);
} catch (InvalidKeyException e) {
throw new IllegalArgumentException("无效的私钥", e);
} catch (BadPaddingException | IllegalBlockSizeException e) {
throw new BadPaddingException("解密失败");
}
}
/**
* 获取私钥
* @param privateKeyPath 私钥文件路径 (required)
* @return 私钥对象
*/
public static PrivateKey getPrivateKey(String privateKeyPath) throws IOException {
try (FileInputStream inputStream = new FileInputStream(privateKeyPath)) {
String keyString = IOUtil.toString(inputStream);
keyString =
keyString
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s+", "");
return KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(keyString)));
} catch (IOException e) {
throw new UncheckedIOException(e);
}catch (NoSuchAlgorithmException e) {
throw new UnsupportedOperationException(e);
} catch (InvalidKeySpecException e) {
throw new IllegalArgumentException(e);
}
}
* 获取秘钥明文
步骤三:利用步骤一、二中得到的账单密文ciphertext,密钥key和接口返回的随机字符串nonce解密账单,得到账单明文。
解密腾讯文件返回的数据
/**
* 数据解密
* @param associatedData
* @param nonce
* @param ciphertext
* @param aesKey
* @return
* @throws GeneralSecurityException
* @throws IOException
*/
public static String decryptToString(String associatedData, byte[] nonce, byte[] ciphertext, byte[] aesKey)
throws GeneralSecurityException, IOException {
try {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec key = new SecretKeySpec(aesKey, "AES");
GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
cipher.updateAAD(associatedData.getBytes(StandardCharsets.UTF_8));
byte[] bytes;
try {
bytes = cipher.doFinal(ciphertext);
}catch (GeneralSecurityException e) {
e.printStackTrace();
throw new IllegalArgumentException(e);
}
return new String(bytes, StandardCharsets.UTF_8);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new IllegalStateException(e);
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
throw new IllegalArgumentException(e);
}
}
步骤四:把明文数据以excel文件返回
数据转成实体
/**
* string 转实体
*/
public static List<BillFlowInfoVo> stringToCsvFile(String notifyData) {
List<BillFlowInfoVo> result = new ArrayList<>();
String[] list = notifyData.split("\r\n");
IntStream.range(0, list.length).forEach(index -> {
if (index > 0) {
String[] valList = list[index].split(",");
BillFlowInfoVo infoVo = new BillFlowInfoVo();
if (valList.length == 1) {
infoVo.setTime(valList[0]);
}else {
infoVo.setTime(valList[0]);
infoVo.setOrderId(valList[1]);
infoVo.setOrderSn(valList[2]);
infoVo.setBusinessName(valList[3]);
infoVo.setBusinessType(valList[4]);
infoVo.setSzType(valList[5]);
infoVo.setSzMoney(valList[6]);
infoVo.setAccount(valList[7]);
infoVo.setEditPerson(valList[8]);
infoVo.setRemark(valList[9]);
infoVo.setBusinessSn(valList[10]);
infoVo.setSubMchId(valList[11]);
infoVo.setAccountType(valList[12]);
}
result.add(infoVo);
}
});
return result;
}
实体类
@Data
public class BillFlowInfoVo implements Serializable {
/**
* 记账时间
*/
@ExcelProperty("记账时间")
private String time;
/**
* 微信支付业务单号
*/
@ExcelProperty("微信支付业务单号")
private String orderId;
/**
* 资金流水单号
*/
@ExcelProperty("资金流水单号")
private String orderSn;
/**
* 业务名称
*/
@ExcelProperty("业务名称")
private String businessName;
/**
* 业务类型
*/
@ExcelProperty("业务类型")
private String businessType;
/**
* 收支类型
*/
@ExcelProperty("收支类型")
private String szType;
/**
* 收支金额
*/
@ExcelProperty("收支金额")
private String szMoney;
/**
* 账户结余
*/
@ExcelProperty("账户结余")
private String account;
/**
* 资金变更提交申请人
*/
@ExcelProperty("资金变更提交申请人")
private String editPerson;
/**
* 备注
*/
@ExcelProperty("备注")
private String remark;
/**
* 业务凭证号
*/
@ExcelProperty("业务凭证号")
private String businessSn;
/**
* 电商二级商户号
*/
@ExcelProperty("电商二级商户号")
private String subMchId;
/**
* 账户类型
*/
@ExcelProperty("账户类型")
private String accountType;
}
打开excel文件
package com.equipl.oms.api.wxpay.facilitator;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.equipl.common.consts.SysConst;
import com.equipl.common.consts.WeChatServeConst;
import com.equipl.common.utils.WechatSignUtil;
import com.equipl.common.vo.ResultMsg;
import com.equipl.common.vo.pay.*;
import com.equipl.oms.api.feign.IPmsApplicationServePayService;
import com.equipl.oms.api.feign.ISysEnterpriseApplyTwoPayService;
import com.equipl.oms.api.service.*;
import com.equipl.oms.api.utils.WxPayUtils;
import com.equipl.oms.entity.*;
import com.equipl.pms.entity.PmsApplicationServePay;
import com.github.binarywang.wxpay.bean.applyment.ApplymentStateQueryResult;
import com.github.binarywang.wxpay.bean.applyment.WxPayApplyment4SubCreateRequest;
import com.github.binarywang.wxpay.bean.applyment.WxPayApplymentCreateResult;
import com.github.binarywang.wxpay.bean.ecommerce.*;
import com.github.binarywang.wxpay.bean.ecommerce.enums.FundBillTypeEnum;
import com.github.binarywang.wxpay.bean.ecommerce.enums.SpAccountTypeEnum;
import com.github.binarywang.wxpay.bean.ecommerce.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.Applyment4SubService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.Applyment4SubServiceImpl;
import com.github.binarywang.wxpay.service.impl.EcommerceServiceImpl;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.qcloud.cos.utils.IOUtils;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.core.http.*;
import com.wechat.pay.java.core.http.ResponseBody;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
/**
* 微信商户服务商支付模式
*
* @author MrPing
* @since 2024/4/23
*/
@Slf4j
@RestController
@RequestMapping("wxPay/service")
public class WeChatServiceController {
@Autowired
private IPmsApplicationServePayService iPmsApplicationServePayService;
@Autowired
private ISysEnterpriseApplyTwoPayService iSysEnterpriseApplyTwoPayService;
@Autowired
private OmsProfitShareLogService omsProfitShareLogService;
@Autowired
private OmsProfitShareReturnService omsProfitShareReturnService;
@Autowired
private OmsPaymentInfoService omsPaymentInfoService;
@Autowired
private OmsServeRefundsLogService omsServeRefundsLogService;
@Autowired
private OmsWithdrawMoneyLogService omsWithdrawMoneyLogService;
private HttpClient httpClient;
public static final String CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
/**
* 构建配置
* @return
*/
public PmsApplicationServePay getConfig() {
PmsApplicationServePay servePay = iPmsApplicationServePayService.getServePayEntity();
Config config = new RSAAutoCertificateConfig.Builder()
.merchantId(servePay.getMchId())
.privateKeyFromPath(servePay.getPrivateKeyPath())
.merchantSerialNumber(servePay.getCertSerialNo())
.apiV3Key(servePay.getApiV3Key())
.build();
httpClient = new DefaultHttpClientBuilder().config(config).build();
return servePay;
}
/**
* 构建配置信息
*/
public WxPayService wxService() {
WxPayConfig payConfig = new WxPayConfig();
PmsApplicationServePay servePay = iPmsApplicationServePayService.getServePayEntity();
payConfig.setAppId(StringUtils.trimToNull(servePay.getAppId()));
payConfig.setMchId(StringUtils.trimToNull(servePay.getMchId()));
payConfig.setApiV3Key(StringUtils.trimToNull(servePay.getApiV3Key()));
payConfig.setCertSerialNo(StringUtils.trimToNull(servePay.getCertSerialNo()));
payConfig.setPrivateKeyPath(servePay.getPrivateKeyPath());
payConfig.setPrivateCertPath(servePay.getPrivateCertPath());
payConfig.setNotifyUrl(StringUtils.trimToNull(servePay.getNotifyUrl()));
payConfig.setTradeType("JSAPI");
payConfig.setSignType("MD5");
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(payConfig);
return wxPayService;
}
/**
* 提交申请单
*/
@PostMapping("/createApply")
public ResultMsg createApply(@RequestBody WxPayApplyment4SubCreateRequest request) throws WxPayException {
// 获取商户配置
WxPayService wxPayService = wxService();
// 调用微信API
Applyment4SubService applyment4SubService = new Applyment4SubServiceImpl(wxPayService);
WxPayApplymentCreateResult apply = applyment4SubService.createApply(request);
String applyMentId = apply.getApplymentId(); // 返回申请单ID
return ResultMsg.success(applyMentId);
}
/**
* 通过申请单号查询申请状态
*/
@GetMapping("/queryApply")
public ResultMsg queryApply(@RequestParam(required = true) String applymentId) throws WxPayException {
// 获取商户配置
WxPayService wxPayService = wxService();
// 调用API 查询申请状态
Applyment4SubService applyment4SubService=new Applyment4SubServiceImpl(wxPayService);
ApplymentStateQueryResult result = applyment4SubService.queryApplyStatusByApplymentId(applymentId);
return ResultMsg.success(result);
}
/**
* 发起支付
* type: 1->JSAPI, 2->小程序,3->H5,4->Native,5->APP
*/
@PostMapping("/create")
public ResultMsg createOrder(@RequestBody PartnerTransactionsRequest orderRequest, @RequestParam("type") Integer type) throws IOException, SignatureException, NoSuchAlgorithmException, InvalidKeyException, WxPayException {
TradeTypeEnum typeEnum;
boolean isAtOnce = false;
if (type == 1 || type == 2 || type == 5) {
typeEnum = type == 5 ? TradeTypeEnum.APP : TradeTypeEnum.JSAPI;
} else {
isAtOnce = true;
typeEnum = type == 3 ? TradeTypeEnum.MWEB : TradeTypeEnum.NATIVE;
if (type == 3) {
orderRequest.getSceneInfo().setPayerClientIp("127.0.0.1");
}
}
// 获取商户配置
PmsApplicationServePay wxPayProperties = iPmsApplicationServePayService.getServePayEntity();
WxPayService wxPayService = wxService();
//发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 2. 根据订单系统传过来的订单信息组装支付参数,创建支付订单
//服务商应用ID
orderRequest.setSpAppid(wxPayProperties.getAppId());
//服务商户号
orderRequest.setSpMchid(wxPayProperties.getMchId());
//设置交易结束时间为2小时后
long twoHoursInMillis = 2 * 60 * 60 * 1000; // 2小时对应的毫秒数
orderRequest.setTimeExpire(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date(new Date().getTime() + twoHoursInMillis)));
//回调地址
orderRequest.setNotifyUrl(wxPayProperties.getNotifyUrl());
try {
//发起下单请求
TransactionsResult partner = ecommerceService.partner(typeEnum, orderRequest);
// 返回支付跳转或二维码链接
if (isAtOnce){
return ResultMsg.success(partner);
}
//生成签名
WxUnifiedOrderVo tokenJSAPI = WechatSignUtil.getTokenJSAPI(wxPayProperties.getAppId(), partner.getPrepayId(), wxPayProperties.getPrivateKeyPath());
// 订单号
tokenJSAPI.setOrderId(Long.valueOf(orderRequest.getOutTradeNo()));
// TODO 添加支付记录
OmsPaymentInfo info = new OmsPaymentInfo();
info.setOrderId(orderRequest.getOutTradeNo());
info.setTotalAmount(BigDecimal.valueOf(orderRequest.getAmount().getTotal()).divide(new BigDecimal(100)));
info.setSubject("微信收付通");
info.setPaymentStatus("0");
info.setCreateTime(LocalDateTime.now());
omsPaymentInfoService.save(info);
return ResultMsg.success(tokenJSAPI);
}catch (ServiceException e) {
log.error(e.getErrorMessage());
return ResultMsg.error(e.getErrorMessage());
}catch (Exception e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 支付回调通知处理
* @param resultData
* @throws WxPayException
*/
@PostMapping("/notify")
public void parseOrderNotifyResult(@RequestBody HashMap<String, Object> resultData) throws WxPayException {
// 获取商户配置
WxPayService wxPayService = wxService();
log.info("回调:{}",resultData);
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
PartnerTransactionsNotifyResult notifyResult = ecommerceService.parsePartnerNotifyResult(String.valueOf(resultData), null);
//此处解析到了回调信息
log.info("回调:{}",notifyResult.getResult());
//业务逻辑
}
/**
* 主动查询支付信息
*/
@GetMapping("/order/select")
public ResultMsg wxSelectOrderStatus(@RequestParam("orderId") String orderId, @RequestParam("sellerEnterpriseId") String sellerEnterpriseId) throws WxPayException {
// 获取特约商户id
ResultMsg query = iSysEnterpriseApplyTwoPayService.query(sellerEnterpriseId);
if (query.getData() == null || query.getCode() != 0) {
return ResultMsg.error("订单查询异常,无法获取卖方支付商户号!");
}
JSONObject jsonObject = new JSONObject(query.getData());
// 获取商户配置
PmsApplicationServePay wxPayProperties = iPmsApplicationServePayService.getServePayEntity();
WxPayService wxPayService = wxService();
//构建ecommerceService
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
//构建PartnerTransactionsQueryRequest对象
PartnerTransactionsQueryRequest queryRequest = new PartnerTransactionsQueryRequest();
queryRequest.setOutTradeNo(orderId);
queryRequest.setSpMchid(wxPayProperties.getMchId());
queryRequest.setSubMchid(jsonObject.getStr("subMchId"));
PartnerTransactionsResult partnerTransactionsResult=new PartnerTransactionsResult();
try {
//普通查询订单API
partnerTransactionsResult = ecommerceService.queryPartnerTransactions(queryRequest);
return ResultMsg.success(partnerTransactionsResult);
} catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 请求分账
*/
@PostMapping("profitSharing")
public ResultMsg profitSharing(@RequestBody ProFitSharingVo proFitSharingVo) throws WxPayException {
// 发起分账
try {
// 获取分账方信息
ResultMsg query = iSysEnterpriseApplyTwoPayService.query(proFitSharingVo.getToEnterpriseId());
if (query.getData() == null || query.getCode() != 0) {
return ResultMsg.error("请求分账异常,无法获取分账方商户号!");
}
JSONObject jsonObject = new JSONObject(query.getData());
// 获取商户配置
PmsApplicationServePay wxPayProperties = iPmsApplicationServePayService.getServePayEntity();
WxPayService wxPayService = wxService();
//发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 根据订单系统传过来的订单信息组装支付参数,创建支付订单
ProfitSharingRequest profitSharingRequest = new ProfitSharingRequest();
// 服务商应用ID
profitSharingRequest.setAppid(wxPayProperties.getAppId());
// 二级商户号
profitSharingRequest.setSubMchid(jsonObject.getStr("subMchId"));
// 微信订单号
PartnerTransactionsQueryRequest queryRequest = new PartnerTransactionsQueryRequest();
queryRequest.setOutTradeNo(proFitSharingVo.getOrderId());
queryRequest.setSpMchid(wxPayProperties.getMchId());
queryRequest.setSubMchid(jsonObject.getStr("subMchId"));
//普通查询订单API
PartnerTransactionsResult partnerTransactionsResult = ecommerceService.queryPartnerTransactions(queryRequest);
profitSharingRequest.setTransactionId(partnerTransactionsResult.getTransactionId());
// 生成分账单号
profitSharingRequest.setOutOrderNo(String.valueOf(IdWorker.getId()));
// 是否分账完成
profitSharingRequest.setFinish(proFitSharingVo.getFinish());
// 分账接收方
ProfitSharingRequest.Receiver receiver = new ProfitSharingRequest.Receiver();
// 企业申请时的信息
JSONObject auditData = jsonObject.getJSONObject("auditData");
// 分账接收方类型:商户
receiver.setType("MERCHANT_ID");
// 分账接收方账号:是商户号(mch_id或者sub_mch_id)
if (proFitSharingVo.getIsPlatform()){
// 分账到服务商
receiver.setReceiverAccount(wxPayProperties.getMchId());
}else {
// 分账到二级商户
ResultMsg twoResult = iSysEnterpriseApplyTwoPayService.query(proFitSharingVo.getFormEnterpriseId());
JSONObject jsonObject1 = new JSONObject(twoResult.getData());
receiver.setReceiverAccount(jsonObject1.getStr("subMchId"));
}
// 分账金额
receiver.setAmount(proFitSharingVo.getAmount());
// 分账描述
receiver.setDescription(proFitSharingVo.getDescription());
// 添加分账方信息
List<ProfitSharingRequest.Receiver> list = new ArrayList<>();
list.add(receiver);
profitSharingRequest.setReceivers(list);
//普通查询订单API
ProfitSharingResult sharingResult = ecommerceService.profitSharing(profitSharingRequest);
// TODO 添加到分账记录表
OmsProfitShareLog shareLog = new OmsProfitShareLog();
shareLog.setOrderId(proFitSharingVo.getOrderId());
shareLog.setTransactionId(partnerTransactionsResult.getTransactionId());
shareLog.setOutOrderNo(profitSharingRequest.getOutOrderNo());
shareLog.setWxOutOrderNo(sharingResult.getOrderId());
shareLog.setToEnterpriseId(proFitSharingVo.getToEnterpriseId());
shareLog.setToSubMchId(profitSharingRequest.getSubMchid());
shareLog.setIsPlatform(proFitSharingVo.getIsPlatform() ? 1:0);
shareLog.setFormEnterpriseId(proFitSharingVo.getIsPlatform() ? SysConst.YQ_ENTERPRISE_ID: proFitSharingVo.getFormEnterpriseId());
shareLog.setFormMchId(receiver.getReceiverAccount());
shareLog.setAmount(proFitSharingVo.getAmount());
shareLog.setDescription(receiver.getDescription());
shareLog.setCreateTime(LocalDateTime.now());
shareLog.setFinish(proFitSharingVo.getFinish() ? 1:0);
omsProfitShareLogService.save(shareLog);
return ResultMsg.success(sharingResult);
}catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 分账查询
*/
@GetMapping("profitShare/query")
public ResultMsg queryShareProfit(@RequestParam("enterpriseId") String enterpriseId, @RequestParam("orderId") String orderId) throws WxPayException {
// 分账出资的电商平台二级商户
ResultMsg twoResult = iSysEnterpriseApplyTwoPayService.query(enterpriseId);
JSONObject jsonObject1 = new JSONObject(twoResult.getData());
String subMchId = jsonObject1.getStr("subMchId");
LambdaQueryWrapper<OmsProfitShareLog> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(OmsProfitShareLog::getToEnterpriseId, enterpriseId)
.eq(OmsProfitShareLog::getOrderId, orderId);
List<OmsProfitShareLog> list = omsProfitShareLogService.list(wrapper);
List<ProfitSharingResult> result = new ArrayList<>();
// 获取配置
WxPayService wxPayService = wxService();
//发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
for (OmsProfitShareLog shareLog : list) {
ProfitSharingQueryRequest queryRequest = new ProfitSharingQueryRequest();
queryRequest.setSubMchid(subMchId);
queryRequest.setTransactionId(shareLog.getTransactionId());
queryRequest.setOutOrderNo(shareLog.getOutOrderNo());
try {
// 查询分账
ProfitSharingResult sharingResult = ecommerceService.queryProfitSharing(queryRequest);
result.add(sharingResult);
}catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
return ResultMsg.success(result);
}
/**
* 请求分账回退
*/
@PostMapping("returnorders")
public ResultMsg returnorders(@RequestBody ReturnOrdersRequest request) {
// 获取配置
WxPayService wxPayService = wxService();
//发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
LambdaQueryWrapper<OmsProfitShareLog> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(StringUtils.isNotBlank(request.getOutOrderNo()), OmsProfitShareLog::getOutOrderNo, request.getOutOrderNo());
OmsProfitShareLog logServiceOne = omsProfitShareLogService.getOne(wrapper, false);
try {
// 请求分账回退
request.setOutReturnNo(String.valueOf(IdWorker.getId()));
ReturnOrdersResult returnOrders = ecommerceService.returnOrders(request);
// TODO 插入分账回退记录
OmsProfitShareReturn shareReturn = new OmsProfitShareReturn();
shareReturn.setOrderId(logServiceOne.getOrderId());
shareReturn.setSubMchId(request.getSubMchid());
shareReturn.setOutOrderNo(request.getOutOrderNo());
shareReturn.setWxOutOrderNo(logServiceOne.getWxOutOrderNo());
shareReturn.setOutReturnNo(returnOrders.getOutReturnNo());
shareReturn.setWxOutReturnNo(returnOrders.getReturnNo());
shareReturn.setReturnMchId(returnOrders.getReturnMchid());
shareReturn.setAmount(returnOrders.getAmount());
shareReturn.setDescription(request.getDescription());
shareReturn.setStatus(returnOrders.getResult());
if (StringUtils.isNotBlank(returnOrders.getFailReason())) {
shareReturn.setFailReason(returnOrders.getFailReason());
}
if ("SUCCESS".equals(returnOrders.getResult())){
shareReturn.setFinishTime(LocalDateTime.now());
}
shareReturn.setCreateTime(LocalDateTime.now());
omsProfitShareReturnService.save(shareReturn);
return ResultMsg.success(returnOrders);
}catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 查询分账回退结果
*/
@PostMapping("query/returnorders")
public ResultMsg queryReturnorders(@RequestBody ReturnOrdersQueryRequest queryRequest) {
// 获取配置
WxPayService wxPayService = wxService();
//发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 获取分账回退申请记录
LambdaQueryWrapper<OmsProfitShareReturn> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(OmsProfitShareReturn::getOutReturnNo, queryRequest.getOutReturnNo());
OmsProfitShareReturn shareReturn = omsProfitShareReturnService.getOne(wrapper, false);
try {
ReturnOrdersResult ordersResult = ecommerceService.queryReturnOrders(queryRequest);
// TODO 更新分账退款状态已变化
if(!ordersResult.getResult().equals(shareReturn.getStatus())) {
ordersResult.setResult(ordersResult.getResult());
ordersResult.setFailReason(ordersResult.getFailReason());
if (StringUtils.isNotBlank(ordersResult.getFailReason())) {
shareReturn.setFailReason(ordersResult.getFailReason());
}
if ("SUCCESS".equals(ordersResult.getResult())){
shareReturn.setFinishTime(LocalDateTime.now());
}
omsProfitShareReturnService.updateById(shareReturn);
}
return ResultMsg.success(ordersResult);
}catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 完结分账
*/
@PostMapping("finishOrder")
public ResultMsg finishOrder(@RequestBody FinishOrderRequest request) {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 调取完结
try {
ProfitSharingResult result = ecommerceService.finishOrder(request);
return ResultMsg.success(result);
} catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 查询订单剩余待分金额
* transactionId: 查询订单接口获取
*/
@GetMapping("amounts")
public ResultMsg amounts(@RequestParam("transactionId") String transactionId) {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 调取查询
try {
ProfitSharingOrdersUnSplitAmountRequest request = new ProfitSharingOrdersUnSplitAmountRequest();
request.setTransactionId(transactionId);
ProfitSharingOrdersUnSplitAmountResult result = ecommerceService.queryProfitSharingOrdersUnsplitAmount(request);
return ResultMsg.success(result);
} catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 申请退款
*/
@PostMapping("refunds")
public ResultMsg refunds(@RequestBody RefundsMoneyVo refundsMoneyVo) {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 获取分账方信息
ResultMsg query = iSysEnterpriseApplyTwoPayService.query(refundsMoneyVo.getEnterpriseId());
if (query.getData() == null || query.getCode() != 0) {
return ResultMsg.error("申请退款异常,无法获取分账方商户号!");
}
JSONObject jsonObject = new JSONObject(query.getData());
// 获取商户配置
PmsApplicationServePay wxPayProperties = iPmsApplicationServePayService.getServePayEntity();
// 调取查询
try {
RefundsRequest request = new RefundsRequest();
request.setSubMchid(jsonObject.getStr("subMchId"));
request.setSpAppid(wxPayProperties.getAppId());
request.setOutTradeNo(refundsMoneyVo.getOrderId());
request.setOutRefundNo(String.valueOf(IdWorker.getId()));
request.setReason(refundsMoneyVo.getReason());
request.setNotifyUrl(wxPayProperties.getNotifyUrl());
RefundsRequest.Amount amount = RefundsRequest.Amount.builder().total(refundsMoneyVo.getTotal()).refund(refundsMoneyVo.getRefund()).currency(refundsMoneyVo.getCurrency()).build();
request.setAmount(amount);
// 调用退款
RefundsResult result = ecommerceService.refunds(request);
// TODO 添加退款申请记录
OmsServeRefundsLog refundsLog = new OmsServeRefundsLog();
refundsLog.setOrderId(refundsMoneyVo.getOrderId());
refundsLog.setOutRefundNo(request.getOutRefundNo());
refundsLog.setEnterpriseId(refundsMoneyVo.getEnterpriseId());
refundsLog.setSubMchId(jsonObject.getStr("subMchId"));
refundsLog.setTotalMoney(new BigDecimal(refundsMoneyVo.getTotal()).divide(new BigDecimal(100)));
refundsLog.setRefundMoney(new BigDecimal(refundsMoneyVo.getRefund()).divide(new BigDecimal(100)));
refundsLog.setReason(refundsMoneyVo.getReason());
refundsLog.setCreateTime(LocalDateTime.now());
refundsLog.setWxOutRefundNo(result.getRefundId());
omsServeRefundsLogService.save(refundsLog);
return ResultMsg.success(result);
} catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 退款查询
*/
@GetMapping("queryRefunds")
public ResultMsg queryRefunds(@RequestParam("orderId") String orderId) {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 查询退款申请记录
LambdaQueryWrapper<OmsServeRefundsLog> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(OmsServeRefundsLog::getOrderId, orderId);
List<OmsServeRefundsLog> list = omsServeRefundsLogService.list(wrapper);
List<RefundQueryResult> result = new ArrayList<>();
for (OmsServeRefundsLog refundsLog : list) {
try {
RefundQueryResult queryResult = ecommerceService.queryRefundByOutRefundNo(refundsLog.getSubMchId(), refundsLog.getOutRefundNo());
result.add(queryResult);
// TODO 更新状态
if (StringUtils.isBlank(refundsLog.getStatus()) || !queryResult.getStatus().equals(refundsLog.getStatus())){
if ("SUCCESS".equals(queryResult.getStatus())) {
refundsLog.setCallbackTime(LocalDateTime.now());
}
refundsLog.setStatus(queryResult.getStatus());
omsServeRefundsLogService.updateById(refundsLog);
}
}catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
return ResultMsg.success(result);
}
/**
* 查询二级商户账户实时余额
*/
@GetMapping("subNowBalance")
public ResultMsg subNowBalance(@RequestParam("enterpriseId") String enterpriseId) {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 获取二级商户信息
ResultMsg query = iSysEnterpriseApplyTwoPayService.query(enterpriseId);
if (query.getData() == null || query.getCode() != 0) {
return ResultMsg.error("该商户未申请二级商户号!");
}
JSONObject jsonObject = new JSONObject(query.getData());
try {
FundBalanceResult result = ecommerceService.subNowBalance(jsonObject.getStr("subMchId"));
return ResultMsg.success(result);
}catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 查询电商平台账户实时余额
*/
@GetMapping("spNowBalance")
public ResultMsg spNowBalance() {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
try {
FundBalanceResult result = ecommerceService.spNowBalance(SpAccountTypeEnum.BASIC);
return ResultMsg.success(result);
}catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 查询二级商户账户日终余额
* enterpriseId: 商户
* date: 日期 -> 2019-08-17
*/
@GetMapping("subDayEndBalance")
public ResultMsg subDayEndBalance(@RequestParam("enterpriseId") String enterpriseId, @RequestParam("date") String date) {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 获取二级商户信息
ResultMsg query = iSysEnterpriseApplyTwoPayService.query(enterpriseId);
if (query.getData() == null || query.getCode() != 0) {
return ResultMsg.error("该商户未申请二级商户号!");
}
JSONObject jsonObject = new JSONObject(query.getData());
try {
FundBalanceResult result = ecommerceService.subDayEndBalance(jsonObject.getStr("subMchId"), date);
return ResultMsg.success(result);
}catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 查询电商平台账户日终余额
* date: 日期 -> 2019-08-17
*/
@GetMapping("spDayEndBalance")
public ResultMsg spDayEndBalance(@RequestParam("date") String date) {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
try {
FundBalanceResult result = ecommerceService.spDayEndBalance(SpAccountTypeEnum.BASIC, date);
return ResultMsg.success(result);
}catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 二级商户预约提现
*/
@PostMapping("subWithdraw")
public ResultMsg subWithdraw(@RequestBody WithdrawVo withdrawVo) {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 获取二级商户信息
ResultMsg query = iSysEnterpriseApplyTwoPayService.query(withdrawVo.getEnterpriseId());
if (query.getData() == null || query.getCode() != 0) {
return ResultMsg.error("该商户未申请二级商户号!");
}
JSONObject jsonObject = new JSONObject(query.getData());
try {
SubWithdrawRequest request = new SubWithdrawRequest();
request.setSubMchid(jsonObject.getStr("subMchId"));
request.setOutRequestNo(String.valueOf(IdWorker.getId()));
request.setAmount(withdrawVo.getAmount());
request.setRemark(withdrawVo.getRemark());
SubWithdrawResult result = ecommerceService.subWithdraw(request);
// TODO 添加提现申请记录
OmsWithdrawMoneyLog moneyLog = new OmsWithdrawMoneyLog();
moneyLog.setOutRequestNo(request.getOutRequestNo());
moneyLog.setWithdrawId(result.getWithdrawId());
moneyLog.setEnterpriseId(withdrawVo.getEnterpriseId());
moneyLog.setMchId(result.getSubMchid());
moneyLog.setAmount(new BigDecimal(withdrawVo.getAmount()).divide(new BigDecimal(100)));
moneyLog.setRemark(withdrawVo.getRemark());
moneyLog.setCreateTime(LocalDateTime.now());
omsWithdrawMoneyLogService.save(moneyLog);
return ResultMsg.success(result);
}catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 二级商户查询预约提现状态
* withdrawMoneyLogId: 预约提现申请记录id
*/
@GetMapping("querySubWithdrawByOutRequestNo")
public ResultMsg querySubWithdrawByOutRequestNo(@RequestParam("withdrawMoneyLogId") String withdrawMoneyLogId) {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 获取申请记录
OmsWithdrawMoneyLog moneyLog = omsWithdrawMoneyLogService.getById(withdrawMoneyLogId);
if (moneyLog == null) return ResultMsg.error("未找到该提现记录申请");
try {
SubWithdrawStatusResult result = ecommerceService.querySubWithdrawByOutRequestNo(moneyLog.getMchId(), moneyLog.getOutRequestNo());
// TODO 更新状态
if (StringUtils.isBlank(moneyLog.getStatus()) || !result.getStatus().equals(moneyLog.getStatus())) {
moneyLog.setStatus(result.getStatus());
moneyLog.setUpdateTime(LocalDateTime.now());
if (result.getReason() != null) {
moneyLog.setReason(result.getReason());
}
omsWithdrawMoneyLogService.updateById(moneyLog);
}
return ResultMsg.success(result);
}catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
}
}
/**
* 申请下载交易账单
*/
@PostMapping("tradeBill")
public ResultMsg tradeBill(@RequestBody TradeBillVo tradeBillVo, HttpServletResponse response) {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
String subMchId = null;
if (StringUtils.isNotBlank(tradeBillVo.getEnterpriseId())) {
// 获取二级商户信息
ResultMsg query = iSysEnterpriseApplyTwoPayService.query(tradeBillVo.getEnterpriseId());
if (query.getData() == null || query.getCode() != 0) {
return ResultMsg.error("该商户未申请二级商户号!");
}
JSONObject jsonObject = new JSONObject(query.getData());
subMchId = jsonObject.getStr("subMchId");
}
try {
TradeBillRequest request = TradeBillRequest.builder()
.billDate(tradeBillVo.getBillDate())
.billType(tradeBillVo.getBillType())
.tarType(tradeBillVo.getTarType())
.subMchid(subMchId).build();
TradeBillResult result = ecommerceService.applyBill(request);
downloadBill(result.getDownloadUrl(), response);
return ResultMsg.success(result);
}catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 申请资金账单
*/
@PostMapping("fundFlowBill")
public ResultMsg fundFlowBill(@RequestBody TradeBillVo tradeBillVo, HttpServletResponse response) {
// 获取配置
PmsApplicationServePay config = getConfig();
// 调用地址
String urlApi = "";
if (tradeBillVo.getIsMchQuery()) {
String url = WeChatServeConst.ECOMMERCE_FUND_FLOW_BILL;
urlApi = url.replace("{bill_date}",tradeBillVo.getBillDate())
.replace("{account_type}", tradeBillVo.getAccountType())
.replace("{algorithm}", tradeBillVo.getAlgorithm());
}else {
String url = WeChatServeConst.FUND_FLOW_BILL;
urlApi = url.replace("{bill_date}", tradeBillVo.getBillDate())
.replace("{account_type}", tradeBillVo.getAccountType());
}
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.addHeader(Constant.ACCEPT, MediaType.APPLICATION_JSON.getValue());
headers.addHeader(Constant.CONTENT_TYPE, MediaType.APPLICATION_JSON.getValue());
headers.addHeader(Constant.WECHAT_PAY_SERIAL, config.getPlatformSerialNo());
HttpRequest httpRequest =
new HttpRequest.Builder()
.httpMethod(HttpMethod.GET)
.url(urlApi)
.headers(headers)
.build();
try {
HttpResponse<HttpResponse> resp = httpClient.execute(httpRequest, HttpResponse.class);
ResponseBody result = resp.getBody();
JSONObject jsonObject = new JSONObject(result).getJSONObject("body");
downloadBill(jsonObject.getStr("download_url"), response);
return ResultMsg.success(result);
}catch (ServiceException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
} catch (IOException | WxPayException e) {
throw new RuntimeException(e);
}
}
/**
* 申请二级商户资金账单
*/
@PostMapping("getAllSubMchFundFlowBill")
public void getAllSubMchFundFlowBill(@RequestBody TradeBillVo tradeBillVo, HttpServletResponse response) {
PmsApplicationServePay config = getConfig();
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
try {
FundBillRequest request = FundBillRequest.builder()
.billDate(tradeBillVo.getBillDate())
.accountType(tradeBillVo.getAccountType())
.algorithm(tradeBillVo.getAlgorithm()).build();
FundBillResult result = ecommerceService.applyFundBill(FundBillTypeEnum.SUB_FUND_FLOW_BILL, request);
if (result.getDownloadBillCount() > 0) {
JSONArray billList = new JSONArray(result.getDownloadBillList());
for (Object object : billList) {
JSONObject object1 = new JSONObject(object);
byte[] ciphertext = downloadUrl(object1.getStr("downloadUrl"));
String encryptKey = WxPayUtils.rsaDecryptOAEP(object1.getStr("encryptKey"), config.getPrivateKeyPath());
String notifyData = WxPayUtils.decryptToString("",
object1.getStr("nonce").getBytes(StandardCharsets.UTF_8),
ciphertext,
encryptKey.getBytes(StandardCharsets.UTF_8));
log.info(notifyData);
// TODO 导出为.csv文件
List<BillFlowInfoVo> infoVos = WxPayUtils.stringToCsvFile(notifyData);
String fileName = new Date().getTime() + ".xlsx";
response.setContentType(CONTENT_TYPE);
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
EasyExcel.write(response.getOutputStream(), BillFlowInfoVo.class).sheet().doWrite(infoVos);
}
}
}catch (ServiceException e) {
log.error(e.getMessage());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 申请分账账单
*/
@PostMapping("profitSharingBill")
public ResultMsg profitSharingBill(@RequestBody TradeBillVo tradeBillVo, HttpServletResponse response) {
// 获取配置
PmsApplicationServePay config = getConfig();
// 获取二级商户信息
String subMchId = null;
if (StringUtils.isNotBlank(tradeBillVo.getEnterpriseId())) {
ResultMsg query = iSysEnterpriseApplyTwoPayService.query(tradeBillVo.getEnterpriseId());
if (query.getData() == null || query.getCode() != 0) {
return ResultMsg.error("该商户未申请二级商户号!");
}
JSONObject jsonObject = new JSONObject(query.getData());
subMchId = jsonObject.getStr("subMchId");
}
try {
String url = "https://api.mch.weixin.qq.com/v3/profitsharing/bills?bill_date=" + tradeBillVo.getBillDate();
if (subMchId != null) {
url = url + "&sub_mchid=" + subMchId;
}
if (StringUtils.isNotBlank(tradeBillVo.getTarType())) {
url = url + "&tar_type=" + subMchId;
}
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.addHeader(Constant.ACCEPT, MediaType.APPLICATION_JSON.getValue());
headers.addHeader(Constant.CONTENT_TYPE, MediaType.APPLICATION_JSON.getValue());
headers.addHeader(Constant.WECHAT_PAY_SERIAL, config.getPlatformSerialNo());
HttpRequest httpRequest =
new HttpRequest.Builder()
.httpMethod(HttpMethod.GET)
.url(url)
.headers(headers)
.build();
HttpResponse<HttpResponse> resp = httpClient.execute(httpRequest, HttpResponse.class);
ResponseBody result = resp.getBody();
JSONObject jsonObject = new JSONObject(result).getJSONObject("body");
downloadBill(jsonObject.getStr("download_url"), response);
return ResultMsg.success(result);
}catch (WxPayException e) {
log.error(e.getMessage());
return ResultMsg.error(e.getMessage());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 下载账单
*/
private void downloadBill(String downloadUrl, HttpServletResponse response) throws WxPayException, IOException {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 下载账单
String fileName = new Date().getTime() + ".xlsx";
InputStream inputStream = ecommerceService.downloadBill(downloadUrl);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
response.getOutputStream().write(buffer, 0, bytesRead);
}
response.getOutputStream().flush();
response.getOutputStream().close();
inputStream.close();
}
/**
* 下载账单转成 byte[]
* @param downloadUrl
* @return
* @throws Exception
*/
private byte[] downloadUrl(String downloadUrl) throws Exception {
// 获取配置
WxPayService wxPayService = wxService();
// 发起V3 服务商发起支付
EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
// 下载账单
InputStream inputStream = ecommerceService.downloadBill(downloadUrl);
byte[] bytes = IOUtils.toByteArray(inputStream);
return bytes;
}
}
文件接口例子