|
@@ -144,81 +144,149 @@ class PaymentOrderService extends BaseService
|
|
|
return $msg;
|
|
return $msg;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public static function createPayout($memberId ,$amount ,$channel ,$bank_name ,$account ,$card_no)
|
|
|
|
|
|
|
+ public static function createPayout($memberId, $amount, $channel, $bank_name, $account, $card_no)
|
|
|
{
|
|
{
|
|
|
-
|
|
|
|
|
$default_amount = $amount;
|
|
$default_amount = $amount;
|
|
|
$result = [];
|
|
$result = [];
|
|
|
$result['chat_id'] = $memberId;
|
|
$result['chat_id'] = $memberId;
|
|
|
|
|
|
|
|
- $wallet = WalletService::findOne(['member_id' => $memberId]);
|
|
|
|
|
- $balance = $wallet->available_balance;
|
|
|
|
|
- if (bccomp($balance, $amount, 2) < 0) {
|
|
|
|
|
- $result['text'] = '您的钱包余额不足!';
|
|
|
|
|
- return $result;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // 在调用三方支付前开始事务
|
|
|
|
|
+ DB::beginTransaction();
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ $wallet = WalletService::findOne(['member_id' => $memberId]);
|
|
|
|
|
+ if (!$wallet) {
|
|
|
|
|
+ $result['text'] = '钱包不存在!';
|
|
|
|
|
+ return $result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $balance = $wallet->available_balance;
|
|
|
|
|
+ if (bccomp($balance, $amount, 2) < 0) {
|
|
|
|
|
+ $result['text'] = '您的钱包余额不足!';
|
|
|
|
|
+ return $result;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- $available_balance = bcsub($balance, $amount, 10);
|
|
|
|
|
-
|
|
|
|
|
- $data = [];
|
|
|
|
|
- $data['type'] = self::TYPE_PAYOUT;
|
|
|
|
|
- $order_no = self::createOrderNo('sj'.$data['type'].'_',$memberId);
|
|
|
|
|
- $data['order_no'] = $order_no;
|
|
|
|
|
- $data['member_id'] = $memberId;
|
|
|
|
|
- $amount = number_format($amount, 2, '.', '');
|
|
|
|
|
- $data['amount'] = $amount;
|
|
|
|
|
- $data['channel'] = $channel;
|
|
|
|
|
- $data['bank_name'] = $bank_name;
|
|
|
|
|
- $data['account'] = $account;
|
|
|
|
|
- $data['card_no'] = $card_no;
|
|
|
|
|
- $data['callback_url'] = SanJinService::getNotifyUrl();
|
|
|
|
|
- $data['status'] = self::STATUS_STAY;
|
|
|
|
|
|
|
+ $available_balance = bcsub($balance, $amount, 10);
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
+ $data = [];
|
|
|
|
|
+ $data['type'] = self::TYPE_PAYOUT;
|
|
|
|
|
+ $order_no = self::createOrderNo('sj'.$data['type'].'_', $memberId);
|
|
|
|
|
+ $data['order_no'] = $order_no;
|
|
|
|
|
+ $data['member_id'] = $memberId;
|
|
|
|
|
+ $amount = number_format($amount, 2, '.', '');
|
|
|
|
|
+ $data['amount'] = $amount;
|
|
|
|
|
+ $data['channel'] = $channel;
|
|
|
|
|
+ $data['bank_name'] = $bank_name;
|
|
|
|
|
+ $data['account'] = $account;
|
|
|
|
|
+ $data['card_no'] = $card_no;
|
|
|
|
|
+ $data['callback_url'] = SanJinService::getNotifyUrl();
|
|
|
|
|
+ $data['status'] = self::STATUS_STAY;
|
|
|
|
|
+
|
|
|
|
|
+ // 先预扣款(锁定资金)
|
|
|
|
|
+ $wallet->available_balance = $available_balance;
|
|
|
|
|
+ if (!$wallet->save()) {
|
|
|
|
|
+ DB::rollBack();
|
|
|
|
|
+ $result['text'] = '钱包更新失败!';
|
|
|
|
|
+ return $result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 创建待处理状态的提现记录
|
|
|
|
|
+ $info = self::model()::create($data);
|
|
|
|
|
+ $id = $info->id;
|
|
|
|
|
|
|
|
|
|
+ // 记录余额变动日志
|
|
|
|
|
+ BalanceLogService::addLog(
|
|
|
|
|
+ $memberId,
|
|
|
|
|
+ $default_amount,
|
|
|
|
|
+ $balance,
|
|
|
|
|
+ $available_balance,
|
|
|
|
|
+ '三方提现',
|
|
|
|
|
+ $id,
|
|
|
|
|
+ '钱宝提现'
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
- $ret = SanJinService::payout($amount,$order_no,$bank_name,$account,$card_no);
|
|
|
|
|
|
|
+ // 提交事务,确保预扣款成功
|
|
|
|
|
+ DB::commit();
|
|
|
|
|
+
|
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
|
|
+ // 预扣款失败,回滚事务
|
|
|
|
|
+ DB::rollBack();
|
|
|
|
|
+ $result['text'] = '系统繁忙,请稍后重试!';
|
|
|
|
|
+ Log::error('提现预扣款失败: ' . $e->getMessage(), [
|
|
|
|
|
+ 'member_id' => $memberId,
|
|
|
|
|
+ 'amount' => $amount
|
|
|
|
|
+ ]);
|
|
|
|
|
+ return $result;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if($ret['code'] == 200){
|
|
|
|
|
|
|
+ // 调用三方支付接口(在事务外)
|
|
|
|
|
+ $ret = SanJinService::payout($amount, $order_no, $bank_name, $account, $card_no);
|
|
|
|
|
|
|
|
|
|
+ if ($ret['code'] == 200) {
|
|
|
|
|
+ // 更新提现记录状态为处理中
|
|
|
DB::beginTransaction();
|
|
DB::beginTransaction();
|
|
|
try {
|
|
try {
|
|
|
- $wallet->available_balance = $available_balance;
|
|
|
|
|
- $wallet->save();
|
|
|
|
|
|
|
+ $info->status = self::STATUS_PROCESS;
|
|
|
|
|
+ $info->save();
|
|
|
|
|
+ DB::commit();
|
|
|
|
|
|
|
|
- $data['status'] = self::STATUS_PROCESS;
|
|
|
|
|
- $info = self::model()::create($data);
|
|
|
|
|
- $id = $info->id;
|
|
|
|
|
|
|
+ $text = "✅ 提现申请已提交!\n\n";
|
|
|
|
|
+ $text .= "钱包余额:{$available_balance} RMB\n";
|
|
|
|
|
+ $text .= "提现金额:{$default_amount} RMB\n";
|
|
|
|
|
+ $text .= "⌛️请等待系统处理, 到账时间可能需要几分钟!\n";
|
|
|
|
|
|
|
|
|
|
+ $result['text'] = $text;
|
|
|
|
|
+
|
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
|
|
+ DB::rollBack();
|
|
|
|
|
+ // 状态更新失败,但资金已扣款且三方支付已成功
|
|
|
|
|
+ // 这里可以记录告警,需要人工干预
|
|
|
|
|
+ Log::error('提现状态更新失败: ' . $e->getMessage(), [
|
|
|
|
|
+ 'member_id' => $memberId,
|
|
|
|
|
+ 'order_no' => $order_no
|
|
|
|
|
+ ]);
|
|
|
|
|
+ $result['text'] = '提现申请已提交,系统处理中...';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 三方支付失败,需要回滚之前的预扣款
|
|
|
|
|
+ DB::beginTransaction();
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 恢复钱包余额
|
|
|
|
|
+ $wallet->available_balance = $balance;
|
|
|
|
|
+ $wallet->save();
|
|
|
|
|
+
|
|
|
|
|
+ // 更新提现记录状态为失败
|
|
|
|
|
+ $info->status = self::STATUS_FAIL;
|
|
|
|
|
+ $info->remark = $ret['msg'];
|
|
|
|
|
+ $info->save();
|
|
|
|
|
+
|
|
|
|
|
+ // 记录退款日志
|
|
|
BalanceLogService::addLog(
|
|
BalanceLogService::addLog(
|
|
|
$memberId,
|
|
$memberId,
|
|
|
$default_amount,
|
|
$default_amount,
|
|
|
- $balance,
|
|
|
|
|
$available_balance,
|
|
$available_balance,
|
|
|
|
|
+ $balance,
|
|
|
'三方提现',
|
|
'三方提现',
|
|
|
$id,
|
|
$id,
|
|
|
- '钱宝提现'
|
|
|
|
|
|
|
+ '提现失败退款'
|
|
|
);
|
|
);
|
|
|
-
|
|
|
|
|
- $text = "✅ 提现申请已提交!\n\n";
|
|
|
|
|
- $text .= "钱包余额:{$available_balance} RMB\n";
|
|
|
|
|
- $text .= "提现金额:{$default_amount} RMB\n";
|
|
|
|
|
- $text .= "⌛️请等待系统处理, 到账时间可能需要几分钟!\n";
|
|
|
|
|
-
|
|
|
|
|
- $result['text'] = $text;
|
|
|
|
|
|
|
+
|
|
|
DB::commit();
|
|
DB::commit();
|
|
|
- }catch (\Exception $e) {
|
|
|
|
|
|
|
+ $result['text'] = $ret['msg'];
|
|
|
|
|
+
|
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
DB::rollBack();
|
|
DB::rollBack();
|
|
|
- $result['text'] = $e->getMessage();
|
|
|
|
|
- return $result;
|
|
|
|
|
- // 记录错误日志或抛出异常
|
|
|
|
|
|
|
+ // 回滚失败,需要记录告警,人工干预
|
|
|
|
|
+ Log::error('提现失败回滚异常: ' . $e->getMessage(), [
|
|
|
|
|
+ 'member_id' => $memberId,
|
|
|
|
|
+ 'order_no' => $order_no,
|
|
|
|
|
+ 'amount' => $amount
|
|
|
|
|
+ ]);
|
|
|
|
|
+ $result['text'] = '提现失败,请联系客服处理退款!';
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- }else{
|
|
|
|
|
- $result['text'] = $ret['msg'];
|
|
|
|
|
- return $result;
|
|
|
|
|
-
|
|
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
return $result;
|
|
return $result;
|
|
|
}
|
|
}
|
|
|
|
|
|