|
@@ -0,0 +1,260 @@
|
|
|
+package com.fuint.common.service.impl;
|
|
|
+
|
|
|
+import com.alipay.api.AlipayApiException;
|
|
|
+import com.alipay.api.domain.AlipayTradePayModel;
|
|
|
+import com.alipay.api.domain.AlipayTradeQueryModel;
|
|
|
+import com.alipay.api.domain.AlipayTradeRefundModel;
|
|
|
+import com.alipay.api.internal.util.AlipaySignature;
|
|
|
+import com.alipay.api.response.AlipayTradePayResponse;
|
|
|
+import com.alipay.api.response.AlipayTradeQueryResponse;
|
|
|
+import com.alipay.api.response.AlipayTradeRefundResponse;
|
|
|
+import com.fuint.common.bean.AliPayBean;
|
|
|
+import com.fuint.common.dto.OrderDto;
|
|
|
+import com.fuint.common.dto.UserOrderDto;
|
|
|
+import com.fuint.common.enums.*;
|
|
|
+import com.fuint.common.service.*;
|
|
|
+import com.fuint.framework.exception.BusinessCheckException;
|
|
|
+import com.fuint.framework.web.ResponseObject;
|
|
|
+import com.fuint.repository.model.*;
|
|
|
+import com.fuint.utils.StringUtil;
|
|
|
+import com.ijpay.alipay.AliPayApi;
|
|
|
+import com.ijpay.alipay.AliPayApiConfig;
|
|
|
+import com.ijpay.alipay.AliPayApiConfigKit;
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 云闪付相关接口
|
|
|
+ *
|
|
|
+ * Created by FSQ
|
|
|
+ * CopyRight https://www.fuint.cn
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@AllArgsConstructor
|
|
|
+public class UnionPayServiceImpl implements UnionPayService {
|
|
|
+
|
|
|
+ private static final Logger logger = LoggerFactory.getLogger(UnionPayServiceImpl.class);
|
|
|
+
|
|
|
+ private AliPayBean aliPayBean;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 订单服务接口
|
|
|
+ * */
|
|
|
+ private OrderService orderService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 店铺服务接口
|
|
|
+ * */
|
|
|
+ private StoreService storeService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建预支付订单
|
|
|
+ *
|
|
|
+ * @param userInfo 会员信息
|
|
|
+ * @param orderInfo 订单信息
|
|
|
+ * @param payAmount 支付金额
|
|
|
+ * @param authCode 付款码
|
|
|
+ * @param giveAmount 赠送金额
|
|
|
+ * @param ip 支付IP地址
|
|
|
+ * @param platform 支付平台
|
|
|
+ * @return
|
|
|
+ * */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public ResponseObject createPrepayOrder(MtUser userInfo, MtOrder orderInfo, Integer payAmount, String authCode, Integer giveAmount, String ip, String platform) throws BusinessCheckException {
|
|
|
+ logger.info("UnionPayService createPrepayOrder inParams userInfo={} payAmount={} giveAmount={} goodsInfo={}", userInfo, payAmount, giveAmount, orderInfo);
|
|
|
+
|
|
|
+ String goodsInfo = orderInfo.getOrderSn();
|
|
|
+ if (orderInfo.getType().equals(OrderTypeEnum.PRESTORE.getKey())) {
|
|
|
+ goodsInfo = OrderTypeEnum.PRESTORE.getValue();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新支付金额
|
|
|
+ BigDecimal payAmount1 = new BigDecimal(payAmount).divide(new BigDecimal("100"));
|
|
|
+ OrderDto reqDto = new OrderDto();
|
|
|
+ reqDto.setId(orderInfo.getId());
|
|
|
+ reqDto.setPayAmount(payAmount1);
|
|
|
+ reqDto.setPayType(orderInfo.getPayType());
|
|
|
+ reqDto.setOrderSn(orderInfo.getOrderSn());
|
|
|
+ orderService.updateOrder(reqDto);
|
|
|
+
|
|
|
+ getApiConfig(orderInfo.getStoreId());
|
|
|
+ String notifyUrl = aliPayBean.getDomain();
|
|
|
+ AlipayTradePayModel model = new AlipayTradePayModel();
|
|
|
+ model.setAuthCode(authCode);
|
|
|
+ model.setSubject(goodsInfo);
|
|
|
+ model.setTotalAmount(payAmount1.toString());
|
|
|
+ model.setOutTradeNo(orderInfo.getOrderSn());
|
|
|
+ model.setStoreId(orderInfo.getStoreId().toString());
|
|
|
+ model.setScene("bar_code");
|
|
|
+
|
|
|
+ String code = "";
|
|
|
+ try {
|
|
|
+ AlipayTradePayResponse response = AliPayApi.tradePayToResponse(model, notifyUrl);
|
|
|
+ code = response.getCode();
|
|
|
+ String msg = response.getMsg();
|
|
|
+ logger.info("UnionPayService createPrepayOrder return code: {}, msg ", code, msg);
|
|
|
+ if (!code.equals("10000") || !msg.equalsIgnoreCase("Success")) {
|
|
|
+ if (code.equals("10003")) {
|
|
|
+ // 需要会员输入支付密码,等待10秒后查询订单
|
|
|
+ try {
|
|
|
+ Thread.sleep(10000);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ Map<String, String> payResult = queryPaidOrder(orderInfo.getStoreId(), response.getTradeNo(), orderInfo.getOrderSn());
|
|
|
+ if (payResult == null) {
|
|
|
+ throw new BusinessCheckException("支付宝支付失败");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new BusinessCheckException("支付宝支付出错:" + msg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("UnionPayService createPrepayOrder exception {}", e.getMessage());
|
|
|
+ throw new BusinessCheckException("支付宝支付出错,请检查配置项");
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, String> respData = new HashMap<>();
|
|
|
+ respData.put("result", code);
|
|
|
+
|
|
|
+ ResponseObject responseObject = new ResponseObject(200, "支付宝支付接口返回成功", respData);
|
|
|
+ logger.info("UnionPayService createPrepayOrder outParams {}", responseObject.toString());
|
|
|
+
|
|
|
+ return responseObject;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 支付回调
|
|
|
+ *
|
|
|
+ * @param params 请求参数
|
|
|
+ * @return
|
|
|
+ * */
|
|
|
+ @Override
|
|
|
+ public Boolean checkCallBack(Map<String, String> params) throws Exception {
|
|
|
+ String orderSn = params.get("out_trade_no") != null ? params.get("out_trade_no") : "";
|
|
|
+ Integer storeId = 0;
|
|
|
+ UserOrderDto orderDto = orderService.getOrderByOrderSn(orderSn);
|
|
|
+ if (orderDto != null && orderDto.getStoreInfo() != null) {
|
|
|
+ storeId = orderDto.getStoreInfo().getId();
|
|
|
+ }
|
|
|
+ getApiConfig(storeId);
|
|
|
+ return AlipaySignature.rsaCheckV1(params, aliPayBean.getPublicKey(), "UTF-8", "RSA2");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取支付配置
|
|
|
+ *
|
|
|
+ * @param storeId 店铺ID
|
|
|
+ * @return
|
|
|
+ * */
|
|
|
+ public AliPayApiConfig getApiConfig(Integer storeId) throws BusinessCheckException {
|
|
|
+ AliPayApiConfig aliPayApiConfig;
|
|
|
+ String appId = aliPayBean.getAppId();
|
|
|
+ String privateKey = aliPayBean.getPrivateKey();
|
|
|
+ String publicKey = aliPayBean.getPublicKey();
|
|
|
+
|
|
|
+ // 优先读取店铺的支付账号
|
|
|
+ MtStore mtStore = storeService.queryStoreById(storeId);
|
|
|
+ if (mtStore != null && StringUtil.isNotEmpty(mtStore.getAlipayAppId()) && StringUtil.isNotEmpty(mtStore.getAlipayPrivateKey()) && StringUtil.isNotEmpty(mtStore.getAlipayPublicKey())) {
|
|
|
+ appId = mtStore.getAlipayAppId();
|
|
|
+ privateKey = mtStore.getAlipayPrivateKey();
|
|
|
+ publicKey = mtStore.getAlipayPublicKey();
|
|
|
+ }
|
|
|
+
|
|
|
+ aliPayApiConfig = AliPayApiConfig.builder()
|
|
|
+ .setAppId(appId)
|
|
|
+ .setAliPayPublicKey(publicKey)
|
|
|
+ .setCharset("UTF-8")
|
|
|
+ .setPrivateKey(privateKey)
|
|
|
+ .setServiceUrl(aliPayBean.getServerUrl())
|
|
|
+ .setSignType("RSA2")
|
|
|
+ .build();
|
|
|
+
|
|
|
+ AliPayApiConfigKit.setThreadLocalAppId(appId);
|
|
|
+ AliPayApiConfigKit.setThreadLocalAliPayApiConfig(aliPayApiConfig);
|
|
|
+
|
|
|
+ return aliPayApiConfig;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询支付订单
|
|
|
+ *
|
|
|
+ * @param storeId 店铺ID
|
|
|
+ * @param tradeNo 交易单号
|
|
|
+ * @param orderSn 订单号
|
|
|
+ * @return
|
|
|
+ * */
|
|
|
+ @Override
|
|
|
+ public Map<String, String> queryPaidOrder(Integer storeId, String tradeNo, String orderSn) throws BusinessCheckException {
|
|
|
+ try {
|
|
|
+ AlipayTradeQueryModel model = new AlipayTradeQueryModel();
|
|
|
+ if (StringUtil.isNotEmpty(orderSn)) {
|
|
|
+ model.setOutTradeNo(orderSn);
|
|
|
+ }
|
|
|
+ if (StringUtil.isNotEmpty(tradeNo)) {
|
|
|
+ model.setTradeNo(tradeNo);
|
|
|
+ }
|
|
|
+ getApiConfig(storeId);
|
|
|
+ AlipayTradeQueryResponse response = AliPayApi.tradeQueryToResponse(model);
|
|
|
+ if (response != null) {
|
|
|
+ // TradeStatus:TRADE_SUCCESS(交易支付成功,可进行退款)或 TRADE_FINISHED(交易结束,不可退款)
|
|
|
+ if (response.getTradeStatus() != null && response.getTradeStatus().equals("TRADE_SUCCESS")) {
|
|
|
+ Map<String, String> result = new HashMap<>();
|
|
|
+ result.put("tradeNo", response.getTradeNo());
|
|
|
+ result.put("status", response.getTradeStatus());
|
|
|
+ result.put("payAmount", response.getBuyerPayAmount());
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (AlipayApiException e) {
|
|
|
+ logger.info("AlipayService queryPaidOrder response", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发起售后退款
|
|
|
+ *
|
|
|
+ * @param storeId 店铺ID
|
|
|
+ * @param orderSn 订单号
|
|
|
+ * @param totalAmount 订单总金额
|
|
|
+ * @param refundAmount 售后金额
|
|
|
+ * @param platform 订单平台
|
|
|
+ * @return
|
|
|
+ * */
|
|
|
+ public Boolean doRefund(Integer storeId, String orderSn, BigDecimal totalAmount, BigDecimal refundAmount, String platform) throws BusinessCheckException {
|
|
|
+ try {
|
|
|
+ logger.info("AlipayService.doRefund orderSn = {}, totalFee = {}, refundFee = {}", orderSn, totalAmount, refundAmount);
|
|
|
+ if (StringUtil.isEmpty(orderSn)) {
|
|
|
+ throw new BusinessCheckException("退款订单号不能为空...");
|
|
|
+ }
|
|
|
+ if (refundAmount.compareTo(totalAmount) > 0) {
|
|
|
+ throw new BusinessCheckException("退款金额不能大于总金额...");
|
|
|
+ }
|
|
|
+ getApiConfig(storeId);
|
|
|
+ AlipayTradeRefundModel model = new AlipayTradeRefundModel();
|
|
|
+ model.setOutTradeNo(orderSn);
|
|
|
+ model.setRefundAmount(refundAmount.toString());
|
|
|
+ model.setRefundReason("申请退款");
|
|
|
+ AlipayTradeRefundResponse refundResponse = AliPayApi.tradeRefundToResponse(model);
|
|
|
+ String code = refundResponse.getCode();
|
|
|
+ String msg = refundResponse.getMsg();
|
|
|
+ String subMsg = refundResponse.getSubMsg() == null ? msg : refundResponse.getSubMsg();
|
|
|
+ logger.info("AlipayService refundResult response Body = {}", refundResponse.getBody());
|
|
|
+ if (!code.equals("10000") || !msg.equalsIgnoreCase("Success")) {
|
|
|
+ throw new BusinessCheckException("支付宝退款失败," + subMsg);
|
|
|
+ }
|
|
|
+ } catch (AlipayApiException e) {
|
|
|
+ logger.error("AlipayService.doRefund error = {}", e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|