|
|
@@ -13,6 +13,9 @@ use bizHd\hb\classes\HbClass;
|
|
|
use bizHd\hb\classes\HbManageClass;
|
|
|
use bizHd\order\classes\OrderClass;
|
|
|
use bizHd\order\classes\SettleClass;
|
|
|
+use bizMall\order\classes\WxFreezeBalanceClass;
|
|
|
+use bizMall\order\classes\WxOrderShippingClass;
|
|
|
+use bizMall\order\classes\RechargeWxExtClass;
|
|
|
use bizHd\shop\classes\ShopExtClass;
|
|
|
use bizHd\shop\classes\MainClass;
|
|
|
use bizHd\user\classes\UserGrowthClass;
|
|
|
@@ -170,8 +173,12 @@ class RechargeClass extends BaseClass
|
|
|
return self::add($data, true);
|
|
|
}
|
|
|
|
|
|
- //第三支付后流程 ssh 2021.4.27
|
|
|
- public static function thirdPay($payWay, $orderSn, $totalFee, $attach, $transactionId = '')
|
|
|
+ /**
|
|
|
+ * 拉卡拉/微信充值回调入账。
|
|
|
+ * $transactionId 写入 returnCode(拉卡拉 trade_no,退款用);
|
|
|
+ * $accTradeNo 写入 thirdPayNo(账户端单号/微信 transaction_id,虚拟发货用)。
|
|
|
+ */
|
|
|
+ public static function thirdPay($payWay, $orderSn, $totalFee, $attach, $transactionId = '', $accTradeNo = '')
|
|
|
{
|
|
|
$recharge = RechargeClass::getByCondition(['orderSn' => $orderSn], true);
|
|
|
if (empty($recharge)) {
|
|
|
@@ -184,6 +191,9 @@ class RechargeClass extends BaseClass
|
|
|
}
|
|
|
if ($recharge->payStatus == 1) {
|
|
|
noticeUtil::push("充值付款成功,收到回调,但订单是已经支付过了,orderSn:" . $orderSn, '15280215347');
|
|
|
+ // 已入账仍补 thirdPayNo 并尝试虚拟发货:首次回调发货失败时后续通知可补录
|
|
|
+ self::saveThirdPayNoIfEmpty($recharge, $accTradeNo);
|
|
|
+ self::tryWxVirtualShipping($recharge, $accTradeNo);
|
|
|
return false;
|
|
|
}
|
|
|
$id = $recharge->id;
|
|
|
@@ -192,12 +202,60 @@ class RechargeClass extends BaseClass
|
|
|
'onlinePay' => 2,
|
|
|
'side' => 1,
|
|
|
];
|
|
|
- $recharge->returnCode = $transactionId;
|
|
|
+ $recharge->returnCode = mb_substr(trim((string)$transactionId), 0, 50);
|
|
|
+ $accTradeNo = trim((string)$accTradeNo);
|
|
|
+ if ($accTradeNo !== '') {
|
|
|
+ $recharge->thirdPayNo = mb_substr($accTradeNo, 0, 50);
|
|
|
+ }
|
|
|
$recharge->save(false);
|
|
|
self::complete($recharge, $payWay, $params);
|
|
|
+ self::tryWxVirtualShipping($recharge, $accTradeNo);
|
|
|
return $recharge;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 已入账记录补写 acc_trade_no。thirdPayNo 已有值则不覆盖,避免把退款用的 returnCode 搞混。
|
|
|
+ */
|
|
|
+ protected static function saveThirdPayNoIfEmpty($recharge, $accTradeNo)
|
|
|
+ {
|
|
|
+ $accTradeNo = trim((string)$accTradeNo);
|
|
|
+ if ($accTradeNo === '' || empty($recharge)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ $current = trim((string)($recharge->thirdPayNo ?? ''));
|
|
|
+ if ($current !== '') {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ $recharge->thirdPayNo = mb_substr($accTradeNo, 0, 50);
|
|
|
+ $recharge->save(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * mallApp 微信支付充值成功后向微信录入虚拟发货。
|
|
|
+ * 失败只记日志,不回滚开户入账。
|
|
|
+ */
|
|
|
+ public static function tryWxVirtualShipping($recharge, $accTradeNo = '')
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ WxOrderShippingClass::uploadVirtualByRecharge($recharge, $accTradeNo);
|
|
|
+ } catch (\Throwable $e) {
|
|
|
+ Yii::error('充值微信虚拟发货异常: ' . $e->getMessage(), 'wx-order-shipping');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 支付回调 10 秒去重命中时补录发货:此时入账可能已完成,只再走微信虚拟发货。
|
|
|
+ */
|
|
|
+ public static function tryWxVirtualShippingByOrderSn($orderSn, $accTradeNo = '')
|
|
|
+ {
|
|
|
+ $recharge = self::getByCondition(['orderSn' => $orderSn], true);
|
|
|
+ if (empty($recharge)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ self::saveThirdPayNoIfEmpty($recharge, $accTradeNo);
|
|
|
+ self::tryWxVirtualShipping($recharge, $accTradeNo);
|
|
|
+ }
|
|
|
+
|
|
|
//处理充值流程 ssh 20250321
|
|
|
public static function complete($recharge, $payWay, $params)
|
|
|
{
|
|
|
@@ -550,10 +608,14 @@ class RechargeClass extends BaseClass
|
|
|
}
|
|
|
|
|
|
if ($recharge->onlinePay == 2) {
|
|
|
- //如果线上充值,门店余额增加
|
|
|
+ // 线上充值:mallApp 微信先进冻结池,支付宝等仍立即增加可提现余额
|
|
|
$shop = ShopClass::getLockById($shopId);
|
|
|
$main = MainClass::getLockById($mainId);
|
|
|
- ShopClass::skRechargeAddBalance($main, $shop, $recharge);
|
|
|
+ if (WxFreezeBalanceClass::shouldFreezeMallWxRecharge($recharge)) {
|
|
|
+ WxFreezeBalanceClass::freezeOnRechargePay($main, $shop, $recharge);
|
|
|
+ } else {
|
|
|
+ ShopClass::skRechargeAddBalance($main, $shop, $recharge);
|
|
|
+ }
|
|
|
} else {
|
|
|
if ($recharge->payWay == 4) {
|
|
|
//现在现金充值要增加现金
|
|
|
@@ -650,6 +712,8 @@ class RechargeClass extends BaseClass
|
|
|
$aliPay = intval(dict::getDict('payWay', 'alipay'));
|
|
|
$cashPay = intval(dict::getDict('payWay', 'cash'));
|
|
|
$onlineMain = null;
|
|
|
+ // 未结算入账的 mall 微信充值:退款只解冻,不要求 balance 够
|
|
|
+ $refundFromFreeze = false;
|
|
|
|
|
|
if ($isOnline) {
|
|
|
if ($payWay !== $wxPay && $payWay !== $aliPay) {
|
|
|
@@ -663,7 +727,14 @@ class RechargeClass extends BaseClass
|
|
|
if (empty($onlineMain)) {
|
|
|
util::fail('没有找到资产信息');
|
|
|
}
|
|
|
- if (bccomp((string)($onlineMain->balance ?? '0'), $amount, 2) < 0) {
|
|
|
+ if ($payWay === $wxPay && WxFreezeBalanceClass::shouldFreezeMallWxRecharge($recharge)) {
|
|
|
+ $ext = \bizMall\order\classes\RechargeWxExtClass::getByRechargeId($rechargeId);
|
|
|
+ if (!empty($ext) && (int)($ext['balancePosted'] ?? 0) !== 1
|
|
|
+ && bccomp((string)($ext['freezeAmount'] ?? '0'), '0', 2) > 0) {
|
|
|
+ $refundFromFreeze = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!$refundFromFreeze && bccomp((string)($onlineMain->balance ?? '0'), $amount, 2) < 0) {
|
|
|
util::fail('门店余额不足,无法退款');
|
|
|
}
|
|
|
self::refundOnlineByLakala($recharge, $shop, $amount, $returnCode);
|
|
|
@@ -743,12 +814,18 @@ class RechargeClass extends BaseClass
|
|
|
if (empty($main)) {
|
|
|
util::fail('没有找到资产信息');
|
|
|
}
|
|
|
- ShopClass::customRechargeRefundReduceBalance($main, $shop, $recharge, dict::getDict('capitalType', 'xhRecharge', 'id'), $staffName);
|
|
|
+ // 未入账:只解冻写冻结明细;已入账或非冻结单:仍扣可提现余额
|
|
|
+ $needReduce = WxFreezeBalanceClass::unfreezeOnRechargeRefund($main, $shop, $recharge);
|
|
|
+ if (bccomp($needReduce, '0', 2) > 0) {
|
|
|
+ ShopClass::customRechargeRefundReduceBalance($main, $shop, $recharge, dict::getDict('capitalType', 'xhRecharge', 'id'), $staffName);
|
|
|
+ }
|
|
|
} elseif ($payWay === $cashPay) {
|
|
|
self::cashRechargeRefundReduceMoney($recharge, $shop, $staffName, $amount);
|
|
|
}
|
|
|
|
|
|
self::markRechargeRefunded($recharge);
|
|
|
+ // 未录入成功时取消发货补录;队列里已有消息消费时也会因 isRefund 跳过
|
|
|
+ RechargeWxExtClass::cancelShipRetry((int)$recharge->id, '已退款,跳过发货补录');
|
|
|
$recharge->balance = $hd->balance;
|
|
|
$recharge->save(false);
|
|
|
|