Completed
Push — master ( 5ddcc0...9e0ead )
by Carlos
42s
created

API::refund()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 17
ccs 8
cts 8
cp 1
rs 9.4285
cc 3
eloc 13
nc 4
nop 5
crap 3
1
<?php
2
3
/*
4
 * This file is part of the overtrue/wechat.
5
 *
6
 * (c) overtrue <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
/**
13
 * API.php.
14
 *
15
 * @author    overtrue <[email protected]>
16
 * @copyright 2015 overtrue <[email protected]>
17
 *
18
 * @link      https://github.com/overtrue
19
 * @link      http://overtrue.me
20
 */
21
namespace EasyWeChat\Payment;
22
23
use EasyWeChat\Core\AbstractAPI;
24
use EasyWeChat\Support\Collection;
25
use EasyWeChat\Support\XML;
26
use Psr\Http\Message\ResponseInterface;
27
28
/**
29
 * Class API.
30
 */
31
class API extends AbstractAPI
32
{
33
    /**
34
     * Merchant instance.
35
     *
36
     * @var Merchant
37
     */
38
    protected $merchant;
39
40
    // api
41
    const API_PAY_ORDER = 'https://api.mch.weixin.qq.com/pay/micropay';
42
    const API_PREPARE_ORDER = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
43
    const API_QUERY = 'https://api.mch.weixin.qq.com/pay/orderquery';
44
    const API_CLOSE = 'https://api.mch.weixin.qq.com/pay/closeorder';
45
    const API_REVERSE = 'https://api.mch.weixin.qq.com/secapi/pay/reverse';
46
    const API_REFUND = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
47
    const API_QUERY_REFUND = 'https://api.mch.weixin.qq.com/pay/refundquery';
48
    const API_DOWNLOAD_BILL = 'https://api.mch.weixin.qq.com/pay/downloadbill';
49
    const API_REPORT = 'https://api.mch.weixin.qq.com/payitil/report';
50
    const API_URL_SHORTEN = 'https://api.mch.weixin.qq.com/tools/shorturl';
51
    const API_AUTH_CODE_TO_OPENID = 'https://api.mch.weixin.qq.com/tools/authcodetoopenid';
52
53
    // order id types.
54
    const TRANSCATION_ID = 'transcation_id';
55
    const OUT_TRADE_NO = 'out_trade_no';
56
    const OUT_REFUND_NO = 'out_refund_no';
57
    const REFUND_ID = 'refund_id';
58
59
    // bill types.
60
    const BILL_TYPE_ALL = 'ALL';
61
    const BILL_TYPE_SUCCESS = 'SUCCESS';
62
    const BILL_TYPE_REFUND = 'REFUND';
63
    const BILL_TYPE_REVOKED = 'REVOKED';
64
65
    /**
66
     * API constructor.
67
     *
68
     * @param \EasyWeChat\Payment\Merchant $merchant
69
     */
70 11
    public function __construct(Merchant $merchant)
71
    {
72 11
        $this->merchant = $merchant;
73 11
    }
74
75
    /**
76
     * Pay the order.
77
     *
78
     * @param Order $order
79
     *
80
     * @return \EasyWeChat\Support\Collection
81
     */
82
    public function pay(Order $order)
83
    {
84
        return $this->request(self::API_PAY_ORDER, $order->all());
85
    }
86
87
    /**
88
     * Prepare order to pay.
89
     *
90
     * @param Order $order
91
     *
92
     * @return \EasyWeChat\Support\Collection
93
     */
94 1
    public function prepare(Order $order)
95
    {
96 1
        return $this->request(self::API_PREPARE_ORDER, $order->all());
97
    }
98
99
    /**
100
     * Query order.
101
     *
102
     * @param string $orderNo
103
     * @param string $type
104
     */
105 1
    public function query($orderNo, $type = self::OUT_TRADE_NO)
106
    {
107
        $params = [
108 1
            $type => $orderNo,
109 1
        ];
110
111 1
        return $this->request(self::API_QUERY, $params);
112
    }
113
114
    /**
115
     * Query order by transcation_id.
116
     *
117
     * @param string $transcationId
118
     *
119
     * @return \EasyWeChat\Support\Collection
120
     */
121 1
    public function queryByTranscationId($transcationId)
122
    {
123 1
        return $this->query($transcationId, self::TRANSCATION_ID);
124
    }
125
126
    /**
127
     * Close order by out_trade_no.
128
     *
129
     * @param $tradeNo
130
     *
131
     * @return \EasyWeChat\Support\Collection
132
     */
133 1
    public function close($tradeNo)
134
    {
135
        $params = [
136 1
            'out_trade_no' => $tradeNo,
137 1
        ];
138
139 1
        return $this->request(self::API_CLOSE, $params);
140
    }
141
142
    /**
143
     * Reverse order.
144
     *
145
     * @param string $orderNo
146
     * @param string $type
147
     *
148
     * @return \EasyWeChat\Support\Collection
149
     */
150 1
    public function reverse($orderNo, $type = self::OUT_TRADE_NO)
151
    {
152
        $params = [
153 1
            $type => $orderNo,
154 1
        ];
155
156 1
        return $this->request(self::API_REVERSE, $params);
157
    }
158
159
    /**
160
     * Reverse order by transcation_id.
161
     *
162
     * @param int $transcationId
163
     *
164
     * @return \EasyWeChat\Support\Collection
165
     */
166
    public function reverseByTranscationId($transcationId)
167
    {
168
        return $this->reverse($transcationId, self::TRANSCATION_ID);
169
    }
170
171
    /**
172
     * Make a refund request.
173
     *
174
     * @param string $orderNo
175
     * @param float  $totalFee
176
     * @param float  $refundFee
177
     * @param string $opUserId
178
     * @param string $type
179
     *
180
     * @return \EasyWeChat\Support\Collection
181
     */
182 1
    public function refund(
183
        $orderNo,
184
        $totalFee,
185
        $refundFee = null,
186
        $opUserId = null,
187
        $type = self::OUT_TRADE_NO
188
        ) {
189
        $params = [
190 1
            $type => $orderNo,
191 1
            'total_fee' => $totalFee,
192 1
            'refund_fee' => $refundFee ?: $totalFee,
193 1
            'refund_fee_type' => $this->merchant->fee_type,
194 1
            'op_user_id' => $opUserId ?: $this->merchant->merchant_id,
195 1
        ];
196
197 1
        return $this->request(self::API_REFUND, $params);
198
    }
199
200
    /**
201
     * Refund by transcation id.
202
     *
203
     * @param string $orderNo
204
     * @param float  $totalFee
205
     * @param float  $refundFee
206
     * @param string $opUserId
207
     *
208
     * @return \EasyWeChat\Support\Collection
209
     */
210
    public function refundByTranscationId(
211
        $orderNo,
212
        $totalFee,
213
        $refundFee = null,
214
        $opUserId = null
215
        ) {
216
        return $this->refund($orderNo, $totalFee, $refundFee, $opUserId, self::TRANSCATION_ID);
217
    }
218
219
    /**
220
     * Query refund status.
221
     *
222
     * @param string $orderNo
223
     * @param string $type
224
     *
225
     * @return \EasyWeChat\Support\Collection
226
     */
227 1
    public function queryRefund($orderNo, $type = self::OUT_TRADE_NO)
228
    {
229
        $params = [
230 1
            $type => $orderNo,
231 1
        ];
232
233 1
        return $this->request(self::API_QUERY_REFUND, $params);
234
    }
235
236
    /**
237
     * Query refund status by out_refund_no.
238
     *
239
     * @param string $refundNo
240
     *
241
     * @return \EasyWeChat\Support\Collection
242
     */
243
    public function queryRefundByRefundNo($refundNo)
244
    {
245
        return $this->queryRefund($refundNo, self::OUT_REFUND_NO);
246
    }
247
248
    /**
249
     * Query refund status by transaction_id.
250
     *
251
     * @param string $transcationId
252
     *
253
     * @return \EasyWeChat\Support\Collection
254
     */
255
    public function queryRefundByTranscationId($transcationId)
256
    {
257
        return $this->queryRefund($transcationId, self::TRANSCATION_ID);
258
    }
259
260
    /**
261
     * Query refund status by refund_id.
262
     *
263
     * @param string $refundId
264
     *
265
     * @return \EasyWeChat\Support\Collection
266
     */
267
    public function queryRefundByRefundId($refundId)
268
    {
269
        return $this->queryRefund($refundId, self::REFUND_ID);
270
    }
271
272
    /**
273
     * Download bill history as a table file.
274
     *
275
     * @param string $date
276
     * @param string $type
277
     *
278
     * @return stream
279
     */
280 1
    public function downloadBill($date, $type = self::BILL_TYPE_ALL)
281
    {
282
        $params = [
283 1
            'bill_date' => $date,
284 1
            'bill_type' => $type,
285 1
        ];
286
287 1
        return $this->request(self::API_DOWNLOAD_BILL, $params);
288
    }
289
290
    /**
291
     * Convert long url to short url.
292
     *
293
     * @param string $url
294
     *
295
     * @return \EasyWeChat\Support\Collection
296
     */
297 1
    public function urlShorten($url)
298
    {
299 1
        return $this->request(self::API_URL_SHORTEN, ['long_url' => $url]);
300
    }
301
302
    /**
303
     * Report API status to WeChat.
304
     *
305
     * @param string $api
306
     * @param int    $timeConsuming
307
     * @param string $resultCode
308
     * @param string $returnCode
309
     * @param array  $other         ex: err_code,err_code_des,out_trade_no,user_ip...
310
     *
311
     * @return \EasyWeChat\Support\Collection
312
     */
313
    public function report($api, $timeConsuming, $resultCode, $returnCode, array $other = [])
0 ignored issues
show
Coding Style introduced by
report uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
314
    {
315
        $params = array_merge([
316
            'interface_url' => $api,
317
            'execute_time_' => $timeConsuming,
318
            'return_code' => $returnCode,
319
            'return_msg' => null,
320
            'result_code' => $resultCode,
321
            'user_ip' => $_SERVER['SERVER_ADDR'],
322
            'time' => time(),
323
        ], $other);
324
325
        return $this->request(self::API_REPORT, $params);
326
    }
327
328
    /**
329
     * Get openid by auth code.
330
     *
331
     * @param string $authCode
332
     *
333
     * @return \EasyWeChat\Support\Collection
334
     */
335 1
    public function authCodeToOpenId($authCode)
336
    {
337 1
        return $this->request(self::API_AUTH_CODE_TO_OPENID, ['auth_code' => $authCode]);
338
    }
339
340
    /**
341
     * Merchant setter.
342
     *
343
     * @param Merchant $merchant
344
     *
345
     * @return $this
346
     */
347 1
    public function setMerchant(Merchant $merchant)
348
    {
349 1
        $this->merchant = $merchant;
350 1
    }
351
352
    /**
353
     * Merchant getter.
354
     *
355
     * @return Merchant
356
     */
357 1
    public function getMerchant()
358
    {
359 1
        return $this->merchant;
360
    }
361
362
    /**
363
     * Make a API request.
364
     *
365
     * @param string $api
366
     * @param array  $params
367
     * @param string $method
368
     *
369
     * @return \EasyWeChat\Support\Collection
370
     */
371 9
    protected function request($api, array $params, $method = 'post')
372
    {
373 9
        $params['appid'] = $this->merchant->app_id;
374 9
        $params['mch_id'] = $this->merchant->merchant_id;
375 9
        $params['device_info'] = $this->merchant->device_info;
376 9
        $params['time_stamp'] = time();
377 9
        $params['nonce_str'] = uniqid();
378 9
        $params['sign'] = generate_sign($params, $this->merchant->key, 'md5');
379
380 9
        return $this->parseResponse($this->getHttp()->{$method}($api, XML::build($params)));
381
    }
382
383
    /**
384
     * Parse Response XML to array.
385
     *
386
     * @param string $response
387
     *
388
     * @return \EasyWeChat\Support\Collection
389
     */
390 9
    protected function parseResponse($response)
391
    {
392 9
        if ($response instanceof ResponseInterface) {
393
            $response = $response->getBody();
394
        }
395
396 9
        return new Collection((array) XML::parse($response));
397
    }
398
}
399