首页 > 其他分享 >SpringBoot+微信支付-JSAPI

SpringBoot+微信支付-JSAPI

时间:2024-06-04 20:33:17浏览次数:32  
标签:return String 微信 JSAPI payChannel new import cashierPayment SpringBoot

引入微信支付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;
        }
    }

}

标签:return,String,微信,JSAPI,payChannel,new,import,cashierPayment,SpringBoot
From: https://www.cnblogs.com/gtnotgod/p/18231651

相关文章

  • springboot3整合高版本spring data neo4j
    本博客适用于springboodataneo4j7.2.6版本,详情阅读官网https://docs.spring.io/spring-data/neo4j/reference/7.2/introduction-and-preface/index.html,中文网只更新到了6版本entity->nodeentity->relation@Node("Movie")//取代了老版本的nodeentity,他表示的就是labelp......
  • springboot+vue+mybatis学生奖惩管理系统+PPT+论文+讲解+售后
    在如今社会上,关于信息上面的处理,没有任何一个企业或者个人会忽视,如何让信息急速传递,并且归档储存查询,采用之前的纸张记录模式已经不符合当前使用要求了。所以,对学生奖惩信息管理的提升,也为了对学生奖惩信息进行更好的维护,学生奖惩管理系统的出现就变得水到渠成不可缺少。通过对......
  • springboot+vue+mybatis大学生就业管理系统+PPT+论文+讲解+售后
    现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本学生就业管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事......
  • Redis 结合 Docker 搭建集群,并整合SpringBoot
    软件版本Redis7.2.5Docker26.1.3 准备工作由于docker直接拉取运行了,所以需要提前准备配置文件Indexof/releases/(redis.io)下载后,把redis-7.2.5.tar.gz\redis-7.2.5.tar\redis-7.2.5\里的redis.confsentinel.conf复制出来 概览结构如上图所示,准备6个服务器。......
  • springboot智慧校园管理系统的设计与实现(文档+源码)
    大家好,我是永钊,一个混迹在java圈的码农,今天要和大家聊的是一款基于springboot的智慧校园管理系统,项目源码请联系永钊,目前有各类成品毕设javawebsshssmspringboot等等项目框架,源码丰富,欢迎咨询。 本网站系统采用了Mysql数据库,Java语言,SpringBoot框架等技术进行编程实......
  • springboot的设计与实现(文档+源码)足球青训俱乐部管理后台系统
    大家好,我是永钊,一个混迹在java圈的码农,今天要和大家聊的是一款基于springboot的足球青训俱乐部管理后台系统,项目源码请联系永钊,目前有各类成品毕设javawebsshssmspringboot等等项目框架,源码丰富,欢迎咨询。 本网站系统重点阐述了足球青训俱乐部管理后台系统的开发过程,......
  • 在线考试|基于Springboot的在线考试管理系统设计与实现(源码+数据库+文档)
    在线考试管理系统目录目录基于Springboot的在线考试管理系统设计与实现一、前言二、系统设计三、系统功能设计 1、前台:2、后台管理员功能四、数据库设计 五、核心代码 六、论文参考七、最新计算机毕设选题推荐八、源码获取:博主介绍:✌️大厂码农|毕设布道师,......
  • 健身管理小程序|基于微信开发健身管理小程序的系统设计与实现(源码+数据库+文档)
    健身管理小程序目录基于微信开发健身管理小程序设计与实现一、前言二、系统设计三、系统功能设计 小程序端:后台四、数据库设计 五、核心代码 六、论文参考七、最新计算机毕设选题推荐八、源码获取:博主介绍:✌️大厂码农|毕设布道师,阿里云开发社区乘风者计划专......
  • Java毕业设计 基于springboot vue大学新生报到系统
    Java毕业设计基于springbootvue大学新生报到系统SpringBoot大学新生报到系统功能介绍首页图片轮播报道流程流程详情校园公告公告详情登录注册个人中心更新信息学生后台登录个人中心修改密码个人信息学生报到班级分配宿舍分配缴费信息管理员登录个......
  • Manjaro Linux下使用wine运行企业微信
    开始因为工作原因所以必须用到企业微信,但是企业微信是目前主流办公软件中可能唯一一个不支持Linux系统的软件了,于是只能使用wine来运行windows版本来使用。期间遇到了各种坑在此记录一下,以便于能帮到同样需要的同学,也希望腾讯能够尽快开发Linux原生的企业微信。安装首先我们需......