|
|
@@ -13,6 +13,7 @@ use App\Services\Payment\JdPayService;
|
|
|
use App\Services\Payment\NoPayService;
|
|
|
use App\Services\Payment\QianBaoService;
|
|
|
use App\Services\Payment\SanJinService;
|
|
|
+use App\Services\Payment\ZimuPayService;
|
|
|
use App\Services\ConfigService;
|
|
|
|
|
|
/**
|
|
|
@@ -240,7 +241,7 @@ class PaymentOrderService extends BaseService
|
|
|
}
|
|
|
|
|
|
// 没有找到支付通道
|
|
|
- if (empty($channel) && !JdPayService::isChannel($paymentType) && !NoPayService::isRechargeChannel($paymentType)) {
|
|
|
+ if (empty($channel) && !JdPayService::isChannel($paymentType) && !NoPayService::isRechargeChannel($paymentType) && !ZimuPayService::isRechargeChannel($paymentType)) {
|
|
|
// $text = "发起充值失败 \n";
|
|
|
// $text .= "最低充值:" . $min . " \n";
|
|
|
// $text .= "最高充值:" . $max . " \n";
|
|
|
@@ -254,6 +255,54 @@ class PaymentOrderService extends BaseService
|
|
|
return $result;
|
|
|
}
|
|
|
|
|
|
+ if (ZimuPayService::isRechargeChannel($paymentType) || ZimuPayService::isRechargeChannel($channel)) {
|
|
|
+ $channel = ZimuPayService::CHANNEL_RECHARGE;
|
|
|
+ $bankName = $selectedProduct['name'] ?? '808充值';
|
|
|
+ $data = [];
|
|
|
+ $data['type'] = self::TYPE_PAY;
|
|
|
+ $data['member_id'] = $memberId;
|
|
|
+ $data['amount'] = ZimuPayService::amount($amount);
|
|
|
+ $data['channel'] = $channel;
|
|
|
+ $data['fee'] = $amount * $rate;
|
|
|
+ $data['bank_name'] = $bankName;
|
|
|
+ $order_no = self::createOrderNo('zm' . $data['type'] . '_', $memberId);
|
|
|
+ $data['order_no'] = $order_no;
|
|
|
+ $data['callback_url'] = ZimuPayService::getPayNotifyUrl();
|
|
|
+ $data['remark'] = '充值费率:' . $rate;
|
|
|
+ $data['status'] = self::STATUS_STAY;
|
|
|
+
|
|
|
+ $ret = ZimuPayService::pay($amount, $order_no, (string)$memberId);
|
|
|
+ Log::channel('payment')->info('ZIMU支付发起', [
|
|
|
+ 'order_no' => $order_no,
|
|
|
+ 'member_id' => $memberId,
|
|
|
+ 'amount' => $data['amount'],
|
|
|
+ 'response' => $ret,
|
|
|
+ ]);
|
|
|
+ if (($ret['code'] ?? -1) == 0) {
|
|
|
+ $item = $ret['data'] ?? [];
|
|
|
+ $payUrl = $item['payUrl'] ?? '';
|
|
|
+ $data['status'] = self::STATUS_PROCESS;
|
|
|
+ $data['pay_no'] = $item['orderNo'] ?? '';
|
|
|
+ $data['pay_url'] = $payUrl;
|
|
|
+ $data['pay_data'] = json_encode($ret, JSON_UNESCAPED_UNICODE);
|
|
|
+ static::$MODEL::create($data);
|
|
|
+
|
|
|
+ if ($payUrl) {
|
|
|
+ $result['image'] = asset(self::createPaymentQrCode($payUrl));
|
|
|
+ }
|
|
|
+ $result['text'] = "{$bankName}确认 \n";
|
|
|
+ $result['text'] .= "请使用浏览器扫码或者复制支付地址到浏览器打开 \n";
|
|
|
+ $result['text'] .= "支付地址:{$payUrl}\n";
|
|
|
+ $result['text'] .= "支付金额:" . $amount . " RMB \n";
|
|
|
+ $result['text'] .= "支付完成后请耐心等待,支付到账会第一时间通知您! \n";
|
|
|
+ $result['url'] = $payUrl;
|
|
|
+ } else {
|
|
|
+ $result['text'] = $ret['msg'] ?? 'ZIMU支付发起失败';
|
|
|
+ $result['code'] = 20002;
|
|
|
+ }
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
if (NoPayService::isRechargeChannel($paymentType) || NoPayService::isRechargeChannel($channel)) {
|
|
|
$channel = NoPayService::isRechargeChannel($paymentType) ? $paymentType : $channel;
|
|
|
$bankName = $selectedProduct['name'] ?? 'NO快捷充值';
|
|
|
@@ -394,6 +443,51 @@ class PaymentOrderService extends BaseService
|
|
|
*/
|
|
|
public static function receivePay($params)
|
|
|
{
|
|
|
+ if (ZimuPayService::getAppId() !== '' && ($params['appId'] ?? '') === ZimuPayService::getAppId()) {
|
|
|
+ $info = self::findOne(['order_no' => $params['mchOrderNo'] ?? '']);
|
|
|
+ if (!$info || $info->type != self::TYPE_PAY || !ZimuPayService::isRechargeChannel($info->channel)) {
|
|
|
+ Log::error('ZIMU充值回调订单不存在或类型不匹配', [
|
|
|
+ 'mch_order_no' => $params['mchOrderNo'] ?? '',
|
|
|
+ 'order_id' => $info->id ?? null,
|
|
|
+ 'order_type' => $info->type ?? null,
|
|
|
+ 'channel' => $info->channel ?? null,
|
|
|
+ ]);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!ZimuPayService::verifyNotify($params)) {
|
|
|
+ Log::error('ZIMU充值回调验签失败', [
|
|
|
+ 'mch_order_no' => $params['mchOrderNo'] ?? '',
|
|
|
+ 'app_id' => $params['appId'] ?? '',
|
|
|
+ 'signature' => ZimuPayService::notifySignatureDiagnostics($params),
|
|
|
+ ]);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (bccomp(ZimuPayService::amount($info->amount), ZimuPayService::amount($params['amount'] ?? 0), 2) !== 0) {
|
|
|
+ Log::error('ZIMU充值回调金额不一致', [
|
|
|
+ 'mch_order_no' => $params['mchOrderNo'] ?? '',
|
|
|
+ 'order_amount' => $info->amount,
|
|
|
+ 'callback_amount' => $params['amount'] ?? null,
|
|
|
+ ]);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if ($info->status != self::STATUS_PROCESS) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ $processed = self::applyPayCallback(
|
|
|
+ $info,
|
|
|
+ ZimuPayService::amount($info->amount),
|
|
|
+ (string)$params['status'],
|
|
|
+ ZimuPayService::PAY_STATUS_SUCCESS,
|
|
|
+ ZimuPayService::PAY_STATUS_FAIL,
|
|
|
+ $params
|
|
|
+ );
|
|
|
+ if ($processed && (string)$params['status'] === ZimuPayService::PAY_STATUS_SUCCESS) {
|
|
|
+ self::notifyUser($info->member_id, "✅ 支付成功 \n充值金额:{$info->amount} RMB \n订单号:{$info->order_no} \n您充值的金额已到账,请注意查收!");
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
if (NoPayService::getDepositMerchantId() !== '' && ($params['appId'] ?? '') === NoPayService::getDepositMerchantId()) {
|
|
|
$info = self::findOne(['order_no' => $params['merchantOrderNo'] ?? '']);
|
|
|
if (!$info || $info->type != self::TYPE_PAY || !NoPayService::isRechargeChannel($info->channel)) {
|
|
|
@@ -656,6 +750,38 @@ class PaymentOrderService extends BaseService
|
|
|
}
|
|
|
$order->pay_no = $ret['data']['orderNo'] ?? '';
|
|
|
$order->pay_data = json_encode($ret, JSON_UNESCAPED_UNICODE);
|
|
|
+ } elseif (ZimuPayService::isPayoutChannel($order->channel)) {
|
|
|
+ self::assertZimuBalanceEnough($amount, [
|
|
|
+ 'order_id' => $order->id,
|
|
|
+ 'order_no' => $order->order_no,
|
|
|
+ 'member_id' => $order->member_id,
|
|
|
+ 'channel' => $order->channel,
|
|
|
+ ]);
|
|
|
+ if (ZimuPayService::isCashChannel($order->channel)) {
|
|
|
+ $ret = ZimuPayService::cash(
|
|
|
+ $amount,
|
|
|
+ $order->order_no,
|
|
|
+ (string)$order->account,
|
|
|
+ (string)$order->card_no,
|
|
|
+ (string)$order->bank_name,
|
|
|
+ ZimuPayService::cashPayMethod((string)$order->bank_name)
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ $ret = ZimuPayService::withdraw($amount, $order->order_no, (string)$order->member_id, (string)$order->card_no, (string)$order->account);
|
|
|
+ }
|
|
|
+ Log::channel('payment')->info('ZIMU提现/代付接口调用', [
|
|
|
+ 'order_id' => $order->id,
|
|
|
+ 'order_no' => $order->order_no,
|
|
|
+ 'member_id' => $order->member_id,
|
|
|
+ 'amount' => $amount,
|
|
|
+ 'channel' => $order->channel,
|
|
|
+ 'response' => $ret,
|
|
|
+ ]);
|
|
|
+ if (($ret['code'] ?? -1) != 0) {
|
|
|
+ throw new Exception($ret['msg'] ?? 'ZIMU提现/代付失败', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+ $order->pay_no = $ret['data']['orderNo'] ?? '';
|
|
|
+ $order->pay_data = json_encode($ret, JSON_UNESCAPED_UNICODE);
|
|
|
} elseif (JdPayService::isChannel($order->channel)) {
|
|
|
self::assertJdBalanceEnough($amount, [
|
|
|
'order_id' => $order->id,
|
|
|
@@ -767,6 +893,8 @@ class PaymentOrderService extends BaseService
|
|
|
$data['callback_url'] = NoPayService::getWithdrawNotifyUrl();
|
|
|
} elseif (JdPayService::isChannel($channel)) {
|
|
|
$data['callback_url'] = JdPayService::getRemitNotifyUrl();
|
|
|
+ } elseif (ZimuPayService::isPayoutChannel($channel)) {
|
|
|
+ $data['callback_url'] = ZimuPayService::getPayoutNotifyUrl();
|
|
|
} else {
|
|
|
$data['callback_url'] = QianBaoService::getNotifyUrl();
|
|
|
}
|
|
|
@@ -828,6 +956,46 @@ class PaymentOrderService extends BaseService
|
|
|
'error' => $e->getMessage(),
|
|
|
]);
|
|
|
}
|
|
|
+ } elseif (ZimuPayService::isPayoutChannel($channel)) {
|
|
|
+ try {
|
|
|
+ self::assertZimuBalanceEnough($amount, [
|
|
|
+ 'order_no' => $order_no,
|
|
|
+ 'member_id' => $memberId,
|
|
|
+ 'channel' => $channel,
|
|
|
+ ]);
|
|
|
+ if (ZimuPayService::isCashChannel($channel)) {
|
|
|
+ $ret = ZimuPayService::cash(
|
|
|
+ $amount,
|
|
|
+ $order_no,
|
|
|
+ (string)$account,
|
|
|
+ (string)$card_no,
|
|
|
+ (string)$bank_name,
|
|
|
+ ZimuPayService::cashPayMethod((string)$bank_name)
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ $ret = ZimuPayService::withdraw($amount, $order_no, (string)$memberId, (string)$card_no, (string)$account);
|
|
|
+ }
|
|
|
+ Log::channel('payment')->info('ZIMU提现/代付接口调用', [
|
|
|
+ 'order_no' => $order_no,
|
|
|
+ 'member_id' => $memberId,
|
|
|
+ 'amount' => $amount,
|
|
|
+ 'channel' => $channel,
|
|
|
+ 'response' => $ret,
|
|
|
+ ]);
|
|
|
+ $success = (($ret['code'] ?? -1) == 0);
|
|
|
+ $failureMessage = $ret['msg'] ?? 'ZIMU提现/代付失败';
|
|
|
+ } catch (Exception $e) {
|
|
|
+ $ret = ['msg' => $e->getMessage()];
|
|
|
+ $success = false;
|
|
|
+ $failureMessage = $e->getMessage();
|
|
|
+ Log::channel('payment_error')->error('ZIMU提现/代付接口异常', [
|
|
|
+ 'order_no' => $order_no,
|
|
|
+ 'member_id' => $memberId,
|
|
|
+ 'amount' => $amount,
|
|
|
+ 'channel' => $channel,
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
+ ]);
|
|
|
+ }
|
|
|
} elseif (JdPayService::isChannel($channel)) {
|
|
|
try {
|
|
|
self::assertJdBalanceEnough($amount, [
|
|
|
@@ -882,7 +1050,7 @@ class PaymentOrderService extends BaseService
|
|
|
DB::beginTransaction();
|
|
|
try {
|
|
|
$info->status = self::STATUS_PROCESS;
|
|
|
- if (NoPayService::isWithdrawChannel($channel) || JdPayService::isChannel($channel)) {
|
|
|
+ if (NoPayService::isWithdrawChannel($channel) || JdPayService::isChannel($channel) || ZimuPayService::isPayoutChannel($channel)) {
|
|
|
$info->pay_no = $ret['data']['orderNo'] ?? '';
|
|
|
$info->pay_data = json_encode($ret, JSON_UNESCAPED_UNICODE);
|
|
|
}
|
|
|
@@ -949,6 +1117,37 @@ class PaymentOrderService extends BaseService
|
|
|
*/
|
|
|
public static function receiveOrder($params)
|
|
|
{
|
|
|
+ if (ZimuPayService::getAppId() !== '' && ($params['appId'] ?? '') === ZimuPayService::getAppId()) {
|
|
|
+ $info = self::findOne(['order_no' => $params['mchOrderNo'] ?? '']);
|
|
|
+ if (!$info || $info->type != self::TYPE_PAYOUT || !ZimuPayService::isPayoutChannel($info->channel)) {
|
|
|
+ Log::error('ZIMU提现/代付回调订单不存在或类型不匹配', [
|
|
|
+ 'mch_order_no' => $params['mchOrderNo'] ?? '',
|
|
|
+ 'order_id' => $info->id ?? null,
|
|
|
+ 'order_type' => $info->type ?? null,
|
|
|
+ 'channel' => $info->channel ?? null,
|
|
|
+ ]);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!ZimuPayService::verifyNotify($params)) {
|
|
|
+ Log::error('ZIMU提现/代付回调验签失败', [
|
|
|
+ 'mch_order_no' => $params['mchOrderNo'] ?? '',
|
|
|
+ 'app_id' => $params['appId'] ?? '',
|
|
|
+ 'signature' => ZimuPayService::notifySignatureDiagnostics($params),
|
|
|
+ ]);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (bccomp(ZimuPayService::amount($info->amount), ZimuPayService::amount($params['amount'] ?? 0), 2) !== 0) {
|
|
|
+ Log::error('ZIMU提现/代付回调金额不一致', [
|
|
|
+ 'mch_order_no' => $params['mchOrderNo'] ?? '',
|
|
|
+ 'order_amount' => $info->amount,
|
|
|
+ 'callback_amount' => $params['amount'] ?? null,
|
|
|
+ ]);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ self::onSubmitZimuPayout($params, $info);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
if (NoPayService::getWithdrawMerchantId() !== '' && ($params['appId'] ?? '') === NoPayService::getWithdrawMerchantId()) {
|
|
|
$info = self::findOne(['order_no' => $params['merchantOrderNo'] ?? '']);
|
|
|
if (!$info || $info->type != self::TYPE_PAYOUT || !NoPayService::isWithdrawChannel($info->channel)) {
|
|
|
@@ -1131,6 +1330,62 @@ class PaymentOrderService extends BaseService
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public static function onSubmitZimuPayout($params, $info)
|
|
|
+ {
|
|
|
+ $notification = null;
|
|
|
+ $successStatus = ZimuPayService::isCashChannel($info->channel)
|
|
|
+ ? ZimuPayService::CASH_STATUS_SUCCESS
|
|
|
+ : ZimuPayService::WITHDRAW_STATUS_SUCCESS;
|
|
|
+ $failStatus = ZimuPayService::isCashChannel($info->channel)
|
|
|
+ ? ZimuPayService::CASH_STATUS_FAIL
|
|
|
+ : ZimuPayService::WITHDRAW_STATUS_FAIL;
|
|
|
+
|
|
|
+ try {
|
|
|
+ DB::transaction(function () use ($params, $info, &$notification, $successStatus, $failStatus) {
|
|
|
+ $order = PaymentOrder::where('id', $info->id)->lockForUpdate()->first();
|
|
|
+ if (!$order || $order->status != self::STATUS_PROCESS) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ $order->callback_data = json_encode($params, JSON_UNESCAPED_UNICODE);
|
|
|
+ if ((string)$params['status'] === $successStatus) {
|
|
|
+ $order->status = self::STATUS_SUCCESS;
|
|
|
+ $order->save();
|
|
|
+ $accountLabel = ZimuPayService::isCashChannel($order->channel) ? '收款账号' : '808钱包地址';
|
|
|
+ $notification = "✅ 提现通知 \n提现平台:{$order->bank_name} \n收款人:{$order->account} \n{$accountLabel}:{$order->card_no} \n提现金额:{$order->amount} \n提现成功,金额已到账,请注意查收!";
|
|
|
+ } elseif ((string)$params['status'] === $failStatus) {
|
|
|
+ $order->status = self::STATUS_FAIL;
|
|
|
+ $order->save();
|
|
|
+
|
|
|
+ $wallet = WalletModel::where('member_id', $order->member_id)->lockForUpdate()->first();
|
|
|
+ if (!$wallet) {
|
|
|
+ throw new Exception('钱包不存在', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+ $balance = $wallet->available_balance;
|
|
|
+ $availableBalance = bcadd($balance, ZimuPayService::amount($order->amount), 10);
|
|
|
+ $wallet->available_balance = $availableBalance;
|
|
|
+ $wallet->save();
|
|
|
+
|
|
|
+ BalanceLogService::addLog($order->member_id, $order->amount, $balance, $availableBalance, '三方提现', $order->id, '提现失败退款');
|
|
|
+ $accountLabel = ZimuPayService::isCashChannel($order->channel) ? '收款账号' : '808钱包地址';
|
|
|
+ $notification = "❌ 提现通知 \n提现平台:{$order->bank_name} \n收款人:{$order->account} \n{$accountLabel}:{$order->card_no} \n提现金额:{$order->amount} \n提现失败,金额已返回钱包,请注意查收!";
|
|
|
+ } else {
|
|
|
+ $order->save();
|
|
|
+ }
|
|
|
+ }, 3);
|
|
|
+
|
|
|
+ if ($notification !== null) {
|
|
|
+ self::notifyUser($info->member_id, $notification);
|
|
|
+ }
|
|
|
+ } catch (Exception $e) {
|
|
|
+ Log::channel('payment_error')->error('ZIMU提现/代付回调处理异常', [
|
|
|
+ 'order_id' => $info->id,
|
|
|
+ 'params' => $params,
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public static function onSubmitPayout($params, $info)
|
|
|
{
|
|
|
$memberId = $info->member_id;
|
|
|
@@ -1234,6 +1489,41 @@ class PaymentOrderService extends BaseService
|
|
|
return $msg;
|
|
|
}
|
|
|
|
|
|
+ if (ZimuPayService::isRechargeChannel($info->channel)) {
|
|
|
+ $ret = ZimuPayService::queryPayOrder($info->order_no);
|
|
|
+ Log::channel('payment')->info('ZIMU支付查询订单', $ret);
|
|
|
+ if (($ret['code'] ?? -1) == 0) {
|
|
|
+ $item = $ret['data'] ?? [];
|
|
|
+ if ((string)($item['status'] ?? '') === ZimuPayService::PAY_STATUS_SUCCESS) {
|
|
|
+ $processed = self::applyPayCallback(
|
|
|
+ $info,
|
|
|
+ ZimuPayService::amount($info->amount),
|
|
|
+ ZimuPayService::PAY_STATUS_SUCCESS,
|
|
|
+ ZimuPayService::PAY_STATUS_SUCCESS,
|
|
|
+ ZimuPayService::PAY_STATUS_FAIL,
|
|
|
+ $ret
|
|
|
+ );
|
|
|
+ $msg['code'] = $processed ? self::YES : self::NOT;
|
|
|
+ $msg['msg'] = $processed ? '支付成功' : '订单已处理';
|
|
|
+ } elseif ((string)($item['status'] ?? '') === ZimuPayService::PAY_STATUS_FAIL) {
|
|
|
+ self::applyPayCallback(
|
|
|
+ $info,
|
|
|
+ ZimuPayService::amount($info->amount),
|
|
|
+ ZimuPayService::PAY_STATUS_FAIL,
|
|
|
+ ZimuPayService::PAY_STATUS_SUCCESS,
|
|
|
+ ZimuPayService::PAY_STATUS_FAIL,
|
|
|
+ $ret
|
|
|
+ );
|
|
|
+ $msg['msg'] = '支付失败';
|
|
|
+ } else {
|
|
|
+ $msg['msg'] = '支付中';
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $msg['msg'] = '查询失败:' . ($ret['msg'] ?? '');
|
|
|
+ }
|
|
|
+ return $msg;
|
|
|
+ }
|
|
|
+
|
|
|
if (JdPayService::isChannel($info->channel)) {
|
|
|
$ret = JdPayService::queryPayOrder($info->pay_no ?? '', $info->order_no);
|
|
|
Log::channel('payment')->info('JD支付查询订单', $ret);
|
|
|
@@ -1329,6 +1619,35 @@ class PaymentOrderService extends BaseService
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private static function assertZimuBalanceEnough($amount, array $context = []): void
|
|
|
+ {
|
|
|
+ $ret = ZimuPayService::balance();
|
|
|
+ Log::channel('payment')->info('ZIMU余额查询', $context + [
|
|
|
+ 'amount' => $amount,
|
|
|
+ 'response' => $ret,
|
|
|
+ ]);
|
|
|
+ if (($ret['code'] ?? -1) != 0) {
|
|
|
+ $logContext = $context + [
|
|
|
+ 'amount' => $amount,
|
|
|
+ 'response' => $ret,
|
|
|
+ ];
|
|
|
+ Log::channel('payment_error')->error('ZIMU余额查询失败', $logContext);
|
|
|
+ Log::error('ZIMU余额查询失败', $logContext);
|
|
|
+ throw new Exception($ret['msg'] ?? 'ZIMU余额查询失败', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+ $balance = $ret['data']['balance'] ?? null;
|
|
|
+ if ($balance === null || bccomp((string)$balance, ZimuPayService::amount($amount), 2) < 0) {
|
|
|
+ $logContext = $context + [
|
|
|
+ 'amount' => $amount,
|
|
|
+ 'balance' => $balance,
|
|
|
+ 'response' => $ret,
|
|
|
+ ];
|
|
|
+ Log::channel('payment_error')->error('ZIMU商户余额不足', $logContext);
|
|
|
+ Log::error('ZIMU商户余额不足', $logContext);
|
|
|
+ throw new Exception('ZIMU商户余额不足', HttpStatus::CUSTOM_ERROR);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private static function notifyUser($chatId, string $text): void
|
|
|
{
|
|
|
if ((int)User::where('member_id', $chatId)->value('from') !== -1) {
|