WithdrawalDestination.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <?php
  2. namespace App\Services;
  3. use App\Constants\HttpStatus;
  4. use App\Services\Payment\JdPayService;
  5. use App\Services\Payment\NoPayService;
  6. use App\Services\Payment\QianBaoService;
  7. use App\Services\Payment\ZimuPayService;
  8. use Exception;
  9. final class WithdrawalDestination
  10. {
  11. public const MANUAL_METHODS = [
  12. 'bank' => '银行卡',
  13. 'wechat' => '微信',
  14. 'alipay' => '支付宝',
  15. ];
  16. public static function requiresBankName(string $channel): bool
  17. {
  18. return $channel === QianBaoService::ALIPAY_TO_CARD || ZimuPayService::isCashChannel($channel);
  19. }
  20. public static function requiresBankBranch(string $channel, string $bankName = ''): bool
  21. {
  22. return $channel === QianBaoService::ALIPAY_TO_CARD
  23. || ($channel === 'rgtx' && self::manualMethod($bankName) === 'bank');
  24. }
  25. public static function bankBranch(string $channel, string $bankName, ?string $branch): ?string
  26. {
  27. if (!self::requiresBankBranch($channel, $bankName)) {
  28. return null;
  29. }
  30. $branch = trim($branch ?? '');
  31. if ($branch === '' || mb_strlen($branch) > 255) {
  32. throw new Exception(lang('请输入开户行支行名称'), HttpStatus::CUSTOM_ERROR);
  33. }
  34. return $branch;
  35. }
  36. public static function resolve(string $channel, array $params): array
  37. {
  38. $bankName = trim($params['bank_name'] ?? '');
  39. $cardNo = trim($params['card_no'] ?? '');
  40. if ($channel === 'rgtx') {
  41. $method = $params['payout_method'] ?? self::manualMethod($bankName);
  42. if ($method !== 'bank') {
  43. $image = $params['qr_image'] ?? ($method === 'wechat' ? $cardNo : '');
  44. if (!self::isQrImage($image)) {
  45. throw new Exception(lang('请上传有效的收款码图片'), HttpStatus::CUSTOM_ERROR);
  46. }
  47. if ($method === 'alipay' && ($cardNo === '' || filter_var($cardNo, FILTER_VALIDATE_URL))) {
  48. throw new Exception(lang('请输入支付宝账号'), HttpStatus::CUSTOM_ERROR);
  49. }
  50. return [
  51. 'bank_name' => self::MANUAL_METHODS[$method],
  52. 'card_no' => $method === 'alipay' ? $cardNo : '',
  53. 'qr_image' => $image,
  54. ];
  55. }
  56. if ($bankName === '' || self::manualMethod($bankName) !== 'bank') {
  57. throw new Exception(lang('请输入银行名称'), HttpStatus::CUSTOM_ERROR);
  58. }
  59. } elseif (self::requiresBankName($channel) && $bankName === '') {
  60. throw new Exception(lang('请输入银行名称'), HttpStatus::CUSTOM_ERROR);
  61. }
  62. if ($cardNo === '') {
  63. throw new Exception(lang('请输入收款账号'), HttpStatus::CUSTOM_ERROR);
  64. }
  65. $bankName = match (true) {
  66. $channel === QianBaoService::ALIPAY_TO_ALIPAY => '支付宝',
  67. $channel === QianBaoService::NUMBER_RMB => '数字人民币',
  68. ZimuPayService::isWithdrawChannel($channel) => $bankName ?: '808币提现-钱包地址',
  69. JdPayService::isChannel($channel) => $bankName ?: 'JD钱包',
  70. NoPayService::isWithdrawChannel($channel) => $bankName ?: 'NO钱包',
  71. default => $bankName,
  72. };
  73. return [
  74. 'bank_name' => $bankName,
  75. 'bank_branch' => self::bankBranch($channel, $bankName, $params['bank_branch'] ?? null),
  76. 'card_no' => $cardNo,
  77. ];
  78. }
  79. public static function manualResponse(string $bankName, string $cardNo, ?string $qrImage): array
  80. {
  81. $method = self::manualMethod($bankName);
  82. if ($method === 'bank') {
  83. return ['payout_method' => $method, 'card_no' => $cardNo, 'qr_image' => null];
  84. }
  85. if ($qrImage === null && self::isQrImage($cardNo)) {
  86. // Older QR-only records put the image in card_no.
  87. $qrImage = $cardNo;
  88. $cardNo = '';
  89. }
  90. return ['payout_method' => $method, 'card_no' => $method === 'wechat' ? '' : $cardNo, 'qr_image' => $qrImage];
  91. }
  92. private static function isQrImage(string $value): bool
  93. {
  94. return filter_var($value, FILTER_VALIDATE_URL) !== false && parse_url($value, PHP_URL_SCHEME) === 'https';
  95. }
  96. private static function manualMethod(string $bankName): string
  97. {
  98. return match ($bankName) {
  99. '微信' => 'wechat',
  100. '支付宝' => 'alipay',
  101. default => 'bank',
  102. };
  103. }
  104. }