| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- <?php
- namespace App\Services;
- use App\Constants\HttpStatus;
- use App\Services\Payment\JdPayService;
- use App\Services\Payment\NoPayService;
- use App\Services\Payment\QianBaoService;
- use App\Services\Payment\ZimuPayService;
- use Exception;
- final class WithdrawalDestination
- {
- public const MANUAL_METHODS = [
- 'bank' => '银行卡',
- 'wechat' => '微信',
- 'alipay' => '支付宝',
- ];
- /** 提现通道列表加上前端表单需要的字段(requires_* 和人工提现的收款方式),会员和代理共用。 */
- public static function describeChannels(array $list): array
- {
- foreach ($list as &$item) {
- $channel = $item['value'];
- $item['requires_real_name'] = true;
- $item['requires_bank_name'] = WithdrawalDestination::requiresBankName($channel);
- $item['requires_bank_branch'] = $channel === 'DF001';
- if ($channel === 'DF001') {
- $item['bank_name_label'] = lang('银行名称');
- $item['bank_branch_label'] = lang('开户行');
- }
- if ($channel === 'rgtx') {
- $item['payout_methods'] = [];
- foreach (WithdrawalDestination::MANUAL_METHODS as $value => $label) {
- $method = ['value' => $value, 'label' => lang($label),
- 'requires_bank_name' => $value === 'bank', 'requires_card_no' => $value !== 'wechat',
- 'requires_bank_branch' => $value === 'bank',
- 'requires_qr_image' => $value !== 'bank'];
- if ($value === 'bank') {
- $method['bank_name_label'] = lang('银行名称');
- $method['bank_branch_label'] = lang('开户行');
- }
- $item['payout_methods'][] = $method;
- }
- }
- }
- unset($item);
- return $list;
- }
- public static function requiresBankName(string $channel): bool
- {
- return $channel === QianBaoService::ALIPAY_TO_CARD || ZimuPayService::isCashChannel($channel);
- }
- public static function requiresBankBranch(string $channel, string $bankName = ''): bool
- {
- return $channel === QianBaoService::ALIPAY_TO_CARD
- || ($channel === 'rgtx' && self::manualMethod($bankName) === 'bank');
- }
- public static function bankBranch(string $channel, string $bankName, ?string $branch): ?string
- {
- if (!self::requiresBankBranch($channel, $bankName)) {
- return null;
- }
- $branch = trim($branch ?? '');
- if ($branch === '' || mb_strlen($branch) > 255) {
- throw new Exception(lang('请输入开户行支行名称'), HttpStatus::CUSTOM_ERROR);
- }
- return $branch;
- }
- public static function resolve(string $channel, array $params): array
- {
- $bankName = trim($params['bank_name'] ?? '');
- $cardNo = trim($params['card_no'] ?? '');
- if ($channel === 'rgtx') {
- $method = $params['payout_method'] ?? self::manualMethod($bankName);
- if ($method !== 'bank') {
- $image = $params['qr_image'] ?? ($method === 'wechat' ? $cardNo : '');
- if (!self::isQrImage($image)) {
- throw new Exception(lang('请上传有效的收款码图片'), HttpStatus::CUSTOM_ERROR);
- }
- if ($method === 'alipay' && ($cardNo === '' || filter_var($cardNo, FILTER_VALIDATE_URL))) {
- throw new Exception(lang('请输入支付宝账号'), HttpStatus::CUSTOM_ERROR);
- }
- return [
- 'bank_name' => self::MANUAL_METHODS[$method],
- 'card_no' => $method === 'alipay' ? $cardNo : '',
- 'qr_image' => $image,
- ];
- }
- if ($bankName === '' || self::manualMethod($bankName) !== 'bank') {
- throw new Exception(lang('请输入银行名称'), HttpStatus::CUSTOM_ERROR);
- }
- } elseif (self::requiresBankName($channel) && $bankName === '') {
- throw new Exception(lang('请输入银行名称'), HttpStatus::CUSTOM_ERROR);
- }
- if ($cardNo === '') {
- throw new Exception(lang('请输入收款账号'), HttpStatus::CUSTOM_ERROR);
- }
- $bankName = match (true) {
- $channel === QianBaoService::ALIPAY_TO_ALIPAY => '支付宝',
- $channel === QianBaoService::NUMBER_RMB => '数字人民币',
- ZimuPayService::isWithdrawChannel($channel) => $bankName ?: '808币提现-钱包地址',
- JdPayService::isChannel($channel) => $bankName ?: 'JD钱包',
- NoPayService::isWithdrawChannel($channel) => $bankName ?: 'NO钱包',
- default => $bankName,
- };
- return [
- 'bank_name' => $bankName,
- 'bank_branch' => self::bankBranch($channel, $bankName, $params['bank_branch'] ?? null),
- 'card_no' => $cardNo,
- ];
- }
- public static function manualResponse(string $bankName, string $cardNo, ?string $qrImage): array
- {
- $method = self::manualMethod($bankName);
- if ($method === 'bank') {
- return ['payout_method' => $method, 'card_no' => $cardNo, 'qr_image' => null];
- }
- if ($qrImage === null && self::isQrImage($cardNo)) {
- // Older QR-only records put the image in card_no.
- $qrImage = $cardNo;
- $cardNo = '';
- }
- return ['payout_method' => $method, 'card_no' => $method === 'wechat' ? '' : $cardNo, 'qr_image' => $qrImage];
- }
- private static function isQrImage(string $value): bool
- {
- return filter_var($value, FILTER_VALIDATE_URL) !== false && parse_url($value, PHP_URL_SCHEME) === 'https';
- }
- private static function manualMethod(string $bankName): string
- {
- return match ($bankName) {
- '微信' => 'wechat',
- '支付宝' => 'alipay',
- default => 'bank',
- };
- }
- }
|