Authored by LUOXC

重构人工打款

Showing 18 changed files with 397 additions and 61 deletions
@@ -3,6 +3,9 @@ package com.yohoufo.dal.order.model; @@ -3,6 +3,9 @@ package com.yohoufo.dal.order.model;
3 import java.math.BigDecimal; 3 import java.math.BigDecimal;
4 4
5 public class OrdersPayTransfer { 5 public class OrdersPayTransfer {
  6 +
  7 + public static final Integer INTERFACE_TYPE_TRANSFER_WHEN_EXCEED_MILLION = 2;
  8 +
6 private Integer id; 9 private Integer id;
7 10
8 private Long buyerOrderCode; 11 private Long buyerOrderCode;
@@ -40,13 +40,16 @@ import com.yohoufo.order.service.handler.BuyerCancelCompensateComputeHandler; @@ -40,13 +40,16 @@ import com.yohoufo.order.service.handler.BuyerCancelCompensateComputeHandler;
40 import com.yohoufo.order.service.handler.BuyerOrderPayDiffTimeHandler; 40 import com.yohoufo.order.service.handler.BuyerOrderPayDiffTimeHandler;
41 import com.yohoufo.order.service.pay.AbstractPayService; 41 import com.yohoufo.order.service.pay.AbstractPayService;
42 import com.yohoufo.order.service.pay.alipay.AlipayOuyinService; 42 import com.yohoufo.order.service.pay.alipay.AlipayOuyinService;
  43 +import com.yohoufo.order.service.pay.alipay.AlipayServiceAbstract;
43 import com.yohoufo.order.service.pay.wallet.WalletPayService; 44 import com.yohoufo.order.service.pay.wallet.WalletPayService;
44 import com.yohoufo.order.service.pay.weixin.WeixinMiniappPayService; 45 import com.yohoufo.order.service.pay.weixin.WeixinMiniappPayService;
45 import com.yohoufo.order.service.pay.weixin.WeixinPayUFORealAppService; 46 import com.yohoufo.order.service.pay.weixin.WeixinPayUFORealAppService;
46 import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator; 47 import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator;
47 import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta; 48 import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta;
  49 +import com.yohoufo.order.service.transfer.TransferResult;
48 import com.yohoufo.order.utils.LoggerUtils; 50 import com.yohoufo.order.utils.LoggerUtils;
49 import com.yohoufo.order.utils.PaymentHelper; 51 import com.yohoufo.order.utils.PaymentHelper;
  52 +import com.yohoufo.order.utils.ServiceExceptions;
50 import lombok.val; 53 import lombok.val;
51 import org.apache.commons.collections.CollectionUtils; 54 import org.apache.commons.collections.CollectionUtils;
52 import org.apache.commons.lang3.StringUtils; 55 import org.apache.commons.lang3.StringUtils;
@@ -1001,6 +1004,8 @@ public class PaymentServiceImpl implements IPaymentService { @@ -1001,6 +1004,8 @@ public class PaymentServiceImpl implements IPaymentService {
1001 if (tradeBillsMapper.selectByDealRelateId(tradeBillsId) != null) { 1004 if (tradeBillsMapper.selectByDealRelateId(tradeBillsId) != null) {
1002 throw new ServiceException(400, "manualDeal:该流水已经处理过"); 1005 throw new ServiceException(400, "manualDeal:该流水已经处理过");
1003 } 1006 }
  1007 + long orderCode = tradeBills.getOrderCode();
  1008 + String logTag = "manualDeal orderCode is " + orderCode + "tradeBillId is " + tradeBillsId;
1004 AuthorizeResultRespVO account = getAlipayAccount(tradeBills.getUid()); 1009 AuthorizeResultRespVO account = getAlipayAccount(tradeBills.getUid());
1005 if (account == null || 1010 if (account == null ||
1006 (StringUtils.isBlank(account.getAlipayAccount()) && StringUtils.isBlank(account.getAlipayId()))) { 1011 (StringUtils.isBlank(account.getAlipayAccount()) && StringUtils.isBlank(account.getAlipayId()))) {
@@ -1015,7 +1020,7 @@ public class PaymentServiceImpl implements IPaymentService { @@ -1015,7 +1020,7 @@ public class PaymentServiceImpl implements IPaymentService {
1015 logger.info("manualDeal uid {} 支付宝账号uid无值使用账号{}", tradeBills.getUid(), account.getAlipayAccount()); 1020 logger.info("manualDeal uid {} 支付宝账号uid无值使用账号{}", tradeBills.getUid(), account.getAlipayAccount());
1016 alipayAccount = account.getAlipayAccount(); 1021 alipayAccount = account.getAlipayAccount();
1017 } 1022 }
1018 - long orderCode = tradeBills.getOrderCode(); 1023 +
1019 1024
1020 BigDecimal amount = null; 1025 BigDecimal amount = null;
1021 try { 1026 try {
@@ -1098,93 +1103,101 @@ public class PaymentServiceImpl implements IPaymentService { @@ -1098,93 +1103,101 @@ public class PaymentServiceImpl implements IPaymentService {
1098 throw new ServiceException(500, "退款失败id=" + tradeBillsId); 1103 throw new ServiceException(500, "退款失败id=" + tradeBillsId);
1099 } 1104 }
1100 } 1105 }
1101 - JSONObject jsonObject = null;  
1102 - Integer interfaceType = null;  
1103 try { 1106 try {
1104 OrdersPayTransfer transfer = ordersPayTransferMapper.selectByBuyerOrderCode(orderCode); 1107 OrdersPayTransfer transfer = ordersPayTransferMapper.selectByBuyerOrderCode(orderCode);
1105 - if (transfer == null) {  
1106 - throw new ServiceException(400, "转账记录不存在,流水id=" + tradeBillsId);  
1107 - }  
1108 - if (transfer == null || transfer.getStatus() == 1) {  
1109 - throw new ServiceException(400, "转账记录已成功转账,流水id=" + tradeBillsId); 1108 + ServiceExceptions.throwServiceExceptionIf(() -> Objects.isNull(transfer),
  1109 + 400, "转账记录不存在[" + tradeBillsId + "]");
  1110 + ServiceExceptions.throwServiceExceptionIf(() -> transfer.getStatus() == 1,
  1111 + 400, "转账记录已成功转账,请不要重复操作。");
  1112 + Integer interfaceType = transfer.getInterfaceType();
  1113 + logger.info("{}, transfer channel router {}", logTag, interfaceType);
  1114 + if (OrdersPayTransfer.INTERFACE_TYPE_TRANSFER_WHEN_EXCEED_MILLION.equals(interfaceType)) {
  1115 + transferWithAlipayExceedMillionTransfer(tradeBills, orderCode, logTag, account, amount, transfer);
  1116 + } else {
  1117 + transferWithAlipayTransfer(logTag, tradeBills, orderCode, account, amount, now, transfer);
1110 } 1118 }
1111 - interfaceType = transfer.getInterfaceType();  
1112 -  
1113 - logger.info("manualDeal orderCode={}, tradeBillId={}, 转账接口类型为 {}", orderCode, tradeBillsId, interfaceType);  
1114 - if (interfaceType != null && interfaceType == 2) {  
1115 - logger.info("manualDeal orderCode={}, tradeBillId={}, 转账接口类型为 超过100万的接口", orderCode, tradeBillsId);  
1116 - Map<String, String> mapResult = transferWhenExceedMillion(transfer.getId(), preSuccess, orderCode, account, amount, now);  
1117 - String resultStr = JSON.toJSONString(mapResult);  
1118 - jsonObject = JSON.parseObject(resultStr);  
1119 - if(!StringUtils.equals("T", mapResult.get("is_success"))) {  
1120 - throw new ServiceException(500, "转账失败:返回={}" + resultStr); 1119 + } catch (Exception e) {
  1120 + logger.warn("{}, transfer fail", logTag, e);
  1121 + alarm("人工处理转账失败",
  1122 + "ufo.order.manualDeal",
  1123 + "订单号:" + orderCode + ",操作类型(转账),流水id=" + tradeBillsId + ",msg=" + e.getMessage());
  1124 + logger.info("{}, rollback lock", logTag);
  1125 + preSuccess.setDealStatus(0);
  1126 + tradeBillsMapper.updateToFailByPrimaryKey(preSuccess);
  1127 + logger.info("{}, rollback lock success", logTag);
  1128 + if (e instanceof ServiceException) {
  1129 + throw e;
1121 } else { 1130 } else {
1122 - return; 1131 + ServiceExceptions.throwServiceException(500, "转账失败id=" + tradeBillsId);
1123 } 1132 }
  1133 + } finally {
  1134 + logger.info("{}, complete", logTag);
1124 } 1135 }
1125 -  
1126 - logger.info("manualDeal orderCode={}, tradeBillId={}, 转账接口类型为 小于100万的接口", orderCode, tradeBillsId);  
1127 - jsonObject = alipayService.transferMoney(Long.toString(orderCode), account.getAlipayId(), account.getAlipayAccount(), amount);  
1128 - if (jsonObject == null) {  
1129 - logger.warn("manualDeal 转账失败 , req is {}", req);  
1130 - throw new ServiceException(500, "转账失败:阿里接口返回null");  
1131 } 1136 }
1132 - logger.info("manualDeal 转账阿里接口返回 {}", jsonObject.toJSONString());  
1133 - // 成功  
1134 - Integer code = null;  
1135 - String orderId = null;  
1136 - if (jsonObject.containsKey("code")  
1137 - && (code = jsonObject.getInteger("code")) == 10000  
1138 - && jsonObject.containsKey("order_id")  
1139 - && StringUtils.isNotBlank(orderId = jsonObject.getString("order_id"))) {  
1140 - logger.info("manualDeal转账成功,targeAccount is {}, amount is {}", alipayAccount, amount); 1137 +
  1138 + private void transferWithAlipayTransfer(String logTag, TradeBills tradeBills, long orderCode, AuthorizeResultRespVO account, BigDecimal amount, int now, OrdersPayTransfer transfer) {
  1139 + TransferResult transferResult = alipayService.newAlipayTransfer()
  1140 + .transferOrderCode(Long.toString(orderCode))
  1141 + .alipayUid(account.getAlipayId())
  1142 + .alipayAccount(account.getAlipayAccount())
  1143 + .transferAmount(amount)
  1144 + .transfer();
  1145 + if (transferResult.getCode() == 200) {
  1146 + logger.info("{}, transfer success and out trade no is {}", logTag, orderCode);
1141 // 加新流水 1147 // 加新流水
1142 tradeBills.setDealRelateId(tradeBills.getId()); 1148 tradeBills.setDealRelateId(tradeBills.getId());
1143 tradeBills.setId(null); 1149 tradeBills.setId(null);
1144 tradeBills.setTradeStatus(100); 1150 tradeBills.setTradeStatus(100);
1145 tradeBills.setCreateTime(now); 1151 tradeBills.setCreateTime(now);
1146 addTradeBills(tradeBills); 1152 addTradeBills(tradeBills);
1147 - 1153 + // ?
1148 OrdersPayTransfer transferSuccess = new OrdersPayTransfer(); 1154 OrdersPayTransfer transferSuccess = new OrdersPayTransfer();
1149 transferSuccess.setId(transfer.getId()); 1155 transferSuccess.setId(transfer.getId());
1150 - transferSuccess.setAlipayTradeId(orderId); 1156 + transferSuccess.setAlipayTradeId(transferResult.getTradeNo());
1151 transferSuccess.setStatus(1); 1157 transferSuccess.setStatus(1);
1152 transferSuccess.setUpdateTime(now); 1158 transferSuccess.setUpdateTime(now);
1153 ordersPayTransferMapper.updateByPrimaryKeySelective(transferSuccess); 1159 ordersPayTransferMapper.updateByPrimaryKeySelective(transferSuccess);
1154 - } else {  
1155 - logger.warn("manualDealErr 返回code或者order_id不是成功状态,code={}, orderId={}", code, orderId);  
1156 - // 上报  
1157 - throw new ServiceException(500, "转账失败:返回code="+code+",order_id="+orderId); 1160 + }else {
  1161 + logger.warn("{}, transfer fail {}", logTag,transferResult);
  1162 + throw new ServiceException(transferResult.getCode(), transferResult.getMsg());
1158 } 1163 }
1159 - } catch (Exception e) {  
1160 - /*if (interfaceType != null && interfaceType == 2) {  
1161 - return;  
1162 - }*/  
1163 - logger.warn("manualDealErr 转账失败 , orderCode is {}, msg is {}", orderCode, e.getMessage());  
1164 - String alarmMsg = "订单号:" + orderCode + ",操作类型(转账),流水id=" + tradeBillsId + ",msg=" + e.getMessage();  
1165 - if (jsonObject != null) {  
1166 - alarmMsg += ",阿里返回DETAIL=" + jsonObject.toJSONString(); 1164 +
1167 } 1165 }
1168 - logger.info("manualDealErr 转账失败 , alarmMsg is {}", alarmMsg);  
1169 - alarm("人工处理转账失败", "ufo.order.manualDeal", alarmMsg);  
1170 - preSuccess.setDealStatus(0);  
1171 - tradeBillsMapper.updateToFailByPrimaryKey(preSuccess);  
1172 - if (e instanceof ServiceException) {  
1173 - throw new ServiceException(((ServiceException) e).getCode(), "转账失败id=" + tradeBillsId + "," + e.getMessage()); 1166 +
  1167 + private void transferWithAlipayExceedMillionTransfer(TradeBills tradeBills, long orderCode, String logTag, AuthorizeResultRespVO account, BigDecimal amount, OrdersPayTransfer transfer) {
  1168 + String businessId = transfer.getId() + "_" + tradeBills.getId();
  1169 + TransferResult transferResult = alipayService.newAlipayExceedMillionTransfer()
  1170 + .transferOrderCode( Long.toString(orderCode))
  1171 + .alipayUid(account.getAlipayId())
  1172 + .alipayAccount(account.getAlipayAccount())
  1173 + .transferAmount(amount)
  1174 + .businessId(businessId)
  1175 + .userName(account.getCertName())
  1176 + .transfer();
  1177 + // success to wait
  1178 + if (transferResult.getCode() == 200) {
  1179 + logger.info("{}, transfer success and out trade no is {}", logTag, businessId);
  1180 + // 更新流水状态为转账中
  1181 + tradeBills.setDealStatus(0);
  1182 + tradeBills.setTradeStatus(TradeBills.Status.TRANSFER_WAITING.getCode());
  1183 + tradeBillsMapper.updateSelectiveByPrimaryKeyNoCondition(tradeBills);
  1184 + logger.info("{}, the trade bill has updated to transfer waiting", logTag);
1174 } else { 1185 } else {
1175 - throw new ServiceException(500, "转账失败id=" + tradeBillsId);  
1176 - }  
1177 - } finally {  
1178 - logger.info("manualDeal转账结束, tradeBillsId is {}!", tradeBillsId); 1186 + logger.warn("{}, transfer fail {}", logTag,transferResult);
  1187 + throw new ServiceException(transferResult.getCode(), transferResult.getMsg());
1179 } 1188 }
1180 } 1189 }
1181 1190
1182 1191
1183 private Map<String, String> transferWhenExceedMillion(Integer transferId, TradeBills tradeBills, long orderCode, AuthorizeResultRespVO account, 1192 private Map<String, String> transferWhenExceedMillion(Integer transferId, TradeBills tradeBills, long orderCode, AuthorizeResultRespVO account,
1184 BigDecimal amount, int now) throws Exception { 1193 BigDecimal amount, int now) throws Exception {
1185 - Map<String, String> mapResult = alipayService.transferMoneyWhenExceedMillion(Long.toString(orderCode),  
1186 - transferId + "_" + tradeBills.getId(), account.getAlipayId(), account.getAlipayAccount(),  
1187 - account.getCertName(), amount); 1194 + Map<String, String> mapResult = alipayService.transferMoneyWhenExceedMillion(
  1195 + Long.toString(orderCode),
  1196 + transferId + "_" + tradeBills.getId(),
  1197 + account.getAlipayId(),
  1198 + account.getAlipayAccount(),
  1199 + account.getCertName(),
  1200 + amount);
1188 logger.info("transferWhenExceedMillion 转账阿里接口(总金额超过100万)返回 {}, orderCode is {}, transferId is {}, tradeBillsId is {}, alibillId is {}", mapResult, orderCode, transferId, tradeBills.getId(), transferId + "_" + tradeBills.getId()); 1201 logger.info("transferWhenExceedMillion 转账阿里接口(总金额超过100万)返回 {}, orderCode is {}, transferId is {}, tradeBillsId is {}, alibillId is {}", mapResult, orderCode, transferId, tradeBills.getId(), transferId + "_" + tradeBills.getId());
1189 // success to wait 1202 // success to wait
1190 if (StringUtils.equals("T", mapResult.get("is_success"))) { 1203 if (StringUtils.equals("T", mapResult.get("is_success"))) {
@@ -14,11 +14,16 @@ import com.yohoufo.common.utils.RSAUtils; @@ -14,11 +14,16 @@ import com.yohoufo.common.utils.RSAUtils;
14 import com.yohoufo.common.utils.WXUtil; 14 import com.yohoufo.common.utils.WXUtil;
15 import com.yohoufo.dal.order.OrdersPayHbfqMapper; 15 import com.yohoufo.dal.order.OrdersPayHbfqMapper;
16 import com.yohoufo.dal.order.model.OrdersPayHbfq; 16 import com.yohoufo.dal.order.model.OrdersPayHbfq;
  17 +import com.yohoufo.dal.order.model.TradeBills;
17 import com.yohoufo.order.common.HbfqEnum; 18 import com.yohoufo.order.common.HbfqEnum;
18 import com.yohoufo.order.config.AlipayConfig; 19 import com.yohoufo.order.config.AlipayConfig;
19 import com.yohoufo.order.constants.RefundContant; 20 import com.yohoufo.order.constants.RefundContant;
20 import com.yohoufo.order.model.*; 21 import com.yohoufo.order.model.*;
21 import com.yohoufo.order.service.pay.AbstractPayService; 22 import com.yohoufo.order.service.pay.AbstractPayService;
  23 +import com.yohoufo.order.service.transfer.TransferChannel;
  24 +import com.yohoufo.order.service.transfer.TransferResult;
  25 +import lombok.Builder;
  26 +import lombok.Data;
22 import org.apache.commons.lang3.StringUtils; 27 import org.apache.commons.lang3.StringUtils;
23 import org.slf4j.Logger; 28 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory; 29 import org.slf4j.LoggerFactory;
@@ -185,6 +190,184 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { @@ -185,6 +190,184 @@ public abstract class AlipayServiceAbstract extends AbstractPayService {
185 return result; 190 return result;
186 } 191 }
187 192
  193 + public class AlipayTransfer implements TransferChannel {
  194 +
  195 + String transferOrderCode;
  196 + String alipayUid;
  197 + String alipayAccount;
  198 + BigDecimal transferAmount;
  199 +
  200 + private AlipayTransfer(){
  201 +
  202 + }
  203 +
  204 + public AlipayTransfer transferOrderCode(String transferOrderCode){
  205 + this.transferOrderCode = transferOrderCode;
  206 + return this;
  207 + }
  208 +
  209 + public AlipayTransfer alipayUid(String alipayUid){
  210 + this.alipayUid = alipayUid;
  211 + return this;
  212 + }
  213 +
  214 + public AlipayTransfer alipayAccount(String alipayAccount){
  215 + this.alipayAccount = alipayAccount;
  216 + return this;
  217 + }
  218 +
  219 + public AlipayTransfer transferAmount(BigDecimal transferAmount){
  220 + this.transferAmount = transferAmount;
  221 + return this;
  222 + }
  223 +
  224 + @Override
  225 + public TransferResult transfer() {
  226 + Map<String, String> queryParams = buildTransferParams(transferOrderCode, alipayUid, alipayAccount, transferAmount);
  227 + String respTxt;
  228 + try {
  229 + respTxt = sendOpenApiRequestWithException(transferOrderCode, queryParams);
  230 + } catch (Exception e) {
  231 + logger.warn("transfer fail transferOrderCode is {} alipayUid is {} alipayAccount is {} transferAmount is {}",
  232 + transferOrderCode, alipayUid, alipayAccount, transferAmount, e);
  233 + return TransferResult.builder()
  234 + .code(599)
  235 + .msg("未知异常:" + e.getMessage())
  236 + .build();
  237 + }
  238 + if (StringUtils.isNotBlank(respTxt)){
  239 + JSONObject json = JSON.parseObject(respTxt);
  240 + JSONObject result = json.getJSONObject("alipay_fund_trans_toaccount_transfer_response");
  241 + String code = result.getString("code");
  242 + String msg = result.getString("msg");
  243 + String out_biz_no = result.getString("out_biz_no");
  244 + String order_id = result.getString("order_id");
  245 + String pay_date = result.getString("pay_date");
  246 + if (StringUtils.equals("10000", code)) {
  247 + if(StringUtils.isNoneBlank(order_id)){
  248 + return TransferResult.builder()
  249 + .code(200)
  250 + .msg(msg)
  251 + .transferOrderCode(out_biz_no)
  252 + .tradeNo(order_id)
  253 + .payDate(pay_date)
  254 + .build();
  255 + }else {
  256 + return TransferResult.builder()
  257 + .code(599)
  258 + .msg("未知异常:code is 10000 but order_id is blank")
  259 + .build();
  260 + }
  261 +
  262 + } else {
  263 + return transformError(result.getString("sub_code"), result.getString("sub_msg"));
  264 + }
  265 + } else {
  266 + return TransferResult.builder()
  267 + .code(500)
  268 + .msg("Response data is blank")
  269 + .build();
  270 + }
  271 + }
  272 + }
  273 +
  274 + public AlipayTransfer newAlipayTransfer(){
  275 + return new AlipayTransfer();
  276 + }
  277 +
  278 + public AlipayExceedMillionTransferChannel newAlipayExceedMillionTransfer(){
  279 + return new AlipayExceedMillionTransferChannel();
  280 + }
  281 +
  282 + private TransferResult transformError(String sub_code, String sub_msg) {
  283 + /*
  284 + * 错误描述:系统繁忙
  285 + * 解决方案:可能发生了网络或者系统异常,导致无法判定准确的转账结果。
  286 + * 此时,商户不能直接当做转账成功或者失败处理,可以考虑采用相同的out_biz_no重发请求,
  287 + * 或者通过调用“(alipay.fund.trans.order.query)”来查询该笔转账订单的最终状态。
  288 + */
  289 + if (StringUtils.equals("SYSTEM_ERROR", sub_code)) {
  290 + return TransferResult.builder()
  291 + .code(501)
  292 + .msg("可能发生了网络或者系统异常,请重试。")
  293 + .build();
  294 + } else if (StringUtils.equals("EXCEED_LIMIT_PERSONAL_SM_AMOUNT", sub_code)) {
  295 + return TransferResult.builder()
  296 + .code(502)
  297 + .msg("转账给个人支付宝账户单笔最多5万元。")
  298 + .build();
  299 + } else if (StringUtils.equals("EXCEED_LIMIT_ENT_SM_AMOUNT", sub_code)) {
  300 + return TransferResult.builder()
  301 + .code(503)
  302 + .msg("转账给企业支付宝账户单笔最多10万元。")
  303 + .build();
  304 + } else if (StringUtils.equals("EXCEED_LIMIT_SM_MIN_AMOUNT", sub_code)) {
  305 + return TransferResult.builder()
  306 + .code(504)
  307 + .msg("单笔最低转账金额0.1元。")
  308 + .build();
  309 + } else if (StringUtils.equals("EXCEED_LIMIT_DM_MAX_AMOUNT", sub_code)) {
  310 + return TransferResult.builder()
  311 + .code(505)
  312 + .msg("单日最多可转100万元,请明天重试。")
  313 + .build();
  314 + } else if (StringUtils.equals("EXCEED_LIMIT_UNRN_DM_AMOUNT", sub_code)) {
  315 + return TransferResult.builder()
  316 + .code(506)
  317 + .msg("收款账户未实名,单日最多可收款1000元,请明天重试。")
  318 + .build();
  319 + } else if (StringUtils.equals("PAYER_PAYEE_CANNOT_SAME", sub_code)) {
  320 + return TransferResult.builder()
  321 + .code(507)
  322 + .msg("请检查一下收款方信息填写是否为付款方本人。")
  323 + .build();
  324 + }
  325 + /*
  326 + 错误描述:根据监管部门的要求,对方未完善身份信息或未开立余额账户,无法收款
  327 + 解决方案:可能发生了网络或者系统异常,导致无法判定准确的转账结果。
  328 + */
  329 + else if (StringUtils.equals("PERMIT_NON_BANK_LIMIT_PAYEE", sub_code)) {
  330 + return TransferResult.builder()
  331 + .code(508)
  332 + .msg("请联系收款方登录支付宝站内或手机客户端更新身份信息后重试。")
  333 + .build();
  334 + }
  335 + /*
  336 + 错误描述:根据监管部门的要求,需要付款用户更新身份信息才能继续操作
  337 + 解决方案:根据监管部门的要求,需要付款用户登录支付宝站内或手机客户端更新身份信息才能继续操作。
  338 + */
  339 + else if (StringUtils.equals("PAYER_CERT_EXPIRED", sub_code)) {
  340 + return TransferResult.builder()
  341 + .code(509)
  342 + .msg("请联系收款方登录支付宝站内或手机客户端完善身份信息后重试。")
  343 + .build();
  344 + }/*
  345 + 错误描述:根据监管部门的要求,需要付款用户更新身份信息才能继续操作
  346 + 解决方案:根据监管部门的要求,需要付款用户登录支付宝站内或手机客户端更新身份信息才能继续操作。
  347 + */ else if (StringUtils.equals("PAYER_CERT_EXPIRED", sub_code)) {
  348 + return TransferResult.builder()
  349 + .code(510)
  350 + .msg("请联系收款方登录支付宝站内或手机客户端补全身份信息后重试。")
  351 + .build();
  352 + } else if (StringUtils.equals("REMARK_HAS_SENSITIVE_WORD", sub_code)) {
  353 + return TransferResult.builder()
  354 + .code(511)
  355 + .msg("转账备注包含敏感词,请修改备注文案后重试。")
  356 + .build();
  357 + } else if (StringUtils.equals("PAYER_BALANCE_NOT_ENOUGH", sub_code)) {
  358 + return TransferResult.builder()
  359 + .code(512)
  360 + .msg("付款账户余额不足,请联系财务保持付款账户余额充足。")
  361 + .build();
  362 + } else {
  363 + return TransferResult.builder()
  364 + .code(599)
  365 + .msg("未知异常:sub_code is " + sub_code + ",sub_msg is " + sub_msg)
  366 + .build();
  367 + }
  368 + }
  369 +
  370 +
188 /** 371 /**
189 * 转账功能 372 * 转账功能
190 * @param transferOrderCode 373 * @param transferOrderCode
@@ -208,6 +391,89 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { @@ -208,6 +391,89 @@ public abstract class AlipayServiceAbstract extends AbstractPayService {
208 return result; 391 return result;
209 } 392 }
210 393
  394 + public class AlipayExceedMillionTransferChannel implements TransferChannel{
  395 +
  396 + String transferOrderCode;
  397 + String alipayUid;
  398 + String alipayAccount;
  399 + BigDecimal transferAmount;
  400 + String businessId;
  401 + String userName;
  402 +
  403 + private AlipayExceedMillionTransferChannel(){
  404 +
  405 + }
  406 +
  407 + public AlipayExceedMillionTransferChannel transferOrderCode(String transferOrderCode){
  408 + this.transferOrderCode = transferOrderCode;
  409 + return this;
  410 + }
  411 +
  412 + public AlipayExceedMillionTransferChannel alipayUid(String alipayUid){
  413 + this.alipayUid = alipayUid;
  414 + return this;
  415 + }
  416 +
  417 + public AlipayExceedMillionTransferChannel alipayAccount(String alipayAccount){
  418 + this.alipayAccount = alipayAccount;
  419 + return this;
  420 + }
  421 +
  422 + public AlipayExceedMillionTransferChannel transferAmount(BigDecimal transferAmount){
  423 + this.transferAmount = transferAmount;
  424 + return this;
  425 + }
  426 +
  427 + public AlipayExceedMillionTransferChannel businessId(String businessId){
  428 + this.businessId = businessId;
  429 + return this;
  430 + }
  431 +
  432 + public AlipayExceedMillionTransferChannel userName(String userName){
  433 + this.userName = userName;
  434 + return this;
  435 + }
  436 +
  437 + @Override
  438 + public TransferResult transfer() {
  439 + Map<String, String> queryParams = buildTransferParamsWhenExceedMillion(transferOrderCode, businessId, alipayUid, alipayAccount, userName, transferAmount);
  440 + String respTxt;
  441 + try {
  442 + respTxt = sendMApiRequestWithException(transferOrderCode, queryParams);
  443 + } catch (Exception e) {
  444 + logger.warn("transfer fail transferOrderCode is {} alipayUid is {} alipayAccount is {} transferAmount is {}",
  445 + transferOrderCode, alipayUid, alipayAccount, transferAmount, e);
  446 + return TransferResult.builder()
  447 + .code(599)
  448 + .msg("未知异常:" + e.getMessage())
  449 + .build();
  450 + }
  451 +
  452 + Map<String, String> result;
  453 + if (StringUtils.isNotBlank(respTxt)){
  454 + result = WXUtil.parseWXPayXml(respTxt);
  455 + if (StringUtils.equals("T", result.get("is_success"))) {
  456 + return TransferResult.builder()
  457 + .code(200)
  458 + .msg("ok")
  459 + .build();
  460 + } else {
  461 + String error = result.get("error");
  462 + return TransferResult.builder()
  463 + .code(599)
  464 + .msg("未知异常:error is " + error)
  465 + .build();
  466 + }
  467 + } else {
  468 + return TransferResult.builder()
  469 + .code(500)
  470 + .msg("Response data is blank")
  471 + .build();
  472 + }
  473 + }
  474 +
  475 + }
  476 +
211 public PayQueryBo transferQuery(String buyerOrderCode) { 477 public PayQueryBo transferQuery(String buyerOrderCode) {
212 String tradeNo = buyerOrderCode; 478 String tradeNo = buyerOrderCode;
213 Map<String, String> queryParams = buildAlipayTransferQueryParams(tradeNo); 479 Map<String, String> queryParams = buildAlipayTransferQueryParams(tradeNo);
  1 +package com.yohoufo.order.service.transfer;
  2 +
  3 +public interface TransferChannel {
  4 +
  5 + TransferResult transfer();
  6 +
  7 +}
  1 +package com.yohoufo.order.service.transfer;
  2 +
  3 +import com.yohoufo.order.service.pay.alipay.AlipayOuyinService;
  4 +import org.springframework.beans.factory.annotation.Autowired;
  5 +import org.springframework.stereotype.Service;
  6 +
  7 +public interface TransferChannelRouter {
  8 +
  9 +
  10 +}
  1 +package com.yohoufo.order.service.transfer;
  2 +
  3 +import lombok.Builder;
  4 +
  5 +@Builder
  6 +@lombok.Value
  7 +public class TransferResult {
  8 +
  9 + private int code;
  10 +
  11 + private String msg;
  12 +
  13 + private String transferOrderCode;
  14 +
  15 + private String tradeNo;
  16 +
  17 + private String payDate;
  18 +
  19 +}
@@ -3,18 +3,36 @@ package com.yohoufo.order.utils; @@ -3,18 +3,36 @@ package com.yohoufo.order.utils;
3 import com.yoho.error.ServiceError; 3 import com.yoho.error.ServiceError;
4 import com.yoho.error.exception.ServiceException; 4 import com.yoho.error.exception.ServiceException;
5 5
  6 +import java.util.function.Function;
  7 +import java.util.function.Predicate;
  8 +
6 /** 9 /**
7 * @author LUOXC 10 * @author LUOXC
8 * @date 2019/1/9 11:14 11 * @date 2019/1/9 11:14
9 */ 12 */
10 public class ServiceExceptions { 13 public class ServiceExceptions {
11 14
  15 + @FunctionalInterface
  16 + public interface Condition {
  17 + boolean test();
  18 + }
  19 +
12 public static void throwServiceException(String message) { 20 public static void throwServiceException(String message) {
13 ServiceException serviceException = new ServiceException(ServiceError.ORDER_SERVICE_ERROR); 21 ServiceException serviceException = new ServiceException(ServiceError.ORDER_SERVICE_ERROR);
14 serviceException.setParams(message); 22 serviceException.setParams(message);
15 throw serviceException; 23 throw serviceException;
16 } 24 }
17 25
  26 + public static void throwServiceExceptionIf(Condition condition, int code, String message) {
  27 + if (condition.test()) {
  28 + throw new ServiceException(code, message);
  29 + }
  30 + }
  31 +
  32 + public static void throwServiceException(int code, String message) {
  33 + throw new ServiceException(code, message);
  34 + }
  35 +
18 public static void throwServiceException(ServiceError serviceError) { 36 public static void throwServiceException(ServiceError serviceError) {
19 throw new ServiceException(serviceError); 37 throw new ServiceException(serviceError);
20 } 38 }