审查视图

addons/epay/library/Service.php 9.7 KB
王智 authored
1 2 3 4 5
<?php

namespace addons\epay\library;

use Exception;
王智 authored
6
use think\Response;
王智 authored
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
use think\Session;
use Yansongda\Pay\Pay;

/**
 * 订单服务类
 *
 * @package addons\epay\library
 */
class Service
{

    /**
     * @param array|float $amount    订单金额
     * @param string      $orderid   订单号
     * @param string      $type      支付类型,可选alipay或wechat
     * @param string      $title     订单标题
     * @param string      $notifyurl 通知回调URL
     * @param string      $returnurl 跳转返回URL
     * @param string      $method    支付方法
王智 authored
26
     * @return string
王智 authored
27 28
     * @throws Exception
     */
王智 authored
29
    public static function submitOrder($amount, $orderid = null, $type = null, $title = null, $notifyurl = null, $returnurl = null, $method = null)
王智 authored
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
    {
        if (!is_array($amount)) {
            $params = [
                'amount'    => $amount,
                'orderid'   => $orderid,
                'type'      => $type,
                'title'     => $title,
                'notifyurl' => $notifyurl,
                'returnurl' => $returnurl,
                'method'    => $method,
            ];
        } else {
            $params = $amount;
        }
        $type = isset($params['type']) && in_array($params['type'], ['alipay', 'wechat']) ? $params['type'] : 'wechat';
        $method = isset($params['method']) ? $params['method'] : 'web';
        $orderid = isset($params['orderid']) ? $params['orderid'] : date("YmdHis") . mt_rand(100000, 999999);
        $amount = isset($params['amount']) ? $params['amount'] : 1;
        $title = isset($params['title']) ? $params['title'] : "支付";
        $auth_code = isset($params['auth_code']) ? $params['auth_code'] : '';
        $openid = isset($params['openid']) ? $params['openid'] : '';

        $request = request();
        $notifyurl = isset($params['notifyurl']) ? $params['notifyurl'] : $request->root(true) . '/addons/epay/index/' . $type . 'notify';
        $returnurl = isset($params['returnurl']) ? $params['returnurl'] : $request->root(true) . '/addons/epay/index/' . $type . 'return/out_trade_no/' . $orderid;
        $html = '';
        $config = Service::getConfig($type);
        $config['notify_url'] = $notifyurl;
        $config['return_url'] = $returnurl;

        if ($type == 'alipay') {
            //创建支付对象
            $pay = Pay::alipay($config);
王智 authored
63
            //支付宝支付,请根据你的需求,仅选择你所需要的即可
王智 authored
64 65 66 67 68
            $params = [
                'out_trade_no' => $orderid,//你的订单号
                'total_amount' => $amount,//单位元
                'subject'      => $title,
            ];
王智 authored
69 70 71 72
            if ($method == 'web') {
                //如果是移动端自动切换为wap
                $method = $request->isMobile() ? 'wap' : $method;
            }
王智 authored
73 74 75

            switch ($method) {
                case 'web':
王智 authored
76 77 78
                    //电脑支付,跳转
                    $html = $pay->web($params);
                    Response::create($html)->send();
王智 authored
79 80
                    break;
                case 'wap':
王智 authored
81 82 83
                    //手机网页支付,跳转
                    $html = $pay->wap($params);
                    Response::create($html)->send();
王智 authored
84 85
                    break;
                case 'app':
王智 authored
86 87
                    //APP支付,直接返回字符串
                    $html = $pay->app($params);
王智 authored
88 89
                    break;
                case 'scan':
王智 authored
90 91
                    //扫码支付,直接返回字符串
                    $html = $pay->scan($params);
王智 authored
92 93
                    break;
                case 'pos':
王智 authored
94
                    //刷卡支付,直接返回字符串
王智 authored
95 96
                    //刷卡支付必须要有auth_code
                    $params['auth_code'] = $auth_code;
王智 authored
97
                    $html = $pay->pos($params);
王智 authored
98 99
                    break;
                default:
王智 authored
100
                    //其它支付类型请参考:https://docs.pay.yansongda.cn/alipay
王智 authored
101 102 103 104
            }
        } else {
            //如果是PC支付,判断当前环境,进行跳转
            if ($method == 'web') {
王智 authored
105 106
                if ((strpos($request->server('HTTP_USER_AGENT'), 'MicroMessenger') !== false)) {
                    Session::delete("openid");
王智 authored
107 108
                    Session::set("wechatorderdata", $params);
                    $url = addon_url('epay/api/wechat', [], true, true);
王智 authored
109 110 111 112
                    header("location:{$url}");
                    exit;
                } elseif ($request->isMobile()) {
                    $method = 'wap';
王智 authored
113 114 115 116 117 118 119 120 121 122 123
                }
            }

            //创建支付对象
            $pay = Pay::wechat($config);
            $params = [
                'out_trade_no' => $orderid,//你的订单号
                'body'         => $title,
                'total_fee'    => $amount * 100, //单位分
            ];
            switch ($method) {
王智 authored
124 125 126 127 128
                case 'web':
                    //电脑支付,跳转到自定义展示页面(FastAdmin独有)
                    $html = $pay->web($params);
                    Response::create($html)->send();
                    break;
王智 authored
129 130 131 132
                case 'mp':
                    //公众号支付
                    //公众号支付必须有openid
                    $params['openid'] = $openid;
王智 authored
133
                    $html = $pay->mp($params);
王智 authored
134 135 136 137
                    break;
                case 'wap':
                    //手机网页支付,跳转
                    $params['spbill_create_ip'] = $request->ip(0, false);
王智 authored
138 139 140
                    $html = $pay->wap($params);
                    header("location:{$html}");
                    exit;
王智 authored
141 142 143
                    break;
                case 'app':
                    //APP支付,直接返回字符串
王智 authored
144
                    $html = $pay->app($params);
王智 authored
145 146 147
                    break;
                case 'scan':
                    //扫码支付,直接返回字符串
王智 authored
148
                    $html = $pay->scan($params);
王智 authored
149 150 151 152 153
                    break;
                case 'pos':
                    //刷卡支付,直接返回字符串
                    //刷卡支付必须要有auth_code
                    $params['auth_code'] = $auth_code;
王智 authored
154
                    $html = $pay->pos($params);
王智 authored
155 156 157 158 159
                    break;
                case 'miniapp':
                    //小程序支付,直接返回字符串
                    //小程序支付必须要有openid
                    $params['openid'] = $openid;
王智 authored
160
                    $html = $pay->miniapp($params);
王智 authored
161 162 163 164
                    break;
                default:
            }
        }
王智 authored
165 166 167
        //返回字符串
        $html = is_array($html) ? json_encode($html) : $html;
        return $html;
王智 authored
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
    }

    /**
     * 验证回调是否成功
     * @param string $type   支付类型
     * @param array  $config 配置信息
     * @return bool|\Yansongda\Pay\Gateways\Alipay|\Yansongda\Pay\Gateways\Wechat
     */
    public static function checkNotify($type, $config = [])
    {
        $type = strtolower($type);
        if (!in_array($type, ['wechat', 'alipay'])) {
            return false;
        }
        try {
            $config = self::getConfig($type);
            $pay = $type == 'wechat' ? Pay::wechat($config) : Pay::alipay($config);
            $data = $pay->verify();

            if ($type == 'alipay') {
                if (in_array($data['trade_status'], ['TRADE_SUCCESS', 'TRADE_FINISHED'])) {
                    return $pay;
                }
            } else {
                return $pay;
            }
        } catch (Exception $e) {
            return false;
        }

        return false;
    }

    /**
王智 authored
202
     * 验证返回是否成功
王智 authored
203 204
     * @param string $type   支付类型
     * @param array  $config 配置信息
王智 authored
205
     * @return bool|\Yansongda\Pay\Gateways\Alipay
王智 authored
206 207 208
     */
    public static function checkReturn($type, $config = [])
    {
王智 authored
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
        $type = strtolower($type);
        if (!in_array($type, ['wechat', 'alipay'])) {
            return false;
        }
        //微信无需验证
        if ($type == 'wechat') {
            return true;
        }
        try {
            $pay = Pay::alipay(self::getConfig($type));
            $data = $pay->verify(request()->get('', null, 'trim'));
            if ($data) {
                return $pay;
            }
        } catch (Exception $e) {
            return false;
        }

        return false;
王智 authored
228 229 230 231 232 233 234 235 236 237 238 239 240
    }

    /**
     * 获取配置
     * @param string $type 支付类型
     * @return array|mixed
     */
    public static function getConfig($type = 'wechat')
    {
        $config = get_addon_config('epay');
        $config = isset($config[$type]) ? $config[$type] : $config['wechat'];
        if ($config['log']) {
            $config['log'] = [
王智 authored
241
                'file'  => LOG_PATH . '/epaylogs/' . $type . '-' . date("Y-m-d") . '.log',
王智 authored
242 243 244
                'level' => 'debug'
            ];
        }
王智 authored
245 246
        if (isset($config['cert_client']) && substr($config['cert_client'], 0, 6) == '/epay/') {
            $config['cert_client'] = ADDON_PATH . $config['cert_client'];
王智 authored
247
        }
王智 authored
248 249
        if (isset($config['cert_key']) && substr($config['cert_key'], 0, 6) == '/epay/') {
            $config['cert_key'] = ADDON_PATH . $config['cert_key'];
王智 authored
250 251 252 253 254 255 256 257 258 259
        }

        $config['notify_url'] = empty($config['notify_url']) ? addon_url('epay/api/notifyx', [], false) . '/type/' . $type : $config['notify_url'];
        $config['notify_url'] = !preg_match("/^(http:\/\/|https:\/\/)/i", $config['notify_url']) ? request()->root(true) . $config['notify_url'] : $config['notify_url'];
        $config['return_url'] = empty($config['return_url']) ? addon_url('epay/api/returnx', [], false) . '/type/' . $type : $config['return_url'];
        $config['return_url'] = !preg_match("/^(http:\/\/|https:\/\/)/i", $config['return_url']) ? request()->root(true) . $config['return_url'] : $config['return_url'];
        return $config;
    }

}