微信支付和支付宝支付整合(含设计模式1)

微信支付和支付宝支付整合(含设计模式1)

1.说明:

设计模式:单例+策略模式+抽象

在开发中经常对接微信支付和支付宝支付,相对来说,阿里的文档比微信的接口文档清晰一点,这里用的第三方库(com.github.binarywang)整合两个支付

开箱即用。

​ 微信支付分开放平台和公众号,具体的请自行参考文裆自行配置. https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_9&index=1

​ 支付宝文档地址 https://opendocs.alipay.com/apis/api_1/alipay.trade.pay

微信支付大致可以分为 :

-  原生扫码支付(NATIVE) 扫码
-  App支付(APP) 
-  公众号支付/小程序支付.(JSAPI)  注意下单是需要带openid (所申请的公众号绑定的openid)
-  H5支付(MWEB)     l
-  (刷卡支付)MICROPAY

支付宝:

-  pc
-  app
-  h5

2.依赖准备

  • 阿里

    <aliyun-java-sdk.version>4.5.20</aliyun-java-sdk.version>
    <weixin-java-pay.version>4.0.0</weixin-java-pay.version>
    <ali-java-pay.version>4.13.0.ALL</ali-java-pay.version>
    
                <dependency>
                    <groupId>com.aliyun</groupId>
                    <artifactId>aliyun-java-sdk-core</artifactId>
                    <version>${aliyun-java-sdk.version}</version>
                </dependency>
    
              <dependency>
                    <groupId>com.alipay.sdk</groupId>
                    <artifactId>alipay-sdk-java</artifactId>
                    <version>${ali-java-pay.version}</version>
                </dependency>
    
    
    
  • 微信

    		 <dependency>
                    <groupId>com.github.binarywang</groupId>
                    <artifactId>weixin-java-pay</artifactId>
                    <version>${weixin-java-pay.version}</version>
                </dependency>
    

3.话不多说,开撸

  • 支付抽象类

    package com.ac.flaget.pay.abstracts;
    
    import com.ac.flaget.common.bean.ReturnValue;
    import com.ac.flaget.pay.request.PayRequest;
    import com.ac.flaget.pay.request.RefundRequest;
    import com.ac.flaget.pay.response.PayResponse;
    import com.ac.flaget.pay.response.RefundResponse;
    import com.github.binarywang.wxpay.exception.WxPayException;
    
    /**
     * @author: crayWen
     * @date: 2021-05-17 16:02
     * @desc: 支付抽象类
     */
    public interface AbstractPay<PayReq extends PayRequest,RefundReq extends RefundRequest> {
    
        /**
         * 预支付(包含验签)
         * @param request  请求参数
         * @return PayResponse  返回的信息
         */
        ReturnValue<PayResponse> pay(PayReq request)  throws WxPayException;
    
        /**
         * 支付结果主动查询
         */
        ReturnValue<PayResponse> payQuery(PayReq request);
    
        /**
         * 支付取消
         */
        ReturnValue<PayResponse> payCancel(PayReq request);
    
        /**
         * 退款
         */
        ReturnValue<RefundResponse> refund(RefundReq request);
    
        /**
         * 退款结果主动查询
         */
        ReturnValue<RefundResponse> refundQuery(RefundReq request);
    
        /**
         * 验证签名
         */
        Boolean verifySign(String jsonObject, Integer verifyType);
    }
    
    
    	
    

  • 支付配置,单例

    package com.ac.flaget.pay.config;
    
    import com.ac.flaget.pay.sdk.FlagPayClient;
    import com.ac.flaget.pay.sdk.alipay.api.AliPayApi;
    import com.ac.flaget.pay.sdk.alipay.config.impl.AliPayAppConfig;
    import com.ac.flaget.pay.sdk.alipay.config.impl.AliPayH5Config;
    import com.ac.flaget.pay.sdk.fgpay.api.WalletApi;
    import com.ac.flaget.pay.sdk.wxpay.api.WxPayApi;
    import com.ac.flaget.pay.sdk.wxpay.config.impl.WxPayAppConfig;
    import com.ac.flaget.pay.sdk.wxpay.config.impl.WxPayH5Config;
    import com.ac.flaget.user.web.handler.WalletHandler;
    import lombok.AllArgsConstructor;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @author: cray wen
     * @date: 2021-06-18 11:09
     * @desc: 支付配置类
     */
    @Configuration
    @AllArgsConstructor
    @ConditionalOnClass({WxPayH5Config.class,WxPayAppConfig.class,AliPayH5Config.class,AliPayAppConfig.class})
    public class PayConfiguration {
    
        /**
         * 等同于注解     @Resource 前提加 @AllArgsConstructor
         */
        private final WxPayH5Config wxPayH5Config;
        private final WxPayAppConfig wxPayAppConfig;
        private final AliPayH5Config aliPayH5Config;
        private final AliPayAppConfig aliPayAppConfig;
        private final WalletHandler walletHandler;
    
    
        @Bean
        public WxPayApi wxPayAppApi() {
            return new WxPayApi(wxPayAppConfig);
        }
        @Bean
        public WxPayApi wxPayH5Api() {
            return new WxPayApi(wxPayH5Config);
        }
        @Bean
        public AliPayApi aliPayAppApi() {
            return new AliPayApi(aliPayAppConfig);
        }
        @Bean
        public AliPayApi aliPayH5Api() {
            return new AliPayApi(aliPayH5Config);
        }
    
        @Bean(name = "apiWalletHandler")
        public WalletApi walletApi(){
            return new WalletApi(walletHandler);
        }
    
        /**
         * 只存在一个实例,并在启动时就初始化了
         */
        @Bean
        @ConditionalOnMissingBean
        public FlagPayClient flagPayClient(){
            return new FlagPayClient(wxPayAppApi(),wxPayH5Api(),aliPayAppApi(),aliPayH5Api(),walletApi());
        }
    
    }
    
    
  • 支付策略切换类

    支付配置 分为APP 和 H5配置,具体参考文档

    package com.ac.flaget.pay.sdk;
    
    import com.ac.flaget.pay.abstracts.AbstractPay;
    import com.ac.flaget.pay.enums.PayChannelEnum;
    import com.ac.flaget.pay.request.PayRequest;
    import com.ac.flaget.pay.request.RefundRequest;
    import com.ac.flaget.pay.sdk.alipay.api.AliPayApi;
    import com.ac.flaget.pay.sdk.fgpay.api.WalletApi;
    import com.ac.flaget.pay.sdk.wxpay.api.WxPayApi;
    import lombok.extern.slf4j.Slf4j;
    
    import java.util.Objects;
    
    /**
     * @author: cray wen
     * @date: 2021-05-27 11:14
     * @desc: 支付切换类
     */
    @Slf4j
    public class FlagPayClient {
    
        /**
         *切换api
         */
        private final WxPayApi wxAppPayApi;
        private final WxPayApi wxH5PayApi;
        private final AliPayApi aliAppPayApi;
        private final AliPayApi aliH5PayApi;
        private final WalletApi walletApi;
    
        public FlagPayClient(
                             WxPayApi wxAppPayApi,
                             WxPayApi wxH5PayApi ,
                             AliPayApi aliAppPayApi,
                             AliPayApi aliPayH5Api,
                             WalletApi walletApi){
            this.wxAppPayApi  = wxAppPayApi;
            this. wxH5PayApi  = wxH5PayApi;
            this.aliAppPayApi = aliAppPayApi;
            this.aliH5PayApi = aliPayH5Api;
            this.walletApi =walletApi;
        }
    
        /**
         *
         * @param payStyle 支付类型
         * @param configType APP(公众开放平台)
         */
        public AbstractPay<PayRequest, RefundRequest> getPayApi(Integer payStyle,Integer configType){
            if(Objects.isNull(payStyle)){
                log.info("支付类型为空:{}",payStyle);
                return null;
            }
            if(PayChannelEnum.PayTypeEnum.ALIPAY.getCode().intValue() == payStyle && PayChannelEnum.PayConfigTypeEnum.APP.getCode().intValue() == configType) {
                return aliAppPayApi;
            }
            if(PayChannelEnum.PayTypeEnum.ALIPAY.getCode().intValue() == payStyle && PayChannelEnum.PayConfigTypeEnum.H5.getCode().intValue() == configType) {
                return aliH5PayApi;
            }
            if(PayChannelEnum.PayTypeEnum.WEIPAY.getCode().intValue() == payStyle && PayChannelEnum.PayConfigTypeEnum.APP.getCode().intValue() == configType) {
                return wxAppPayApi;
            }
            if(PayChannelEnum.PayTypeEnum.WEIPAY.getCode().intValue() == payStyle && PayChannelEnum.PayConfigTypeEnum.H5.getCode().intValue() == configType) {
                return wxH5PayApi;
            }
            if(PayChannelEnum.PayTypeEnum.WALLET.getCode().intValue()==payStyle){
                return walletApi;
            }
            return null;
        }
    
    }
    
    
  • 支付宝配置接口类

    package com.ac.flaget.pay.sdk.alipay.config;
    
    /**
     * @author: cray wen
     * @date: 2021-05-27 11:26
     * @desc: 支付宝 配置
     */
    public interface AliCustomConfig {
    
        /**
         * 支付宝支付根地址
         */
        public String getAliPayUrl();
        /**
         * 支付宝加密算法私钥
         */
        public String getAliPayPrivateKey();
        /**
         * 支付宝加密算法公钥
         */
        public String getAliPayPublicKey();
        /**
         * 支付宝APPID
         */
        public String getAliPayAppid();
        /**
         * 支付宝支付回调通知URL
         */
        public String getAliPayPayNotifyUrl();
        /**
         * 支付宝支付前端页面回跳页面url
         */
        public String getAliPayReturnPageUrl();
    
    
        public Boolean getAliUseSandboxEnv();
    
        public String getSignType();
    
        public String getCharset();
    
    }
    
    

    配置实现就不贴了, AliPayH5Config ; AliPayAppConfig ;

    有app 和h5 自行实现spring bean 注入或者是 xxl job实现等

  • 微信配置接口类

    package com.ac.flaget.pay.sdk.wxpay.config;
    
    /**
     * @author: cray wen
     * @date: 2021-05-27 11:39
     * @desc:
     */
    public interface WxCustomConfig {
    
        /**
         * 设置微信公众号或者小程序等的appid
         */
        public String getWexinAppId();
        /**
         * 微信支付商户号
         */
        public String getWexinMchId();
        /**
         * 微信支付商户密钥
         */
        public String getWexinMchKey();
        /**
         * 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除
         */
        public String getWexinSubAppId();
        /**
         * 服务商模式下的子商户号,普通模式请不要配置,最好是请在配置文件中将对应项删除
         */
        public String getWexinSubMchId();
        /**
         * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定
         */
        public String getWexinKeyPath();
        /**
         * 异步通知url
         */
        public String getWexinNotifyUrl();
        /**
         * 退款通知url
         */
        public String getWexinRefundNotifyUrl();
        /**
         * 是否使用沙箱环境
         */
        public Boolean getWexinUseSandboxEnv();
    
        public String getSignType();
    
        public String getCharset();
    }
    
    

    与支付宝类似,有app 和h5支付的实现类

    WxPayH5Config WxPayAppConfig;

  • 配置实现类其中一个

    package com.ac.flaget.pay.sdk.wxpay.config.impl;
    
    import com.ac.flaget.pay.sdk.wxpay.config.WxCustomConfig;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    
    /**
     * @author: craywen
     * @date: 2021-06-08 11:36
     * @desc:
     */
    @Service
    public class WxPayAppConfig implements WxCustomConfig {
    
        @Value("${pay.config.wx.app.appId}")
        private String wexinAppId;
    
        @Value("${pay.config.wx.app.mchId}")
        private String wxinMchId;
    
        @Value("${pay.config.wx.app.mchKey}")
        private String wexinMchKey;
    
        @Value("${pay.config.wx.app.keyPath}")
        private String wexinKeyPath;
    
        @Value("${pay.config.wx.app.notifyUrl}")
        private String wexinNotifyUrl;
    
        @Value("${pay.config.wx.app.useSandboxEnv}")
        private Boolean wexinUseSandboxEnv;
    
        @Override
        public String getSignType() {
            return "MD5";
        }
    
        @Override
        public String getCharset() {
            return "UTF-8";
        }
    

支付相关实现类(主要实现抽象支付类的主要方法)

  • 支付宝支付
@Slf4j
public class AliPayApi implements AbstractPay<PayRequest, RefundRequest> {

    private AliCustomConfig aliCustomConfig;
    private AlipayClient alipayClient;

    public AliPayApi(AliCustomConfig aliCustomConfig) {
        this.aliCustomConfig = aliCustomConfig;
        alipayClient = new DefaultAlipayClient(aliCustomConfig.getAliPayUrl(), aliCustomConfig.getAliPayAppid(), aliCustomConfig.getAliPayPrivateKey(), AlipayConstants.FORMAT_JSON, AlipayConstants.CHARSET_UTF8, aliCustomConfig.getAliPayPublicKey(), AlipayConstants.SIGN_TYPE_RSA2);
    }

pay 方法(预支付下单)

   @Override
    public ReturnValue<PayResponse> pay(PayRequest payRequest) {
        long timeMillis = System.currentTimeMillis();
        try {
            if (PayTradeTypeEnum.H5_PAY_TRADE_TYPE.getCode().intValue() != payRequest.getTradeType() &&
                    PayTradeTypeEnum.PC_PAY_TRADE_TYPE.getCode().intValue() != payRequest.getTradeType() &&
                    PayTradeTypeEnum.APP_PAY_TRADE_TYPE.getCode().intValue() != payRequest.getTradeType()) {
                return ReturnValue.ofFailed(PayErrorCodeEnum.PAY_ERROR_CODE_2310006.getCode(), PayErrorCodeEnum.PAY_ERROR_CODE_2310006.getDesc());
            }
            AlipayRequest<?> alipayRequest = null;
            AlipayResponse alipayResponse = null;
            //网页返回网页
            if (PayTradeTypeEnum.H5_PAY_TRADE_TYPE.getCode().intValue() == payRequest.getTradeType()) {
                alipayRequest = new AlipayTradeWapPayRequest();
                ((AlipayTradeWapPayRequest) alipayRequest).setBizContent("" +
                        "{\"out_trade_no\":\"" + payRequest.getRequestOrderSn() + "\","
                        + "\"total_amount\":\"" + payRequest.getPayAmount() + "\","
                        + "\"subject\":\"" + payRequest.getBody() + "\","
                        + "\"body\":\"" + payRequest.getBody() + "\","
                        + "\"product_code\":\"QUICK_WAP_WAY\"}");
            }
            //pc
            if (PayTradeTypeEnum.PC_PAY_TRADE_TYPE.getCode().intValue() == payRequest.getTradeType()) {
                alipayRequest = new AlipayTradePagePayRequest();
                ((AlipayTradePagePayRequest) alipayRequest).setBizContent("{" +
                        "\"out_trade_no\":\"" + payRequest.getRequestOrderSn() + "\","
                        + "\"total_amount\":\"" + payRequest.getPayAmount() + "\","
                        + "\"subject\":\"" + payRequest.getBody() + "\","
                        + "\"body\":\"" + payRequest.getBody() + "\","
                        + "\"passback_params\":\"" + payRequest.getTradeType() + "\","
                        + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

            }
            //唤起App(aa)
            if (PayTradeTypeEnum.APP_PAY_TRADE_TYPE.getCode().intValue() == payRequest.getTradeType()) {
                alipayRequest = new AlipayTradeAppPayRequest();
                ((AlipayTradeAppPayRequest) alipayRequest).setBizContent("{" +
                        "\"out_trade_no\":\"" + payRequest.getRequestOrderSn() + "\","
                        + "\"total_amount\":\"" + payRequest.getPayAmount() + "\","
                        + "\"subject\":\"" + payRequest.getBody() + "\","
                        + "\"body\":\"" + payRequest.getBody() + "\","
                        + "\"product_code\":\"QUICK_MSECURITY_PAY\"}");

            }
            // alipayRequest.setReturnUrl(aliCustomConfig.getAliPayReturnPageUrl());
            alipayRequest.setReturnUrl(payRequest.getReturnUrl());
            alipayRequest.setNotifyUrl(aliCustomConfig.getAliPayPayNotifyUrl());
            if (alipayRequest instanceof AlipayTradeAppPayRequest) {
                alipayResponse = alipayClient.sdkExecute(alipayRequest);
            } else if (alipayRequest instanceof AlipayTradePayRequest) {
                alipayResponse = alipayClient.execute(alipayRequest);
            } else {
//               page 必传get 方式 ,默认post 会使验签方式错误,
//                  if ("GET".equalsIgnoreCase(httpMethod)) {
//                              rsp.setBody(this.getRedirectUrl(requestHolder));
//                          } else {
//                             String baseUrl = this.getRequestUrl(requestHolder);
//                              rsp.setBody(WebUtils.buildForm(baseUrl, requestHolder.getApplicationParams()));
//                        }
                alipayResponse = alipayClient.pageExecute(alipayRequest,RequestMethod.GET.name() );
            }
            log.info("LOG-IN-ALIPAY,支付SDK结果详情 pay request:{} \n,response:{}", JSONUtils.toString(alipayRequest), JSONUtils.toString(alipayResponse));
            if (Objects.nonNull(alipayResponse) && alipayResponse.isSuccess()) {
                PayResponse response = new PayResponse();
                response.setCaskDeskUrl(alipayResponse.getBody());
                response.setCreatePayTime(timeMillis);
                response.setTimeoutPayTime(DateUtils.nextMinute(response.getCreatePayTime(), 15));
                response.setRequestOrderSn(payRequest.getRequestOrderSn());
                response.setThirdRemark("");
                response.setThirdTradeNo("");
                //, URLEncoder.encode(dynStr, StandardCharsets.UTF_8.toString())).build(true)
                response.setSign(alipayResponse.getBody());
                response.setPayStatus(PayStatusEnum.PayOrderStatusEnum.PAYING_STATUS_PAY.getCode());
                return ReturnValue.ofSuccessful(response);
            }
            String errMessageStr = Objects.isNull(alipayResponse) ? "" : alipayResponse.getMsg() + "_" + alipayResponse.getSubMsg();
            return ReturnValue.ofFailed(PayErrorCodeEnum.PAY_ERROR_CODE_2310001.getCode(), PayErrorCodeEnum.PAY_ERROR_CODE_2310001.getDesc() + "[" + errMessageStr + "]");
        } catch (Exception e) {
            log.error("ERROR-IN-AliPayApi-pay", e);
        }
        return ReturnValue.ofFailed(PayErrorCodeEnum.PAY_ERROR_CODE_2310001.getCode(), PayErrorCodeEnum.PAY_ERROR_CODE_2310001.getDesc());
    }

支付主动查询结果(异步回调请见文章二)

    @Override
    public ReturnValue<PayResponse> payQuery(PayRequest payRequest) {
        try {
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            request.setBizContent("{\"out_trade_no\":\"" + payRequest.getRequestOrderSn() + "\"" + "}");
            AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.execute(request);
            log.info("LOG-IN-ALIPAY,支付SDK查询支付结果详情 pay request:{},response:{}", JSONUtils.toString(alipayTradeQueryResponse), JSONUtils.toString(alipayTradeQueryResponse));
            if (Objects.nonNull(alipayTradeQueryResponse) && alipayTradeQueryResponse.isSuccess()) {
                PayResponse response = new PayResponse();
                response.setPayStatus(ConvertStatusUtil.getConvertAliPayStatus(alipayTradeQueryResponse.getTradeStatus()));
                response.setPaySuccessTime(System.currentTimeMillis());
                response.setThirdTradeNo(alipayTradeQueryResponse.getTradeNo());
                response.setTotalAmount(new BigDecimal(alipayTradeQueryResponse.getTotalAmount()));
                return ReturnValue.ofSuccessful(response);
            }
            String errMessageStr = Objects.isNull(alipayTradeQueryResponse) ? "" : alipayTradeQueryResponse.getMsg() + "_" + alipayTradeQueryResponse.getSubMsg();
            return ReturnValue.ofFailed(PayErrorCodeEnum.PAY_ERROR_CODE_2310003.getCode(), PayErrorCodeEnum.PAY_ERROR_CODE_2310003.getDesc() + "[" + errMessageStr + "]");
        } catch (Exception e) {
            log.error("ERROR-IN-AliPayApi-payQuery", e);

        }
        return ReturnValue.ofFailed(PayErrorCodeEnum.PAY_ERROR_CODE_2310003.getCode(), PayErrorCodeEnum.PAY_ERROR_CODE_2310003.getDesc());
    }
  • 微信支付

    继承 WxPayServiceApacheHttpImpl,的方法和属性

    @Slf4j
    public class WxPayApi extends WxPayServiceApacheHttpImpl implements AbstractPay<PayRequest, RefundRequest> {
    
        private Logger logger = LoggerFactory.getLogger(WxPayApi.class);
    
        //配置信息
        private WxCustomConfig wxCustomConfig;
    
        public WxPayApi(WxCustomConfig wxCustomConfig) {
            this.wxCustomConfig = wxCustomConfig;
            WxPayConfig payConfig = new WxPayConfig();
            payConfig.setAppId(StringUtils.trimToNull(wxCustomConfig.getWexinAppId()));
            payConfig.setMchId(StringUtils.trimToNull(wxCustomConfig.getWexinMchId()));
            payConfig.setMchKey(StringUtils.trimToNull(wxCustomConfig.getWexinMchKey()));
            payConfig.setSubAppId(StringUtils.trimToNull(wxCustomConfig.getWexinSubAppId()));
            payConfig.setSubMchId(StringUtils.trimToNull(wxCustomConfig.getWexinSubMchId()));
            payConfig.setKeyPath(StringUtils.trimToNull(wxCustomConfig.getWexinKeyPath()));
            // 可以指定是否使用沙箱环境
            payConfig.setUseSandboxEnv(wxCustomConfig.getWexinUseSandboxEnv());
            this.setConfig(payConfig);
        }
    

    预支付

       @Override
        public ReturnValue<PayResponse> pay(PayRequest request) throws WxPayException {
            long currentTimeMillis = System.currentTimeMillis();
            if (PayTradeTypeEnum.H5_PAY_TRADE_TYPE.getCode().intValue() != request.getTradeType() &&
                    PayTradeTypeEnum.PC_PAY_TRADE_TYPE.getCode().intValue() != request.getTradeType() &&
                    PayTradeTypeEnum.APP_PAY_TRADE_TYPE.getCode().intValue() != request.getTradeType() &&
                    PayTradeTypeEnum.WXGZH_PAY_TRADE_TYPE.getCode().intValue() != request.getTradeType() &&
                    PayTradeTypeEnum.WXMINIPROGRAM_PAY_TRADE_TYPE.getCode().intValue() != request.getTradeType()) {
                throw new BusinessException(PayErrorCodeEnum.PAY_ERROR_CODE_2310001.getCode(), PayErrorCodeEnum.PAY_ERROR_CODE_2310001.getDesc());
            }
            String tradeTypeStr = "";
            //
            //PC 扫码
            if (PayTradeTypeEnum.PC_PAY_TRADE_TYPE.getCode().intValue() == request.getTradeType()) {
                tradeTypeStr = WxPayConstants.TradeType.NATIVE;
                //APP
            } else if (PayTradeTypeEnum.APP_PAY_TRADE_TYPE.getCode().intValue() == request.getTradeType()) {
                tradeTypeStr = WxPayConstants.TradeType.APP;
                //JSAPI 需要带公众号绑定的openid much_id
            } else if (PayTradeTypeEnum.WXGZH_PAY_TRADE_TYPE.getCode().intValue() == request.getTradeType() ||
                    PayTradeTypeEnum.WXMINIPROGRAM_PAY_TRADE_TYPE.getCode().intValue() == request.getTradeType()) {
                tradeTypeStr = WxPayConstants.TradeType.JSAPI;
                // H5
            } else {
                tradeTypeStr = WxPayConstants.TradeType.MWEB;
            }
            Object result = null;
            WxPayUnifiedOrderRequest orderRequest = null;
            try {
                orderRequest = WxPayUnifiedOrderRequest.newBuilder().body(request.getBody())
                        .totalFee(request.getPayAmount().multiply(new BigDecimal(PayConstant.multiple)).intValue())
                        .spbillCreateIp(request.getSpbillCreateIp())
                        .notifyUrl(wxCustomConfig.getWexinNotifyUrl())
                        .tradeType(tradeTypeStr)
                        .outTradeNo(request.getRequestOrderSn())
                        .productId(request.getSkuId())
                        .deviceInfo((PayTradeTypeEnum.PC_PAY_TRADE_TYPE.getCode().intValue() == request.getTradeType()) ? "WEB" : "")
                        .build();
                ///JSAPI 需要带公众号绑定的openid much_id
                if (PayTradeTypeEnum.WXGZH_PAY_TRADE_TYPE.getCode().intValue() == request.getTradeType() ||
                        PayTradeTypeEnum.WXMINIPROGRAM_PAY_TRADE_TYPE.getCode().intValue() == request.getTradeType()) {
    
                    orderRequest.setOpenid(request.getOpenId());
                    orderRequest.setMchId(wxCustomConfig.getWexinMchId());
                }
                result = this.createOrder(orderRequest);
            } catch (WxPayException e) {
                log.error("微信支付失败:请求参数:request:{}, ", JSONUtils.toString(orderRequest), e);
            }
            log.info("LOG-IN-pay result,{},request:{}", JSONUtils.toString(result), JSONUtils.toString(request));
            PayResponse response = new PayResponse();
            response.setCreatePayTime(currentTimeMillis);
            response.setTimeoutPayTime(DateUtils.nextMinute(response.getCreatePayTime(), 5));
            response.setThirdRemark("");
            response.setThirdTradeNo("");
            response.setPayStatus(PayStatusEnum.PayOrderStatusEnum.PAYING_STATUS_PAY.getCode());
            response.setRequestOrderSn(request.getRequestOrderSn());
            if (result instanceof WxPayMwebOrderResult) {
                //微信统一H5 支付
                WxPayMwebOrderResult wxPayMwebOrderResult = (WxPayMwebOrderResult) result;
                response.setCaskDeskUrl(wxPayMwebOrderResult.getMwebUrl()+"&redirect_url="+request.getReturnUrl());
            } else if (result instanceof WxPayNativeOrderResult) {
                // 微信扫码支付统一下单后发起支付拼接所需参数实现类
                response.setCaskDeskUrl(((WxPayNativeOrderResult) result).getCodeUrl());
            } else if (result instanceof WxPayMpOrderResult) {
                //微信JsAPi支付 微信公众号支付进行统一下单后组装所需参数的类(WxPayMpOrderResult)
                WxPayMpOrderResult wxPayMpOrderResult = (WxPayMpOrderResult) result;
                response.setSign(wxPayMpOrderResult.getPaySign());
            } else if (result instanceof WxPayAppOrderResult) {
                //APP支付调用统一下单接口后的组装所需参数的实现类(WxPayAppOrderResult)
                WxPayAppOrderResult wxPayAppOrderResult = (WxPayAppOrderResult) result;
                response.setSign(wxPayAppOrderResult.getSign());
            }
            //基础返回的签名数据拷贝
            BeanUtils.copyProperties(result, response);
            return ReturnValue.ofSuccessful(response);
        }
    

    支付主动查询支付结果(异步回调请见文章二)

        @Override
        public ReturnValue<PayResponse> payQuery(PayRequest request) {
            try {
                WxPayOrderQueryResult result = this.queryOrder(WxPayOrderQueryRequest.newBuilder().outTradeNo(request.getRequestOrderSn()).build());
                if (!PayStatusEnum.SUCCESS.equals(result.getReturnCode())) {
                    log.error("查询支付信息失败,{}", result.getReturnMsg());
                    return ReturnValue.ofFailed(PayErrorCodeEnum.PAY_ERROR_CODE_2310002.getCode(), PayErrorCodeEnum.PAY_ERROR_CODE_2310002.getDesc());
                }
                PayOrderNotifyResponse payOrderNotifyResponse = new PayOrderNotifyResponse();
                BeanUtils.copyProperties(result, payOrderNotifyResponse);
                PayResponse response = new PayResponse();
                response.setPayStatus(ConvertStatusUtil.getConvertWeixinPayStatus(payOrderNotifyResponse.getTradeState()));
                response.setTotalAmount(new BigDecimal(payOrderNotifyResponse.getTotalFee()));
                response.setThirdTradeNo(payOrderNotifyResponse.getTransactionId());
                response.setPaySuccessTime(DateUtils.toDate(payOrderNotifyResponse.getTimeEnd(), "yyyyMMddHHmmss"));
                return ReturnValue.ofSuccessful(response);
            } catch (Exception e) {
                log.error("ERROR-IN-payQuery,request:{}", JSONUtils.toString(request));
            }
            return ReturnValue.ofFailed(PayErrorCodeEnum.PAY_ERROR_CODE_2310003.getCode(), PayErrorCodeEnum.PAY_ERROR_CODE_2310003.getDesc());
        }
    

    喜欢的话可以点赞,评论后面的功能会再后续文章更新

    (注意:微信支付有串单的问题,这边使用的是每次预支付会生成不同的第三方订单号,所以每个订单再有效的时间内,可以跨支付方式唤起支付)

    签名等是第三方框架验证,看下源代码就很容易理解,还是封装的比较好的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值