326 lines
10 KiB
PHP
326 lines
10 KiB
PHP
<?php
|
|
|
|
namespace Modules\Withdraw\Models\Traits;
|
|
|
|
use App\Models\DayDataChain;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Jason\Chain33;
|
|
use Modules\Chain\Models\Address;
|
|
use Modules\Payment\Facades\Pay;
|
|
use Modules\Payment\Models\Traits\WithConfig;
|
|
use Modules\Withdraw\Events\WithdrawAuditPass;
|
|
use Modules\Withdraw\Events\WithdrawAuditReject;
|
|
use Modules\Withdraw\Models\Account;
|
|
use Modules\Withdraw\Models\Config;
|
|
use Modules\Withdraw\Models\Withdraw;
|
|
use Yansongda\Pay\Plugin\Alipay\Fund\TransUniTransferPlugin;
|
|
|
|
trait WithdrawActions
|
|
{
|
|
|
|
use WithConfig;
|
|
|
|
/**
|
|
* Notes: 通过
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/9/26 15:20
|
|
* @param string $remark
|
|
* @return bool
|
|
* @throws \Exception
|
|
*/
|
|
public function pass(string $remark = ''): bool
|
|
{
|
|
if (! $this->canAudit()) {
|
|
throw new \Exception('该提现记录已经被审核');
|
|
}
|
|
|
|
try {
|
|
if ($this->type == self::TYPE_ALIPAY) {
|
|
|
|
if (! $this->alipayAccount) {
|
|
throw new \Exception('未找到支付宝账户');
|
|
}
|
|
|
|
$allPlugins = Pay::alipay()
|
|
->mergeCommonPlugins([TransUniTransferPlugin::class]);
|
|
|
|
$params = [
|
|
'out_biz_no' => $this->withdraw_no,
|
|
'trans_amount' => $this->take,
|
|
'payee_info' => [
|
|
'identity' => $this->alipayAccount->identity,
|
|
'identity_type' => $this->alipayAccount->identity_type,
|
|
'name' => $this->alipayAccount->name,
|
|
],
|
|
];
|
|
|
|
$res = Pay::alipay($this->getPayConfig('alipay'))->pay($allPlugins, $params);
|
|
if ($res->code != 10000) {
|
|
throw new \Exception($res->sub_msg);
|
|
}
|
|
|
|
}
|
|
|
|
DB::transaction(function () use ($remark) {
|
|
$this->status = Withdraw::STATUS_PASS;
|
|
$this->paid_at = now();
|
|
$this->save();
|
|
});
|
|
|
|
$this->addLog(Withdraw::STATUS_INIT, $remark);
|
|
|
|
event(new WithdrawAuditPass($this));
|
|
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notes: 驳回
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/9/26 15:21
|
|
* @param string $remark
|
|
* @return bool
|
|
* @throws \Exception
|
|
*/
|
|
public function reject(string $remark = ''): bool
|
|
{
|
|
if (! $this->canAudit()) {
|
|
throw new \Exception('该提现记录已经被审核');
|
|
}
|
|
|
|
try {
|
|
DB::transaction(function () use ($remark) {
|
|
$this->status = Withdraw::STATUS_REJECT;
|
|
$this->paid_at = now();
|
|
$this->save();
|
|
|
|
$is_chain = config('withdraw.is_chain', false);
|
|
|
|
if (! $is_chain) {
|
|
$this->user->account->rule('withdraw_in', $this->amount, false, [
|
|
'withdraw_id' => $this->id,
|
|
]);
|
|
} else {
|
|
$hash = $this->rejectPick();
|
|
$source = [
|
|
'reject_hash' => $hash,
|
|
];
|
|
|
|
$this->update(['source' => $source]);
|
|
}
|
|
|
|
$this->addLog(Withdraw::STATUS_REJECT, $remark);
|
|
|
|
event(new WithdrawAuditReject($this));
|
|
|
|
});
|
|
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notes: 添加记录
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/9/27 8:56
|
|
* @param $status
|
|
* @param string $remark
|
|
* @return bool
|
|
*/
|
|
public function addLog($status, string $remark = ''): bool
|
|
{
|
|
$this->logs()->create([
|
|
'status' => $status,
|
|
'remark' => $remark,
|
|
]);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Notes: 创建提现信息
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/9/27 10:14
|
|
*/
|
|
public static function createInfo($user, $params): bool
|
|
{
|
|
try {
|
|
DB::transaction(function () use ($user, $params) {
|
|
|
|
$type = $params->type ?? 0;
|
|
$bank_account_id = $params->bank_account_id ?? 0;
|
|
$amount = $params->amount;
|
|
|
|
$account_name = config('withdraw.account');
|
|
$source = [
|
|
$account_name => $amount,
|
|
];
|
|
|
|
$cash = $amount;
|
|
|
|
$is_chain = config('withdraw.is_chain', false);
|
|
|
|
$balance = $is_chain ? $user->getStoneBalance() : $user->account->{$account_name};
|
|
|
|
if ($amount > $balance) {
|
|
throw new \Exception('提现失败,余额不足');
|
|
}
|
|
|
|
if ($is_chain) {
|
|
$cost = (new DayDataChain())->getStoneValue();
|
|
$cash = bcmul($cost, $amount, 2);
|
|
$source = array_merge($source, ['cost' => $cost,]);
|
|
}
|
|
|
|
$withdraw_min = Config::getValue('min', 1);
|
|
|
|
if ($withdraw_min > 0 && $cash < $withdraw_min) {
|
|
throw new \Exception("提现失败,提现金额必须大于等于{$withdraw_min}");
|
|
}
|
|
|
|
$tax_value = Config::getValue('tax', 0);
|
|
|
|
$tax = $tax_value ? round($cash * $tax_value / 100, 2) : 0;
|
|
$take = $cash - $tax;
|
|
|
|
if ($type == Withdraw::TYPE_BANK) {
|
|
$bank_account = Account::find($bank_account_id);
|
|
if (! $bank_account) {
|
|
throw new \Exception('提现失败,未找到提现账户信息');
|
|
}
|
|
|
|
if ($bank_account->user->isNot($user)) {
|
|
throw new \Exception('提现失败,您不可使用此提现账户');
|
|
}
|
|
|
|
$info = $user->withdraws()->create([
|
|
'bank_account_id' => $bank_account_id,
|
|
'amount' => $cash,
|
|
'tax' => $tax, //手续费
|
|
'take' => $take, //实到金额
|
|
'source' => $source,
|
|
'type' => Withdraw::TYPE_BANK,
|
|
]);
|
|
} else {
|
|
$alipay_account = $user->alipayAccounts()->create([
|
|
'name' => $params->name,
|
|
'identity' => $params->identity,
|
|
'identity_type' => 'ALIPAY_LOGON_ID',
|
|
]);
|
|
|
|
$info = $user->withdraws()->create([
|
|
'alipay_account_id' => $alipay_account->id,
|
|
'amount' => $cash,
|
|
'tax' => $tax, //手续费
|
|
'take' => $take, //实到金额
|
|
'source' => $source,
|
|
'type' => Withdraw::TYPE_ALIPAY,
|
|
]);
|
|
}
|
|
|
|
if (! $is_chain) {
|
|
$user->account->rule('withdraw_out', -$cash, false, [
|
|
'withdraw_id' => $info->id,
|
|
]);
|
|
} else {
|
|
$hash = $info->pick();//转到代持账户
|
|
$source = array_merge($source, ['hash' => $hash,]);
|
|
|
|
$info->update(['source' => $source]);
|
|
}
|
|
});
|
|
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notes: 申请提现时将提现金额转入代持账户
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/9/27 10:34
|
|
* @return string
|
|
* @throws \Exception
|
|
*/
|
|
public function pick(): string
|
|
{
|
|
$to_address = Config::getValue('withdraw_addr', '');
|
|
|
|
if (! $to_address) {
|
|
throw new \Exception('提现失败,缺少代持账户信息,请管理人员配置代持账户。');
|
|
}
|
|
|
|
$number = $this->source['coins'] ?? 0;
|
|
if (! $number) {
|
|
throw new \Exception('提现数据错误');
|
|
}
|
|
|
|
$from_address = $this->user->blockChain->address;
|
|
$balance = coinsFormat(Chain33::Balance()->get($from_address)['balance']);
|
|
|
|
if ($number > $balance) {
|
|
throw new \Exception('提现失败,数量不足');
|
|
}
|
|
|
|
try {
|
|
$fromAddr = Address::where('address', $from_address)->first();
|
|
|
|
return Chain33::Transaction()
|
|
->coins($to_address, $number * 1e8, $fromAddr->private_key, 0, '用户提现');
|
|
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Notes: description
|
|
*
|
|
* @Author: 玄尘
|
|
* @Date : 2021/9/27 14:45
|
|
* @return string
|
|
* @throws \Exception
|
|
*/
|
|
public function rejectPick(): string
|
|
{
|
|
$from_address = Config::getValue('withdraw_addr', '');
|
|
|
|
if (! $from_address) {
|
|
throw new \Exception('提现失败,缺少代持账户信息,请管理人员配置代持账户。');
|
|
}
|
|
|
|
$number = $this->source['coins'] ?? 0;
|
|
if (! $number) {
|
|
throw new \Exception('提现数据错误');
|
|
}
|
|
|
|
$to_address = $this->user->blockChain->address;
|
|
$balance = coinsFormat(Chain33::Balance()->get($from_address)['balance']);
|
|
|
|
if ($number > $balance) {
|
|
throw new \Exception('驳回失败,代持账户数量不足');
|
|
}
|
|
|
|
try {
|
|
$fromAddr = Address::where('address', $from_address)->first();
|
|
|
|
return Chain33::Transaction()
|
|
->coins($to_address, $number * 1e8, $fromAddr->private_key, 0, '驳回提现');
|
|
|
|
} catch (\Exception $e) {
|
|
throw new \Exception($e->getMessage());
|
|
}
|
|
}
|
|
|
|
} |