Showing
18 changed files
with
441 additions
and
105 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; |
order/debug.log
0 → 100644
@@ -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,104 +1103,112 @@ public class PaymentServiceImpl implements IPaymentService { | @@ -1098,104 +1103,112 @@ 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 { | ||
1104 | - 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); | ||
1110 | - } | ||
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); | ||
1121 | - } else { | ||
1122 | - return; | ||
1123 | - } | ||
1124 | - } | ||
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 | - } | ||
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); | ||
1141 | - // 加新流水 | ||
1142 | - tradeBills.setDealRelateId(tradeBills.getId()); | ||
1143 | - tradeBills.setId(null); | ||
1144 | - tradeBills.setTradeStatus(100); | ||
1145 | - tradeBills.setCreateTime(now); | ||
1146 | - addTradeBills(tradeBills); | ||
1147 | - | ||
1148 | - OrdersPayTransfer transferSuccess = new OrdersPayTransfer(); | ||
1149 | - transferSuccess.setId(transfer.getId()); | ||
1150 | - transferSuccess.setAlipayTradeId(orderId); | ||
1151 | - transferSuccess.setStatus(1); | ||
1152 | - transferSuccess.setUpdateTime(now); | ||
1153 | - 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); | ||
1158 | - } | ||
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(); | ||
1167 | - } | ||
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()); | ||
1174 | - } else { | ||
1175 | - throw new ServiceException(500, "转账失败id=" + tradeBillsId); | ||
1176 | - } | ||
1177 | - } finally { | ||
1178 | - logger.info("manualDeal转账结束, tradeBillsId is {}!", tradeBillsId); | ||
1179 | - } | 1106 | + try { |
1107 | + OrdersPayTransfer transfer = ordersPayTransferMapper.selectByBuyerOrderCode(orderCode); | ||
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); | ||
1118 | + } | ||
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; | ||
1130 | + } else { | ||
1131 | + ServiceExceptions.throwServiceException(500, "转账失败id=" + tradeBillsId); | ||
1132 | + } | ||
1133 | + } finally { | ||
1134 | + logger.info("{}, complete", logTag); | ||
1135 | + } | ||
1180 | } | 1136 | } |
1181 | 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); | ||
1147 | + // 加新流水 | ||
1148 | + tradeBills.setDealRelateId(tradeBills.getId()); | ||
1149 | + tradeBills.setId(null); | ||
1150 | + tradeBills.setTradeStatus(100); | ||
1151 | + tradeBills.setCreateTime(now); | ||
1152 | + addTradeBills(tradeBills); | ||
1153 | + // ? | ||
1154 | + OrdersPayTransfer transferSuccess = new OrdersPayTransfer(); | ||
1155 | + transferSuccess.setId(transfer.getId()); | ||
1156 | + transferSuccess.setAlipayTradeId(transferResult.getTradeNo()); | ||
1157 | + transferSuccess.setStatus(1); | ||
1158 | + transferSuccess.setUpdateTime(now); | ||
1159 | + ordersPayTransferMapper.updateByPrimaryKeySelective(transferSuccess); | ||
1160 | + }else { | ||
1161 | + logger.warn("{}, transfer fail {}", logTag,transferResult); | ||
1162 | + throw new ServiceException(transferResult.getCode(), transferResult.getMsg()); | ||
1163 | + } | ||
1164 | + | ||
1165 | + } | ||
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); | ||
1185 | + } else { | ||
1186 | + logger.warn("{}, transfer fail {}", logTag,transferResult); | ||
1187 | + throw new ServiceException(transferResult.getCode(), transferResult.getMsg()); | ||
1188 | + } | ||
1189 | + } | ||
1190 | + | ||
1182 | 1191 | ||
1183 | - private Map<String, String> transferWhenExceedMillion(Integer transferId, TradeBills tradeBills, long orderCode, AuthorizeResultRespVO account, | ||
1184 | - 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); | 1192 | + private Map<String, String> transferWhenExceedMillion(Integer transferId, TradeBills tradeBills, long orderCode, AuthorizeResultRespVO account, |
1193 | + BigDecimal amount, int now) throws Exception { | ||
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"))) { | ||
1191 | - tradeBills.setDealStatus(0); | ||
1192 | - tradeBills.setTradeStatus(TradeBills.Status.TRANSFER_WAITING.getCode()); | ||
1193 | - // wait | ||
1194 | - tradeBillsMapper.updateSelectiveByPrimaryKeyNoCondition(tradeBills); | 1203 | + if (StringUtils.equals("T", mapResult.get("is_success"))) { |
1204 | + tradeBills.setDealStatus(0); | ||
1205 | + tradeBills.setTradeStatus(TradeBills.Status.TRANSFER_WAITING.getCode()); | ||
1206 | + // wait | ||
1207 | + tradeBillsMapper.updateSelectiveByPrimaryKeyNoCondition(tradeBills); | ||
1195 | logger.info("transferWhenExceedMillion 转账阿里接口(总金额超过100万)更新之后的tradeBill: {}", tradeBillsMapper.selectByPrimaryKey(tradeBills.getId())); | 1208 | logger.info("transferWhenExceedMillion 转账阿里接口(总金额超过100万)更新之后的tradeBill: {}", tradeBillsMapper.selectByPrimaryKey(tradeBills.getId())); |
1196 | } | 1209 | } |
1197 | - return mapResult; | ||
1198 | - } | 1210 | + return mapResult; |
1211 | + } | ||
1199 | 1212 | ||
1200 | private boolean exceedMillion(JSONObject jsonObject) { | 1213 | private boolean exceedMillion(JSONObject jsonObject) { |
1201 | // {"msg":"Business Failed","code":"40004","sub_msg":"单日最多可转100万元","sub_code":"EXCEED_LIMIT_DM_MAX_AMOUNT"} | 1214 | // {"msg":"Business Failed","code":"40004","sub_msg":"单日最多可转100万元","sub_code":"EXCEED_LIMIT_DM_MAX_AMOUNT"} |
@@ -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; |
@@ -49,7 +54,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | @@ -49,7 +54,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | ||
49 | protected abstract String getAppId(); | 54 | protected abstract String getAppId(); |
50 | 55 | ||
51 | protected abstract String getPartnerId(); | 56 | protected abstract String getPartnerId(); |
52 | - | 57 | + |
53 | protected String getAccountUserName() { | 58 | protected String getAccountUserName() { |
54 | return ""; | 59 | return ""; |
55 | } | 60 | } |
@@ -57,7 +62,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | @@ -57,7 +62,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | ||
57 | protected String getAccountEmail() { | 62 | protected String getAccountEmail() { |
58 | return ""; | 63 | return ""; |
59 | } | 64 | } |
60 | - | 65 | + |
61 | protected String getRsaAliMApipubKey() { | 66 | protected String getRsaAliMApipubKey() { |
62 | return ""; | 67 | return ""; |
63 | } | 68 | } |
@@ -70,7 +75,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | @@ -70,7 +75,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | ||
70 | 75 | ||
71 | @Value("${alipay.notifyurl}") | 76 | @Value("${alipay.notifyurl}") |
72 | private String notifyURL; | 77 | private String notifyURL; |
73 | - | 78 | + |
74 | @Value("${alipay.transfer.notifyurl}") | 79 | @Value("${alipay.transfer.notifyurl}") |
75 | private String transferNotifyURL; | 80 | private String transferNotifyURL; |
76 | 81 | ||
@@ -168,7 +173,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | @@ -168,7 +173,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | ||
168 | * @param alipayAccount | 173 | * @param alipayAccount |
169 | * @param transferAmount | 174 | * @param transferAmount |
170 | * @return | 175 | * @return |
171 | - * @throws Exception | 176 | + * @throws Exception |
172 | */ | 177 | */ |
173 | public JSONObject transferMoney(String transferOrderCode, String alipayUid, String alipayAccount, BigDecimal transferAmount) throws Exception{ | 178 | public JSONObject transferMoney(String transferOrderCode, String alipayUid, String alipayAccount, BigDecimal transferAmount) throws Exception{ |
174 | 179 | ||
@@ -184,14 +189,192 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | @@ -184,14 +189,192 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | ||
184 | } | 189 | } |
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 |
191 | * @param alipayAccount | 374 | * @param alipayAccount |
192 | * @param transferAmount | 375 | * @param transferAmount |
193 | * @return | 376 | * @return |
194 | - * @throws Exception | 377 | + * @throws Exception |
195 | */ | 378 | */ |
196 | public Map<String, String> transferMoneyWhenExceedMillion(String transferOrderCode, String businessId, String alipayUid, String alipayAccount, String userName, BigDecimal transferAmount) throws Exception{ | 379 | public Map<String, String> transferMoneyWhenExceedMillion(String transferOrderCode, String businessId, String alipayUid, String alipayAccount, String userName, BigDecimal transferAmount) throws Exception{ |
197 | 380 | ||
@@ -207,7 +390,90 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | @@ -207,7 +390,90 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | ||
207 | } | 390 | } |
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); |
@@ -245,14 +511,14 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | @@ -245,14 +511,14 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | ||
245 | logger.info("[{}] trade openapi resp: {}", orderCode, response); | 511 | logger.info("[{}] trade openapi resp: {}", orderCode, response); |
246 | return response; | 512 | return response; |
247 | } | 513 | } |
248 | - | 514 | + |
249 | private String sendOpenApiRequestWithException(String orderCode, Map<String, String> paramMap) throws Exception { | 515 | private String sendOpenApiRequestWithException(String orderCode, Map<String, String> paramMap) throws Exception { |
250 | logger.info("[{}] send openapi request: {}", orderCode, paramMap); | 516 | logger.info("[{}] send openapi request: {}", orderCode, paramMap); |
251 | String response = httpClient.postFormData(AlipayConfig.OPENAPI_URL, paramMap); | 517 | String response = httpClient.postFormData(AlipayConfig.OPENAPI_URL, paramMap); |
252 | logger.info("[{}] trade openapi resp: {}", orderCode, response); | 518 | logger.info("[{}] trade openapi resp: {}", orderCode, response); |
253 | return response; | 519 | return response; |
254 | } | 520 | } |
255 | - | 521 | + |
256 | private String sendMApiRequestWithException(String orderCode, Map<String, String> paramMap) throws Exception { | 522 | private String sendMApiRequestWithException(String orderCode, Map<String, String> paramMap) throws Exception { |
257 | logger.info("[{}] send openapi request: {}", orderCode, paramMap); | 523 | logger.info("[{}] send openapi request: {}", orderCode, paramMap); |
258 | StringBuilder paramStr = new StringBuilder(); | 524 | StringBuilder paramStr = new StringBuilder(); |
@@ -291,7 +557,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | @@ -291,7 +557,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | ||
291 | params.put("sign", RSAUtils.sign(preSignStr, getRsaPrivateKey(), AlipayConfig.input_charset)); | 557 | params.put("sign", RSAUtils.sign(preSignStr, getRsaPrivateKey(), AlipayConfig.input_charset)); |
292 | return params; | 558 | return params; |
293 | } | 559 | } |
294 | - | 560 | + |
295 | /** | 561 | /** |
296 | * openapi支付查询 | 562 | * openapi支付查询 |
297 | * @param orderData | 563 | * @param orderData |
@@ -349,7 +615,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | @@ -349,7 +615,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | ||
349 | params.put("sign", RSAUtils.sign(preSignStr, getRsaPrivateKey(), AlipayConfig.input_charset)); | 615 | params.put("sign", RSAUtils.sign(preSignStr, getRsaPrivateKey(), AlipayConfig.input_charset)); |
350 | return params; | 616 | return params; |
351 | } | 617 | } |
352 | - | 618 | + |
353 | /** | 619 | /** |
354 | * 单笔转账 | 620 | * 单笔转账 |
355 | * @param orderData | 621 | * @param orderData |
@@ -367,7 +633,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | @@ -367,7 +633,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | ||
367 | params.put("batch_num", "1"); | 633 | params.put("batch_num", "1"); |
368 | params.put("batch_fee", transferAmount.toString()); | 634 | params.put("batch_fee", transferAmount.toString()); |
369 | params.put("email", getAccountEmail()); | 635 | params.put("email", getAccountEmail()); |
370 | - | 636 | + |
371 | StringBuilder detailAppender = new StringBuilder(); | 637 | StringBuilder detailAppender = new StringBuilder(); |
372 | detailAppender.append(businessId).append("^"); | 638 | detailAppender.append(businessId).append("^"); |
373 | if (StringUtils.isNotBlank(alipayUid)) { | 639 | if (StringUtils.isNotBlank(alipayUid)) { |
@@ -536,7 +802,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | @@ -536,7 +802,7 @@ public abstract class AlipayServiceAbstract extends AbstractPayService { | ||
536 | } | 802 | } |
537 | return payData; | 803 | return payData; |
538 | } | 804 | } |
539 | - | 805 | + |
540 | public TransferData getTransferData(String data) { | 806 | public TransferData getTransferData(String data) { |
541 | if (StringUtils.isBlank(data)) { | 807 | if (StringUtils.isBlank(data)) { |
542 | return null; | 808 | return null; |
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 | } |
order/yoho.logs.basedir_IS_UNDEFINED/ufo.gateway.env.namespace_IS_UNDEFINED/buyer-order.log
0 → 100644
order/yoho.logs.basedir_IS_UNDEFINED/ufo.gateway.env.namespace_IS_UNDEFINED/graph_verify_switch.log
0 → 100644
order/yoho.logs.basedir_IS_UNDEFINED/ufo.gateway.env.namespace_IS_UNDEFINED/mq-consumer.log
0 → 100644
order/yoho.logs.basedir_IS_UNDEFINED/ufo.gateway.env.namespace_IS_UNDEFINED/mq-producer.log
0 → 100644
order/yoho.logs.basedir_IS_UNDEFINED/ufo.gateway.env.namespace_IS_UNDEFINED/order-close.log
0 → 100644
order/yoho.logs.basedir_IS_UNDEFINED/ufo.gateway.env.namespace_IS_UNDEFINED/recommend.log
0 → 100644
-
Please register or login to post a comment