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);
}
}
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;
}
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);
}
}
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);
}
}
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);
}
Aggregations