Search in sources :

Example 1 with WechatPaymentSetting

use of cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting in project lilishop by lilishop.

the class WechatPlugin method mpPay.

@Override
public ResultMessage<Object> mpPay(HttpServletRequest request, PayParam payParam) {
    try {
        Connect connect = connectService.queryConnect(ConnectQueryDTO.builder().userId(UserContext.getCurrentUser().getId()).unionType(ConnectEnum.WECHAT_MP_OPEN_ID.name()).build());
        if (connect == null) {
            return null;
        }
        Payer payer = new Payer();
        payer.setOpenid(connect.getUnionId());
        CashierParam cashierParam = cashierSupport.cashierParam(payParam);
        // 支付金额
        Integer fen = CurrencyUtil.fen(cashierParam.getPrice());
        // 第三方付款订单
        String outOrderNo = SnowFlake.getIdStr();
        // 过期时间
        String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);
        // 微信小程序,appid 需要单独获取,这里读取了联合登陆配置的appid ,实际场景小程序自动登录,所以这个appid是最为保险的做法
        // 如果有2开需求,这里需要调整,修改这个appid的获取途径即可
        String appid = wechatPaymentSetting().getMpAppId();
        if (StringUtils.isEmpty(appid)) {
            throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
        }
        String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam), StandardCharsets.UTF_8);
        WechatPaymentSetting setting = wechatPaymentSetting();
        UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel().setAppid(appid).setMchid(setting.getMchId()).setDescription(cashierParam.getDetail()).setOut_trade_no(outOrderNo).setTime_expire(timeExpire).setAttach(attach).setNotify_url(notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.WECHAT)).setAmount(new Amount().setTotal(fen)).setPayer(payer);
        log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
        PaymentHttpResponse response = WechatApi.v3(RequestMethodEnums.POST, WechatDomain.CHINA.toString(), WechatApiEnum.JS_API_PAY.toString(), setting.getMchId(), setting.getSerialNumber(), null, setting.getApiclient_key(), JSONUtil.toJsonStr(unifiedOrderModel));
        // 根据证书序列号查询对应的证书来验证签名结果
        boolean verifySignature = WxPayKit.verifySignature(response, getPlatformCert());
        log.info("verifySignature: {}", verifySignature);
        log.info("统一下单响应 {}", response);
        if (verifySignature) {
            String body = response.getBody();
            JSONObject jsonObject = JSONUtil.parseObj(body);
            String prepayId = jsonObject.getStr("prepay_id");
            Map<String, String> map = WxPayKit.jsApiCreateSign(appid, prepayId, setting.getApiclient_key());
            log.info("唤起支付参数:{}", map);
            return ResultUtil.data(map);
        }
        log.error("微信支付参数验证错误,请及时处理");
        throw new ServiceException(ResultCode.PAY_ERROR);
    } catch (Exception e) {
        log.error("支付异常", e);
        throw new ServiceException(ResultCode.PAY_ERROR);
    }
}
Also used : Connect(cn.lili.modules.connect.entity.Connect) PaymentHttpResponse(cn.lili.modules.payment.kit.core.PaymentHttpResponse) GeneralSecurityException(java.security.GeneralSecurityException) ServiceException(cn.lili.common.exception.ServiceException) WechatPaymentSetting(cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting) ServiceException(cn.lili.common.exception.ServiceException) JSONObject(cn.hutool.json.JSONObject) CashierParam(cn.lili.modules.payment.kit.params.dto.CashierParam)

Example 2 with WechatPaymentSetting

use of cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting in project lilishop by lilishop.

the class WechatPlugin method getPlatformCert.

/**
 * 获取平台公钥
 *
 * @return 平台公钥
 */
private X509Certificate getPlatformCert() {
    // 获取缓存中的平台公钥,如果有则直接返回,否则去微信请求
    String publicCert = cache.getString(CachePrefix.WECHAT_PLAT_FORM_CERT.getPrefix());
    if (!StringUtils.isEmpty(publicCert)) {
        return PayKit.getCertificate(publicCert);
    }
    // 获取平台证书列表
    try {
        WechatPaymentSetting setting = wechatPaymentSetting();
        PaymentHttpResponse response = WechatApi.v3(RequestMethodEnums.GET, WechatDomain.CHINA.toString(), WechatApiEnum.GET_CERTIFICATES.toString(), setting.getMchId(), setting.getSerialNumber(), null, setting.getApiclient_key(), "");
        String body = response.getBody();
        log.info("获取微信平台证书body: {}", body);
        if (response.getStatus() == 200) {
            JSONObject jsonObject = JSONUtil.parseObj(body);
            JSONArray dataArray = jsonObject.getJSONArray("data");
            // 默认认为只有一个平台证书
            JSONObject encryptObject = dataArray.getJSONObject(0);
            JSONObject encryptCertificate = encryptObject.getJSONObject("encrypt_certificate");
            String associatedData = encryptCertificate.getStr("associated_data");
            String cipherText = encryptCertificate.getStr("ciphertext");
            String nonce = encryptCertificate.getStr("nonce");
            publicCert = getPlatformCertStr(associatedData, nonce, cipherText);
            long second = (PayKit.getCertificate(publicCert).getNotAfter().getTime() - System.currentTimeMillis()) / 1000;
            cache.put(CachePrefix.WECHAT_PLAT_FORM_CERT.getPrefix(), publicCert, second);
        } else {
            log.error("证书获取失败:{}" + body);
            throw new ServiceException(ResultCode.WECHAT_CERT_ERROR);
        }
        return PayKit.getCertificate(publicCert);
    } catch (Exception e) {
        log.error("证书获取失败", e);
    }
    return null;
}
Also used : WechatPaymentSetting(cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting) JSONObject(cn.hutool.json.JSONObject) ServiceException(cn.lili.common.exception.ServiceException) PaymentHttpResponse(cn.lili.modules.payment.kit.core.PaymentHttpResponse) JSONArray(cn.hutool.json.JSONArray) GeneralSecurityException(java.security.GeneralSecurityException) ServiceException(cn.lili.common.exception.ServiceException)

Example 3 with WechatPaymentSetting

use of cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting in project lilishop by lilishop.

the class WechatPlugin method jsApiPay.

@Override
public ResultMessage<Object> jsApiPay(HttpServletRequest request, PayParam payParam) {
    try {
        Connect connect = connectService.queryConnect(ConnectQueryDTO.builder().userId(UserContext.getCurrentUser().getId()).unionType(ConnectEnum.WECHAT.name()).build());
        if (connect == null) {
            return null;
        }
        Payer payer = new Payer();
        payer.setOpenid(connect.getUnionId());
        CashierParam cashierParam = cashierSupport.cashierParam(payParam);
        // 支付金额
        Integer fen = CurrencyUtil.fen(cashierParam.getPrice());
        // 第三方付款订单
        String outOrderNo = SnowFlake.getIdStr();
        // 过期时间
        String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);
        String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam), StandardCharsets.UTF_8);
        WechatPaymentSetting setting = wechatPaymentSetting();
        String appid = setting.getServiceAppId();
        if (appid == null) {
            throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
        }
        UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel().setAppid(appid).setMchid(setting.getMchId()).setDescription(cashierParam.getDetail()).setOut_trade_no(outOrderNo).setTime_expire(timeExpire).setAttach(attach).setNotify_url(notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.WECHAT)).setAmount(new Amount().setTotal(fen)).setPayer(payer);
        log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
        PaymentHttpResponse response = WechatApi.v3(RequestMethodEnums.POST, WechatDomain.CHINA.toString(), WechatApiEnum.JS_API_PAY.toString(), setting.getMchId(), setting.getSerialNumber(), null, setting.getApiclient_key(), JSONUtil.toJsonStr(unifiedOrderModel));
        // 根据证书序列号查询对应的证书来验证签名结果
        boolean verifySignature = WxPayKit.verifySignature(response, getPlatformCert());
        log.info("verifySignature: {}", verifySignature);
        log.info("统一下单响应 {}", response);
        if (verifySignature) {
            String body = response.getBody();
            JSONObject jsonObject = JSONUtil.parseObj(body);
            String prepayId = jsonObject.getStr("prepay_id");
            Map<String, String> map = WxPayKit.jsApiCreateSign(appid, prepayId, setting.getApiclient_key());
            log.info("唤起支付参数:{}", map);
            return ResultUtil.data(map);
        }
        log.error("微信支付参数验证错误,请及时处理");
        throw new ServiceException(ResultCode.PAY_ERROR);
    } catch (Exception e) {
        log.error("支付异常", e);
        throw new ServiceException(ResultCode.PAY_ERROR);
    }
}
Also used : Connect(cn.lili.modules.connect.entity.Connect) PaymentHttpResponse(cn.lili.modules.payment.kit.core.PaymentHttpResponse) GeneralSecurityException(java.security.GeneralSecurityException) ServiceException(cn.lili.common.exception.ServiceException) WechatPaymentSetting(cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting) ServiceException(cn.lili.common.exception.ServiceException) JSONObject(cn.hutool.json.JSONObject) CashierParam(cn.lili.modules.payment.kit.params.dto.CashierParam)

Example 4 with WechatPaymentSetting

use of cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting in project lilishop by lilishop.

the class WechatPlugin method appPay.

@Override
public ResultMessage<Object> appPay(HttpServletRequest request, PayParam payParam) {
    try {
        CashierParam cashierParam = cashierSupport.cashierParam(payParam);
        // 支付金额
        Integer fen = CurrencyUtil.fen(cashierParam.getPrice());
        // 第三方付款订单
        String outOrderNo = SnowFlake.getIdStr();
        // 过期时间
        String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);
        String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam), StandardCharsets.UTF_8);
        WechatPaymentSetting setting = wechatPaymentSetting();
        String appid = setting.getAppId();
        if (appid == null) {
            throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
        }
        UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel().setAppid(appid).setMchid(setting.getMchId()).setDescription(cashierParam.getDetail()).setOut_trade_no(outOrderNo).setTime_expire(timeExpire).setAttach(attach).setNotify_url(notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.WECHAT)).setAmount(new Amount().setTotal(fen));
        log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
        PaymentHttpResponse response = WechatApi.v3(RequestMethodEnums.POST, WechatDomain.CHINA.toString(), WechatApiEnum.APP_PAY.toString(), setting.getMchId(), setting.getSerialNumber(), null, setting.getApiclient_key(), JSONUtil.toJsonStr(unifiedOrderModel));
        // 根据证书序列号查询对应的证书来验证签名结果
        boolean verifySignature = WxPayKit.verifySignature(response, getPlatformCert());
        log.info("verifySignature: {}", verifySignature);
        log.info("统一下单响应 {}", response);
        if (verifySignature) {
            JSONObject jsonObject = JSONUtil.parseObj(response.getBody());
            String prepayId = jsonObject.getStr("prepay_id");
            Map<String, String> map = WxPayKit.appPrepayIdCreateSign(appid, setting.getMchId(), prepayId, setting.getApiclient_key(), SignType.MD5);
            log.info("唤起支付参数:{}", map);
            return ResultUtil.data(map);
        }
        log.error("微信支付参数验证错误,请及时处理");
        throw new ServiceException(ResultCode.PAY_ERROR);
    } catch (Exception e) {
        log.error("支付异常", e);
        throw new ServiceException(ResultCode.PAY_ERROR);
    }
}
Also used : WechatPaymentSetting(cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting) ServiceException(cn.lili.common.exception.ServiceException) JSONObject(cn.hutool.json.JSONObject) CashierParam(cn.lili.modules.payment.kit.params.dto.CashierParam) PaymentHttpResponse(cn.lili.modules.payment.kit.core.PaymentHttpResponse) GeneralSecurityException(java.security.GeneralSecurityException) ServiceException(cn.lili.common.exception.ServiceException)

Example 5 with WechatPaymentSetting

use of cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting in project lilishop by lilishop.

the class WechatPlugin method verifyNotify.

/**
 * 验证结果,执行支付回调
 *
 * @param request
 * @throws Exception
 */
private void verifyNotify(HttpServletRequest request) throws Exception {
    String timestamp = request.getHeader("Wechatpay-Timestamp");
    String nonce = request.getHeader("Wechatpay-Nonce");
    String serialNo = request.getHeader("Wechatpay-Serial");
    String signature = request.getHeader("Wechatpay-Signature");
    log.info("timestamp:{} nonce:{} serialNo:{} signature:{}", timestamp, nonce, serialNo, signature);
    String result = HttpKit.readData(request);
    log.info("微信支付通知密文 {}", result);
    WechatPaymentSetting setting = wechatPaymentSetting();
    // 校验服务器端响应¬
    String plainText = WxPayKit.verifyNotify(serialNo, result, signature, nonce, timestamp, setting.getApiKey3(), Objects.requireNonNull(getPlatformCert()));
    log.info("微信支付通知明文 {}", plainText);
    JSONObject jsonObject = JSONUtil.parseObj(plainText);
    String payParamStr = jsonObject.getStr("attach");
    String payParamJson = URLDecoder.decode(payParamStr, StandardCharsets.UTF_8);
    PayParam payParam = JSONUtil.toBean(payParamJson, PayParam.class);
    String tradeNo = jsonObject.getStr("transaction_id");
    Double totalAmount = CurrencyUtil.reversalFen(jsonObject.getJSONObject("amount").getDouble("total"));
    PaymentSuccessParams paymentSuccessParams = new PaymentSuccessParams(PaymentMethodEnum.WECHAT.name(), tradeNo, totalAmount, payParam);
    paymentService.success(paymentSuccessParams);
    log.info("微信支付回调:支付成功{}", plainText);
}
Also used : WechatPaymentSetting(cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting) JSONObject(cn.hutool.json.JSONObject) PaymentSuccessParams(cn.lili.modules.payment.kit.dto.PaymentSuccessParams) PayParam(cn.lili.modules.payment.kit.dto.PayParam)

Aggregations

WechatPaymentSetting (cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting)10 ServiceException (cn.lili.common.exception.ServiceException)9 GeneralSecurityException (java.security.GeneralSecurityException)8 PaymentHttpResponse (cn.lili.modules.payment.kit.core.PaymentHttpResponse)7 JSONObject (cn.hutool.json.JSONObject)6 CashierParam (cn.lili.modules.payment.kit.params.dto.CashierParam)5 Connect (cn.lili.modules.connect.entity.Connect)2 Setting (cn.lili.modules.system.entity.dos.Setting)2 JSONArray (cn.hutool.json.JSONArray)1 PayParam (cn.lili.modules.payment.kit.dto.PayParam)1 PaymentSuccessParams (cn.lili.modules.payment.kit.dto.PaymentSuccessParams)1 QQConnectSetting (cn.lili.modules.system.entity.dto.connect.QQConnectSetting)1 WechatConnectSetting (cn.lili.modules.system.entity.dto.connect.WechatConnectSetting)1 AlipayPaymentSetting (cn.lili.modules.system.entity.dto.payment.AlipayPaymentSetting)1 PaymentSupportSetting (cn.lili.modules.system.entity.dto.payment.PaymentSupportSetting)1 PaymentSupportForm (cn.lili.modules.system.entity.dto.payment.dto.PaymentSupportForm)1 SettingEnum (cn.lili.modules.system.entity.enums.SettingEnum)1