You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
payment/app/Service/PaymentService.php

762 lines
31 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Service;
use App\Exception\ApiException;
use App\Exception\BasicException;
use App\Exception\BusinessException;
use App\Helper\Baofu\Baofu;
use App\Helper\StringHelper;
use App\Model\App;
use App\Model\BankCard;
use App\Model\Order;
use App\Model\OrderSplitInfo;
use App\Model\Refund;
use App\Model\RefundSplitInfo;
use App\Model\User;
use App\Model\Withdraw;
use App\Model\WithdrawApply;
class PaymentService extends AbstractService
{
public function generateMemberId($appKey, $cardNo) {
return md5($appKey . '-' . $cardNo);
}
public function generateMemberIdNew($appId, $outMemberId) {
return md5($appId . '-' . $outMemberId);
}
public function payment(array $data, App $app, string $token) {
$user = User::where('app_id', $app->app_id)->where('user_id', $data['userId'])->first();
if (empty($user)) {
throw new BusinessException('用户不存在');
}
$order = Order::where('app_id', $app->app_id)->where('out_order_no', $data['outOrderNo'])->first();
if ($order) {
throw new BusinessException('订单号重复');
}
$data['payType'] = $data['payType'] ?? 'CARD';
$payMethod = $data['payMethod'] ?? 'paymentSplit';
[$order, $orderSplitInfos] = $this->createOrder($app, $data, $user, $payMethod);
$splitInfoList = $this->buildSplitInfoList($orderSplitInfos);
if ($payMethod == 'paymentSplit') {
return $this->paymentSplit($order, $user, $splitInfoList, $token);
} elseif($payMethod == 'unionPay') {
return $this->unionPay($order, $user, $splitInfoList, $token);
} else {
throw new BusinessException('payMethod不支持');
}
}
public function transferPay(array $data, App $app, string $token)
{
$user = User::where('app_id', $app->app_id)->where('user_id', $data['userId'])->first();
if (empty($user)) {
throw new BusinessException('用户不存在');
}
$order = Order::where('app_id', $app->app_id)->where('out_order_no', $data['outOrderNo'])->first();
if ($order) {
throw new BusinessException('订单号重复');
}
[$order, $orderSplitInfos] = $this->createOrder($app, $data, $user, 'transferSplitPay');
$splitInfoList = $this->buildSplitInfoList($orderSplitInfos);
return $this->transferSplitPay($order, $user, $splitInfoList, $token);
}
private function buildSplitInfoList($orderSplitInfos) {
$splitInfoList = [];
foreach ($orderSplitInfos as $splitInfo) {
$splitInfoList[] = [
'subOutOrderNo' => $splitInfo['sub_order_no'],
'contractNo' => $splitInfo['contract_no'],
'customerType' => $splitInfo['split_user_type'],
'splitAmount' => $splitInfo['split_amount'],
'sellerFlag' => $splitInfo['seller_flag'],
];
}
return $splitInfoList;
}
private function paymentSplit(Order $order, User $user, array $splitInfoList, string $token)
{
try {
$baofu = new Baofu();
$url = $baofu->paymentSplit([
'loginNo' => $user->member_id,
'outOrderNo' => $order->order_no,
'amount' => $order->amount,
'paidType' => $order->pay_type,
'agreementNo' => $order->agreement_no,
'pwdPayExpTime' => $order->expires_in,
'splitInfoList' => $splitInfoList,
], $token);
$order->status = 'APPLY_SUCCESS';
$order->applied_at = date('Y-m-d H:i:s');
$order->pay_url = $url;
$order->save();
return ['url' => $url];
} catch (ApiException $e) {
$order->status = 'APPLY_FAILED';
$order->applied_at = date('Y-m-d H:i:s');
$order->error_code = $e->getErrorCode();
$order->error_message = $e->getMessage();
$order->save();
throw $e;
}
}
private function transferSplitPay(Order $order, User $user, array $splitInfoList, string $token)
{
try {
$baofu = new Baofu();
$result = $baofu->transferSplitPay([
'loginNo' => $user->member_id,
'outOrderNo' => $order->order_no,
'goodsName' => $order->goods_name,
'amount' => $order->amount,
'agreementNo' => $order->agreement_no,
'expireDate' => date('YmdHis', time() + $order->expires_in),
'validDate' => date('Ymd', strtotime($order->valid_date)),
'splitInfoList' => $splitInfoList,
'marketInfo' => $order->market_info,
], $token);
$order->status = 'APPLY_SUCCESS';
$order->applied_at = date('Y-m-d H:i:s');
$order->acs_no = $result['acsNo'];
$order->save();
return $result['acsNo'];
} catch (ApiException $e) {
$order->status = 'APPLY_FAILED';
$order->applied_at = date('Y-m-d H:i:s');
$order->error_code = $e->getErrorCode();
$order->error_message = $e->getMessage();
$order->save();
throw $e;
}
}
private function unionPay(Order $order, User $user, array $splitInfoList, string $token)
{
// ASSURE_SHARE
// ASSURE_PAYMENT
// ASSURE_PORTFOLIO_PAY
// PAYMENT_SPLIT
try {
$baofu = new Baofu();
$result = $baofu->payment([
'loginNo' => $user->member_id,
'outOrderNo' => $order->order_no,
'goodsName' => $order->goods_name,
'amount' => $order->amount,
'paidType' => $order->pay_type,
'agreementNo' => $order->agreement_no,
'expireDate' => date('YmdHis', time() + $order->expires_in),
'validDate' => date('Ymd', $order->valid_date ? strtotime($order->valid_date) : time()),
'splitInfoList' => $splitInfoList,
'chanalId' => $order->channel_id,
'appId' => $order->channel_app_id,
'callType' => 'PAYMENT_SPLIT',
], $token);
$order->status = 'APPLY_SUCCESS';
$order->applied_at = date('Y-m-d H:i:s');
$order->acs_no = $result['body'] ?? '';
$order->save();
return $result;
} catch (ApiException $e) {
$order->status = 'APPLY_FAILED';
$order->applied_at = date('Y-m-d H:i:s');
$order->error_code = $e->getErrorCode();
$order->error_message = $e->getMessage();
$order->save();
throw $e;
}
}
public function createOrder(App $app, array $params, User $user, string $payMethod) {
if ($params['amount'] < 10) {
throw new BusinessException('金额不能小于10');
}
$bankCard = BankCard::where('app_id', $app->app_id)->where('user_id', $user->user_id)->where('agreement_no', $params['agreementNo'])->first();
if (!$bankCard) {
throw new BusinessException('银行卡不存在');
}
$expiresIn = $params['expiresIn'] ?? 10 * 60;
$order = new Order();
$order->app_id = $app->app_id;
$order->user_id = $user->user_id;
$order->member_id = $user->member_id;
$order->order_no = StringHelper::generateOrderNo(StringHelper::ORDER_NO_TYPE_PAY);
$order->out_order_no = $params['outOrderNo'];
$order->amount = $params['amount'];
$order->goods_name = $params['goodsName'] ?? '';
$order->notify_url = $params['notifyUrl'];
$order->return_url = $params['returnUrl'] ?? '';
$order->agreement_no = $params['agreementNo'] ?? '';
$order->status = 'PREPARE';
$order->pay_mode = 'BAOFU';
$order->channel_id = $params['channelId'] ?? '';
$order->channel_app_id = $params['appId'] ?? '';
$order->pay_channel = 'BAOFU';
$order->pay_method = $payMethod;
$order->pay_type = $params['payType'] ?? '';
$order->valid_date = $params['validDate'] ?? null;
$order->expires_in = $expiresIn;
$order->expired_at = date('Y-m-d H:i:s', time() + $expiresIn);
$order->market_info = $params['marketInfo'] ?? [];
$order->org_split_info_list = $params['splitInfoList'];
$order->remark = $params['remark'] ?? '';
$order->last_card_no = $bankCard->last_card_no;
$order->card_user_name = $bankCard->card_user_name;
$order->bank_mobile = $bankCard->bank_mobile;
$order->bank_name = $bankCard->bank_name;
$order->bank_code = $bankCard->bank_code;
$order->card_type = $bankCard->card_type;
$order->cnaps_code = $bankCard->cnaps_code;
$order->is_account_pay = isset($params['isAccountPay']) && $params['isAccountPay'] ? 1 :0;
$order->save();
$platformAccount = User::getPlatformAccount($params['isAccountPay']);
$feeRate = 0.007;
if ($params['isAccountPay']) {
$feeRate = 0.0023;
}
$fee = $platformAccount ? floor($order->amount * $feeRate) : 0;
if ($fee <= 0) {
$fee = 1;
}
$orderSplitInfos = [];
$splitUserIds = array_column($params['splitInfoList'], 'splitUserId');
$users = User::where('app_id', $app->app_id)->whereIn('user_id', $splitUserIds)->get()->keyBy('user_id');
foreach ($params['splitInfoList'] as $splitInfo) {
$splitUser = $users[$splitInfo['splitUserId']] ?? null;
if (empty($splitUser)) {
throw new BusinessException('分账用户不存在');
}
$splitAmount = $splitInfo['sellerFlag'] == 1 ? ($splitInfo['splitAmount'] - $fee): $splitInfo['splitAmount'];
$orderSplitInfos[] = [
'app_id' => $app->app_id,
'user_id' => $user->user_id,
'member_id' => $user->member_id,
'split_member_id' => $splitUser->member_id,
'split_user_id' => $splitInfo['splitUserId'],
'split_user_type' => $splitUser->user_type,
'order_no' => $order->order_no,
'out_order_no' => $order->out_order_no,
'sub_order_no' => StringHelper::generateOrderNo(StringHelper::ORDER_NO_TYPE_PAY_SPLIT),
'sub_out_order_no' => $splitInfo['subOutOrderNo'],
'split_amount' => $splitAmount,
'contract_no' => $splitUser->contract_no,
'seller_flag' => $splitInfo['sellerFlag'],
];
}
if ($fee) {
$feeSubOrderNo = StringHelper::generateOrderNo(StringHelper::ORDER_NO_TYPE_PAY_SPLIT);
$orderSplitInfos[] = [
'app_id' => $app->app_id,
'user_id' => $user->user_id,
'member_id' => $user->member_id,
'split_member_id' => $platformAccount->member_id,
'split_user_id' => $platformAccount->user_id,
'split_user_type' => $platformAccount->user_type,
'order_no' => $order->order_no,
'out_order_no' => $order->out_order_no,
'sub_order_no' => $feeSubOrderNo,
'sub_out_order_no' => $feeSubOrderNo,
'split_amount' => $fee,
'contract_no' => $platformAccount->contract_no,
'seller_flag' => 0,
];
}
if ($params['isAccountPay']) {
$feeSubOrderNo = StringHelper::generateOrderNo(StringHelper::ORDER_NO_TYPE_PAY_SPLIT);
$mainAccount = User::where('user_id', 'ACT_5')->first();
$orderSplitInfos[] = [
'app_id' => $app->app_id,
'user_id' => $user->user_id,
'member_id' => $user->member_id,
'split_member_id' => $mainAccount->member_id,
'split_user_id' => $mainAccount->user_id,
'split_user_type' => $mainAccount->user_type == 'MERCHANT' ? 'B_ACCOUNT' : $mainAccount->user_type,
'order_no' => $order->order_no,
'out_order_no' => $order->out_order_no,
'sub_order_no' => $feeSubOrderNo,
'sub_out_order_no' => $feeSubOrderNo,
'split_amount' => $order->amount - $fee,
'contract_no' => $mainAccount->contract_no,
'seller_flag' => 0,
];
}
OrderSplitInfo::insert($orderSplitInfos);
return [$order, $orderSplitInfos];
}
public function updateOrder($params, array $statusList = null) {
$order = Order::where('order_no', $params['order_no'])->first();
if (empty($order)) {
return null;
}
if ($statusList && !in_array($order->status, $statusList)) {
return null;
}
$order->third_order_no = $params['third_order_no'];
$order->status = $params['status'];
$order->finished_at = date('Y-m-d H:i:s', strtotime($params['finished_at']));
$order->error_message = $params['error_message'] ?? '';
$order->transaction_id = $params['transaction_id'] ?? '';
$order->out_transaction_id = $params['out_transaction_id'] ?? '';
$order->save();
return $order;
}
public function refundApply(array $data, App $app) {
$user = User::where('app_id', $app->app_id)->where('user_id', $data['userId'])->first();
if (!$user) {
throw new BusinessException('用户不存在');
}
$order = Order::where('app_id', $app->app_id)->where('out_order_no', $data['outOrderNo'])->first();
if (empty($order)) {
throw new BusinessException('订单号不存在');
}
if ($order->status != 'SUCCESS') {
throw new BusinessException('该订单状态不能发起退款');
}
$refund = Refund::where('app_id', $app->app_id)->where('out_refund_no', $data['outRefundNo'])->first();
if ($refund) {
throw new BusinessException('该退款单已经存在');
}
$refund = new Refund();
$refund->app_id = $app->app_id;
$refund->user_id = $user->user_id;
$refund->member_id = $user->member_id;
$refund->order_no = $order->order_no;
$refund->out_order_no = $order->out_order_no;
$refund->refund_no = StringHelper::generateOrderNo(StringHelper::ORDER_NO_TYPE_REFUND);
$refund->out_refund_no = $data['outRefundNo'];
$refund->refund_amount = $data['refundAmount'];
$refund->refund_reason = $data['refundReason'];
$refund->notify_url = $data['notifyUrl'] ?? '';
$refund->org_refund_split_info_list = $data['refundSplitInfoList'] ?? [];
$refund->remark = $data['remark'] ?? '';
$refund->applied_at = date('Y-m-d H:i:s');
$refundSplitInfoList = [];
$refundSplitInfos = [];
foreach ($order->orderSplitInfos as $splitInfo) {
$refundSplitInfoList[] = [
'orgSubOutOrderNo' => $splitInfo->sub_order_no,
'refundAmount' => (string)$splitInfo->split_amount,
];
$refundSplitInfos[$splitInfo->sub_order_no] = [
'app_id' => $splitInfo->user_id,
'user_id' => $splitInfo->user_id,
'member_id' => $splitInfo->member_id,
'user_id' => $splitInfo->user_id,
'split_member_id' => $splitInfo->split_member_id,
'split_user_id' => $splitInfo->split_user_id,
'refund_no' => $refund->refund_no,
'out_refund_no' => $refund->out_refund_no,
'order_no' => $splitInfo->order_no,
'out_order_no' => $splitInfo->out_order_no,
'sub_order_no' => $splitInfo->sub_order_no,
'sub_out_order_no' => $splitInfo->sub_out_order_no,
'refund_amount' => $splitInfo->split_amount,
'status' => Refund::STATUS_PREPARE,
'message' => '',
];
}
try {
$baofu = new Baofu();
$result = $baofu->profitShareRefundApply([
'loginNo' => $user->member_id,
'refundTradeId' => $refund->refund_no,
'refundTradeType' => 'REFUND_APPLY',
'orgTradeId' => $refund->order_no,
'refundAmount' => $refund->refund_amount,
'refundReason' => $refund->refund_reason,
'refundSplitInfoList' => $refundSplitInfoList,
]);
$refund->status = 'APPLY_SUCCESS';
$refund->real_refund_amount = $result['refundAmount'];
foreach ($result['refundSplitResultList'] as $refundSplitResult) {
$subOrderNo = $refundSplitResult['orgSubOutOrderNo'];
$refundSplitInfos[$subOrderNo]['status'] = Refund::getStatusByShortStatus($refundSplitResult['status']);
$refundSplitInfos[$subOrderNo]['message'] = $refundSplitResult['message'] ?: '';
}
RefundSplitInfo::insert($refundSplitInfos);
$refund->save();
} catch (BasicException $e) {
$refund->status = 'APPLY_FAILED';
$refund->error_code = $e->getCode();
$refund->error_message = $e->getMessage();
foreach ($refundSplitInfos as $key => $refundSplitInfo) {
$refundSplitInfos[$key]['status'] = 'APPLY_FAILED';
$refundSplitInfos[$key]['message'] = $e->getMessage();
}
RefundSplitInfo::insert($refundSplitInfos);
$refund->save();
throw $e;
}
}
public function refundConfirm(array $data, App $app, string $token)
{
$user = User::where('app_id', $app->app_id)->where('user_id', $data['userId'])->first();
if (!$user) {
throw new BusinessException('用户不存在');
}
$order = Order::where('app_id', $app->app_id)->where('out_order_no', $data['outOrderNo'])->first();
if (empty($order)) {
throw new BusinessException('订单号不存在');
}
if ($order->status != 'SUCCESS') {
throw new BusinessException('该订单状态不能发起退款');
}
$refund = Refund::where('app_id', $app->app_id)->where('out_refund_no', $data['outRefundNo'])->first();
if (empty($refund)) {
throw new BusinessException('退款申请不存在');
}
if ($refund->status != Refund::STATUS_APPLY_SUCCESS || $refund->status != Refund::STATUS_CONFIRM_FAILED) {
throw new BusinessException('该退款单未申请成功');
}
try {
$baofu = new Baofu();
$result = $baofu->profitShareRefundConfirm([
'loginNo' => $user->member_id,
'refundTradeId' => $refund->refund_no,
'refundTradeType' => 'REFUND_APPLY',
'orgTradeId' => $refund->order_no,
'refundAmount' => $refund->refund_amount,
'notifyUrl' => $data['notifyUrl'],
], $token);
$refund->status = Refund::getStatusByShortStatus($result['refundStatus']);
$refund->third_refund_no = $result['refundOrderId'];
$refund->save();
} catch (ApiException $e) {
$refund->status = Refund::STATUS_CONFIRM_FAILED;
$refund->error_code = $e->getCode();
$refund->error_message = $e->getMessage();
$refund->save();
throw $e;
}
}
public function updateRefund($params)
{
$refund = Refund::where('refund_no', $params['refund_no'])->where('status', 'APPLY_FAILED')->first();
if (empty($refund)) {
return null;
}
$refund->third_refund_no = $params['third_refund_no'];
$refund->status = Refund::getStatusByShortStatus($params['status']);
$refund->refund_success_at = date('Y-m-d H:i:s', strtotime($params['refund_success_at']));
$refund->error_message = $params['error_message'];
$refund->save();
return $refund;
}
public function confirmPay(array $data, App $app, string $token)
{
$user = User::where('app_id', $app->app_id)->where('user_id', $data['userId'])->first();
if (empty($user)) {
throw new BusinessException('用户不存在');
}
$order = Order::where('app_id', $app->app_id)->where('out_order_no', $data['oldOutOrderNo'])->first();
if (empty($order)) {
throw new BusinessException('订单不存在');
}
if ($order->status != Order::STATUS_SUCCESS) {
throw new BusinessException('订单状态异常');
}
$confirmSplitInfoList = [];
foreach ($order->orderSplitInfos as $orderSplitInfo) {
$confirmSplitInfoList[] = [
'oldSubOutOrderNo' => $orderSplitInfo->sub_order_no,
'splitAmount' => $orderSplitInfo->split_amount,
];
}
try {
$baofu = new Baofu();
$result = $baofu->confirmAssurePortfolioPay([
'loginNo' => $user->member_id,
'oldOutOrderNo' => $order->order_no,
'assureConfirmSplitInfoList' => $confirmSplitInfoList,
'outOrderNo' => StringHelper::generateOrderNo(StringHelper::ORDER_NO_TYPE_CONFIRM_PAY),
'amount' => $data['amount'],
], $token);
$order->status = 'CONFIRM_SUCCESS';
$order->save();
return $result;
} catch (ApiException $e) {
$order->status = 'CONFIRM_FAILED';
$order->error_code = $e->getCode();
$order->error_message = $e->getMessage();
$order->save();
throw $e;
}
}
public function queryOrder(array $data, App $app)
{
$type = $data['type'] ?? 'PAYMENT';
$orderNo = null;
$memberId = null;
if ($type == 'WITHDRAW') {
$withdraw = Withdraw::where('app_id', $app->app_id)->where('out_withdraw_no', $data['outOrderNo'])->first();
if (empty($withdraw)) {
throw new BusinessException('提现记录不存在');
}
$memberId = $withdraw->member_id;
$orderNo = $withdraw->withdraw_no;
} elseif ($type == 'PAYMENT') {
$order = Order::where('app_id', $app->app_id)->where('out_order_no', $data['outOrderNo'])->first();
if (empty($order)) {
throw new BusinessException('订单不存在');
}
$memberId = $order->member_id;
$orderNo = $order->order_no;
} else {
throw new BusinessException('查询类型错误');
}
$baofu = new Baofu();
$result = $baofu->queryOrder([
'loginNo' => $memberId,
'tradeId' => $orderNo,
]);
$info = [
'member_id' => $memberId,
'order_no' => $orderNo,
'third_order_no' => $result['requestNo'] ?? '',
'status' => $result['status'],
'amount' => $result['amount'],
'fee' => $result['feeAmt'] ?? 0,
'fee_acc' => $result['feeAcc'] ?? 0,
'finished_at' => $result['finishDate'],
'error_message' => $result['errorMsg'] ?? '',
'transaction_id' => $result['transactionId'] ?? '',
'out_transaction_id' => $result['outTransactionId'] ?? '',
];
if ($result['tradeType'] == 'WITHDRAW') {
return $this->updateWithdraw($info);
} elseif (in_array($result['tradeType'], ['ASSURE_RECHARGE', 'PAYMENT_SPLIT_API', 'ASSURE_PORTFOLIO_PAY'])) {
return $this->updateOrder($info);
} else {
return true;
}
}
public function withdrawApply(array $data, App $app) {
$user = User::where('app_id', $app->app_id)->where('user_id', $data['userId'])->first();
if (empty($user)) {
throw new BusinessException('用户不存在');
}
$apply = new WithdrawApply();
$apply->app_id = $app->app_id;
$apply->user_id = $user->user_id;
$apply->member_id = $user->member_id;
$apply->account_name = $data['accountName'];
$apply->batch_num = StringHelper::generateOrderNo(StringHelper::ORDER_NO_TYPE_WITHDRAW_APPLY_BATCH_NUM);
$apply->apply_no = StringHelper::generateOrderNo(StringHelper::ORDER_NO_TYPE_WITHDRAW_APPLY_NO);
$apply->out_apply_no = $data['outApplyNo'];
$apply->notify_url = $data['notifyUrl'];
$apply->amount = $data['amount'];
$apply->status = 'PREPARE';
$apply->summary = $data['summary'] ?? '转账';
$apply->applied_at = date('Y-m-d H:i:s');
$apply->save();
$baofu = new Baofu();
$data = [
'transContent' => [
[
'transNo' => $apply->apply_no,
'transMoney' => round($apply->amount / 100, 2),
'transType' => 2,
'transAccNo' => $user->contract_no,
'transAccName' => $apply->account_name,
'transSummary' => $apply->summary,
]
]
];
try {
$result = $baofu->transferWithdraw($data);
$apply->third_apply_no = $result[0]['transOrderId'];
$apply->third_batch_num = $result[0]['transBatchId'];
$apply->status = 'APPLY_SUCCESS';
$apply->save();
return ['batchNum' => $apply->batch_num, 'applyNo' => $apply->apply_no];
} catch (ApiException $e) {
$apply->status = 'APPLY_FAILED';
$apply->error_code = $e->getCode();
$apply->error_message = $e->getMessage();
$apply->save();
throw $e;
}
}
public function withdrawApplyQuery(array $data, App $app) {
$user = User::where('app_id', $app->app_id)->where('user_id', $data['userId'])->first();
if (empty($user)) {
throw new BusinessException('用户不存在');
}
$apply = WithdrawApply::where('app_id', $app->app_id)->where('out_apply_no', $data['outApplyNo'])->first();
$baofu = new Baofu();
$data = [
'transContent' => [
[
'transNo' => $apply->apply_no,
'transBatchId' => $apply->third_batch_num,
]
]
];
try {
$result = $baofu->transferWithdrawQuery($data);
$item = $result[0];
$apply->fee = intval($item['transFee'] * 100);
$apply->third_apply_no = $item['transOrderId'];
$apply->third_batch_num = $item['transBatchId'];
$apply->status = WithdrawApply::getStatusByShortStatus($item['state']);
$apply->save();
return ['fee' => $apply->fee, 'status' => $apply->status, 'amount' => $apply->amount];
} catch (ApiException $e) {
throw $e;
}
}
public function withdraw(array $data, App $app, string $token) {
$withdrawType = $data['withdrawType'] ?? 'normal';
$user = User::where('app_id', $app->app_id)->where('user_id', $data['userId'])->first();
if (empty($user)) {
throw new BusinessException('用户不存在');
}
$withdraw = new Withdraw();
$withdraw->app_id = $app->app_id;
$withdraw->user_id = $user->user_id;
$withdraw->member_id = $user->member_id;
$withdraw->agreement_no = $data['agreementNo'];
$withdraw->withdraw_no = StringHelper::generateOrderNo(StringHelper::ORDER_NO_TYPE_WITHDRAW_NO);
$withdraw->out_withdraw_no = $data['outWithdrawNo'];
$withdraw->withdraw_type = $withdrawType;
$withdraw->amount = $data['amount'];
$withdraw->status = 'PREPARE';
$withdraw->applied_at = date('Y-m-d H:i:s');
$withdraw->notify_url = $data['notifyUrl'];
$withdraw->save();
if ($withdrawType == 'entrust') {
return $this->doEntrustWithdraw($data, $withdraw, $token);
} else {
return $this->doWithdraw($data, $withdraw, $token);
}
}
private function doWithdraw(array $data, Withdraw $withdraw, string $token) {
try {
$baofu = new Baofu();
$result = $baofu->withdraw([
'amount' => intval($data['amount']),
'loginNo' => $withdraw->member_id,
'agreementNo' => $data['agreementNo'],
'outOrderNo' => $withdraw->withdraw_no,
], $token);
$withdraw->status = 'APPLY_SUCCESS';
$withdraw->withdraw_url = $result;
$withdraw->save();
return $result;
} catch (ApiException $e) {
$withdraw->status = 'APPLY_FAILED';
$withdraw->error_code = $e->getCode();
$withdraw->error_message = $e->getMessage();
$withdraw->save();
throw $e;
}
}
private function doEntrustWithdraw(array $data, Withdraw $withdraw, string $token) {
try {
$baofu = new Baofu();
$result = $baofu->entrustWithdraw([
'amount' => intval($data['amount']),
'loginNo' => $withdraw->member_id,
'agreementNo' => $data['agreementNo'],
'outOrderNo' => $withdraw->withdraw_no,
], $token);
$withdraw->status = 'APPLY_SUCCESS';
$withdraw->withdraw_url = $result;
$withdraw->save();
return $result;
} catch (ApiException $e) {
$withdraw->status = 'APPLY_FAILED';
$withdraw->error_code = $e->getCode();
$withdraw->error_message = $e->getMessage();
$withdraw->save();
throw $e;
}
}
public function updateWithdraw($params, array $statusList = null) {
$withdraw = Withdraw::where('withdraw_no', $params['order_no'])->first();
if (empty($withdraw)) {
return null;
}
if ($statusList && !in_array($withdraw->status, $statusList)) {
return null;
}
$withdraw->third_withdraw_no = $params['third_order_no'];
$withdraw->status = $params['status'];
$withdraw->fee = $params['fee'] ?? 0;
$withdraw->fee_acc = $params['fee_acc'] ?? 0;
$withdraw->finished_at = $params['finished_at'] ?? null;
$withdraw->save();
return $withdraw;
}
public function updateWithdrawApply($params, array $statusList = null) {
$apply = WithdrawApply::where('apply_no', $params['transNo'])->first();
if (empty($apply)) {
return null;
}
if ($statusList && !in_array($apply->status, $statusList)) {
return null;
}
$apply->fee = intval($params['transFee'] * 100);
$apply->third_apply_no = $params['transOrderId'];
$apply->third_batch_num = $params['transBatchId'];
$apply->status = WithdrawApply::getStatusByShortStatus($params['state']);
$apply->save();
return $apply;
}
}