|
@@ -10,6 +10,7 @@ use Exception;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
use App\Services\Payment\JdPayService;
|
|
use App\Services\Payment\JdPayService;
|
|
|
|
|
+use App\Services\Payment\NoPayService;
|
|
|
use App\Services\Payment\QianBaoService;
|
|
use App\Services\Payment\QianBaoService;
|
|
|
use App\Services\Payment\SanJinService;
|
|
use App\Services\Payment\SanJinService;
|
|
|
use App\Services\ConfigService;
|
|
use App\Services\ConfigService;
|
|
@@ -239,7 +240,7 @@ class PaymentOrderService extends BaseService
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 没有找到支付通道
|
|
// 没有找到支付通道
|
|
|
- if (empty($channel) && !JdPayService::isChannel($paymentType)) {
|
|
|
|
|
|
|
+ if (empty($channel) && !JdPayService::isChannel($paymentType) && !NoPayService::isRechargeChannel($paymentType)) {
|
|
|
// $text = "发起充值失败 \n";
|
|
// $text = "发起充值失败 \n";
|
|
|
// $text .= "最低充值:" . $min . " \n";
|
|
// $text .= "最低充值:" . $min . " \n";
|
|
|
// $text .= "最高充值:" . $max . " \n";
|
|
// $text .= "最高充值:" . $max . " \n";
|
|
@@ -253,6 +254,53 @@ class PaymentOrderService extends BaseService
|
|
|
return $result;
|
|
return $result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if (NoPayService::isRechargeChannel($paymentType) || NoPayService::isRechargeChannel($channel)) {
|
|
|
|
|
+ $channel = NoPayService::isRechargeChannel($paymentType) ? $paymentType : $channel;
|
|
|
|
|
+ $bankName = $selectedProduct['name'] ?? 'NO快捷充值';
|
|
|
|
|
+ $data = [];
|
|
|
|
|
+ $data['type'] = self::TYPE_PAY;
|
|
|
|
|
+ $data['member_id'] = $memberId;
|
|
|
|
|
+ $data['amount'] = NoPayService::amount($amount);
|
|
|
|
|
+ $data['channel'] = $channel;
|
|
|
|
|
+ $data['fee'] = $amount * $rate;
|
|
|
|
|
+ $data['bank_name'] = $bankName;
|
|
|
|
|
+ $order_no = self::createOrderNo('no' . $data['type'] . '_', $memberId);
|
|
|
|
|
+ $data['order_no'] = $order_no;
|
|
|
|
|
+ $data['callback_url'] = NoPayService::getDepositNotifyUrl();
|
|
|
|
|
+ $data['remark'] = '充值费率:' . $rate;
|
|
|
|
|
+ $data['status'] = self::STATUS_STAY;
|
|
|
|
|
+
|
|
|
|
|
+ $ret = NoPayService::pay($amount, $order_no, (string)$memberId, $channel);
|
|
|
|
|
+ Log::channel('payment')->info('NO支付发起', [
|
|
|
|
|
+ 'order_no' => $order_no,
|
|
|
|
|
+ 'member_id' => $memberId,
|
|
|
|
|
+ 'amount' => $data['amount'],
|
|
|
|
|
+ 'channel' => $channel,
|
|
|
|
|
+ 'response' => $ret,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ if (($ret['code'] ?? -1) == 0) {
|
|
|
|
|
+ $payUrl = $ret['data']['url'] ?? '';
|
|
|
|
|
+ $data['status'] = self::STATUS_PROCESS;
|
|
|
|
|
+ $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'] ?? 'NO支付发起失败';
|
|
|
|
|
+ $result['code'] = 20002;
|
|
|
|
|
+ }
|
|
|
|
|
+ return $result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (JdPayService::isChannel($paymentType) || JdPayService::isChannel($channel)) {
|
|
if (JdPayService::isChannel($paymentType) || JdPayService::isChannel($channel)) {
|
|
|
$channel = JdPayService::CHANNEL;
|
|
$channel = JdPayService::CHANNEL;
|
|
|
$bankName = $selectedProduct['name'] ?? 'JD钱包';
|
|
$bankName = $selectedProduct['name'] ?? 'JD钱包';
|
|
@@ -346,6 +394,35 @@ class PaymentOrderService extends BaseService
|
|
|
*/
|
|
*/
|
|
|
public static function receivePay($params)
|
|
public static function receivePay($params)
|
|
|
{
|
|
{
|
|
|
|
|
+ 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)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!NoPayService::verifyDepositNotify($params)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (bccomp(NoPayService::amount($info->amount), NoPayService::amount($params['amount'] ?? 0), 2) !== 0) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($info->status != self::STATUS_PROCESS) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $processed = self::applyPayCallback(
|
|
|
|
|
+ $info,
|
|
|
|
|
+ NoPayService::amount($info->amount),
|
|
|
|
|
+ (string)$params['state'],
|
|
|
|
|
+ NoPayService::STATE_SUCCESS,
|
|
|
|
|
+ NoPayService::STATE_FAIL,
|
|
|
|
|
+ $params
|
|
|
|
|
+ );
|
|
|
|
|
+ if ($processed && (string)$params['state'] === NoPayService::STATE_SUCCESS) {
|
|
|
|
|
+ self::notifyUser($info->member_id, "✅ 支付成功 \n充值金额:{$info->amount} RMB \n订单号:{$info->order_no} \n您充值的金额已到账,请注意查收!");
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (($params['userCode'] ?? '') === JdPayService::getMerchantId()) {
|
|
if (($params['userCode'] ?? '') === JdPayService::getMerchantId()) {
|
|
|
$info = self::findOne(['order_no' => $params['orderCode'] ?? ''])
|
|
$info = self::findOne(['order_no' => $params['orderCode'] ?? ''])
|
|
|
?: static::$MODEL::where('pay_no', $params['orderCode'] ?? '')->first();
|
|
?: static::$MODEL::where('pay_no', $params['orderCode'] ?? '')->first();
|
|
@@ -548,7 +625,22 @@ class PaymentOrderService extends BaseService
|
|
|
if (!$order) throw new Exception("订单不存在_{$orderId}", HttpStatus::CUSTOM_ERROR);
|
|
if (!$order) throw new Exception("订单不存在_{$orderId}", HttpStatus::CUSTOM_ERROR);
|
|
|
$amount = $order->amount;
|
|
$amount = $order->amount;
|
|
|
$amount = number_format($amount, 2, '.', '');
|
|
$amount = number_format($amount, 2, '.', '');
|
|
|
- if (JdPayService::isChannel($order->channel)) {
|
|
|
|
|
|
|
+ if (NoPayService::isWithdrawChannel($order->channel)) {
|
|
|
|
|
+ $ret = NoPayService::withdraw($amount, $order->order_no, (string)$order->member_id, (string)$order->account, (string)$order->card_no);
|
|
|
|
|
+ Log::channel('payment')->info('NO提现接口调用', [
|
|
|
|
|
+ 'order_id' => $order->id,
|
|
|
|
|
+ 'order_no' => $order->order_no,
|
|
|
|
|
+ 'member_id' => $order->member_id,
|
|
|
|
|
+ 'amount' => $amount,
|
|
|
|
|
+ 'q_account' => $order->card_no,
|
|
|
|
|
+ 'response' => $ret,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ if (($ret['code'] ?? -1) != 0) {
|
|
|
|
|
+ throw new Exception($ret['msg'] ?? 'NO提现失败', 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, [
|
|
self::assertJdBalanceEnough($amount, [
|
|
|
'order_id' => $order->id,
|
|
'order_id' => $order->id,
|
|
|
'order_no' => $order->order_no,
|
|
'order_no' => $order->order_no,
|
|
@@ -655,7 +747,13 @@ class PaymentOrderService extends BaseService
|
|
|
$data['bank_name'] = $bank_name;
|
|
$data['bank_name'] = $bank_name;
|
|
|
$data['account'] = $account;
|
|
$data['account'] = $account;
|
|
|
$data['card_no'] = $card_no;
|
|
$data['card_no'] = $card_no;
|
|
|
- $data['callback_url'] = JdPayService::isChannel($channel) ? JdPayService::getRemitNotifyUrl() : QianBaoService::getNotifyUrl();
|
|
|
|
|
|
|
+ if (NoPayService::isWithdrawChannel($channel)) {
|
|
|
|
|
+ $data['callback_url'] = NoPayService::getWithdrawNotifyUrl();
|
|
|
|
|
+ } elseif (JdPayService::isChannel($channel)) {
|
|
|
|
|
+ $data['callback_url'] = JdPayService::getRemitNotifyUrl();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $data['callback_url'] = QianBaoService::getNotifyUrl();
|
|
|
|
|
+ }
|
|
|
$data['status'] = self::STATUS_STAY;
|
|
$data['status'] = self::STATUS_STAY;
|
|
|
$data['remark'] = '提现费率:0.2%+2';
|
|
$data['remark'] = '提现费率:0.2%+2';
|
|
|
|
|
|
|
@@ -690,7 +788,31 @@ class PaymentOrderService extends BaseService
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 调用三方支付接口(在事务外)
|
|
// 调用三方支付接口(在事务外)
|
|
|
- if (JdPayService::isChannel($channel)) {
|
|
|
|
|
|
|
+ if (NoPayService::isWithdrawChannel($channel)) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ $ret = NoPayService::withdraw($amount, $order_no, (string)$memberId, (string)$account, (string)$card_no);
|
|
|
|
|
+ Log::channel('payment')->info('NO提现接口调用', [
|
|
|
|
|
+ 'order_no' => $order_no,
|
|
|
|
|
+ 'member_id' => $memberId,
|
|
|
|
|
+ 'amount' => $amount,
|
|
|
|
|
+ 'q_account' => $card_no,
|
|
|
|
|
+ 'response' => $ret,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ $success = (($ret['code'] ?? -1) == 0);
|
|
|
|
|
+ $failureMessage = $ret['msg'] ?? 'NO提现失败';
|
|
|
|
|
+ } catch (Exception $e) {
|
|
|
|
|
+ $ret = ['msg' => $e->getMessage()];
|
|
|
|
|
+ $success = false;
|
|
|
|
|
+ $failureMessage = $e->getMessage();
|
|
|
|
|
+ Log::channel('payment_error')->error('NO提现接口异常', [
|
|
|
|
|
+ 'order_no' => $order_no,
|
|
|
|
|
+ 'member_id' => $memberId,
|
|
|
|
|
+ 'amount' => $amount,
|
|
|
|
|
+ 'q_account' => $card_no,
|
|
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+ } elseif (JdPayService::isChannel($channel)) {
|
|
|
try {
|
|
try {
|
|
|
self::assertJdBalanceEnough($amount, [
|
|
self::assertJdBalanceEnough($amount, [
|
|
|
'order_no' => $order_no,
|
|
'order_no' => $order_no,
|
|
@@ -744,7 +866,7 @@ class PaymentOrderService extends BaseService
|
|
|
DB::beginTransaction();
|
|
DB::beginTransaction();
|
|
|
try {
|
|
try {
|
|
|
$info->status = self::STATUS_PROCESS;
|
|
$info->status = self::STATUS_PROCESS;
|
|
|
- if (JdPayService::isChannel($channel)) {
|
|
|
|
|
|
|
+ if (NoPayService::isWithdrawChannel($channel) || JdPayService::isChannel($channel)) {
|
|
|
$info->pay_no = $ret['data']['orderNo'] ?? '';
|
|
$info->pay_no = $ret['data']['orderNo'] ?? '';
|
|
|
$info->pay_data = json_encode($ret, JSON_UNESCAPED_UNICODE);
|
|
$info->pay_data = json_encode($ret, JSON_UNESCAPED_UNICODE);
|
|
|
}
|
|
}
|
|
@@ -811,6 +933,21 @@ class PaymentOrderService extends BaseService
|
|
|
*/
|
|
*/
|
|
|
public static function receiveOrder($params)
|
|
public static function receiveOrder($params)
|
|
|
{
|
|
{
|
|
|
|
|
+ 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)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!NoPayService::verifyWithdrawNotify($params)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (bccomp(NoPayService::amount($info->amount), NoPayService::amount($params['amount'] ?? 0), 2) !== 0) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ self::onSubmitNoPayout($params, $info);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (($params['userCode'] ?? '') === JdPayService::getMerchantId()) {
|
|
if (($params['userCode'] ?? '') === JdPayService::getMerchantId()) {
|
|
|
$info = self::findOne(['order_no' => $params['customerOrderCode'] ?? ''])
|
|
$info = self::findOne(['order_no' => $params['customerOrderCode'] ?? ''])
|
|
|
?: static::$MODEL::where('pay_no', $params['orderCode'] ?? '')->first();
|
|
?: static::$MODEL::where('pay_no', $params['orderCode'] ?? '')->first();
|
|
@@ -915,6 +1052,53 @@ class PaymentOrderService extends BaseService
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ public static function onSubmitNoPayout($params, $info)
|
|
|
|
|
+ {
|
|
|
|
|
+ $notification = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ DB::transaction(function () use ($params, $info, &$notification) {
|
|
|
|
|
+ $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['state'] === NoPayService::STATE_SUCCESS) {
|
|
|
|
|
+ $order->status = self::STATUS_SUCCESS;
|
|
|
|
|
+ $order->save();
|
|
|
|
|
+ $notification = "✅ 提现通知 \n提现平台:{$order->bank_name} \n收款人:{$order->account} \nNO钱包账号:{$order->card_no} \n提现金额:{$order->amount} \n提现成功,金额已到账,请注意查收!";
|
|
|
|
|
+ } elseif ((string)$params['state'] === NoPayService::STATE_FAIL) {
|
|
|
|
|
+ $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, NoPayService::amount($order->amount), 10);
|
|
|
|
|
+ $wallet->available_balance = $availableBalance;
|
|
|
|
|
+ $wallet->save();
|
|
|
|
|
+
|
|
|
|
|
+ BalanceLogService::addLog($order->member_id, $order->amount, $balance, $availableBalance, '三方提现', $order->id, '提现失败退款');
|
|
|
|
|
+ $notification = "❌ 提现通知 \n提现平台:{$order->bank_name} \n收款人:{$order->account} \nNO钱包账号:{$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('NO提现回调处理异常', [
|
|
|
|
|
+ 'order_id' => $info->id,
|
|
|
|
|
+ 'params' => $params,
|
|
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public static function onSubmitPayout($params, $info)
|
|
public static function onSubmitPayout($params, $info)
|
|
|
{
|
|
{
|
|
|
$memberId = $info->member_id;
|
|
$memberId = $info->member_id;
|
|
@@ -983,6 +1167,41 @@ class PaymentOrderService extends BaseService
|
|
|
$msg['code'] = self::NOT;
|
|
$msg['code'] = self::NOT;
|
|
|
$info = self::findOne(['id' => $id]);
|
|
$info = self::findOne(['id' => $id]);
|
|
|
if ($info && $info->status == self::STATUS_PROCESS) {
|
|
if ($info && $info->status == self::STATUS_PROCESS) {
|
|
|
|
|
+ if (NoPayService::isRechargeChannel($info->channel)) {
|
|
|
|
|
+ $ret = NoPayService::queryPayOrder($info->order_no, (string)$info->member_id);
|
|
|
|
|
+ Log::channel('payment')->info('NO支付查询订单', $ret);
|
|
|
|
|
+ if (($ret['code'] ?? -1) == 0) {
|
|
|
|
|
+ $item = $ret['data'] ?? [];
|
|
|
|
|
+ if ((string)($item['state'] ?? '') === NoPayService::STATE_SUCCESS) {
|
|
|
|
|
+ $processed = self::applyPayCallback(
|
|
|
|
|
+ $info,
|
|
|
|
|
+ NoPayService::amount($info->amount),
|
|
|
|
|
+ NoPayService::STATE_SUCCESS,
|
|
|
|
|
+ NoPayService::STATE_SUCCESS,
|
|
|
|
|
+ NoPayService::STATE_FAIL,
|
|
|
|
|
+ $ret
|
|
|
|
|
+ );
|
|
|
|
|
+ $msg['code'] = $processed ? self::YES : self::NOT;
|
|
|
|
|
+ $msg['msg'] = $processed ? '支付成功' : '订单已处理';
|
|
|
|
|
+ } elseif ((string)($item['state'] ?? '') === NoPayService::STATE_FAIL) {
|
|
|
|
|
+ self::applyPayCallback(
|
|
|
|
|
+ $info,
|
|
|
|
|
+ NoPayService::amount($info->amount),
|
|
|
|
|
+ NoPayService::STATE_FAIL,
|
|
|
|
|
+ NoPayService::STATE_SUCCESS,
|
|
|
|
|
+ NoPayService::STATE_FAIL,
|
|
|
|
|
+ $ret
|
|
|
|
|
+ );
|
|
|
|
|
+ $msg['msg'] = '支付失败';
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $msg['msg'] = '支付中';
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $msg['msg'] = '查询失败:' . ($ret['msg'] ?? '');
|
|
|
|
|
+ }
|
|
|
|
|
+ return $msg;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (JdPayService::isChannel($info->channel)) {
|
|
if (JdPayService::isChannel($info->channel)) {
|
|
|
$ret = JdPayService::queryPayOrder($info->pay_no ?? '', $info->order_no);
|
|
$ret = JdPayService::queryPayOrder($info->pay_no ?? '', $info->order_no);
|
|
|
Log::channel('payment')->info('JD支付查询订单', $ret);
|
|
Log::channel('payment')->info('JD支付查询订单', $ret);
|