com.github.binarywang.wxpay.service.impl.EcommerceServiceImpl Maven / Gradle / Ivy
package com.github.binarywang.wxpay.service.impl;
import com.github.binarywang.wxpay.bean.ecommerce.*;
import com.github.binarywang.wxpay.bean.ecommerce.enums.BillTypeEnum;
import com.github.binarywang.wxpay.bean.ecommerce.enums.SpAccountTypeEnum;
import com.github.binarywang.wxpay.bean.ecommerce.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.EcommerceService;
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.common.base.CaseFormat;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.RequiredArgsConstructor;
import org.apache.commons.beanutils.BeanMap;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@RequiredArgsConstructor
public class EcommerceServiceImpl implements EcommerceService {
private static final Gson GSON = new GsonBuilder().create();
private final WxPayService payService;
@Override
public ApplymentsResult createApply(ApplymentsRequest request) throws WxPayException {
String url = String.format("%s/v3/ecommerce/applyments/", this.payService.getPayBaseUrl());
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(result, ApplymentsResult.class);
}
@Override
public ApplymentsStatusResult queryApplyStatusByApplymentId(String applymentId) throws WxPayException {
String url = String.format("%s/v3/ecommerce/applyments/%s", this.payService.getPayBaseUrl(), applymentId);
String result = this.payService.getV3(URI.create(url));
return GSON.fromJson(result, ApplymentsStatusResult.class);
}
@Override
public ApplymentsStatusResult queryApplyStatusByOutRequestNo(String outRequestNo) throws WxPayException {
String url = String.format("%s/v3/ecommerce/applyments/out-request-no/%s", this.payService.getPayBaseUrl(), outRequestNo);
String result = this.payService.getV3(URI.create(url));
return GSON.fromJson(result, ApplymentsStatusResult.class);
}
@Override
public TransactionsResult combine(TradeTypeEnum tradeType, CombineTransactionsRequest request) throws WxPayException {
String url = this.payService.getPayBaseUrl() + tradeType.getCombineUrl();
String response = this.payService.postV3(url, GSON.toJson(request));
return GSON.fromJson(response, TransactionsResult.class);
}
@Override
public T combineTransactions(TradeTypeEnum tradeType, CombineTransactionsRequest request) throws WxPayException {
TransactionsResult result = this.combine(tradeType, request);
return result.getPayInfo(tradeType, request.getCombineAppid(),
request.getCombineMchid(), payService.getConfig().getPrivateKey());
}
@Override
public CombineTransactionsNotifyResult parseCombineNotifyResult(String notifyData, SignatureHeader header) throws WxPayException {
if(Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)){
throw new WxPayException("非法请求,头部信息验证失败");
}
NotifyResponse response = GSON.fromJson(notifyData, NotifyResponse.class);
NotifyResponse.Resource resource = response.getResource();
String cipherText = resource.getCiphertext();
String associatedData = resource.getAssociatedData();
String nonce = resource.getNonce();
String apiV3Key = this.payService.getConfig().getApiV3Key();
try {
String result = AesUtils.decryptToString(associatedData, nonce,cipherText, apiV3Key);
CombineTransactionsResult transactionsResult = GSON.fromJson(result, CombineTransactionsResult.class);
CombineTransactionsNotifyResult notifyResult = new CombineTransactionsNotifyResult();
notifyResult.setRawData(response);
notifyResult.setResult(transactionsResult);
return notifyResult;
} catch (GeneralSecurityException | IOException e) {
throw new WxPayException("解析报文异常!", e);
}
}
@Override
public CombineTransactionsResult queryCombineTransactions(String outTradeNo) throws WxPayException {
String url = String.format("%s/v3/combine-transactions/out-trade-no/%s", this.payService.getPayBaseUrl(), outTradeNo);
String response = this.payService.getV3(URI.create(url));
return GSON.fromJson(response, CombineTransactionsResult.class);
}
@Override
public TransactionsResult partner(TradeTypeEnum tradeType, PartnerTransactionsRequest request) throws WxPayException {
String url = this.payService.getPayBaseUrl() + tradeType.getPartnerUrl();
String response = this.payService.postV3(url, GSON.toJson(request));
return GSON.fromJson(response, TransactionsResult.class);
}
@Override
public T partnerTransactions(TradeTypeEnum tradeType, PartnerTransactionsRequest request) throws WxPayException {
TransactionsResult result = this.partner(tradeType, request);
return result.getPayInfo(tradeType, request.getSpAppid(),
request.getSpMchid(), payService.getConfig().getPrivateKey());
}
@Override
public PartnerTransactionsNotifyResult parsePartnerNotifyResult(String notifyData, SignatureHeader header) throws WxPayException {
if(Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)){
throw new WxPayException("非法请求,头部信息验证失败");
}
NotifyResponse response = GSON.fromJson(notifyData, NotifyResponse.class);
NotifyResponse.Resource resource = response.getResource();
String cipherText = resource.getCiphertext();
String associatedData = resource.getAssociatedData();
String nonce = resource.getNonce();
String apiV3Key = this.payService.getConfig().getApiV3Key();
try {
String result = AesUtils.decryptToString(associatedData, nonce,cipherText, apiV3Key);
PartnerTransactionsResult transactionsResult = GSON.fromJson(result, PartnerTransactionsResult.class);
PartnerTransactionsNotifyResult notifyResult = new PartnerTransactionsNotifyResult();
notifyResult.setRawData(response);
notifyResult.setResult(transactionsResult);
return notifyResult;
} catch (GeneralSecurityException | IOException e) {
throw new WxPayException("解析报文异常!", e);
}
}
@Override
public PartnerTransactionsResult queryPartnerTransactions(PartnerTransactionsQueryRequest request) throws WxPayException {
String url = String.format("%s/v3/pay/partner/transactions/out-trade-no/%s", this.payService.getPayBaseUrl(), request.getOutTradeNo());
if (Objects.isNull(request.getOutTradeNo())) {
url = String.format("%s/v3/pay/partner/transactions/id/%s", this.payService.getPayBaseUrl(), request.getTransactionId());
}
String query = String.format("?sp_mchid=%s&sub_mchid=%s", request.getSpMchid(), request.getSubMchid());
URI uri = URI.create(url + query);
String response = this.payService.getV3(uri);
return GSON.fromJson(response, PartnerTransactionsResult.class);
}
@Override
public FundBalanceResult spNowBalance(SpAccountTypeEnum accountType) throws WxPayException {
String url = String.format("%s/v3/merchant/fund/balance/%s", this.payService.getPayBaseUrl(), accountType);
URI uri = URI.create(url);
String response = this.payService.getV3(uri);
return GSON.fromJson(response, FundBalanceResult.class);
}
@Override
public FundBalanceResult spDayEndBalance(SpAccountTypeEnum accountType, String date) throws WxPayException {
String url = String.format("%s/v3/merchant/fund/dayendbalance/%s?date=%s", this.payService.getPayBaseUrl(), accountType, date);
URI uri = URI.create(url);
String response = this.payService.getV3(uri);
return GSON.fromJson(response, FundBalanceResult.class);
}
@Override
public FundBalanceResult subNowBalance(String subMchid) throws WxPayException {
String url = String.format("%s/v3/ecommerce/fund/balance/%s", this.payService.getPayBaseUrl(), subMchid);
URI uri = URI.create(url);
String response = this.payService.getV3(uri);
return GSON.fromJson(response, FundBalanceResult.class);
}
@Override
public FundBalanceResult subDayEndBalance(String subMchid, String date) throws WxPayException {
String url = String.format("%s/v3/ecommerce/fund/enddaybalance/%s?date=%s", this.payService.getPayBaseUrl(), subMchid, date);
URI uri = URI.create(url);
String response = this.payService.getV3(uri);
return GSON.fromJson(response, FundBalanceResult.class);
}
@Override
public ProfitSharingResult profitSharing(ProfitSharingRequest request) throws WxPayException {
String url = String.format("%s/v3/ecommerce/profitsharing/orders", this.payService.getPayBaseUrl());
String response = this.payService.postV3(url, GSON.toJson(request));
return GSON.fromJson(response, ProfitSharingResult.class);
}
@Override
public ProfitSharingResult queryProfitSharing(ProfitSharingQueryRequest request) throws WxPayException {
String url = String.format("%s/v3/ecommerce/profitsharing/orders?sub_mchid=%s&transaction_id=%s&out_order_no=%s",
this.payService.getPayBaseUrl(), request.getSubMchid(), request.getTransactionId(), request.getOutOrderNo());
String response = this.payService.getV3(URI.create(url));
return GSON.fromJson(response, ProfitSharingResult.class);
}
@Override
public ReturnOrdersResult returnOrders(ReturnOrdersRequest request) throws WxPayException {
String url = String.format("%s/v3/ecommerce/profitsharing/returnorders", this.payService.getPayBaseUrl());
String response = this.payService.postV3(url, GSON.toJson(request));
return GSON.fromJson(response, ReturnOrdersResult.class);
}
@Override
public ProfitSharingResult finishOrder(FinishOrderRequest request) throws WxPayException {
String url = String.format("%s/v3/ecommerce/profitsharing/finish-order", this.payService.getPayBaseUrl());
String response = this.payService.postV3(url, GSON.toJson(request));
return GSON.fromJson(response, ProfitSharingResult.class);
}
@Override
public RefundsResult refunds(RefundsRequest request) throws WxPayException {
String url = String.format("%s/v3/ecommerce/refunds/apply", this.payService.getPayBaseUrl());
String response = this.payService.postV3(url, GSON.toJson(request));
return GSON.fromJson(response, RefundsResult.class);
}
@Override
public RefundQueryResult queryRefundByRefundId(String subMchid, String refundId) throws WxPayException {
String url = String.format("%s/v3/ecommerce/refunds/id/%s?sub_mchid=%s", this.payService.getPayBaseUrl(), refundId, subMchid);
String response = this.payService.getV3(URI.create(url));
return GSON.fromJson(response, RefundQueryResult.class);
}
@Override
public RefundQueryResult queryRefundByOutRefundNo(String subMchid, String outRefundNo) throws WxPayException {
String url = String.format("%s/v3/ecommerce/refunds/out-refund-no/%s?sub_mchid=%s", this.payService.getPayBaseUrl(), outRefundNo, subMchid);
String response = this.payService.getV3(URI.create(url));
return GSON.fromJson(response, RefundQueryResult.class);
}
@Override
public RefundNotifyResult parseRefundNotifyResult(String notifyData, SignatureHeader header) throws WxPayException {
if(Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)){
throw new WxPayException("非法请求,头部信息验证失败");
}
NotifyResponse response = GSON.fromJson(notifyData, NotifyResponse.class);
NotifyResponse.Resource resource = response.getResource();
String cipherText = resource.getCiphertext();
String associatedData = resource.getAssociatedData();
String nonce = resource.getNonce();
String apiV3Key = this.payService.getConfig().getApiV3Key();
try {
String result = AesUtils.decryptToString(associatedData, nonce,cipherText, apiV3Key);
RefundNotifyResult notifyResult = GSON.fromJson(result, RefundNotifyResult.class);
notifyResult.setRawData(response);
return notifyResult;
} catch (GeneralSecurityException | IOException e) {
throw new WxPayException("解析报文异常!", e);
}
}
@Override
public SubWithdrawResult subWithdraw(SubWithdrawRequest request) throws WxPayException {
String url = String.format("%s/v3/ecommerce/fund/withdraw", this.payService.getPayBaseUrl());
String response = this.payService.postV3(url, GSON.toJson(request));
return GSON.fromJson(response, SubWithdrawResult.class);
}
@Override
public SpWithdrawResult spWithdraw(SpWithdrawRequest request) throws WxPayException {
String url = String.format("%s/v3/merchant/fund/withdraw", this.payService.getPayBaseUrl());
String response = this.payService.postV3(url, GSON.toJson(request));
return GSON.fromJson(response, SpWithdrawResult.class);
}
@Override
public SubWithdrawStatusResult querySubWithdrawByOutRequestNo(String subMchid, String outRequestNo) throws WxPayException {
String url = String.format("%s/v3/ecommerce/fund/withdraw/out-request-no/%s?sub_mchid=%s", this.payService.getPayBaseUrl(), outRequestNo, subMchid);
String response = this.payService.getV3(URI.create(url));
return GSON.fromJson(response, SubWithdrawStatusResult.class);
}
@Override
public SpWithdrawStatusResult querySpWithdrawByOutRequestNo(String outRequestNo) throws WxPayException {
String url = String.format("%s/v3/merchant/fund/withdraw/out-request-no/%s", this.payService.getPayBaseUrl(), outRequestNo);
String response = this.payService.getV3(URI.create(url));
return GSON.fromJson(response, SpWithdrawStatusResult.class);
}
@Override
public void modifySettlement(String subMchid, SettlementRequest request) throws WxPayException {
String url = String.format("%s/v3/apply4sub/sub_merchants/%s/modify-settlement", this.payService.getPayBaseUrl(), subMchid);
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
}
@Override
public SettlementResult querySettlement(String subMchid) throws WxPayException {
String url = String.format("%s/v3/apply4sub/sub_merchants/%s/settlement", this.payService.getPayBaseUrl(), subMchid);
String response = this.payService.getV3(URI.create(url));
return GSON.fromJson(response, SettlementResult.class);
}
@Override
public BillResult applyBill(BillTypeEnum billType, BillRequest request) throws WxPayException {
String url = String.format(billType.getUrl(), this.payService.getPayBaseUrl(), this.parseURLPair(request));
String response = this.payService.getV3(URI.create(url));
return GSON.fromJson(response, BillResult.class);
}
@Override
public InputStream downloadBill(String url) throws WxPayException {
return this.payService.downloadV3(URI.create(url));
}
/**
* 校验通知签名
* @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());
}
/**
* 对象拼接到url
* @param o 转换对象
* @return 拼接好的string
*/
private String parseURLPair(Object o) {
Map
© 2015 - 2025 Weber Informatics LLC | Privacy Policy