引入微信支付SDK

Maven: com.github.wechatpay-apiv3:wechatpay-java-core:0.2.12
Maven: com.github.wechatpay-apiv3:wechatpay-java:0.2.12

代码示例

package xxxx.cashier.payChannel.handler;

import xxxx.common.domain.model.exception.BusinessException;
import xxxx.cashier.common.LocalTimeUtils;
import xxxx.cashier.common.RuleCommonUilt;
import xxxx.cashier.domain.dto.QueryRefundDto;
import xxxx.cashier.domain.model.CashierPayment;
import xxxx.cashier.domain.model.RefundStatusEnum;
import xxxx.cashier.payChannel.application.WxConfigService;
import xxxx.cashier.payChannel.callback.vo.WxPayRespDto;
import xxxx.cashier.payChannel.domain.model.PayChannel;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.cipher.Signer;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.core.util.NonceUtil;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import java.net.URISyntaxException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.stream.Collectors;
import java.util.stream.Stream; @Slf4j
@Service
public class JsapiPrepayHandler { @Autowired
private WxConfigService wxConfigService; /**
* 微信支付JSAPI下单----改造多核
* 多商户
* @param cashierPayment 订单
* @return WxPayRespDto
*/
public WxPayRespDto handlePrepay(CashierPayment cashierPayment) {
try {
// 微信支付渠道配置
Config wxConfig = wxConfigService.getWxConfig(cashierPayment.getMerchantTableId(),cashierPayment.getPayChannelType());
PayChannel payChannel = wxConfigService.getPayChannel(cashierPayment.getMerchantTableId(),cashierPayment.getPayChannelType());
String wxCallBackUrl = wxConfigService.getWxCallBackUrl(false,cashierPayment.getMerchantId());
// 设置回渠道Id
cashierPayment.setPayChannelId(payChannel.getMid());
// 渠道手续费
// cashierPayment.setChannelServiceFee(payChannel.getFee());
// 下单请求参数
PrepayRequest request = new PrepayRequest();
// 微信appId
request.setAppid(cashierPayment.getAppId());
// 微信商户id||是微信支付收款的商户ID--来自渠道{不是业务商户}
request.setMchid(wxConfig.createCredential().getMerchantId());
// 商品描述
request.setDescription(cashierPayment.getDescription());
// 设置订单超时时间
Date expireTime = cashierPayment.getExpireTime();
if (expireTime == null) {
request.setTimeExpire(LocalDateTime.now().plusMinutes(RuleCommonUilt.WX_EXPIRE_TIME).toString() + "+08:00");
} else {
try {
String expireTimeStr = LocalTimeUtils.simpleDateFormat.format(expireTime);
request.setTimeExpire(expireTimeStr + "+08:00");
} catch (Exception e) {
log.error("xxxx.cashier.payChannel.handler.JsapiPrepayHandler.handlePrepay=:时间格式错误,走默认的过期时间策略");
request.setTimeExpire(LocalDateTime.now().plusMinutes(RuleCommonUilt.WX_EXPIRE_TIME).toString() + "+08:00");
}
}
// 回调地址,仅支持https||微信侧回调收银台的地址
request.setNotifyUrl(wxCallBackUrl);
// 支付订单号||收银台侧的流水号||不是业务系统的流水号
request.setOutTradeNo(cashierPayment.getPaymentNo());
// 订单金额
Amount amount = new Amount();
amount.setTotal(cashierPayment.getAmount().intValue());
amount.setCurrency(cashierPayment.getCurrencyType());
request.setAmount(amount);
// 支付环境
request.setAttach("收银台:" + cashierPayment.getPaymentNo() + ";业务侧:" + cashierPayment.getOrderNo());
// 付款人
Payer payer = new Payer();
// 用户id
payer.setOpenid(cashierPayment.getOpenId());
request.setPayer(payer);
// 支付环境
if (StringUtils.isNotBlank(cashierPayment.getClientIp())) {
SceneInfo sceneInfo = new SceneInfo();
sceneInfo.setPayerClientIp(cashierPayment.getClientIp());
request.setSceneInfo(sceneInfo);
}
// 使用jsapi方式请求
JsapiServiceExtension service =
new JsapiServiceExtension.Builder()
.config(wxConfig)
.signType("RSA") // 不填默认为RSA
.build();
// 发起下单
PrepayWithRequestPaymentResponse prepayResp = service.prepayWithRequestPayment(request);
if (prepayResp == null || StringUtils.isEmpty(prepayResp.getPackageVal())) {
log.error("xxxx.cashier.payChannel.handler.JsapiPrepayHandler.handlePrepay:发起付款失败, 返回的预付款订单号为空");
throw new BusinessException("发起付款失败, 返回的预付款订单号为空");
}
// 下单成功---组装数据
return this.buildWxPayRespVo(cashierPayment, prepayResp);
} catch (Exception e) {
log.error("xxxx.cashier.payChannel.handler.JsapiPrepayHandler.handlePrepay:生成签名失败:{}", e.getMessage(), e);
throw new BusinessException("生成签名失败" + e.getMessage());
}
} /**
* 微信发送--小程序下单返回字段填充
*
* @param cashierPayment cashierPayment
* @param prepayResp prepayResp
* @return WxPayRespDto
* @throws Exception Exception
* @author GuoTong
*/
public WxPayRespDto buildWxPayRespVo(CashierPayment cashierPayment, PrepayWithRequestPaymentResponse prepayResp) throws Exception {
return new WxPayRespDto()
.setPrepayId(prepayResp.getPackageVal())
.setPaymentNo(cashierPayment.getPaymentNo())
.setNonceStr(prepayResp.getNonceStr())
.setTimeStamp(prepayResp.getTimeStamp())
.setPaySign(prepayResp.getPaySign())
.setSignType("RSA");
} /**
* 手动封装---吴爽
*
* @param cashierPayment cashierPayment
* @param prepayId prepayId
* @param wxConfig wxConfig
* @return
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
* @throws SignatureException
* @throws URISyntaxException
*/
public WxPayRespDto getWxPayRespVo(CashierPayment cashierPayment, String prepayId, Config wxConfig) throws Exception { Long timeStamp = System.currentTimeMillis() / 1000;
String nonceStr = NonceUtil.createNonce(32);
// 生成签名
String signatureStr = Stream.of(cashierPayment.getAppId(),
String.valueOf(timeStamp),
nonceStr,
prepayId)
.collect(Collectors.joining("\n", "", "\n"));
Signer signer = wxConfig.createSigner();
String sign = signer.sign(signatureStr).getSign(); return new WxPayRespDto()
.setPrepayId(prepayId)
.setPaymentNo(cashierPayment.getPaymentNo())
.setNonceStr(nonceStr)
.setTimeStamp(timeStamp.toString())
.setPaySign(sign)
.setSignType(signer.getAlgorithm());
} /**
* 商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑。
* <p>
* 查询订单可通过微信支付订单号 (opens new window)和商户订单号 (opens new window)两种方式查询。
* <p>
* 需要调用查询接口的情况:
* <p>
* 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知。
* 调用支付接口后,返回系统错误或未知交易状态情况。
* 调用付款码支付API,返回USERPAYING的状态。
* 调用关单或撤销接口API之前,需确认支付状态。
*
* @param cashierPayment CashierPayment
* @param payChannelTarget payChannelTarget
* @return WxPayRespDto
*/
public Transaction queryOrderInfo(CashierPayment cashierPayment, PayChannel payChannelTarget) {
Long payChannelId = cashierPayment.getPayChannelId();
Config wxConfig = wxConfigService.getWxConfig(payChannelId,payChannelTarget);
QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
request.setMchid(wxConfig.createCredential().getMerchantId());
request.setOutTradeNo(cashierPayment.getPaymentNo());
JsapiServiceExtension service =
new JsapiServiceExtension.Builder()
.config(wxConfig)
.signType("RSA") // 不填默认为RSA
.build();
Transaction transaction = null;
try {
transaction = service.queryOrderByOutTradeNo(request);
} catch (Exception e) {
throw new RuntimeException(e);
}
return transaction;
} /**
* 关闭订单,以下情况需要调用关单接口:
* <p>
* 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;
* 系统下单后,用户支付超时,系统退出不再受理,避免用户继续,请调用关单接口。
*
* @param cashierPayment cashierPayment
*/
public void closePayment(CashierPayment cashierPayment) {
CloseOrderRequest request = new CloseOrderRequest();
Config wxConfig = wxConfigService.getWxConfig(cashierPayment.getPayChannelId(),new PayChannel());
// 使用微信侧的商户
request.setMchid(wxConfig.createCredential().getMerchantId());
// 商户系统内部订单号
request.setOutTradeNo(cashierPayment.getPaymentNo());
JsapiService service = new JsapiService.Builder().config(wxConfig).build();
service.closeOrder(request);
} /**
* 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,
* <p>
* 微信支付将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家帐号上。
*
* @param cashierPayment cashierPayment
* @return Refund
*/
@SuppressWarnings("unchecked,deprecation,unused")
public Refund refundOrderV3(CashierPayment cashierPayment, CashierPayment originalOrder) {
Config wxConfig = wxConfigService.getWxConfig(cashierPayment.getPayChannelId(),new PayChannel());
String wxCallBackUrl = wxConfigService.getWxCallBackUrl(true,originalOrder.getMerchantId());
RefundService service = new RefundService.Builder().config(wxConfig).build();
CreateRequest request = new CreateRequest();
// 退款收银台订单号
request.setOutRefundNo(cashierPayment.getPaymentNo());
// 微信支付订单号(原支付渠道流水号)
request.setTransactionId(cashierPayment.getChannelFlowNo());
// 使用可用余额退款 ===== request.setFundsAccount(ReqFundsAccount.AVAILABLE);
request.setNotifyUrl(wxCallBackUrl);
// 退款金额
AmountReq amountReq = new AmountReq();
// 原始订单金额
amountReq.setTotal(originalOrder.getAmount());
// 退款订单金额
amountReq.setRefund(cashierPayment.getRefundAmount());
amountReq.setCurrency(StringUtils.isEmpty(cashierPayment.getCurrencyType()) ? "CNY" : cashierPayment.getCurrencyType());
request.setAmount(amountReq);
// 发起退款
Refund refund = null;
try {
refund = service.create(request);
} catch (ServiceException e) {
// 捕捉-微信退款下单时返回的状态码是发送HTTP请求成功,服务返回异常。例如返回状态码小于200或大于等于300。
String errorCode = e.getErrorCode();
// 判断由定时任务调度过来的|跳过本地环境---直接操作微信环境---引起本地和微信订单不同步操作
String message = e.getErrorMessage();
if (errorCode.equals("INVALID_REQUEST") && message.equals("订单已全额退款")){
log.info("订单已全额退款"+cashierPayment.getPaymentNo());
throw new BusinessException(Status.SUCCESS.name());
}
log.error("发起退款失败,错误码:{}", errorCode, e);
throw new BusinessException(errorCode);
}
log.debug("退款处理--微信结果:{}", refund.toString());
if (refund.getStatus() == Status.SUCCESS ||
refund.getStatus() == Status.PROCESSING) {
log.info("发起退款成功:" + cashierPayment.getPaymentNo());
return refund;
} else {
log.error("发起退款失败:{}", refund.getStatus());
throw new BusinessException("发起退款失败");
}
} public QueryRefundDto queryRefundOrderV3(CashierPayment refundOrder) {
Config wxConfig = wxConfigService.getWxConfig(refundOrder.getPayChannelId(),new PayChannel());
RefundService service = new RefundService.Builder().config(wxConfig).build();
QueryByOutRefundNoRequest request = new QueryByOutRefundNoRequest();
// 【商户退款单号】 商户系统内部的退款单号
request.setOutRefundNo(refundOrder.getPaymentNo());
Refund refund = service.queryByOutRefundNo(request);
log.error("退款订单查询--微信结果:{}", refund.toString());
// 获取系统的退款单状态
switch (refund.getStatus()) {
case SUCCESS:
log.info("退款成功......");
refundOrder.setStatus(RefundStatusEnum.SUCCESS.getCode());
refundOrder.setChannelRefundSuccessTime(LocalTimeUtils.dealDateFormatWithWx(refund.getSuccessTime()));
break;
case CLOSED:
log.info("退款已关闭......");
refundOrder.setStatus(RefundStatusEnum.CLOSED.getCode());
break;
case PROCESSING:
log.info("退款处理中......");
refundOrder.setStatus(RefundStatusEnum.PROCESSING.getCode());
break;
case ABNORMAL:
log.error("退款异常......");
refundOrder.setStatus(RefundStatusEnum.ABNORMAL.getCode());
break;
default:
break;
}
refundOrder.setChannelRefundStatus(refund.getStatus().name());
refundOrder.setChannelReturnCode(refund.getStatus().name());
return buildQueryRefundDto(refund, refundOrder);
} private QueryRefundDto buildQueryRefundDto(Refund refund, CashierPayment refundOrder) {
QueryRefundDto queryRefundDto = new QueryRefundDto();
queryRefundDto.setRefundNo(refund.getOutRefundNo());
queryRefundDto.setRefundTime(LocalTimeUtils.dealDateFormatWithWx(refund.getSuccessTime()));
queryRefundDto.setCreateTime(LocalTimeUtils.dealDateFormatWithWx(refund.getCreateTime()));
queryRefundDto.setRefundAmount(refund.getAmount().getRefund());
queryRefundDto.setAmount(refund.getAmount().getTotal());
switch (refund.getStatus().name()) {
case "SUCCESS":
queryRefundDto.setStatus(1);
break;
case "CLOSED":
queryRefundDto.setStatus(2);
break;
case "ABNORMAL":
queryRefundDto.setStatus(4);
break;
default:
queryRefundDto.setStatus(3);
break;
}
return queryRefundDto;
}
}

接口

package com.cztech.platform.cashier.payChannel.application;

import com.cztech.platform.cashier.domain.model.PayTypeEnum;
import com.cztech.platform.cashier.payChannel.domain.model.PayChannel;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.notification.NotificationConfig; /**
* packageName com.cztech.platform.cashier.payment
*
* @author GuoTong
* @version JDK 8
* @className WxConfigService
* @date 2024/3/16
* @description 初始化系统配置微信
*/
public interface WxConfigService { /**
* 获取渠道的配置--微信
*
* @param channelId channelId
* @return Config
*/
Config getWxConfig(Long channelId,PayChannel payChannel); /**
* 获取渠道的配置--微信
*
* @param payTypeEnumType PayTypeEnumType
* @return Config
*/
Config getWxConfig(Long merchantId, PayTypeEnum payTypeEnumType); /**
* 微信支付回调验签配置
*
* @return NotificationConfig
*/
NotificationConfig getCallBackConfig(String merchantNo,PayTypeEnum payTypeEnumType); /**
* 获取渠道的配置--渠道自身信息
*
* @param merchantId payTypeEnumType
* @return PayChannel
*/
PayChannel getPayChannel(Long merchantId, PayTypeEnum payTypeEnumType); /**
* 商户号区分回调
* @param isRefund isRefund
* @param merchantNo merchantNo
* @return String
*/
String getWxCallBackUrl(boolean isRefund,String merchantNo);
}

微信配置

package xxxx.platform.cashier.payChannel.application.impl;

import xxxx.common.domain.model.exception.BusinessException;
import xxxx.platform.cashier.common.RuleCommonUilt;
import xxxx.platform.cashier.common.config.SystemGlobalConfigProperties;
import xxxx.platform.cashier.domain.model.PayTypeEnum;
import xxxx.platform.cashier.payChannel.application.PayChannelService;
import xxxx.platform.cashier.payChannel.application.WxConfigService;
import xxxx.platform.cashier.payChannel.domain.model.PayChannel;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* packageName xxxx.platform.cashier.payment
*
* @author GuoTong
* @version JDK 8
* @className WxConfigService
* @date 2024/3/16
* @description 获取微信支付的配置
*/
@SuppressWarnings("all")
@Service
public class WxConfigServiceImpl implements WxConfigService {
private Logger logger = LoggerFactory.getLogger(WxConfigServiceImpl.class);
@Autowired
private PayChannelService payChannelService; @Autowired
private SystemGlobalConfigProperties systemGlobalConfigProperties; /**
* 根据渠道类型和商户ID获取支付通道
*/
private Map<String, Config> configMapByCache = new HashMap<>(); /**
* 根据渠道ID获取支付通道
*/
private Map<Long, Config> configMapByIdCache = new HashMap<>(); /**
* 获取微信支付的配置| 根据商户号隔离
*/
private Map<String, NotificationConfig> notificationConfig = new HashMap<>(); /**
* 渠道缓存
*/
private Map<String, PayChannel> payChannelCache = new HashMap<>();
@Value("${test.windows.certPath:D:\\BaiduNetdiskDownload\\微信支付秘密\\apiclient_key.pem}")
private String certPathTestByWindows; /**
* 内存多级缓存----缓存命中率优先
*/
@Override
public Config getWxConfig(Long channelId, PayChannel payChannelTarget) {
if (configMapByIdCache.get(channelId) != null) {
return configMapByIdCache.get(channelId);
}
PayChannel payChannel = null;
if (payChannelTarget == null && channelId == null) {
logger.error(this.getClass().getName() + RuleCommonUilt.NOT_FIND_PAY_CHANNEL);
throw new BusinessException(RuleCommonUilt.NOT_FIND_PAY_CHANNEL);
}
payChannel = payChannelTarget;
if (payChannel == null || payChannelTarget.getMid() == null) {
payChannel = payChannelService.get(channelId);
}
String merchantId = payChannel.getMerchantId();
String certPath = payChannel.getCertPath();
if (StringUtils.isBlank(certPath)) {
certPath = systemGlobalConfigProperties.getApiclientKeyByWechat();
}
if (StringUtils.isBlank(certPath)) {
throw new BusinessException("微信支付配置错误,请Nacos先配置:微信支付私钥");
}
String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("win")) {
certPath = certPathTestByWindows;
}
String merchantSerialNumber = payChannel.getMerchantSerialNumber();
String apiV3key = payChannel.getPrivateKey();
// 获取微信支付的配置
Config config = getConfig(merchantId, certPath, merchantSerialNumber, apiV3key);
configMapByIdCache.put(channelId, config);
return config;
} /**
* 内存缓存
*/
@Override
public Config getWxConfig(Long merchantMid, PayTypeEnum payTypeEnumType) {
if (configMapByCache.get(RuleCommonUilt.WX_JSAPI + "_" + merchantMid + "_" + payTypeEnumType.getCode()) != null) {
return configMapByCache.get(RuleCommonUilt.WX_JSAPI + "_" + merchantMid + "_" + payTypeEnumType.getCode());
}
// 查找关联关系的-------渠道商户
List<PayChannel> payChannels = payChannelService.getMerchantAssociatedChannelVoGrid(merchantMid, payTypeEnumType.getCode());
if (CollectionUtils.isEmpty(payChannels)) {
logger.error("xxxx.platform.cashier.payChannel.application.impl.WxConfigServiceImpl.getWxConfig(java.lang.Long, xxxx.platform.cashier.domain.model.PayTypeEnum)==>未找到支付通道");
return null;
}
PayChannel payChannelVarT = payChannels.get(0);
String merchantId = payChannelVarT.getMerchantId();
String certPath = payChannelVarT.getCertPath();
if (StringUtils.isBlank(certPath)) {
certPath = systemGlobalConfigProperties.getApiclientKeyByWechat();
}
if (StringUtils.isBlank(certPath)) {
throw new BusinessException("微信支付配置错误,请Nacos先配置:微信支付私钥");
}
String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("win")) {
certPath = certPathTestByWindows;
}
String merchantSerialNumber = payChannelVarT.getMerchantSerialNumber();
String apiV3key = payChannelVarT.getPrivateKey();
// 获取微信支付的配置||内存缓存
Config config = getConfig(merchantId, certPath, merchantSerialNumber, apiV3key);
configMapByCache.put(RuleCommonUilt.WX_JSAPI + "_" + merchantMid + "_" + payTypeEnumType.getCode(), config);
// 渠道赋值
configMapByIdCache.put(payChannelVarT.getMid(), config);
// 渠道缓存
payChannelCache.put(RuleCommonUilt.WX_JSAPI + "_" + merchantMid + "_" + payTypeEnumType.getCode(), payChannelVarT);
return config;
} /**
* 渠道侧接受微信回调|以商户号区分厂商
* lazy多级缓存
*
* @param merchantNo
* @param payTypeEnumType
* @return
*/
@Override
public NotificationConfig getCallBackConfig(String merchantNo, PayTypeEnum payTypeEnumType) {
// 多级缓存---提高性能
if (notificationConfig.get(merchantNo) != null) {
return notificationConfig.get(merchantNo);
}
// 查找关联关系的-------渠道商户
List<PayChannel> payChannels = payChannelService.getThisMerchantNoPayChannel(merchantNo, payTypeEnumType.getCode());
if (CollectionUtils.isEmpty(payChannels)) {
logger.error("xxxx.platform.cashier.payChannel.application.impl.WxConfigServiceImpl.getWxConfig(java.lang.Long, xxxx.platform.cashier.domain.model.PayTypeEnum)==>未找到支付通道");
return null;
}
PayChannel payChannel = payChannels.get(0);
PayChannel payChannelVarT = payChannels.get(0);
String merchantId = payChannel.getMerchantId();
String certPath = payChannel.getCertPath();
if (StringUtils.isBlank(certPath)) {
certPath = systemGlobalConfigProperties.getApiclientKeyByWechat();
}
if (StringUtils.isBlank(certPath)) {
throw new BusinessException("微信支付配置错误,请Nacos先配置:微信支付私钥");
}
String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("win")) {
certPath = certPathTestByWindows;
}
String merchantSerialNumber = payChannel.getMerchantSerialNumber();
String apiV3key = payChannel.getPrivateKey();
// 缓存回写----
NotificationConfig config = getConfig(merchantId, certPath, merchantSerialNumber, apiV3key);
notificationConfig.put(merchantNo, config);
return config;
} private static RSAAutoCertificateConfig getConfig(String merchantId, String certPath, String merchantSerialNumber, String apiV3key) {
return new RSAAutoCertificateConfig.Builder()
.merchantId(merchantId)
.privateKeyFromPath(certPath)
.merchantSerialNumber(merchantSerialNumber)
.apiV3Key(apiV3key)
.build();
} @Override
public PayChannel getPayChannel(Long merchantMid, PayTypeEnum payTypeEnumType) {
PayChannel payChannel = payChannelCache.get(RuleCommonUilt.WX_JSAPI + "_" + merchantMid + "_" + payTypeEnumType.getCode());
if (payChannel != null) {
return payChannel;
}
// 查找关联关系的-------渠道商户
List<PayChannel> payChannels = payChannelService.getMerchantAssociatedChannelVoGrid(merchantMid, payTypeEnumType.getCode());
if (CollectionUtils.isEmpty(payChannels)) {
logger.error("xxxx.platform.cashier.payChannel.application.impl.WxConfigServiceImpl.getPayChannel==>未找到支付通道");
return null;
}
PayChannel payChannelVarT = payChannels.get(0);
payChannelCache.put(RuleCommonUilt.WX_JSAPI + "_" + merchantMid + "_" + payTypeEnumType.getCode(), payChannelVarT);
return payChannelVarT;
} /**
* 获取回调地址|路径参数--最后一位是商户编码:根据商户编码区分
*
* @param isRefund isRefund
* @param merchantNo merchantNo
* @return
*/
@Override
public String getWxCallBackUrl(boolean isRefund, String merchantNo) {
if (!isRefund) {
String callBackUrl = systemGlobalConfigProperties.getBackUrlByWechat();
if (StringUtils.isEmpty(callBackUrl)) {
return "https://cashier.chinamuseum.cn/wxpay/notify/pay";
} else {
callBackUrl = callBackUrl + "/wxpay/notify/pay";
}
return callBackUrl + "/" + merchantNo;
} else {
String callBackUrl = systemGlobalConfigProperties.getBackUrlByWechat();
if (StringUtils.isEmpty(callBackUrl)) {
return "https://cashier.chinamuseum.cn/wxpay/notify/refund";
} else {
callBackUrl = callBackUrl + "/wxpay/notify/refund";
}
return callBackUrl + "/" + merchantNo;
}
} }

SpringBoot+微信支付-JSAPI的更多相关文章

  1. 微信支付JsApi 40163错误

    微信支付JsApi 40163错误错误:未定义数组索引:openid .经过检查发现是 :微信支付授权获取 openId {“errcode”:40163,“errmsg”:“code been us ...

  2. ThinkPHP中实现微信支付(jsapi支付)流程

    https://blog.csdn.net/sinat_35861727/article/details/72783988 之前写过一篇文章讲了 PHP实现微信支付(jsapi支付)流程 ,详见文章: ...

  3. 关于IOS调用微信支付jsapi不起作用的解决方法

    微信支付时,安卓机调用 jsapi可以支付,IOS就不行,点击立即支付,直接返回原立即支付页面,跟刷新页面差不多,解决方案很简单:两句话而已. 不得不说,微信支付坑太多了,我擦..... <sc ...

  4. 微信支付JSAPI模式及退款CodeIgniter集成篇

    微信支付接口文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1 首先你得知道这个jsapi是不能离开微信进行调用支付的,明白 ...

  5. 微信支付JsAPI

    https://pay.weixin.qq.com/wiki/doc/api/download/WxpayAPI_php_v3.zip 下载获取微信支付demo压缩包 打开压缩包,并将其中 Wxpay ...

  6. php 微信支付jsapi

    首先你们公司开通微信支付功能后,会收到一份邮件,里面有账户相关信息,一般有:微信支付商户号,商户平台登录帐号,商户平台登录密码,申请对应的公众号,公众号APPID. 1.下载demo:用上面信息登陆& ...

  7. [微信开发] - 微信支付 JSAPI 形式

    微信官方的JSAPI文档 微信官方的JSAPI支付SDK与DEMO下载 查看JSAPI的API可以从这里看 下载了支付DEMO其实有些地方不对的,比如如果做沙盒测试的时候,需要使用getsignkey ...

  8. 微信支付JSAPI支付

    1.介绍 JSAPI支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付.应用场景有:    ◆ 用户在微信公众账号内进入商家公众号,打开某 ...

  9. 微信支付(JsApi)

    这两天有个小项目用的微信网页jsapi支付 用的thinkphp框架开发 ,首次做微信支付 碰了很多壁,做了简单就记录,方便回顾 也希望对大家能有点帮助,也希望路过的大神批评指正.. 一.必备条件及相 ...

  10. 微信支付-JSAPI支付V3-查询退款

    接口地址 接口链接:https://api.mch.weixin.qq.com/pay/refundquery 是否需要证书 不需要. 请求参数 字段名 变量名 必填 类型 示例值 描述 公众账号ID ...

随机推荐

  1. TotalUninstaller(Setup.ForcedUninstall.exe)可执行程序和源码的下载

    TotalUninstaller(Setup.ForcedUninstall.exe)可执行程序和源码的下载: 链接:https://pan.baidu.com/s/1uBiJ6z1RNVmBEUiF ...

  2. [rustGUI][iced]基于rust的GUI库iced(0.13)的部件学习(00):iced简单窗口的实现以及在窗口显示中文

    前言 本文是关于iced库的部件介绍,iced库是基于rust的GUI库,作者自述是受Elm启发. iced目前的版本是0.13.1,相较于此前的0.12版本,有较大改动. 本合集是基于新版本的关于分 ...

  3. 前端之canvas实现电子签约完成线上签署功能

    最近发现现在租房还是签合同,越来越多采用电子签约的方式进行,好处不用多说节约成本,节约时间.抱着好奇的心理,尝试自己动手实现一个电子签.原来并不复杂主要通过了canvas绘画能力进行实现的. 主要功能 ...

  4. Java AQS学习笔记

    1. AQS介绍 AQS的全称为(AbstractQueuedSynchronizer),这个类在java.util.concurrent.locks包下面. AQS是一个用来构建锁和同步器的框架,使 ...

  5. Swagger介绍和应用

    1.什么是swaggerSwagger是一个规范和完整的框架,用于生成.描述.调用和可视化RESTful风格的Web服务.简单来说,Swagger是一个功能强大的接口管理工具,并且提供了多种编程语言的 ...

  6. Java技术栈总结-基础

    - - -计算机技术演化- - -1 编程语言演化1.1 写在最前  此文用于个人总结,串接知识点 1.2 汇编  举例:mov .add  特点:程序量很大,几百行.几千行乃至几万行 1.3 VB- ...

  7. Java底层知识面试题

    JVM内存结构class文件格式JVM不会理解我们写的Java源文件, 我们必须把Java源文件编译成class文件, 才能被JVM识别, 对于JVM而言,class文件相当于一个接口class文件是 ...

  8. C# 使用NPOI生成Excel文件——合并单元格、设置Style

    using System; using System.IO; using NPOI.HSSF; using NPOI.HPSF; using NPOI.HSSF.UserModel; using NP ...

  9. 利用mybatis拦截器记录sql,辅助我们建立索引(二)

    背景 上一篇中讲述了mybatis的mapper初始化过程和执行过程,这篇再讲讲具体的拦截器的使用,以实现记录sql到持久化存储,通过分析这些sql,我们就能更方便地建立索引. 利用mybatis拦截 ...

  10. 华为交换机VLAN配置

    一.静态VLAN划分 1.查看接口信息 # 查看接口信息 display interfaces # 查看接口状态和配置的简要信息 display interfaces brief 2.静态VLAN划分 ...