package com.tendbird.payserver.pay.service; import com.fasterxml.jackson.databind.node.ObjectNode; import com.tendbird.payserver.pay.domain.PayConfig; import com.tendbird.payserver.pay.domain.PayOrder; import com.tendpay.sdk.Tendpay; import com.tendpay.sdk.TendpayClient; import com.tendpay.sdk.exception.PayException; import com.tendpay.sdk.model.PayOrderCreateReqModel; import com.tendpay.sdk.model.PayOrderQueryReqModel; import com.tendpay.sdk.model.RefundOrderCreateReqModel; import com.tendpay.sdk.model.RefundOrderQueryReqModel; import com.tendpay.sdk.request.PayOrderCreateRequest; import com.tendpay.sdk.request.PayOrderQueryRequest; import com.tendpay.sdk.request.RefundOrderCreateRequest; import com.tendpay.sdk.request.RefundOrderQueryRequest; import com.tendpay.sdk.response.PayOrderCreateResponse; import com.tendpay.sdk.response.PayOrderQueryResponse; import com.tendpay.sdk.response.RefundOrderCreateResponse; import com.tendpay.sdk.response.RefundOrderQueryResponse; import com.tendpay.sdk.util.JacksonUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.util.ObjectUtils; @Slf4j public class PayUtils { private static final int maxQueryRetry = 20; //统一下单 public static PayOrderCreateResponse doTradePay(PayConfig payConfig, PayOrder payOrder) throws Exception { Tendpay.setApiBase(payConfig.getApiUrl()); Tendpay.apiKey = payConfig.getApiKey(); Tendpay.mchNo = payConfig.getMchNo(); Tendpay.appId = payConfig.getAppid(); TendpayClient tendpayClient = TendpayClient.getInstance(Tendpay.appId, Tendpay.apiKey,Tendpay.getApiBase()); PayOrderCreateRequest request = new PayOrderCreateRequest(); PayOrderCreateReqModel model = new PayOrderCreateReqModel(); model.setMchNo(Tendpay.mchNo); // 商户号 model.setAppId(tendpayClient.getAppId()); // 应用ID model.setMchOrderNo(payOrder.getMchOrderNo()); // 商户订单号 model.setWayCode(payOrder.getWayCode()); // 支付方式 model.setAmount(payOrder.getAmount()); // 金额,单位分 model.setCurrency(payOrder.getCurrency()); // 币种,目前只支持cny model.setClientIp("127.0.0.1"); // 发起支付请求客户端的IP地址 model.setSubject(payOrder.getSubject()); // 商品标题 model.setBody(payOrder.getBody()); // 商品描述 model.setNotifyUrl(payConfig.getNotifyUrl()); // 异步通知地址 model.setReturnUrl(payConfig.getReturnUrl()); // 前端跳132457558789533910 // 转地址 model.setChannelExtra(channelExtra(payOrder.getWayCode(), payOrder.getAuthCode())); // 渠道扩展参数 model.setExtParam(payOrder.getExtParam()); // 商户扩展参数,回调时原样返回 request.setBizModel(model); try { PayOrderCreateResponse response = tendpayClient.execute(request); log.info("交易信息:{}", response); // 下单成功 if (response.isSuccess(Tendpay.apiKey)) { return response; } else { throw new Exception(response.getMessage()); } } catch (PayException e) { throw new Exception(e.getMessage()); } } //轮循交易状态 public static PayOrderQueryResponse doTradePayQuery(PayConfig payConfig, String orderNo, String orderId) throws Exception { for (int i = 0; i < maxQueryRetry; i++) { PayOrderQueryResponse orderQueryResponse = doTradePayQuerying(payConfig, orderNo, orderId); if (!ObjectUtils.isEmpty(orderQueryResponse)) { int state = orderQueryResponse.get().getState(); switch (state) { case PayOrder.STATE_ORDER_SUCCESS: case PayOrder.STATE_ORDER_FAIL: case PayOrder.STATE_ORDER_REVERSE: case PayOrder.STATE_ORDER_CLOSED: case PayOrder.STATE_ORDER_REFUND: return orderQueryResponse; default: break; } } Thread.sleep(3000); } return null; } //交易状态查询 public static PayOrderQueryResponse doTradePayQuerying(PayConfig payConfig, String orderNo, String orderId) throws Exception { Tendpay.setApiBase(payConfig.getApiUrl()); Tendpay.apiKey = payConfig.getApiKey(); Tendpay.mchNo = payConfig.getMchNo(); Tendpay.appId = payConfig.getAppid(); TendpayClient tendpayClient = TendpayClient.getInstance(Tendpay.appId, Tendpay.apiKey,Tendpay.getApiBase()); PayOrderQueryRequest request = new PayOrderQueryRequest(); PayOrderQueryReqModel model = new PayOrderQueryReqModel(); model.setMchNo(Tendpay.mchNo); // 商户号 model.setAppId(tendpayClient.getAppId()); // 应用ID model.setMchOrderNo(orderNo); //商户订单号 model.setPayOrderId(orderId); //支付订单号 request.setBizModel(model); try { PayOrderQueryResponse response = tendpayClient.execute(request); if (response.isSuccess(Tendpay.apiKey)) { return response; } else { throw new Exception(response.getMessage()); } } catch (PayException e) { throw new Exception(e.getMessage()); } } //退款交易 public static RefundOrderCreateResponse doTradePayRefund(PayConfig payConfig, PayOrder payOrder) throws Exception { Tendpay.setApiBase(payConfig.getApiUrl()); Tendpay.apiKey = payConfig.getApiKey(); Tendpay.mchNo = payConfig.getMchNo(); Tendpay.appId = payConfig.getAppid(); TendpayClient tendpayClient = TendpayClient.getInstance(Tendpay.appId, Tendpay.apiKey,Tendpay.getApiBase()); RefundOrderCreateRequest request = new RefundOrderCreateRequest(); RefundOrderCreateReqModel model = new RefundOrderCreateReqModel(); model.setMchNo(Tendpay.mchNo); // 商户号 model.setAppId(tendpayClient.getAppId()); // 应用ID if (payOrder.getFlag() == 0) { model.setMchOrderNo(payOrder.getAuthCode()); // 商户支付单号(与支付订单号二者传一) } else { model.setPayOrderId(payOrder.getAuthCode()); //支付订单号(与商户支付单号二者传一) } model.setMchRefundNo(payOrder.getMchOrderNo()); // 商户退款单号 model.setRefundAmount(payOrder.getAmount()); // 退款金额,单位分 model.setCurrency(payOrder.getCurrency()); // 币种,目前只支持cny model.setClientIp("127.0.0.1"); // 发起支付请求客户端的IP地址 model.setRefundReason(payOrder.getReason()); // 退款原因 model.setNotifyUrl(payConfig.getNotifyUrl()); // 异步通知地址 model.setChannelExtra(payOrder.getChannelExtra()); // 渠道扩展参数 model.setExtParam(payOrder.getExtParam()); // 商户扩展参数,回调时原样返回 request.setBizModel(model); try { RefundOrderCreateResponse response = tendpayClient.execute(request); log.info("退款交易:{}", response); // 判断退款发起是否成功(并不代表退款成功) if (response.isSuccess(Tendpay.apiKey)) { String refundOrderId = response.get().getRefundOrderId(); String mchRefundNo = response.get().getMchRefundNo(); return response; } else { throw new Exception(response.getMessage()); } } catch (PayException e) { throw new Exception(e.getMessage()); } } //轮循退款状态 public static RefundOrderQueryResponse doRefundPayQuery(PayConfig payConfig, String orderNo, String orderId) throws Exception { Thread.sleep(1000); for (int i = 0; i < maxQueryRetry; i++) { RefundOrderQueryResponse response = doRefundPayQuerying(payConfig, orderNo, orderId); if (response != null) { int state = response.get().getState(); switch (state) { case PayOrder.STATE_REFUND_SUCCESS: case PayOrder.STATE_REFUND_FAIL: case PayOrder.STATE_REFUND_CLOSED: return response; default: break; } } Thread.sleep(3000); } return null; } //查询退款状态 public static RefundOrderQueryResponse doRefundPayQuerying(PayConfig payConfig, String orderNo, String orderId) throws Exception { TendpayClient tendpayClient = TendpayClient.getInstance(payConfig.getAppid(), payConfig.getApiKey(), payConfig.getApiUrl()); RefundOrderQueryRequest request = new RefundOrderQueryRequest(); RefundOrderQueryReqModel model = new RefundOrderQueryReqModel(); model.setMchNo(payConfig.getMchNo()); // 商户号 model.setAppId(tendpayClient.getAppId()); // 应用ID model.setMchRefundNo(orderNo); //商户退款单号 model.setRefundOrderId(orderId); // 退款单号 request.setBizModel(model); try { RefundOrderQueryResponse response = tendpayClient.execute(request); if (response.isSuccess(Tendpay.apiKey)) { return response; } else { throw new Exception(response.getMessage()); } } catch (PayException e) { throw new Exception(e.getMessage()); } } private static String channelExtra(String wayCode, String data) { if ("WX_LITE".equals(wayCode)) return wxJsapiExtra(data); if ("WX_JSAPI".equals(wayCode)) return wxJsapiExtra(data); if ("WX_BAR".equals(wayCode)) return wxBarExtra(data); if ("ALI_BAR".equals(wayCode)) return aliBarExtra(data); if ("YSF_BAR".equals(wayCode)) return ysfBarExtra(data); if ("UPACP_BAR".equals(wayCode)) return upacpBarExtra(data); if ("QR_CASHIER".equals(wayCode)) return qrCashierExtra(data); if ("AUTO_BAR".equals(wayCode)) return autoBarExtra(data); if ("PP_PC".equals(wayCode)) return ppExtra(data); //if("SAND_H5".equals(wayCode)) return sandH5Extra(); return ""; } private static String wxJsapiExtra(String data) { ObjectNode obj = JacksonUtil.newObjectNode(); obj.put("openId", data); return obj.toString(); } private static String wxBarExtra(String data) { ObjectNode obj = JacksonUtil.newObjectNode(); obj.put("authCode", data); return obj.toString(); } private static String aliBarExtra(String data) { ObjectNode obj = JacksonUtil.newObjectNode(); obj.put("authCode", data); return obj.toString(); } private static String ysfBarExtra(String data) { ObjectNode obj = JacksonUtil.newObjectNode(); obj.put("authCode", data); return obj.toString(); } private static String upacpBarExtra(String data) { ObjectNode obj = JacksonUtil.newObjectNode(); obj.put("authCode", data); return obj.toString(); } private static String qrCashierExtra(String data) { ObjectNode obj = JacksonUtil.newObjectNode(); obj.put("payDataType", data); return obj.toString(); } private static String autoBarExtra(String data) { ObjectNode obj = JacksonUtil.newObjectNode(); obj.put("authCode", data); return obj.toString(); } private static String ppExtra(String data) { ObjectNode obj = JacksonUtil.newObjectNode(); obj.put("cancelUrl", data); return obj.toString(); } }