| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 | <?phpnamespace app\common\Service\Pay\Provider;use think\Log;use think\Exception;use Yansongda\Pay\Pay;use Yansongda\Pay\Contract\HttpClientInterface;use app\common\Enum\ChannelEnum;use app\common\model\pay\Config as PayConfig;use app\common\Service\Pay\HttpClient;use app\common\exception\BusinessException;use app\common\Service\ShopConfigService;/** * 支付提供器基类 * 封装 yansongda 支付库的基础功能 */class Base{    /**     * yansongda 支付示例     * @var Yansongda\Pay\Pay     */    protected $pay = null;    /**     * 支付参数     * @var array     */    public $config = null;    /**     * 支付服务实例     * @var mixed     */    protected $payService = null;    /**     * 平台标识     * @var string     */    protected $platform = null;    /**     * 渠道标识     * @var string     */    protected $channel = null;    /**     * 构造函数     * @param mixed $payService     * @param string $platform     * @param string $channel     */    public function __construct($payService = null, $platform = null, $channel = null)    {        $this->payService = $payService;        $this->platform = $platform;        $this->channel = $channel;    }    /**     * yansongda 支付初始化     *     * @param string $payment     * @param array $config     * @return Yansongda\Pay\Pay     */    public function init($payment, $config = [], $type = 'normal')    {        $this->config = $this->getConfig($payment, $config, $type);        // echo "<pre>";        // print_r($this->config);        // echo "</pre>";        // die();        $this->pay = Pay::config($this->config);        Pay::set(HttpClientInterface::class, HttpClient::instance());       // 使用自定义 client (也继承至 GuzzleHttp\Client)           }    /**     * 获取支付的所有参数     *     * @param string $payment     * @return array     */    protected function getConfig($payment, $config = [], $type = 'normal')    {        // 获取平台配置        $platformConfig = $this->getPlatformConfig();        extract($platformConfig);             $params = $this->getPayConfig($payment, $paymentConfig);        // 格式化支付参数        $params['mode'] = $params['mode'] ?? 0;        if($payment == 'douyin'){            $params = $this->formatConfig($params, ['mini_app_id' => $app_id], $type);        }else{            $params = $this->formatConfig($params, ['app_id' => $app_id], $type);        }                // 合并传入的参数        $params = array_merge($params, $config);        // 合并参数        $config = $this->baseConfig();        $config = array_merge($config, [$payment => ['default' => $params]]);        return $config;    }    /**     * 转换平台名称格式     * 将前端驼峰命名转换为后端下划线格式     *     * @param string $platform     * @return string     */    protected function convertPlatformName($platform)    {        // 将驼峰命名转换为下划线格式        return strtolower(preg_replace('/([A-Z])/', '_$1', lcfirst($platform)));    }    /**     * 获取平台配置参数     *     * @return array     */    protected function getPlatformConfig()    {        // 需要转换   前段穿 DouyinMiniProgram  后端配置是   douyin_mini_program        $platformKey = $this->convertPlatformName($this->platform);        $platformConfig = ShopConfigService::getConfigs('shop.platform.' . $platformKey);        $paymentConfig = $platformConfig['payment'] ?? [];        $app_id = $platformConfig['app_id'] ?? '';              return compact('paymentConfig', 'app_id');    }    /**     * 根据平台以及支付方式 获取支付配置表的配置参数     *     * @param string $payment     * @return array     */    protected function getPayConfig($payment, $paymentConfig)     {        $methods = $paymentConfig['methods'];        $payment_config = $paymentConfig[$payment] ?? 0;        if (!in_array($payment, $methods)) {            throw new BusinessException('当前平台未开启该支付方式');        }        if ($payment_config) {            $payConfig = PayConfig::where('type', $payment)->find($payment_config);        }        if (!isset($payConfig) || !$payConfig) {            throw new BusinessException('支付配置参数不存在');        }        return $payConfig->params;    }    /**     * 获取对应的支付方法名     *     * @param strign $payment     * @return string     */    protected function getMethod($payment)    {        $method = [            'wechat' => [                'WechatOfficialAccount' => 'mp',        //公众号支付 Collection                'WechatMiniProgram' => 'mini',       //小程序支付 Collection                 'H5' => 'wap',                      //手机网站支付 Response                'IOSApp' => 'app',                      // APP 支付 JsonResponse                'AndroidApp' => 'app',                      // APP 支付 JsonResponse            ],            'alipay' => [                'WechatOfficialAccount' => 'wap',       //手机网站支付 Response                'WechatMiniProgram' => 'wap',           //小程序支付                'H5' => 'wap',                      //手机网站支付 Response                'IOSApp' => 'app',                      // APP 支付 JsonResponse                'AndroidApp' => 'app',                      // APP 支付 JsonResponse            ],            'douyin' => [                'DouyinMiniProgram' => 'mini',       //小程序支付 Collection            ],        ];        return $method[$payment][$this->platform];    }    /**     * yansongda 基础配置     *     * @return void     */    protected function baseConfig()    {        $log_path = RUNTIME_PATH . 'log/pay/';        if (!is_dir($log_path)) {            @mkdir($log_path, 0755, true);        }        return [            'logger' => [ // optional                'enable' => true,                'file' => $log_path . 'pay.log',                'level' => config('app_debug') ? 'debug' : 'info', // 建议生产环境等级调整为 info,开发环境为 debug                'type' => 'daily', // optional, 可选 daily.                'max_file' => 30, // optional, 当 type 为 daily 时有效,默认 30 天            ],            'http' => [ // optional                'timeout' => 5.0,                'connect_timeout' => 5.0,                // 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)            ],        ];    }    /**     * 格式化支付参数 (抽象方法,由子类实现)     * @param array $config     * @param array $data     * @param string $type     * @return array     */    protected function formatConfig($config, $data = [], $type = 'normal')    {        return $config;    }    /**     * 记录支付日志     * @param string $message     * @param array $context     * @param string $level     */    protected function logPayment($message, $context = [], $level = 'info')    {        Log::record($message . ' ' . json_encode($context, JSON_UNESCAPED_UNICODE), $level);    }}
 |