Completed
Pull Request — master (#288)
by Carlos
02:48
created

Payment::configForShareAddress()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 3

Importance

Changes 4
Bugs 0 Features 1
Metric Value
c 4
b 0
f 1
dl 0
loc 26
ccs 18
cts 18
cp 1
rs 8.8571
cc 3
eloc 17
nc 4
nop 2
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
 * Payment.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\AccessToken;
24
use EasyWeChat\Core\Exceptions\FaultException;
25
use EasyWeChat\Support\Url as UrlHelper;
26
use EasyWeChat\Support\XML;
27
use Symfony\Component\HttpFoundation\Response;
28
29
/**
30
 * Class Payment.
31
 */
32
class Payment
33
{
34
    /**
35
     * Scheme base path.
36
     */
37
    const SCHEME_PATH = 'weixin://wxpay/bizpayurl';
38
39
    /**
40
     * @var API
41
     */
42
    protected $api;
43
44
    /**
45
     * Merchant instance.
46
     *
47
     * @var \EasyWeChat\Payment\Merchant
48
     */
49
    protected $merchant;
50
51
    /**
52
     * Constructor.
53
     *
54
     * @param Merchant $merchant
55
     */
56 7
    public function __construct(Merchant $merchant)
57
    {
58 7
        $this->merchant = $merchant;
59 7
    }
60
61
    /**
62
     * Build payment scheme for product.
63
     *
64
     * @param string $productId
65
     *
66
     * @return string
67
     */
68 1
    public function scheme($productId)
69
    {
70
        $params = [
71 1
            'appid' => $this->merchant->app_id,
72 1
            'mch_id' => $this->merchant->merchant_id,
73 1
            'time_stamp' => time(),
74 1
            'nonce_str' => uniqid(),
75 1
            'product_id' => $productId,
76 1
        ];
77
78 1
        $params['sign'] = generate_sign($params, $this->merchant->key, 'md5');
79
80 1
        return self::SCHEME_PATH.'?'.http_build_query($params);
81
    }
82
83
    /**
84
     * Handle payment notify.
85
     *
86
     * @param callable $callback
87
     *
88
     * @return Response
89
     */
90 2
    public function handleNotify(callable $callback)
91
    {
92 2
        $notify = $this->getNotify();
93
94 2
        if (!$notify->isValid()) {
95 1
            throw new FaultException('Invalid request XML.', 400);
96
        }
97
98 1
        $notify = $notify->getNotify();
99 1
        $successful = $notify->get('result_code') === 'SUCCESS';
100
101 1
        $handleResult = call_user_func_array($callback, [$notify, $successful]);
102
103 1
        if (is_bool($handleResult) && $handleResult) {
104
            $response = [
105 1
                'return_code' => 'SUCCESS',
106 1
                'return_msg' => 'OK',
107 1
            ];
108 1
        } else {
109
            $response = [
110 1
                'return_code' => 'FAIL',
111 1
                'return_msg' => $handleResult,
112 1
            ];
113
        }
114
115 1
        return new Response(XML::build($response));
116
    }
117
118
    /**
119
     * Gernerate js config for payment.
120
     *
121
     * @param string $prepayId
122
     * @param bool   $json
123
     *
124
     * @return string|array
125
     */
126 1
    public function configForPayment($prepayId, $json = true)
127
    {
128
        $params = [
129 1
            'appId' => $this->merchant->app_id,
130 1
            'timeStamp' => strval(time()),
131 1
            'nonceStr' => uniqid(),
132 1
            'package' => "prepay_id=$prepayId",
133 1
            'signType' => 'MD5',
134 1
        ];
135
136 1
        $params['paySign'] = generate_sign($params, $this->merchant->key, 'md5');
137
138 1
        return $json ? json_encode($params) : $params;
139
    }
140
141
    /**
142
     * Generate js config for share user address.
143
     *
144
     * @param string|accessToken $accessToken
145
     * @param bool               $json
146
     *
147
     * @return string|array
148
     */
149 1
    public function configForShareAddress($accessToken, $json = true)
150
    {
151 1
        if ($accessToken instanceof AccessToken) {
152 1
            $accessToken = $accessToken->getToken();
153 1
        }
154
155
        $params = [
156 1
            'appId' => $this->merchant->app_id,
157 1
            'scope' => 'jsapi_address',
158 1
            'timeStamp' => strval(time()),
159 1
            'nonceStr' => uniqid(),
160 1
            'signType' => 'SHA1',
161 1
        ];
162
163
        $signParams = [
164 1
            'appid' => $params['appId'],
165 1
            'url' => UrlHelper::current(),
166 1
            'timestamp' => $params['timeStamp'],
167 1
            'noncestr' => $params['nonceStr'],
168 1
            'accesstoken' => $accessToken,
169 1
        ];
170
171 1
        $params['addrSign'] = generate_sign($signParams, $this->merchant->key, 'sha1');
172
173 1
        return $json ? json_encode($params) : $params;
174
    }
175
176
    /**
177
     * Merchant setter.
178
     *
179
     * @param Merchant $merchant
180
     */
181 1
    public function setMerchant(Merchant $merchant)
182
    {
183 1
        $this->merchant = $merchant;
184 1
    }
185
186
    /**
187
     * Merchant getter.
188
     *
189
     * @return Merchant
190
     */
191 1
    public function getMerchant()
192
    {
193 1
        return $this->merchant;
194
    }
195
196
    /**
197
     * Return Notify instance.
198
     *
199
     * @return \EasyWeChat\Payment\Notify
200
     */
201 1
    public function getNotify()
202
    {
203 1
        return new Notify($this->merchant);
204
    }
205
206
    /**
207
     * API setter.
208
     *
209
     * @param API $api
210
     */
211 1
    public function setAPI(API $api)
212
    {
213 1
        $this->api = $api;
214 1
    }
215
216
    /**
217
     * Return API instance.
218
     *
219
     * @return API
220
     */
221 1
    public function getAPI()
222
    {
223 1
        return $this->api ?: $this->api = new API($this->getMerchant());
224
    }
225
226
    /**
227
     * Magic call.
228
     *
229
     * @param string $method
230
     * @param array  $args
231
     *
232
     * @return mixed
233
     *
234
     * @codeCoverageIgnore
235
     */
236
    public function __call($method, $args)
237
    {
238
        if (is_callable([$this->getAPI(), $method])) {
239
            return call_user_func_array([$this->api, $method], $args);
240
        }
241
    }
242
}
243