Api::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 4
crap 2
1
<?php
2
3
namespace PayumTW\Mypay;
4
5
use LogicException;
6
use Http\Message\MessageFactory;
7
use Payum\Core\HttpClientInterface;
8
use Payum\Core\Exception\Http\HttpException;
9
10
class Api
11
{
12
    const NOTIFY_TOKEN_FIELD = 'echo_4';
13
14
    // 1  CREDITCARD  信用卡
15
    const CREDITCARD = 'CREDITCARD';
16
    // 2  RECHARGE  儲值卡
17
    const RECHARGE = 'RECHARGE';
18
    // 3  CSTORECODE  超商代碼
19
    const CSTORECODE = 'CSTORECODE';
20
    // 4  WEBATM  WEBATM
21
    const WEBATM = 'WEBATM';
22
    // 5  TELECOM  電信小額
23
    const TELECOM = 'TELECOM';
24
    // 6  E_COLLECTION  虛擬帳號
25
    const E_COLLECTION = 'E_COLLECTION';
26
    // 7  UNIONPAY  銀聯卡
27
    const UNIONPAY = 'UNIONPAY';
28
    // 8  SVC  點數卡
29
    const SVC = 'SVC';
30
    // 9  ABROAD  海外信用卡
31
    const ABROAD = 'ABROAD';
32
    // 10  ALIPAY  支付寶
33
    const ALIPAY = 'ALIPAY';
34
    // 11  SMARTPAY  Smart Pay
35
    const SMARTPAY = 'SMARTPAY';
36
37
    /**
38
     * @var \Payum\Core\HttpClientInterface
39
     */
40
    protected $client;
41
42
    /**
43
     * @var \Http\Message\MessageFactory
44
     */
45
    protected $messageFactory;
46
47
    /**
48
     * @var array
49
     */
50
    protected $options = [];
51
52
    /**
53
     * $encrypter.
54
     *
55
     * @var Encrypter
56
     */
57
    protected $encrypter;
58
59
    /**
60
     * @param array $options
61
     * @param \Payum\Core\HttpClientInterface $client
62
     * @param \Http\Message\MessageFactory $messageFactory
63
     * @param Encrypter $encrypter
64
     *
65
     * @throws \Payum\Core\Exception\InvalidArgumentException if an option is invalid
66
     */
67 7
    public function __construct(array $options, HttpClientInterface $client, MessageFactory $messageFactory, Encrypter $encrypter = null)
68
    {
69 7
        $this->options = $options;
70 7
        $this->client = $client;
71 7
        $this->messageFactory = $messageFactory;
72 7
        $this->encrypter = $encrypter ?: new Encrypter($this->options['key']);
73 7
    }
74
75
    /**
76
     * getApiEndpoint.
77
     *
78
     * @return string
79
     */
80 5
    public function getApiEndpoint()
81
    {
82 5
        return $this->options['sandbox'] === false ? 'https://mypay.tw/api/init' : 'https://pay.usecase.cc/api/init';
83
    }
84
85
    /**
86
     * createTransaction.
87
     *
88
     * @param array $params
89
     * @return array
90
     */
91 1
    public function createTransaction(array $params)
92
    {
93
        $supportedParams = [
94
            // 次特店商務代號  必要  必要
95 1
            'store_uid' => $this->options['store_uid'],
96
            // 消費者帳號(請代入於貴特店中該消費者登記的帳號)  必要  必要
97
            'user_id' => null,
98
            // 消費者姓名(請代入於貴特店中該消費者登記的名稱)
99
            'user_name' => null,
100
            // 消費者真實姓名
101
            'user_real_name' => null,
102
            // 消費者帳單地址
103
            'user_address' => null,
104
            // 消費者身份證字號
105
            'user_sn' => null,
106
            // 消費者家用電話(白天電話)
107
            'user_phone' => null,
108
            // 行動電話國碼(預設886)​
109 1
            'user_cellphone_code' => '886',
110
            // 消費者行動電話
111
            'user_cellphone' => null,
112
            // 消費者 E­Mail
113
            'user_email' => null,
114
            // 消費者生日(格式為 YYYYMMDD,如 20090916)
115
            'user_birthday' => null,
116
            // 訂單總金額(如為定期定額付費,此為一期的金額) = 物品 之總價加總 ­ 折價  必要  必要
117
            'cost' => null,
118
            // 預設交易幣別
119 1
            'currency' => 'TWD',
120
            // 訂單編號(訂單編號建議不要重覆)  必要  必要
121
            'order_id' => null,
122
            // 消費者來源 IP  必要  必要
123 1
            'ip' => $this->options['ip'],
124
            // 訂單內物品數  必要
125
            'item' => null,
126
            /*
127
             * 定期定額付費,期數單位:
128
             * W 為每週定期一次扣款;
129
             * M 為每月定期一次扣款;
130
             * S 為每季定期
131
             * 一次扣款。如未使用到定期定額付費,不需傳此參數
132
             */
133
            'regular' => null,
134
            // 總期數(如為 12 期即代入 12,如果為不限期數,請代入  0,如非定期定額付費,不需傳此參數
135
            'regular_total' => null,
136
            // 1.定期定額式付費編號 2.定期分期式付費編號
137
            'group_id' => null,
138
            // 票券總產生張數
139
            'voucher_total_count' => null,
140
            // 物品總金額
141
            'voucher_total_price ' => null,
142
            // 票券物品數
143
            'voucher_item' => null,
144
            // 預選付費方法,如 pfn=CREDITCARD 即為信用卡付 費。多種類型可用逗號隔開,其他參數請參照附錄一。  必要  必要
145 1
            'pfn' => static::CREDITCARD,
146
            // 交易成功後的轉址(若動態網址可以使用此方式傳遞)
147
            'success_returl' => null,
148
            // 交易失敗後的轉址(若動態網址可以使用此方式傳遞)
149
            'failure_returl' => null,
150
            // 折價(​數值帶負數​)
151
            'discount' => null,
152
            // 當pfn=CSTORECODE或 E_COLLECTION時,此為自訂有效使 用天數,否則以系統設定為預設有效天數
153
            'limit_pay_days' => null,
154
            // 運費,
155
            'shipping_fee' => null,
156
            // 啟用快速結帳
157 1
            'enable_quickpay' => 1,
158
            // 啟用電子錢包
159 1
            'enable_ewallet' => 0,
160
            // 消費者完成電子錢包卡號綁定後 ,直接使用本參數,系統會自動 從綁定卡號扣款 若使用本參數,pfn將自動限制為 信用卡與海外信用卡兩種交易(虛 擬卡號在消費者啟用電子錢包時 ,會背景告知相關資訊,
161
            'virtual_pan' => null,
162
            // 1.支付頁面模式,mypay顯示結果 (預設) 2.背景發動扣款(直接回傳交易回 報參數)
163 1
            'ewallet_type' => 1,
164
            // 定期扣款起扣日(若未指定日期, 或小於今日則將判為當日扣)
165
            'regular_first_charge_date' => null,
166
            // 1網路交易(預設)/2實體交易
167
            'transaction_type' => null,
168
            // 國內信用卡分期限定顯示期數(且必須服務商與 支付頁面設定有支援)
169
            'creditcard_installment' => null,
170
            // 無卡支付商品名稱代碼
171
            'cardless_code' => null,
172
            // 1: 應稅 2:零稅率 3: 免稅
173
            'invoice_ratetype' => null,
174
        ];
175
176 1
        $supportedItemParams = ['id', 'name', 'cost', 'amount'];
177 1
        if (isset($params['items']) === true) {
178 1
            $params['item'] = count($params['items']);
179 1
            $total = 0;
180 1
            foreach ($params['items'] as $key => $item) {
181 1
                if (empty($item['cost']) === true) {
182 1
                    $item['cost'] = $item['price'];
183
                }
184 1
                if (empty($item['amount']) === true) {
185 1
                    $item['amount'] = $item['quantity'];
186
                }
187 1
                foreach ($supportedItemParams as $name) {
188 1
                    $params['i_'.$key.'_'.$name] = $item[$name];
189
                }
190 1
                $params['i_'.$key.'_total'] = $item['cost'] * $item['amount'];
191 1
                $total += $params['i_'.$key.'_total'];
192
            }
193 1
            if (empty($params['cost'])) {
194 1
                $params['cost'] = $total;
195
            }
196
        }
197
198
        // 將 i_,v_,echo_ 開頭加入 $supportedParams
199 1
        foreach ($params as $key => $value) {
200 1
            if (preg_match('/(i|v|echo)_\d+/', $key)) {
201 1
                $supportedParams[$key] = null;
202
            }
203
        }
204
205 1
        $params = array_filter(array_replace(
206 1
            $supportedParams,
207 1
            array_intersect_key($params, $supportedParams)
208
        ));
209
210 1
        return $this->doRequest(
211 1
            $this->encrypter->encryptRequest($this->options['store_uid'], $params, 'api/orders')
212
        );
213
    }
214
215
    /**
216
     * getTransactionData.
217
     *
218
     * @param array $params
219
     * @return array
220
     */
221 1
    public function getTransactionData(array $params)
222
    {
223
        $supportedParams = [
224 1
            'uid' => null,
225
            'key' => null,
226
        ];
227
228 1
        $params = array_filter(array_replace(
229 1
            $supportedParams,
230 1
            array_intersect_key($params, $supportedParams)
231
        ));
232
233 1
        return $this->doRequest(
234 1
            $this->encrypter->encryptRequest($this->options['store_uid'], $params, 'api/queryorder')
235
        );
236
    }
237
238
    /**
239
     * refundTransaction.
240
     *
241
     * @param array $params
242
     * @return array
243
     */
244 1 View Code Duplication
    public function refundTransaction(array $params)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
245
    {
246
        $supportedParams = [
247 1
            'store_uid' => $this->options['store_uid'],
248
            'uid' => null,
249
            'key' => null,
250
            'cost' => null,
251
        ];
252
253 1
        $params = array_filter(array_replace(
254 1
            $supportedParams,
255 1
            array_intersect_key($params, $supportedParams)
256
        ));
257
258 1
        return $this->doRequest(
259 1
            $this->encrypter->encryptRequest($this->options['store_uid'], $params, 'api/refund')
260
        );
261
    }
262
263
    /**
264
     * cancelTransaction.
265
     *
266
     * @param array $params
267
     * @return array
268
     */
269 1 View Code Duplication
    public function cancelTransaction(array $params)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
270
    {
271
        $supportedParams = [
272 1
            'store_uid' => $this->options['store_uid'],
273
            'uid' => null,
274
            'key' => null,
275
        ];
276
277 1
        $params = array_filter(array_replace(
278 1
            $supportedParams,
279 1
            array_intersect_key($params, $supportedParams)
280
        ));
281
282 1
        return $this->doRequest(
283 1
            $this->encrypter->encryptRequest($this->options['store_uid'], $params, 'api/refundcancel')
284
        );
285
    }
286
287
    /**
288
     * verifyHash.
289
     *
290
     * @param array $params
291
     * @param array $details
292
     * @return bool
293
     */
294 1
    public function verifyHash(array $params, $details)
295
    {
296 1
        return $params['key'] === $details['key'];
297
    }
298
299
    /**
300
     * @param array $fields
301
     * @return array
302
     */
303 4
    protected function doRequest(array $fields)
304
    {
305 4
        $request = $this->messageFactory->createRequest('POST', $this->getApiEndpoint(), [
306 4
            'Content-Type' => 'application/x-www-form-urlencoded',
307 4
        ], http_build_query($fields));
308
309 4
        $response = $this->client->send($request);
310
311 4
        $statusCode = $response->getStatusCode();
312 4
        if (false === ($statusCode >= 200 && $statusCode < 300)) {
313
            throw HttpException::factory($request, $response);
314
        }
315
316 4
        $body = $response->getBody()->getContents();
317 4
        $content = json_decode($body, true);
318 4
        if (null === $content) {
319
            throw new LogicException("Response content is not valid json: \n\n{$body}");
320
        }
321
322 4
        return $content;
323
    }
324
}
325