123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- <?php
- namespace app\common\Service\Pay;
- use think\Log;
- use think\Exception;
- use app\common\Enum\ChannelEnum;
- use app\common\Service\Pay\Provider\Base;
- use app\common\exception\BusinessException;
- use app\common\model\pay\Index as PayModel;
- /**
- * 支付服务类 - 工厂模式
- * 配合 yansongda 支付库
- */
- class PayService
- {
- protected $payment;
- protected $platform;
- protected $channel;
- /**
- * 构造函数
- * @param string $payment 支付方式 (wechat|alipay)
- * @param string $platform 平台标识 (可选)
- * @param string $channel 渠道标识 (可选)
- */
- public function __construct($payment, $platform = null, $channel = null)
- {
- $this->payment = $payment;
- $this->platform = $platform ?: $this->getPlatformFromRequest();
- $this->channel = $channel ?: $this->getChannelFromRequest();
- // 验证平台参数
- if (!$this->platform) {
- throw new BusinessException('缺少用户端平台参数');
- }
- // 验证支付方式
- if (!in_array($payment, ['wechat', 'alipay','douyin'])) {
- throw new BusinessException('不支持的支付方式: ' . $payment);
- }
- }
- /**
- * 获取支付提供器
- * @param string $payment 支付方式
- * @return Base
- * @throws Exception
- */
- public function provider($payment = null)
- {
- try {
- $payment = $payment ?: $this->payment;
- $className = "\\app\\common\\Service\\Pay\\Provider\\" . ucfirst(strtolower($payment));
-
- if (!class_exists($className)) {
- throw new Exception("支付提供器不存在: {$className}");
- }
-
- return new $className($this, $this->platform, $this->channel);
- } catch (\Exception $e) {
- Log::error('PayService provider error: ' . $e->getMessage());
- throw new Exception('支付类型不支持: ' . $payment);
- }
- }
- /**
- * 获取当前平台
- * @return string
- */
- public function getPlatform()
- {
- return $this->platform;
- }
- /**
- * 获取当前渠道
- * @return string
- */
- public function getChannel()
- {
- return $this->channel;
- }
- /**
- * 获取当前支付方式
- * @return string
- */
- public function getPayment()
- {
- return $this->payment;
- }
- /**
- * 从请求中获取平台参数
- * @return string|null
- */
- protected function getPlatformFromRequest()
- {
- $request = request();
- return $request->header('platform') ?: $request->param('platform');
- }
- /**
- * 从请求中获取渠道参数
- * @return string|null
- */
- protected function getChannelFromRequest()
- {
- $request = request();
- $channel = $request->header('channel') ?: $request->param('channel');
-
- // 如果没有明确的渠道参数,尝试从平台推断
- if (!$channel && $this->platform) {
- $channel = $this->inferChannelFromPlatform($this->platform);
- }
-
- return $channel;
- }
- /**
- * 从平台推断渠道
- * @param string $platform
- * @return string|null
- */
- protected function inferChannelFromPlatform($platform)
- {
- $platformToChannel = [
- 'WechatOfficialAccount' => ChannelEnum::CHANNEL_WECHAT_OFFICIAL_ACCOUNT,
- 'WechatMiniProgram' => ChannelEnum::CHANNEL_WECHAT_MINI_PROGRAM,
- 'H5' => ChannelEnum::CHANNEL_H5,
- 'App' => ChannelEnum::CHANNEL_ANDROID_APP, // 默认Android,可根据具体情况调整
- 'PC' => ChannelEnum::CHANNEL_PC,
- ];
- return $platformToChannel[$platform] ?? null;
- }
- /**
- * 验证支付环境
- * @param string $payment 支付方式
- * @param string $channel 渠道
- * @return bool
- * @throws Exception
- */
- public function validatePaymentEnvironment($payment, $channel = null)
- {
- $channel = $channel ?: $this->channel;
-
- if (!$channel) {
- return true; // 如果没有渠道信息,跳过验证
- }
- // 微信支付环境验证
- if ($payment === 'wechat') {
- if (!ChannelEnum::isWechatChannel($channel) && $channel !== ChannelEnum::CHANNEL_H5) {
- throw new BusinessException('当前渠道不支持微信支付');
- }
- }
- // 支付功能验证
- if (!ChannelEnum::channelSupportsFeature($channel, 'payment')) {
- throw new BusinessException('当前渠道不支持支付功能');
- }
- return true;
- }
- /**
- * 魔术方法,代理到支付提供器
- * @param string $funcname
- * @param array $arguments
- * @return mixed
- */
- public function __call($funcname, $arguments)
- {
- return $this->provider()->{$funcname}(...$arguments);
- }
- /**
- * 获取支付信息
- * @param string $orderId
- * @return array
- */
- public static function getPayInfo($orderId = 0)
- {
- $payInfo = PayModel::where('order_id', $orderId)->select();
- return $payInfo;
- }
- }
|