Issues (9)

src/Wechat.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Nilnice\Payment;
4
5
use Illuminate\Config\Repository;
6
use Illuminate\Support\Collection;
7
use Illuminate\Support\Str;
8
use Nilnice\Payment\Exception\GatewayException;
9
use Nilnice\Payment\Wechat\Traits\RequestTrait;
10
use Nilnice\Payment\Wechat\Traits\SecurityTrait;
11
use Symfony\Component\HttpFoundation\Request;
12
13
/**
14
 * @method Wechat\AppPayment app(array $array)
15
 * @method Wechat\WapPayment wap(array $array)
16
 * @method Wechat\ScanPayment scan(array $array)
17
 * @method Wechat\PubPayment pub(array $array)
18
 */
19
class Wechat implements GatewayInterface
20
{
21
    use LogTrait;
22
    use RequestTrait;
23
    use SecurityTrait;
24
25
    /**
26
     * @var \Illuminate\Contracts\Config\Repository
27
     */
28
    protected $config;
29
30
    /**
31
     * @var array
32
     */
33
    protected $payload;
34
35
    /**
36
     * @var string
37
     */
38
    protected $gateway;
39
40
    /**
41
     * Wechat constructor.
42
     *
43
     * @param array $config
44
     *
45
     * @throws \Exception
46
     */
47 6
    public function __construct(array $config)
48
    {
49 6
        $this->config = new Repository($config);
50 6
        $env = $this->config->get('env', 'pro');
51 6
        $this->gateway = self::getGatewayUrl($env);
52 6
        $this->payload = [
53
            // 公众账号 ID - 微信分配的公众账号 ID
54 6
            'appid'            => '',
55
56
            // 商户号 - 微信支付分配的商户号
57 6
            'mch_id'           => $this->config->get('mch_id', ''),
58
59
            // 随机字符串	 - 随机字符串,不长于32位
60 6
            'nonce_str'        => Str::random(),
61
62
            // 签名
63 6
            'sign'             => '',
64
65
            // 终端 IP - 必须传正确的客户端 IP
66 6
            'spbill_create_ip' => Request::createFromGlobals()->getClientIp(),
67
68
            // 通知地址 - 接收微信支付异步通知回调地址,通知 url 必须为直接可访问的 url,不能携带参数
69 6
            'notify_url'       => $this->config->get('notify_url'),
70
71
            // 交易类型 - H5 支付的交易类型为 MWEB
72 6
            'trade_type'       => '',
73
        ];
74
75 6
        if ($this->config->has('log.file')) {
76
            $this->registerLogger($this->config, 'Wxpay');
77
        }
78 6
    }
79
80
    /**
81
     * @param string $method
82
     * @param array  $arguments
83
     *
84
     * @return mixed
85
     *
86
     * @throws \Nilnice\Payment\Exception\GatewayException
87
     */
88 3
    public function __call(string $method, array $arguments)
89
    {
90 3
        $this->setAppId($method);
91
92 3
        return $this->dispatcher($method, ...$arguments);
0 ignored issues
show
$arguments is expanded, but the parameter $array of Nilnice\Payment\Wechat::dispatcher() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

92
        return $this->dispatcher($method, /** @scrutinizer ignore-type */ ...$arguments);
Loading history...
93
    }
94
95
    /**
96
     * Query an order information.
97
     *
98
     * @param array|string $order
99
     *
100
     * @return \Illuminate\Support\Collection
101
     *
102
     * @throws \InvalidArgumentException
103
     *
104
     * @throws \Nilnice\Payment\Exception\GatewayException
105
     * @throws \Nilnice\Payment\Exception\InvalidKeyException
106
     * @throws \Nilnice\Payment\Exception\InvalidSignException
107
     */
108
    public function query($order) : Collection
109
    {
110
        $this->setAppId();
111
        $this->payload = self::filterPayload(
112
            $this->payload,
113
            $order,
114
            $this->config
115
        );
116
        $gateway = Constant::WX_PAY_QUERY;
117
118
        return $this->send($gateway, $this->payload, $this->config->get('key'));
119
    }
120
121
    /**
122
     * Close an order.
123
     *
124
     * @param array|string $order
125
     *
126
     * @return \Illuminate\Support\Collection
127
     *
128
     * @throws \InvalidArgumentException
129
     * @throws \Nilnice\Payment\Exception\GatewayException
130
     * @throws \Nilnice\Payment\Exception\InvalidKeyException
131
     * @throws \Nilnice\Payment\Exception\InvalidSignException
132
     */
133
    public function close($order) : Collection
134
    {
135
        $this->setAppId();
136
        unset($this->payload['spbill_create_ip']);
137
        $this->payload = self::filterPayload(
138
            $this->payload,
139
            $order,
140
            $this->config
141
        );
142
        $gateway = Constant::WX_PAY_CLOSE;
143
144
        return $this->send($gateway, $this->payload, $this->config->get('key'));
145
    }
146
147
    /**
148
     * Cancel an order.
149
     *
150
     * @param array|string $order
151
     *
152
     * @return \Illuminate\Support\Collection
153
     */
154
    public function cancel($order) : Collection
155
    {
156
        trigger_error('Wechat did not cancel API, please use close API.');
157
158
        return new Collection();
159
    }
160
161
    /**
162
     * Refund an order.
163
     *
164
     * @param array|string $order
165
     *
166
     * @return \Illuminate\Support\Collection
167
     *
168
     * @throws \InvalidArgumentException
169
     * @throws \Nilnice\Payment\Exception\GatewayException
170
     * @throws \Nilnice\Payment\Exception\InvalidKeyException
171
     * @throws \Nilnice\Payment\Exception\InvalidSignException
172
     */
173
    public function refund($order) : Collection
174
    {
175
        $this->payload = self::filterPayload(
176
            $this->payload,
177
            $order,
178
            $this->config
179
        );
180
181
        return $this->send(
182
            Constant::WX_PAY_REFUND,
183
            $this->payload,
184
            $this->config->get('key'),
185
            $this->config->get('cert_client'),
186
            $this->config->get('cert_key')
187
        );
188
    }
189
190
    /**
191
     * To pay.
192
     *
193
     * @param string $gateway
194
     *
195
     * @return mixed
196
     *
197
     * @throws \Nilnice\Payment\Exception\GatewayException
198
     */
199 3
    protected function toPay(string $gateway)
200
    {
201 3
        $class = new $gateway($this->config); // Instantiate different gateways.
202
203 3
        if ($class instanceof PaymentInterface) {
204 3
            return $class->toPay($this->gateway, $this->payload);
205
        }
206
207
        throw new GatewayException(
208
            "Pay gateway [{$gateway}] must be an instance of the GatewayInterface.",
209
            2
210
        );
211
    }
212
213
    /**
214
     * Pay dispatcher.
215
     *
216
     * @param string $gateway
217
     * @param array  $array
218
     *
219
     * @return mixed
220
     *
221
     * @throws \Nilnice\Payment\Exception\GatewayException
222
     */
223 3
    private function dispatcher(string $gateway, array $array = [])
224
    {
225 3
        $this->payload = array_merge($this->payload, $array);
226 3
        $class = \get_class($this) . '\\' . Str::studly($gateway) . 'Payment';
227
228 3
        if (class_exists($class)) {
229 3
            return $this->toPay($class);
230
        }
231
232
        throw new GatewayException("Pay gateway [{$gateway}] not exists", 1);
233
    }
234
235
    /**
236
     * Set app identify.
237
     *
238
     * @param string $method
239
     */
240 3
    private function setAppId($method = 'wap')
241
    {
242 1
        switch ($method) {
243 2
            case 'app': // APP 支付
244
                $this->payload['appid'] = $this->config->get('app_appid');
245
                $this->payload['mch_id'] = $this->config->get('app_mchid');
246
                break;
247 2
            case 'wap': // H5 支付
248
            case 'bar': // 刷卡支付
249
            case 'scan': // 扫码支付
250 3
                $this->payload['appid'] = $this->config->get('app_id');
251 3
                break;
252
            case 'pub': // 公众号支付
253
                $this->payload['appid'] = $this->config->get('pub_appid');
254
                break;
255
            case 'xcx': // 小程序支付
256
                $this->payload['appid'] = $this->config->get('xcx_appid');
257
                break;
258
        }
259 3
    }
260
261
    /**
262
     * Get gateway url.
263
     *
264
     * @param string $env
265
     *
266
     * @return string
267
     */
268 6
    private static function getGatewayUrl($env = '') : string
269
    {
270 6
        $uri = '';
271 2
        switch ($env) {
272 4
            case 'pro':
273 3
                $uri = Constant::WX_PAY_PRO_URI;
274 3
                break;
275 2
            case 'dev':
276 3
                $uri = Constant::WX_PAY_DEV_URI;
277 3
                break;
278
            case 'hk':
279
                $uri = Constant::WX_PAY_PRO_HK_URI;
280
                break;
281
            default:
282
                break;
283
        }
284
285 6
        return $uri;
286
    }
287
}
288