|
|
|
@ -15,6 +15,8 @@ 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
|
|
|
|
|
{
|
|
|
|
@ -36,11 +38,19 @@ class PaymentService extends AbstractService
|
|
|
|
|
throw new BusinessException('订单号重复');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[$order, $orderSplitInfos] = $this->createOrder($app, $data, $user, 'paymentSplit');
|
|
|
|
|
$data['payType'] = $data['payType'] ?? 'CARD';
|
|
|
|
|
$payMethod = $data['payMethod'] ?? 'paymentSplit';
|
|
|
|
|
[$order, $orderSplitInfos] = $this->createOrder($app, $data, $user, $payMethod);
|
|
|
|
|
|
|
|
|
|
$splitInfoList = $this->buildSplitInfoList($orderSplitInfos);
|
|
|
|
|
|
|
|
|
|
return $this->paymentSplit($order, $user, $splitInfoList, $token);
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
@ -83,7 +93,7 @@ class PaymentService extends AbstractService
|
|
|
|
|
'loginNo' => $user->member_id,
|
|
|
|
|
'outOrderNo' => $order->order_no,
|
|
|
|
|
'amount' => $order->amount,
|
|
|
|
|
'paidType' => 'CARD',
|
|
|
|
|
'paidType' => $order->pay_type,
|
|
|
|
|
'agreementNo' => $order->agreement_no,
|
|
|
|
|
'pwdPayExpTime' => $order->expires_in,
|
|
|
|
|
'splitInfoList' => $splitInfoList,
|
|
|
|
@ -92,7 +102,7 @@ class PaymentService extends AbstractService
|
|
|
|
|
$order->applied_at = date('Y-m-d H:i:s');
|
|
|
|
|
$order->pay_url = $url;
|
|
|
|
|
$order->save();
|
|
|
|
|
return $url;
|
|
|
|
|
return ['url' => $url];
|
|
|
|
|
} catch (ApiException $e) {
|
|
|
|
|
$order->status = 'APPLY_FAILED';
|
|
|
|
|
$order->applied_at = date('Y-m-d H:i:s');
|
|
|
|
@ -133,6 +143,43 @@ class PaymentService extends AbstractService
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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');
|
|
|
|
@ -150,14 +197,18 @@ class PaymentService extends AbstractService
|
|
|
|
|
$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 = 'CARD';
|
|
|
|
|
$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->save();
|
|
|
|
|
|
|
|
|
|
$platformAccount = User::getPlatformAccount();
|
|
|
|
@ -212,17 +263,22 @@ class PaymentService extends AbstractService
|
|
|
|
|
return [$order, $orderSplitInfos];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function updateOrder($params) {
|
|
|
|
|
$order = Order::where('order_no', $params['order_no'])->where('status', 'APPLY_SUCCESS')->first();
|
|
|
|
|
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->error_message = $params['error_message'] ?? '';
|
|
|
|
|
$order->transaction_id = $params['transaction_id'] ?? '';
|
|
|
|
|
$order->out_transaction_id = $params['out_transaction_id'] ?? '';
|
|
|
|
|
$order->save();
|
|
|
|
|
return $order;
|
|
|
|
|
}
|
|
|
|
@ -385,12 +441,12 @@ class PaymentService extends AbstractService
|
|
|
|
|
if (empty($user)) {
|
|
|
|
|
throw new BusinessException('用户不存在');
|
|
|
|
|
}
|
|
|
|
|
$order = Order::where('app_id', $app->app_id)->where('out_order_no', $data['outOrderNo'])->first();
|
|
|
|
|
$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_APPLY_SUCCESS) {
|
|
|
|
|
if ($order->status != Order::STATUS_SUCCESS) {
|
|
|
|
|
throw new BusinessException('订单状态异常');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -410,7 +466,6 @@ class PaymentService extends AbstractService
|
|
|
|
|
'assureConfirmSplitInfoList' => $confirmSplitInfoList,
|
|
|
|
|
'outOrderNo' => StringHelper::generateOrderNo(StringHelper::ORDER_NO_TYPE_CONFIRM_PAY),
|
|
|
|
|
'amount' => $data['amount'],
|
|
|
|
|
'notifyUrl' => $data['notifyUrl'],
|
|
|
|
|
], $token);
|
|
|
|
|
$order->status = 'CONFIRM_SUCCESS';
|
|
|
|
|
$order->save();
|
|
|
|
@ -423,4 +478,248 @@ class PaymentService extends AbstractService
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|