Completed
Push — master ( 4051f5...1a3481 )
by recca
02:04
created

Api::call()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 9
cts 9
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 2
crap 1
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 5
    public function __construct(array $options, HttpClientInterface $client, MessageFactory $messageFactory, Encrypter $encrypter = null)
68
    {
69 5
        $this->options = $options;
70 5
        $this->client = $client;
71 5
        $this->messageFactory = $messageFactory;
72 5
        $this->encrypter = $encrypter ?: new Encrypter($this->options['key']);
73 5
    }
74
75
    /**
76
     * @param array $fields
77
     * @return array
78
     */
79 2
    protected function doRequest(array $fields)
80
    {
81 2
        $request = $this->messageFactory->createRequest('POST', $this->getApiEndpoint(), [
82 2
            'Content-Type' => 'application/x-www-form-urlencoded',
83 2
        ], http_build_query($fields));
84
85 2
        $response = $this->client->send($request);
86
87 2
        $statusCode = $response->getStatusCode();
88 2
        if (false === ($statusCode >= 200 && $statusCode < 300)) {
89
            throw HttpException::factory($request, $response);
90
        }
91
92 2
        $body = $response->getBody()->getContents();
93 2
        $content = json_decode($body, true);
94 2
        if (null === $content) {
95
            throw new LogicException("Response content is not valid json: \n\n{$body}");
96
        }
97
98 2
        return $content;
99
    }
100
101
    /**
102
     * getApiEndpoint.
103
     *
104
     * @return string
105
     */
106 3
    public function getApiEndpoint()
107
    {
108 3
        return $this->options['sandbox'] === false ? 'https://mypay.tw/api/init' : 'https://pay.usecase.cc/api/init';
109
    }
110
111
    /**
112
     * createTransaction.
113
     *
114
     * @param array $params
115
     * @return array
116
     */
117 1
    public function createTransaction(array $params)
118
    {
119
        $supportedParams = [
120
            // 次特店商務代號  必要  必要
121 1
            'store_uid' => $this->options['store_uid'],
122
            // 消費者帳號(請代入於貴特店中該消費者登記的帳號)  必要  必要
123 1
            'user_id' => null,
124
            // 消費者姓名(請代入於貴特店中該消費者登記的名稱)
125 1
            'user_name' => null,
126
            // 消費者真實姓名
127 1
            'user_real_name' => null,
128
            // 消費者帳單地址
129 1
            'user_address' => null,
130
            // 消費者身份證字號
131 1
            'user_sn' => null,
132
            // 消費者家用電話(白天電話)
133 1
            'user_phone' => null,
134
            // 消費者行動電話
135 1
            'user_cellphone' => null,
136
            // 消費者 E­Mail
137 1
            'user_email' => null,
138
            // 消費者生日(格式為 YYYYMMDD,如 20090916)
139 1
            'user_birthday' => null,
140
            // 訂單總金額(如為定期定額付費,此為一期的金額) = 物品 之總價加總 ­ 折價  必要  必要
141 1
            'cost' => null,
142
            // 訂單編號(訂單編號建議不要重覆)  必要  必要
143 1
            'order_id' => null,
144
            // 消費者來源 IP  必要  必要
145 1
            'ip' => $this->options['ip'],
146
            // 訂單內物品數  必要
147 1
            'item' => null,
148
            /*
149
             * 定期定額付費,期數單位:
150
             * W 為每週定期一次扣款;
151
             * M 為每月定期一次扣款;
152
             * S 為每季定期
153
             * 一次扣款。如未使用到定期定額付費,不需傳此參數
154
             */
155 1
            'regular' => null,
156
            // 總期數(如為 12 期即代入 12,如果為不限期數,請代入  0,如非定期定額付費,不需傳此參數
157 1
            'regular_total' => null,
158
            // 票券總產生張數
159 1
            'voucher_total_count' => null,
160
            // 物品總金額
161 1
            'voucher_total_price '=> null,
162
            // 票券物品數
163 1
            'voucher_item' => null,
164
            // 預選付費方法,如 pfn=CREDITCARD 即為信用卡付 費。多種類型可用逗號隔開,其他參數請參照附錄一。  必要  必要
165 1
            'pfn' => static::CREDITCARD,
166
            // 交易成功後的轉址(若動態網址可以使用此方式傳遞)
167 1
            'success_returl' => null,
168
            // 交易失敗後的轉址(若動態網址可以使用此方式傳遞)
169 1
            'failure_returl' => null,
170
            // 折價
171 1
            'discount' => null,
172
            // 當pfn=CSTORECODE或 E_COLLECTION時,此為自訂有效使 用天數,否則以系統設定為預設有效天數
173 1
            'limit_pay_days' => null,
174
            // 運費,
175 1
            'shipping_fee' => null,
176 1
        ];
177
178 1
        $supportedItemParams = ['id', 'name', 'cost', 'amount'];
179 1
        if (isset($params['items']) === true) {
180 1
            $params['item'] = count($params['items']);
181 1
            $total = 0;
182 1
            foreach ($params['items'] as $key => $item) {
183 1
                if (empty($item['cost']) === true) {
184 1
                    $item['cost'] = $item['price'];
185 1
                }
186 1
                if (empty($item['amount']) === true) {
187 1
                    $item['amount'] = $item['quantity'];
188 1
                }
189 1
                foreach ($supportedItemParams as $name) {
190 1
                    $params['i_'.$key.'_'.$name] = $item[$name];
191 1
                }
192 1
                $params['i_'.$key.'_total'] = $item['cost'] * $item['amount'];
193 1
                $total += $params['i_'.$key.'_total'];
194 1
            }
195 1
            if (empty($params['cost'])) {
196 1
                $params['cost'] = $total;
197 1
            }
198 1
        }
199
200
        // 將 i_,v_,echo_ 開頭加入 $supportedParams
201 1
        foreach ($params as $key => $value) {
202 1
            if (preg_match('/(i|v|echo)_\d+/', $key)) {
203 1
                $supportedParams[$key] = null;
204 1
            }
205 1
        }
206
207 1
        $params = array_filter(array_replace(
208 1
            $supportedParams,
209 1
            array_intersect_key($params, $supportedParams)
210 1
        ));
211
212 1
        return $this->doRequest(
213 1
            $this->encrypter->encryptRequest($this->options['store_uid'], $params, 'api/orders')
214 1
        );
215
    }
216
217
    /**
218
     * getTransactionData.
219
     *
220
     * @param mixed $params
221
     * @return array
222
     */
223 1
    public function getTransactionData(array $params)
224
    {
225
        $supportedParams = [
226 1
            'uid' => null,
227 1
            'key' => null,
228 1
        ];
229
230 1
        $params = array_filter(array_replace(
231 1
            $supportedParams,
232 1
            array_intersect_key($params, $supportedParams)
233 1
        ));
234
235 1
        return $this->doRequest(
236 1
            $this->encrypter->encryptRequest($this->options['store_uid'], $params, 'api/queryorder')
237 1
        );
238
    }
239
240
    /**
241
     * verifyHash.
242
     *
243
     * @param array $params
244
     * @param array $details
245
     * @return bool
246
     */
247 1
    public function verifyHash(array $params, $details)
248
    {
249 1
        return $params['key'] === $details['key'];
250
    }
251
}
252