Authored by Lixiaodi

支付超过100万修改

@@ -50,5 +50,17 @@ public class TradeBills { @@ -50,5 +50,17 @@ public class TradeBills {
50 //打款关联id 50 //打款关联id
51 private Integer dealRelateId = 0; 51 private Integer dealRelateId = 0;
52 52
53 - 53 + public static enum Status {
  54 +
  55 + TRANSFER_WAITING(90);
  56 +
  57 + private Status(int code) {
  58 + this.code = code;
  59 + }
  60 + private int code;
  61 + public int getCode() {
  62 + return code;
  63 + }
  64 +
  65 + }
54 } 66 }
@@ -90,6 +90,8 @@ public class AlipayConfig { @@ -90,6 +90,8 @@ public class AlipayConfig {
90 public static final String BLK_ALI_RSA_PUBLIC = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnxj/9qwVfgoUh/y2W89L6BkRAFljhNhgPdyPuBV64bfQNN1PjbCzkIM6qRdKBoLPXmKKMiFYnkd6rAoprih3/PrQEB/VsW8OoM8fxn67UDYuyBTqA23MML9q1+ilIZwBC2AQ2UBVOrFXfFl75p6/B5KsiNG9zpgmLCUYuLkxpLQIDAQAB"; 90 public static final String BLK_ALI_RSA_PUBLIC = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnxj/9qwVfgoUh/y2W89L6BkRAFljhNhgPdyPuBV64bfQNN1PjbCzkIM6qRdKBoLPXmKKMiFYnkd6rAoprih3/PrQEB/VsW8OoM8fxn67UDYuyBTqA23MML9q1+ilIZwBC2AQ2UBVOrFXfFl75p6/B5KsiNG9zpgmLCUYuLkxpLQIDAQAB";
91 91
92 /********************/ //OUYIN 92 /********************/ //OUYIN
  93 + public static final String OUYIN_EMAIL = "ouyin@yoho.cn";
  94 + public static final String OUYIN_USER_NAME = "欧印南京贸易有限公司";
93 public static final String OUYIN_PARTNER = "2088421850636193"; 95 public static final String OUYIN_PARTNER = "2088421850636193";
94 96
95 public static final String OUYIN_APPID = "2016091401906455"; 97 public static final String OUYIN_APPID = "2016091401906455";
@@ -29,6 +29,7 @@ import com.yohoufo.order.model.NotifyResponse; @@ -29,6 +29,7 @@ import com.yohoufo.order.model.NotifyResponse;
29 import com.yohoufo.order.model.PayQueryBo; 29 import com.yohoufo.order.model.PayQueryBo;
30 import com.yohoufo.order.model.PayRefundBo; 30 import com.yohoufo.order.model.PayRefundBo;
31 import com.yohoufo.order.model.PaymentData; 31 import com.yohoufo.order.model.PaymentData;
  32 +import com.yohoufo.order.model.TransferData;
32 import com.yohoufo.order.model.request.PaymentRequest; 33 import com.yohoufo.order.model.request.PaymentRequest;
33 import com.yohoufo.order.model.response.PaymentConfirmRsp; 34 import com.yohoufo.order.model.response.PaymentConfirmRsp;
34 import com.yohoufo.order.model.response.PrepayResponse; 35 import com.yohoufo.order.model.response.PrepayResponse;
@@ -259,6 +260,44 @@ public class PaymentController { @@ -259,6 +260,44 @@ public class PaymentController {
259 logger.info("[{}] reply success to alipay", out_trade_no); 260 logger.info("[{}] reply success to alipay", out_trade_no);
260 response.getWriter().print("success"); 261 response.getWriter().print("success");
261 } 262 }
  263 +
  264 + @IgnoreSignature
  265 + @IgnoreSession
  266 + @RequestMapping(value = "/ufo_alipay_transfer_notify", method = RequestMethod.POST)
  267 + public void notifyAliTransferPayment(HttpServletRequest request, HttpServletResponse response) throws IOException {
  268 + alipayLogger.info("\n\n\n************************* Notify ufo_alipay_transfer_notify");
  269 +
  270 + Map<String, String> params = parseParams(request.getParameterMap());
  271 + alipayLogger.info("[{}] ufo_alipay_transfer_notify Request params: {}", params);
  272 +
  273 +
  274 + String batch_no = params.get("batch_no");
  275 + alipayLogger.info("[{}] ufo_alipay_transfer_notify notification received", batch_no);
  276 +
  277 + //回调验证
  278 + if(!alipayService.notifyVerify(params)) {
  279 + alipayLogger.error("[{}] ufo_alipay_transfer_notify notification verify failed", batch_no);
  280 + return ;
  281 + }
  282 +
  283 + TransferData data = null;
  284 + try {
  285 + TransferData success = alipayService.getTransferData(params.get("success_details"));
  286 + TransferData fail = alipayService.getTransferData(params.get("fail_details"));
  287 + alipayLogger.info("method {} ufo_alipay_transfer_notify data is {},{}", batch_no, success, fail);
  288 + if((success==null && fail==null) ||(success!=null &&fail!=null)) {
  289 + alipayLogger.info("method {} ufo_alipay_transfer_notify success 和 fail 歧义", batch_no);
  290 + }
  291 + data = (fail == null) ? success : fail;
  292 + paymentService.transferSuccess(data);
  293 + } catch (Exception e) {
  294 + alipayLogger.error("[{}] ufo_alipay_transfer_notify notify process failed, ex: {}", batch_no, e);
  295 + return ;
  296 + }
  297 +
  298 + logger.info("[{}] ufo_alipay_transfer_notify reply success to alipay", batch_no);
  299 + response.getWriter().print("success");
  300 + }
262 301
263 /* @RequestMapping(params = "method=ufo.order.transferMon") 302 /* @RequestMapping(params = "method=ufo.order.transferMon")
264 public ApiResponse transferMon(@RequestParam(name = "buyerOrderCode") long buyerOrderCode, 303 public ApiResponse transferMon(@RequestParam(name = "buyerOrderCode") long buyerOrderCode,
  1 +package com.yohoufo.order.model;
  2 +
  3 +import lombok.Data;
  4 +import lombok.ToString;
  5 +
  6 +@Data
  7 +@ToString
  8 +public class TransferData {
  9 +
  10 +
  11 + private String orderCode;
  12 + private Integer transferId;
  13 + private Integer tradeBillsId;
  14 + private String receiveAccount;
  15 + private String receiveUserName;
  16 + private String money;
  17 + private String status;
  18 + private String message;
  19 + /** 支付宝内部流水号. */
  20 + private String alipayTradeId;
  21 + private String time;
  22 +
  23 +}
@@ -4,6 +4,7 @@ package com.yohoufo.order.service; @@ -4,6 +4,7 @@ package com.yohoufo.order.service;
4 import com.yohobuy.ufo.model.order.req.ManualDealRequest; 4 import com.yohobuy.ufo.model.order.req.ManualDealRequest;
5 import com.yohoufo.order.model.PayRefundBo; 5 import com.yohoufo.order.model.PayRefundBo;
6 import com.yohoufo.order.model.PaymentData; 6 import com.yohoufo.order.model.PaymentData;
  7 +import com.yohoufo.order.model.TransferData;
7 import com.yohoufo.order.model.request.PaymentRequest; 8 import com.yohoufo.order.model.request.PaymentRequest;
8 import com.yohoufo.order.model.request.TransferMoneyRequest; 9 import com.yohoufo.order.model.request.TransferMoneyRequest;
9 import com.yohoufo.order.model.response.PaymentConfirmRsp; 10 import com.yohoufo.order.model.response.PaymentConfirmRsp;
@@ -47,6 +48,7 @@ public interface IPaymentService { @@ -47,6 +48,7 @@ public interface IPaymentService {
47 */ 48 */
48 void paySuccess(PaymentData paymentData); 49 void paySuccess(PaymentData paymentData);
49 50
  51 + void transferSuccess(TransferData transferData);
50 52
51 /** 53 /**
52 * 订单退款 54 * 订单退款
@@ -23,6 +23,7 @@ import com.yohoufo.order.constants.RefundContant; @@ -23,6 +23,7 @@ import com.yohoufo.order.constants.RefundContant;
23 import com.yohoufo.order.model.PayQueryBo; 23 import com.yohoufo.order.model.PayQueryBo;
24 import com.yohoufo.order.model.PayRefundBo; 24 import com.yohoufo.order.model.PayRefundBo;
25 import com.yohoufo.order.model.PaymentData; 25 import com.yohoufo.order.model.PaymentData;
  26 +import com.yohoufo.order.model.TransferData;
26 import com.yohoufo.order.model.request.PaymentRequest; 27 import com.yohoufo.order.model.request.PaymentRequest;
27 import com.yohoufo.order.model.request.TranseferCellNode; 28 import com.yohoufo.order.model.request.TranseferCellNode;
28 import com.yohoufo.order.model.request.TransferMoneyRequest; 29 import com.yohoufo.order.model.request.TransferMoneyRequest;
@@ -53,6 +54,7 @@ import org.springframework.stereotype.Service; @@ -53,6 +54,7 @@ import org.springframework.stereotype.Service;
53 54
54 import java.math.BigDecimal; 55 import java.math.BigDecimal;
55 import java.util.Date; 56 import java.util.Date;
  57 +import java.util.Map;
56 import java.util.Objects; 58 import java.util.Objects;
57 import java.util.function.BiFunction; 59 import java.util.function.BiFunction;
58 60
@@ -329,6 +331,71 @@ public class PaymentServiceImpl implements IPaymentService { @@ -329,6 +331,71 @@ public class PaymentServiceImpl implements IPaymentService {
329 logger.info("paySuccess finished. orderCode is {}", orderCode); 331 logger.info("paySuccess finished. orderCode is {}", orderCode);
330 abstractOrderService.processAfterPay(orderInfo); 332 abstractOrderService.processAfterPay(orderInfo);
331 } 333 }
  334 +
  335 + @Override
  336 + public void transferSuccess(TransferData transferData) {
  337 + int now = (int) (System.currentTimeMillis()/1000);
  338 + Integer tradeBillsId = transferData.getTradeBillsId();
  339 + Integer transferId = transferData.getTransferId();
  340 + String orderCode = transferData.getOrderCode();
  341 +
  342 + TradeBills tradeBills = tradeBillsMapper.selectByPrimaryKey(tradeBillsId);
  343 + if (tradeBills == null) {
  344 + throw new ServiceException(400, "transferSuccess:流水不存在");
  345 + }
  346 + if (tradeBills.getTradeStatus() != TradeBills.Status.TRANSFER_WAITING.getCode()) {
  347 + throw new ServiceException(400, "transferSuccess:该流水不是异步转账的");
  348 + }
  349 + OrdersPayTransfer transfer = ordersPayTransferMapper.selectByPrimaryKey(transferId);
  350 + if (transfer == null) {
  351 + throw new ServiceException(400, "transferSuccess:转账记录不存在");
  352 + }
  353 + if (transfer.getStatus() == 1) {
  354 + throw new ServiceException(400, "transferSuccess:转账记录已经成功");
  355 + }
  356 + logger.info("transferSuccess 参数 tradeBillsId={}, tradeBillsId={}, orderCode={}", tradeBillsId, tradeBillsId, orderCode);
  357 + if(StringUtils.equals("S", transferData.getStatus())) {
  358 + // 更新成OK
  359 + TradeBills success = new TradeBills();
  360 + success.setId(tradeBills.getId());
  361 + success.setDealStatus(1);
  362 +
  363 + if (tradeBillsMapper.updateToOkByPrimaryKey(success) == 0) {
  364 + logger.warn("transferSuccess 流水已经被并发处理过 tradeBillsId={}, tradeBillsId={}, orderCode={}", tradeBillsId, tradeBillsId, orderCode);
  365 + return;
  366 + }
  367 +
  368 + logger.info("transferSuccess 旧流水更新成功,准备加新流水 tradeBillsId={}, tradeBillsId={}, orderCode={}", tradeBillsId, tradeBillsId, orderCode);
  369 + // 加新流水
  370 + tradeBills.setDealRelateId(tradeBills.getId());
  371 + tradeBills.setId(null);
  372 + tradeBills.setTradeStatus(100);
  373 + tradeBills.setCreateTime(now);
  374 + addTradeBills(tradeBills);
  375 +
  376 + logger.info("transferSuccess 加新流水成功,准备修改转账状态 tradeBillsId={}, tradeBillsId={}, orderCode={}", tradeBillsId, tradeBillsId, orderCode);
  377 + OrdersPayTransfer newTransfer = new OrdersPayTransfer();
  378 + newTransfer.setId(transfer.getId());
  379 + newTransfer.setStatus(1);
  380 + newTransfer.setUpdateTime(now);
  381 + ordersPayTransferMapper.updateByPrimaryKeySelective(newTransfer);
  382 + logger.info("transferSuccess 修改转账状态成功 tradeBillsId={}, tradeBillsId={}, orderCode={}", tradeBillsId, tradeBillsId, orderCode);
  383 + } else {
  384 + TradeBills fail = new TradeBills();
  385 + fail.setId(tradeBills.getId());
  386 + fail.setDealStatus(0);
  387 + fail.setTradeStatus(299);
  388 + tradeBillsMapper.updateToOkByPrimaryKey(fail);
  389 + logger.info("transferSuccess 旧流水(失败)更新成功,准备改转账表 tradeBillsId={}, tradeBillsId={}, orderCode={}", tradeBillsId, tradeBillsId, orderCode);
  390 +
  391 + OrdersPayTransfer newTransfer = new OrdersPayTransfer();
  392 + newTransfer.setId(transfer.getId());
  393 + newTransfer.setStatus(3);
  394 + newTransfer.setUpdateTime(now);
  395 + ordersPayTransferMapper.updateByPrimaryKeySelective(newTransfer);
  396 + logger.info("transferSuccess 转账表(失败)更新成功 tradeBillsId={}, tradeBillsId={}, orderCode={}", tradeBillsId, tradeBillsId, orderCode);
  397 + }
  398 + }
332 399
333 private OrdersPay saveOrdersPay(PaymentData paymentData, long orderType, OrderInfo orderInfo) { 400 private OrdersPay saveOrdersPay(PaymentData paymentData, long orderType, OrderInfo orderInfo) {
334 401
@@ -553,30 +620,8 @@ public class PaymentServiceImpl implements IPaymentService { @@ -553,30 +620,8 @@ public class PaymentServiceImpl implements IPaymentService {
553 } 620 }
554 int now = (int) (System.currentTimeMillis()/1000); 621 int now = (int) (System.currentTimeMillis()/1000);
555 // 查看是否已经有转账记录 622 // 查看是否已经有转账记录
556 - OrdersPayTransfer exist = ordersPayTransferMapper.selectByBuyerOrderCode(buyerOrderCode);  
557 - if (exist != null) {  
558 - logger.warn("transferMonErr OrdersPayTransfer has exist, orderCode is {}", buyerOrderCode);  
559 - throw new ServiceException(400, "订单已经处理过");  
560 - }  
561 -  
562 - OrdersPayTransfer transfer = new OrdersPayTransfer();  
563 - transfer.setBuyerOrderCode(buyerOrderCode);  
564 - transfer.setSellerOrderCode(sellerOrderCode);  
565 - transfer.setAlipayTradeId("");  
566 - transfer.setAlipayTradeResult("");  
567 - transfer.setTransferType(transferCase.getCode());  
568 - transfer.setUid(targetUid);  
569 - transfer.setAmount(BigDecimal.ZERO);  
570 - transfer.setCreateTime(now);  
571 - transfer.setStatus(0);  
572 -  
573 - try {  
574 - logger.info("transferMon插入初始化转账信息buyerOrderCode is {}, sellerOrderCode is {}", buyerOrderCode, sellerOrderCode);  
575 - ordersPayTransferMapper.insert(transfer);  
576 - } catch (Exception e) {  
577 - logger.warn("transferMonErr insert ordersPayTransfer failed, orderCode is {}, msg is {}", buyerOrderCode, e.getMessage());  
578 - throw new ServiceException(400, "交易记录创建失败");  
579 - } 623 + checkTransferExist(buyerOrderCode);
  624 + OrdersPayTransfer transfer = createTransfer(buyerOrderCode, sellerOrderCode, transferCase.getCode(), null, targetUid, BigDecimal.ZERO, now);
580 625
581 // 增加流水记录 626 // 增加流水记录
582 TradeBills record = new TradeBills(); 627 TradeBills record = new TradeBills();
@@ -686,31 +731,8 @@ public class PaymentServiceImpl implements IPaymentService { @@ -686,31 +731,8 @@ public class PaymentServiceImpl implements IPaymentService {
686 731
687 int now = (int) (System.currentTimeMillis()/1000); 732 int now = (int) (System.currentTimeMillis()/1000);
688 // 查看是否已经有转账记录 733 // 查看是否已经有转账记录
689 - OrdersPayTransfer exist = ordersPayTransferMapper.selectByBuyerOrderCode(orderCode);  
690 - if (exist != null) {  
691 - logger.warn("transAllEarnestErr OrdersPayTransfer has exist, orderCode is {}", orderCode);  
692 - throw new ServiceException(400, "订单已经处理过");  
693 - }  
694 -  
695 - OrdersPayTransfer transfer = new OrdersPayTransfer();  
696 - transfer.setBuyerOrderCode(orderCode);  
697 - transfer.setSellerOrderCode(orderCode);  
698 - transfer.setAlipayTradeId("");  
699 - transfer.setAlipayTradeResult("");  
700 - transfer.setAlipayAccount(alipayAccount);  
701 - transfer.setTransferType(6);  
702 - transfer.setUid(uid);  
703 - transfer.setAmount(amount);  
704 - transfer.setCreateTime(now);  
705 - transfer.setStatus(0);  
706 -  
707 - try {  
708 - logger.info("transAllEarnest插入初始化转账信息orderCode is {}", orderCode);  
709 - ordersPayTransferMapper.insert(transfer);  
710 - } catch (Exception e) {  
711 - logger.warn("transAllEarnestErr insert ordersPayTransfer failed, orderCode is {}, msg is {}", orderCode, e.getMessage());  
712 - throw new ServiceException(400, "交易记录创建失败");  
713 - } 734 + checkTransferExist(orderCode);
  735 + OrdersPayTransfer transfer = createTransfer(orderCode, orderCode, 6, alipayAccount, uid, amount, now);
714 736
715 // 增加流水记录 737 // 增加流水记录
716 TradeBills record = new TradeBills(); 738 TradeBills record = new TradeBills();
@@ -986,7 +1008,18 @@ public class PaymentServiceImpl implements IPaymentService { @@ -986,7 +1008,18 @@ public class PaymentServiceImpl implements IPaymentService {
986 if (transfer == null || transfer.getStatus() == 1) { 1008 if (transfer == null || transfer.getStatus() == 1) {
987 throw new ServiceException(400, "转账记录已成功转账,流水id=" + tradeBillsId); 1009 throw new ServiceException(400, "转账记录已成功转账,流水id=" + tradeBillsId);
988 } 1010 }
989 - 1011 +
  1012 + if(exceedMillion()) {
  1013 + Map<String, String> mapResult = transferWhenExceedMillion(transfer.getId(), preSuccess, orderCode, account, amount, now);
  1014 + String resultStr = JSON.toJSONString(mapResult);
  1015 + jsonObject = JSON.parseObject(resultStr);
  1016 + if(!StringUtils.equals("T", mapResult.get("is_success"))) {
  1017 + throw new ServiceException(500, "转账失败:返回={}" + resultStr);
  1018 + } else {
  1019 + return;
  1020 + }
  1021 + }
  1022 +
990 jsonObject = alipayService.transferMoney(Long.toString(orderCode), account.getAlipayId(), account.getAlipayAccount(), amount); 1023 jsonObject = alipayService.transferMoney(Long.toString(orderCode), account.getAlipayId(), account.getAlipayAccount(), amount);
991 if (jsonObject == null) { 1024 if (jsonObject == null) {
992 logger.warn("manualDeal 转账失败 , req is {}", req); 1025 logger.warn("manualDeal 转账失败 , req is {}", req);
@@ -1007,6 +1040,15 @@ public class PaymentServiceImpl implements IPaymentService { @@ -1007,6 +1040,15 @@ public class PaymentServiceImpl implements IPaymentService {
1007 tradeBills.setTradeStatus(100); 1040 tradeBills.setTradeStatus(100);
1008 tradeBills.setCreateTime(now); 1041 tradeBills.setCreateTime(now);
1009 addTradeBills(tradeBills); 1042 addTradeBills(tradeBills);
  1043 + } else if(exceedMillion(jsonObject)) {
  1044 + Map<String, String> mapResult = transferWhenExceedMillion(transfer.getId(), tradeBills, orderCode, account, amount, now);
  1045 + String resultStr = JSON.toJSONString(mapResult);
  1046 + jsonObject = JSON.parseObject(resultStr);
  1047 + if(!StringUtils.equals("T", mapResult.get("is_success"))) {
  1048 + throw new ServiceException(500, "转账失败:返回={}" + resultStr);
  1049 + } else {
  1050 + return;
  1051 + }
1010 } else { 1052 } else {
1011 logger.warn("manualDealErr 返回code或者order_id不是成功状态,code={}, orderId={}", code, orderId); 1053 logger.warn("manualDealErr 返回code或者order_id不是成功状态,code={}, orderId={}", code, orderId);
1012 // 上报 1054 // 上报
@@ -1031,6 +1073,81 @@ public class PaymentServiceImpl implements IPaymentService { @@ -1031,6 +1073,81 @@ public class PaymentServiceImpl implements IPaymentService {
1031 logger.info("manualDeal转账结束, tradeBillsId is {}!", tradeBillsId); 1073 logger.info("manualDeal转账结束, tradeBillsId is {}!", tradeBillsId);
1032 } 1074 }
1033 } 1075 }
  1076 +
  1077 +
  1078 + private Map<String, String> transferWhenExceedMillion(Integer transferId, TradeBills tradeBills, long orderCode, AuthorizeResultRespVO account,
  1079 + BigDecimal amount, int now) throws Exception {
  1080 + Map<String, String> mapResult = alipayService.transferMoneyWhenExceedMillion(Long.toString(orderCode),
  1081 + transferId + "_" + tradeBills.getId(), account.getAlipayId(), account.getAlipayAccount(),
  1082 + account.getCertName(), amount);
  1083 + logger.info("manualDeal 转账阿里接口(超过100万)返回 {}", mapResult);
  1084 + // success to wait
  1085 + if (StringUtils.equals("T", mapResult.get("is_success"))) {
  1086 + // TODO 加新流水
  1087 + tradeBills.setDealRelateId(tradeBills.getId());
  1088 + tradeBills.setId(null);
  1089 + tradeBills.setTradeStatus(100);
  1090 + tradeBills.setCreateTime(now);
  1091 + addTradeBills(tradeBills);
  1092 +
  1093 + tradeBills.setDealStatus(0);
  1094 + tradeBills.setTradeStatus(99);
  1095 + // wait
  1096 + tradeBillsMapper.updateToOkByPrimaryKey(tradeBills);
  1097 + }
  1098 + return mapResult;
  1099 + }
  1100 +
  1101 + private boolean exceedMillion(JSONObject jsonObject) {
  1102 + // {"msg":"Business Failed","code":"40004","sub_msg":"单日最多可转100万元","sub_code":"EXCEED_LIMIT_DM_MAX_AMOUNT"}
  1103 + if (StringUtils.equals("40004", jsonObject.getString("code"))
  1104 + && StringUtils.equals("EXCEED_LIMIT_DM_MAX_AMOUNT", jsonObject.getString("sub_code"))) {
  1105 + exceedMillion = true;
  1106 + return true;
  1107 + }
  1108 + return false;
  1109 + }
  1110 + private boolean exceedMillion() {
  1111 + return exceedMillion;
  1112 + }
  1113 +
  1114 + private volatile boolean exceedMillion = false;
  1115 +
  1116 + private void checkTransferExist(long orderCode) {
  1117 + // 查看是否已经有转账记录
  1118 + OrdersPayTransfer exist = ordersPayTransferMapper.selectByBuyerOrderCode(orderCode);
  1119 + if (exist != null) {
  1120 + logger.warn("OrdersPayTransfer has exist, orderCode is {}", orderCode);
  1121 + throw new ServiceException(400, "订单已经处理过");
  1122 + }
  1123 + }
  1124 +
  1125 + private OrdersPayTransfer createTransfer(long buyerOrderCode, long sellerOrderCode, Integer transferType, String alipayAccount,
  1126 + Integer uid, BigDecimal amount, int time) {
  1127 + OrdersPayTransfer transfer = new OrdersPayTransfer();
  1128 + transfer.setBuyerOrderCode(buyerOrderCode);
  1129 + transfer.setSellerOrderCode(sellerOrderCode);
  1130 + transfer.setAlipayTradeId("");
  1131 + transfer.setAlipayTradeResult("");
  1132 + transfer.setAlipayAccount(alipayAccount);
  1133 + transfer.setTransferType(transferType);
  1134 + transfer.setUid(uid);
  1135 + transfer.setAmount(amount);
  1136 + transfer.setCreateTime(time);
  1137 + transfer.setStatus(0);
  1138 +
  1139 + try {
  1140 + logger.info("转账 插入初始化转账信息 buyerOrderCode is {},sellerOrderCode is {}", buyerOrderCode, sellerOrderCode);
  1141 + ordersPayTransferMapper.insert(transfer);
  1142 + return transfer;
  1143 + } catch (Exception e) {
  1144 + logger.warn(
  1145 + "transferCreateErr insert ordersPayTransfer failed, buyerOrderCode is {},sellerOrderCode is {}, msg is {}",
  1146 + buyerOrderCode, sellerOrderCode, e.getMessage());
  1147 + throw new ServiceException(400, "交易记录创建失败");
  1148 + }
  1149 + }
  1150 +
1034 1151
1035 public PayQueryBo queryTransferResult(String buyerOrderCode) { 1152 public PayQueryBo queryTransferResult(String buyerOrderCode) {
1036 return alipayService.transferQuery(buyerOrderCode); 1153 return alipayService.transferQuery(buyerOrderCode);
@@ -31,7 +31,15 @@ public class AlipayOuyinService extends AlipayServiceAbstract { @@ -31,7 +31,15 @@ public class AlipayOuyinService extends AlipayServiceAbstract {
31 return AlipayConfig.OUYIN_APPID; 31 return AlipayConfig.OUYIN_APPID;
32 } 32 }
33 33
  34 + @Override
  35 + protected String getAccountUserName() {
  36 + return AlipayConfig.OUYIN_USER_NAME;
  37 + }
34 38
  39 + @Override
  40 + protected String getAccountEmail() {
  41 + return AlipayConfig.OUYIN_EMAIL;
  42 + }
35 43
36 44
37 } 45 }
@@ -9,6 +9,7 @@ import com.yohoufo.common.utils.DateUtil; @@ -9,6 +9,7 @@ import com.yohoufo.common.utils.DateUtil;
9 import com.yohoufo.common.utils.HttpClient; 9 import com.yohoufo.common.utils.HttpClient;
10 import com.yohoufo.common.utils.MD5Utils; 10 import com.yohoufo.common.utils.MD5Utils;
11 import com.yohoufo.common.utils.RSAUtils; 11 import com.yohoufo.common.utils.RSAUtils;
  12 +import com.yohoufo.common.utils.WXUtil;
12 import com.yohoufo.order.config.AlipayConfig; 13 import com.yohoufo.order.config.AlipayConfig;
13 import com.yohoufo.order.constants.RefundContant; 14 import com.yohoufo.order.constants.RefundContant;
14 import com.yohoufo.order.model.*; 15 import com.yohoufo.order.model.*;
@@ -22,6 +23,7 @@ import org.springframework.beans.factory.annotation.Value; @@ -22,6 +23,7 @@ import org.springframework.beans.factory.annotation.Value;
22 import java.io.UnsupportedEncodingException; 23 import java.io.UnsupportedEncodingException;
23 import java.math.BigDecimal; 24 import java.math.BigDecimal;
24 import java.net.URLEncoder; 25 import java.net.URLEncoder;
  26 +import java.text.SimpleDateFormat;
25 import java.util.*; 27 import java.util.*;
26 28
27 public abstract class AlipayServiceAbstract extends AbstractPayService { 29 public abstract class AlipayServiceAbstract extends AbstractPayService {
@@ -41,11 +43,22 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { @@ -41,11 +43,22 @@ public abstract class AlipayServiceAbstract extends AbstractPayService {
41 protected abstract String getAppId(); 43 protected abstract String getAppId();
42 44
43 protected abstract String getPartnerId(); 45 protected abstract String getPartnerId();
  46 +
  47 + protected String getAccountUserName() {
  48 + return "";
  49 + }
  50 +
  51 + protected String getAccountEmail() {
  52 + return "";
  53 + }
44 54
45 55
46 56
47 @Value("${alipay.notifyurl}") 57 @Value("${alipay.notifyurl}")
48 private String notifyURL; 58 private String notifyURL;
  59 +
  60 + @Value("${alipay.transfer.notifyurl}")
  61 + private String transferNotifyURL;
49 62
50 63
51 // public JSONObject prepayRequest(OrderInfo orderInfo){ 64 // public JSONObject prepayRequest(OrderInfo orderInfo){
@@ -155,6 +168,29 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { @@ -155,6 +168,29 @@ public abstract class AlipayServiceAbstract extends AbstractPayService {
155 return result; 168 return result;
156 } 169 }
157 170
  171 + /**
  172 + * 转账功能
  173 + * @param transferOrderCode
  174 + * @param alipayAccount
  175 + * @param transferAmount
  176 + * @return
  177 + * @throws Exception
  178 + */
  179 + public Map<String, String> transferMoneyWhenExceedMillion(String transferOrderCode, String businessId, String alipayUid, String alipayAccount, String userName, BigDecimal transferAmount) throws Exception{
  180 +
  181 + Map<String, String> queryParams = buildTransferParamsWhenExceedMillion(transferOrderCode, businessId, alipayUid, alipayAccount, userName, transferAmount);
  182 + String respTxt = sendOpenApiRequestWithException(transferOrderCode, queryParams);
  183 +
  184 + Map<String, String> result;
  185 +
  186 + if (StringUtils.isNotBlank(respTxt)){
  187 + result = WXUtil.parseWXPayXml(respTxt);
  188 + } else {
  189 + result = new HashMap<>();
  190 + }
  191 + return result;
  192 + }
  193 +
158 public PayQueryBo transferQuery(String buyerOrderCode) { 194 public PayQueryBo transferQuery(String buyerOrderCode) {
159 String tradeNo = buyerOrderCode; 195 String tradeNo = buyerOrderCode;
160 Map<String, String> queryParams = buildAlipayTransferQueryParams(tradeNo); 196 Map<String, String> queryParams = buildAlipayTransferQueryParams(tradeNo);
@@ -313,6 +349,45 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { @@ -313,6 +349,45 @@ public abstract class AlipayServiceAbstract extends AbstractPayService {
313 params.put("sign", RSAUtils.sign(preSignStr, getRsaPrivateKey(), AlipayConfig.input_charset)); 349 params.put("sign", RSAUtils.sign(preSignStr, getRsaPrivateKey(), AlipayConfig.input_charset));
314 return params; 350 return params;
315 } 351 }
  352 +
  353 + /**
  354 + * 单笔转账
  355 + * @param orderData
  356 + * @return
  357 + */
  358 + private Map<String, String> buildTransferParamsWhenExceedMillion(String transferOrderCode, String businessId, String alipayUid, String alipayAccount, String userName, BigDecimal transferAmount) {
  359 + Map<String, String> params = new HashMap<String, String>();
  360 + params.put("service", "batch_trans_notify_no_pwd");
  361 + params.put("partner", getPartnerId());
  362 + params.put("_input_charset", AlipayConfig.input_charset);
  363 + params.put("notify_url", transferNotifyURL);
  364 + params.put("account_name", getAccountUserName());
  365 +
  366 + params.put("batch_no", transferOrderCode);
  367 + params.put("batch_num", "1");
  368 + params.put("batch_fee", transferAmount.toString());
  369 + params.put("email", getAccountEmail());
  370 +
  371 + StringBuilder detailAppender = new StringBuilder();
  372 + detailAppender.append(businessId).append("^");
  373 + if (StringUtils.isNotBlank(alipayUid)) {
  374 + // 流水号1^收款方UserId1^付款金额1^备注说明1
  375 + params.put("detail_version", "1.1");
  376 + detailAppender.append(alipayUid).append("^");
  377 + } else {
  378 + // 流水号1^收款方账号1^收款账号姓名1^付款金额1^备注说明1
  379 + params.put("detail_version", "1.0");
  380 + detailAppender.append(alipayAccount).append("^").append(userName).append("^");
  381 + }
  382 + params.put("detail_data", detailAppender.toString());
  383 + detailAppender.append(transferAmount).append("^UFO_ORDER");
  384 +
  385 +
  386 + String preSignStr = getOpenApiSignString(params);
  387 + params.put("sign", RSAUtils.sign(preSignStr, getRsaPrivateKey(), AlipayConfig.input_charset));
  388 + params.put("sign_type", "RSA");
  389 + return params;
  390 + }
316 391
317 392
318 /** 393 /**
@@ -405,6 +480,38 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { @@ -405,6 +480,38 @@ public abstract class AlipayServiceAbstract extends AbstractPayService {
405 } 480 }
406 return payData; 481 return payData;
407 } 482 }
  483 +
  484 + public TransferData getTransferData(String data) {
  485 + if (StringUtils.isBlank(data)) {
  486 + return null;
  487 + }
  488 + if (data.endsWith("|")) {
  489 + data = data.substring(0, data.length() - 1);
  490 + }
  491 + String[] dataArray = data.split("^");
  492 + if (dataArray.length != 8) {
  493 + logger.error("[{}] getTransferData 支付宝回调数据字段个数有误", data);
  494 + return null;
  495 + }
  496 + // 1流水号^2收款方账号^3收款账号姓名^4付款金额^5成功标识(S)^6成功原因(null)^7支付宝内部流水号^8完成时间
  497 + try {
  498 + TransferData transferData = new TransferData();
  499 + String[] transferIdAndTradeBillId = dataArray[0].split("_");
  500 + transferData.setTransferId(new Integer(transferIdAndTradeBillId[0]));
  501 + transferData.setTradeBillsId(new Integer(transferIdAndTradeBillId[1]));
  502 + transferData.setReceiveAccount(dataArray[1]);
  503 + transferData.setReceiveUserName(dataArray[2]);
  504 + transferData.setMoney(dataArray[3]);
  505 + transferData.setStatus(dataArray[4]);
  506 + transferData.setMessage(dataArray[5]);
  507 + transferData.setAlipayTradeId(dataArray[6]);
  508 + transferData.setTime(dataArray[7]);
  509 + return transferData;
  510 + } catch (NumberFormatException e) {
  511 + logger.error("[{}] getTransferData 支付宝回调数据格式有误", data);
  512 + return null;
  513 + }
  514 + }
408 515
409 516
410 public boolean notifyVerify(Map<String, String> paramsMap) { 517 public boolean notifyVerify(Map<String, String> paramsMap) {
@@ -81,6 +81,8 @@ wechat.notifyurl=http://testapi.yohops.com/payment/weixin_notify @@ -81,6 +81,8 @@ wechat.notifyurl=http://testapi.yohops.com/payment/weixin_notify
81 81
82 alipay.notifyurl=http://testapi.yohops.com/payment/alipay_notify 82 alipay.notifyurl=http://testapi.yohops.com/payment/alipay_notify
83 83
  84 +alipay.transfer.notifyurl=http://testapi.yohops.com/payment/alipay_transfer_notify
  85 +
84 erp-gateway.url=http://java-yoho-erp-gateway.test3.ingress.dev.yohocorp.com/erp-gateway 86 erp-gateway.url=http://java-yoho-erp-gateway.test3.ingress.dev.yohocorp.com/erp-gateway
85 87
86 redis.readonly.proxy.address=192.168.102.45 88 redis.readonly.proxy.address=192.168.102.45
@@ -119,7 +121,7 @@ uic.url=http://java-yoho-uic.test3.ingress.dev.yohocorp.com/uic @@ -119,7 +121,7 @@ uic.url=http://java-yoho-uic.test3.ingress.dev.yohocorp.com/uic
119 yoho.message.controller.url=http://message-controller.yohoops.org/yoho-message-controller 121 yoho.message.controller.url=http://message-controller.yohoops.org/yoho-message-controller
120 122
121 #rabbit address for transaction compensate 123 #rabbit address for transaction compensate
122 -rabbit_host=192.168.102.45:5672 124 +rabbit_host=192.168.104.199:30005
123 rabbit_user=yoho 125 rabbit_user=yoho
124 rabbit_password=yoho 126 rabbit_password=yoho
125 127
@@ -62,6 +62,7 @@ wechat.app.appid=wx049fdaa3ba9cdd7a @@ -62,6 +62,7 @@ wechat.app.appid=wx049fdaa3ba9cdd7a
62 62
63 wechat.notifyurl=${wechat.notifyurl} 63 wechat.notifyurl=${wechat.notifyurl}
64 alipay.notifyurl=${alipay.notifyurl} 64 alipay.notifyurl=${alipay.notifyurl}
  65 +alipay.transfer.notifyurl=${alipay.transfer.notifyurl}
65 66
66 order.seller.earnestmoney.min=${order.seller.earnestmoney.min} 67 order.seller.earnestmoney.min=${order.seller.earnestmoney.min}
67 order.seller.earnestmoney.max=${order.seller.earnestmoney.max} 68 order.seller.earnestmoney.max=${order.seller.earnestmoney.max}