├── .gitignore
├── .idea
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── dbnavigator.xml
├── encodings.xml
├── laravel-spgateway.iml
├── markdown-navigator.xml
├── markdown-navigator
│ └── profiles_settings.xml
├── modules.xml
├── php.xml
├── vcs.xml
└── workspace.xml
├── .phpintel
├── 4bbf36c8a4f9404bb82060c7ed08e25b
├── 4ebe2a4f36294d3cf0bbc08f915aaa61
├── b2f1b871702e46715c7b4161a8799be7
├── c4ea1d5a17bf3938721c8ccb615bd0a4
├── eb77a3262bce4409df8188f60055c61b
└── index
├── Laravel Spgateway.svg
├── README.md
├── composer.json
├── composer.lock
├── config
└── spgateway.php
├── resources
└── views
│ └── send-order.blade.php
└── src
├── Charge.php
├── Facades
├── Encrypt.php
├── MPG.php
├── Receipt.php
├── Refund.php
└── Transfer.php
├── Libraries
└── Helpers.php
├── MPG.php
├── Receipt.php
├── Refund.php
├── SpgatewayServiceProvider.php
└── Transfer.php
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/dbnavigator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/laravel-spgateway.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/php.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | $PROJECT_DIR$/composer.json
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | creditcard
91 |
92 |
93 |
94 |
95 |
96 |
97 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 | 1525935455844
160 |
161 |
162 | 1525935455844
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
--------------------------------------------------------------------------------
/.phpintel/4bbf36c8a4f9404bb82060c7ed08e25b:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s950329/laravel-spgateway/6a2dca3b3e6d73c3b51161fb88513db26ec0473d/.phpintel/4bbf36c8a4f9404bb82060c7ed08e25b
--------------------------------------------------------------------------------
/.phpintel/4ebe2a4f36294d3cf0bbc08f915aaa61:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s950329/laravel-spgateway/6a2dca3b3e6d73c3b51161fb88513db26ec0473d/.phpintel/4ebe2a4f36294d3cf0bbc08f915aaa61
--------------------------------------------------------------------------------
/.phpintel/b2f1b871702e46715c7b4161a8799be7:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s950329/laravel-spgateway/6a2dca3b3e6d73c3b51161fb88513db26ec0473d/.phpintel/b2f1b871702e46715c7b4161a8799be7
--------------------------------------------------------------------------------
/.phpintel/c4ea1d5a17bf3938721c8ccb615bd0a4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s950329/laravel-spgateway/6a2dca3b3e6d73c3b51161fb88513db26ec0473d/.phpintel/c4ea1d5a17bf3938721c8ccb615bd0a4
--------------------------------------------------------------------------------
/.phpintel/eb77a3262bce4409df8188f60055c61b:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s950329/laravel-spgateway/6a2dca3b3e6d73c3b51161fb88513db26ec0473d/.phpintel/eb77a3262bce4409df8188f60055c61b
--------------------------------------------------------------------------------
/.phpintel/index:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/s950329/laravel-spgateway/6a2dca3b3e6d73c3b51161fb88513db26ec0473d/.phpintel/index
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Laravel Spgateway
2 | [](https://packagist.org/packages/leochien/laravel-spgateway)
3 | [](https://packagist.org/packages/leochien/laravel-spgateway)
4 | [](https://packagist.org/packages/leochien/laravel-spgateway)
5 | [](https://packagist.org/packages/leochien/laravel-spgateway)
6 |
7 | Laravel Spgateway是一個開源的 [智付通](https://www.newebpay.com/) 非官方套件
8 |
9 | ## 目錄
10 | 1. [環境要求](#要求)
11 | 2. [安裝](#安裝)
12 | 3. [配置](#配置)
13 | 4. [使用](#使用)
14 | 1. [多功能收款MPG](#多功能收款MPG)
15 | 2. [電子發票](#電子發票串接)
16 | 3. [退款/取消授權](#退款/取消授權)
17 | 4. [平台費用扣款指示](#平台費用扣款指示)
18 | 5. [版本紀錄](#版本紀錄)
19 | 5. [License](#License)
20 |
21 | ## 要求
22 |
23 | 1. PHP >= 7.2.5
24 | 2. Laravel >= 7
25 | 3. Composer
26 |
27 | ## 安裝
28 |
29 | ```
30 | $ composer require leochien/laravel-spgateway
31 | ```
32 |
33 | ## 配置
34 |
35 | ### Laravel 應用
36 |
37 | 1. 在 `config/app.php` 註冊 ServiceProvider 和 Facade (Laravel 5.5 無須手動註冊)
38 |
39 | ```php
40 | 'providers' => [
41 | // ...
42 | LeoChien\Spgateway\SpgatewayServiceProvider::class,
43 | ],
44 | 'aliases' => [
45 | // ...
46 | 'MPG' => LeoChien\Spgateway\Facades\MPG::class,
47 | 'Receipt' => LeoChien\Spgateway\Facades\Receipt::class,
48 | 'Refund' => LeoChien\Spgateway\Facades\Refund::class,
49 | 'Transfer' => LeoChien\Spgateway\Facades\Transfer::class,
50 | ],
51 | ```
52 |
53 | 2. 創建設定檔:
54 |
55 | ```shell
56 | php artisan vendor:publish --provider="LeoChien\Spgateway\SpgatewayServiceProvider"
57 | ```
58 |
59 | 3. 修改 `config/spgateway.php` 中對應的參數。
60 |
61 | 4. 在 `.env` 中加入下列設定
62 |
63 | ```
64 | # 金流系統設定
65 | SPGATEWAY_HASH_KEY=
66 | SPGATEWAY_HASH_IV=
67 |
68 | # 金流合作推廣商系統設定
69 | SPGATEWAY_COMPANY_KEY=
70 | SPGATEWAY_COMPANY_IV=
71 | SPGATEWAY_PARTNER_ID=
72 | SPGATEWAY_MERCHANT_ID_PREFIX=
73 | SPGATEWAY_MERCHANT_ID=
74 |
75 | # 發票系統設定
76 | SPGATEWAY_RECEIPT_KEY=
77 | SPGATEWAY_RECEIPT_IV=
78 | SPGATEWAY_RECEIPT_MERCHANT_ID=
79 | ```
80 |
81 | ## 使用
82 |
83 | ### 多功能收款MPG
84 |
85 | #### 快速上手
86 | 建立訂單
87 | ```
88 | // 產生智付通訂單資料
89 | $order = MPG::generate(
90 | 100,
91 | 'leo@hourmasters.com',
92 | '測試商品'
93 | );
94 |
95 | // $order的 getPostData() 及 getPostDataEncrypted() 會回傳包含即將傳送到智付通的表單資料,可在此時紀錄log
96 |
97 | // 前台送出表單到智付通
98 | return $order->send();
99 | ```
100 |
101 | 解析智付通回傳訂單資料
102 | ```
103 | $tradeInfo = MPG::parse(request()->TradeInfo);
104 | ```
105 |
106 | 查詢訂單
107 | ```
108 | $order = MPG::search(
109 | '20180110151950mTHuUY'
110 | 100
111 | );
112 | ```
113 |
114 | #### 可用方法
115 |
116 | > ### generate ($amount, $email, $itemDesc \[, $params \])
117 |
118 | 產生智付通建立訂單必要欄位
119 |
120 | ##### 參數
121 |
122 | 1. `amount (Integer)`: 訂單金額
123 | 2. `email (String)`: 訂購人Email
124 | 3. `itemDesc (String)`: 商品描述
125 | 5. `[ params (Array) ]`: 其他可選參數,詳見下方參數表
126 |
127 | ##### 回傳
128 |
129 | 1. `(Class)`: MPG Class實體,其中getPostData() 及 getPostDataEncrypted()會回傳即將送到智付通的表單資料
130 |
131 | ##### 使用範例
132 | ```
133 | $order = MPG::generate(
134 | 100,
135 | 'leo@hourmasters.com',
136 | '測試商品'
137 | );
138 | ```
139 |
140 | ##### 參數表
141 |
142 | | 欄位 | 型態 | 可選值 | 預設 | 備註 |
143 | |-----------------|:------------:|:-----------------:|:-------:|----------------------------------------------|
144 | | MerchantOrderNo | Varchar(20) | | | 商店自訂編號,若無填寫則由套件產生 |
145 | | LangType | String | `zh-tw` / `en` | `zh-tw` | |
146 | | TradeLimit | Number | 60 ~ 900 | 180 | |
147 | | ExpireDate | String (Ymd) | | | 範例:20171231 |
148 | | ReturnURL | Url | | | |
149 | | NotifyURL | Url | | | |
150 | | CustomerURL | Url | | | |
151 | | ClientBackURL | Url | | | |
152 | | EmailModify | Number | `0` / `1` | 1 | |
153 | | LoginType | Number | `0` / `1` | 0 | |
154 | | OrderComment | String | | | |
155 | | TokenTerm | String | | | 信用卡快速結帳 |
156 | | CREDIT | Number | `0` / `1` | | 信用卡一次付清 |
157 | | CreditRed | Number | `0` / `1` | | 信用卡紅利 |
158 | | InstFlag | Number | `0` / `1` | | 信用卡分期付款 |
159 | | UNIONPAY | Number | `0` / `1` | | 銀聯卡 |
160 | | WEBATM | Number | `0` / `1` | | WebATM |
161 | | VACC | Number | `0` / `1` | | ATM轉帳 |
162 | | CVS | Number | `0` / `1` | | 超商代碼繳費 |
163 | | BARCODE | Number | `0` / `1` | | 條碼繳費,訂單金額需介於20~20000 |
164 | | CREDITAGREEMENT | Number | `0` / `1` | | 約定信用卡授權 |
165 | | TokenLife | String | | | 約定信用卡付款之有效日期,範例:1912(2019-12) |
166 |
167 | ##### 備註
168 | * 支付方式若無選擇,默認開啟智付通後台設定方式
169 | * 若無傳送訂單編號預設會建立年月日時分秒+6位隨機字串的訂單編號,e.g. 20180110151950mTHuUY
170 |
171 | > ### send ()
172 |
173 | 前台送出智付通訂單建立表單
174 |
175 | ##### 使用範例
176 | ```
177 | $order->send();
178 | ```
179 |
180 | > ### parse ($tradeInfo)
181 |
182 | 解析智付通交易結果回傳參數,也適用於取號完成
183 |
184 | ##### 參數
185 |
186 | 1. `tradeInfo (String)`: 智付通回傳,經AES加密之交易資料
187 |
188 | ##### 回傳
189 | 詳見[智付通文件](https://www.newebpay.com/WebSiteData/document/5.pdf)第六節:交易支付系統回傳參數說明 / 第七節:取號完成系統回傳參數說明
190 | ```
191 | {
192 | "Status": "..."
193 | "Message": "..."
194 | "Result": {...}
195 | }
196 | ```
197 |
198 | ##### 使用範例
199 | ```
200 | $tradeInfo = MPG::parse(request()->TradeInfo);
201 | ```
202 |
203 | > ### search ($orderNo, $amount)
204 |
205 | 產生智付通查詢訂單必要欄位
206 |
207 | ##### 參數
208 |
209 | 1. `orderNo (String)`: 訂單編號
210 | 2. `amount (Integer)`: 訂單金額
211 |
212 | ##### 回傳
213 | 詳見[智付通文件](https://www.newebpay.com/WebSiteData/document/4.pdf)第四章:交易查詢系統回應訊息
214 | ```
215 | {
216 | "Status": "..."
217 | "Message": "..."
218 | "Result": {...}
219 | }
220 | ```
221 |
222 | ##### 使用範例
223 | ```
224 | // 查詢智付通訂單
225 | $order = MPG::search(
226 | '20180110151950mTHuUY'
227 | 100
228 | );
229 | ```
230 |
231 | ### 電子發票
232 |
233 | #### 快速上手
234 | 開立發票
235 | ```
236 | // 產生智付通開立發票資料
237 | $receipt = Receipt::generate([
238 | 'BuyerName' => 'Leo',
239 | 'TotalAmt' => 10,
240 | 'ItemName' => [1],
241 | 'ItemCount' => [1],
242 | 'ItemUnit' => ['式'],
243 | 'ItemPrice' => [10],
244 | ]);
245 |
246 | // $receipt的 getPostData() 及 getPostDataEncrypted 會回傳即將傳送到智付通的表單資料,可在此時紀錄log
247 |
248 | // 送出開立發票申請,取得發票開立回傳結果
249 | $res = $receipt->send();
250 | ```
251 |
252 | 觸發開立發票
253 | ```
254 | // 產生智付通出發開立發票資料
255 | $receipt = Receipt::generateTrigger('17122817285242624', '20171121WJNBX5NNBP', 100);
256 |
257 | // $receipt的 getTriggerPostData() 及 getTriggerPostDataEncrypted() 會回傳即將傳送到智付通的表單資料,可在此時紀錄log
258 |
259 | // 送出觸發開立發票申請,取得發票觸發開立回傳結果
260 | $res = $receipt->send();
261 | ```
262 |
263 | 作廢發票
264 | ```
265 | // 產生智付通作廢發票資料
266 | $receipt = Receipt::generateInvalid('YF83646422', '作廢原因');
267 |
268 | // $receipt的 getInvalidPostData() 及 getInvalidPostDataEncrypted() 會回傳即將傳送到智付通的表單資料,可在此時紀錄log
269 |
270 | // 送出作廢發票申請,取得作廢發票回傳結果
271 | $res = $receipt->sendInvalid();
272 | ```
273 |
274 | 查詢發票
275 | ```
276 | // 查詢發票資料
277 | $receipt = Receipt::search('20171121WJNBX5NNBP', 100);
278 | ```
279 | #### 可用方法
280 |
281 | > ### generate ($params)
282 |
283 | 產生智付通開立電子發票必要欄位
284 |
285 | ##### 參數
286 |
287 | 1. `params (Array)`: 詳見下方可選參數
288 |
289 | ##### 回傳
290 |
291 | 1. `(Class)`: Class實體,其中getPostData() 及 getPostDataEncrypted()包含即將送到智付通的表單資料
292 |
293 | ##### 使用範例
294 | ```
295 | $receipt = Receipt::generate([
296 | 'BuyerName' => 'Leo',
297 | 'TotalAmt' => 10,
298 | 'ItemName' => [1],
299 | 'ItemCount' => [1],
300 | 'ItemUnit' => ['式'],
301 | 'ItemPrice' => [10],
302 | ]);
303 | ```
304 |
305 | ##### 可選參數
306 |
307 | | 欄位 | 必填 | 型態 | 可選值 | 預設 | 備註 |
308 | |------------------|:----:|:--------------:|:---------------------:|:-----:|------------------------------------|
309 | | TransNum | | String | | | 智付寶平台交易序號 |
310 | | MerchantOrderNo | | String | | | 商店自訂編號,若無填寫則由套件產生 |
311 | | Status | | Number | `0` / `1` / `3` | 1 | 開立發票方式 |
312 | | CreateStatusTime | | String (Y-m-d) | | | 範例:2017-12-31 |
313 | | Category | | String | `B2B` / `B2C` | `B2C` | |
314 | | BuyerName | ✔ | String | | | |
315 | | BuyerUBN | | String | | | |
316 | | BuyerAddress | | String | | | |
317 | | BuyerEmail | | Email | | | |
318 | | CarrierType | | String | `0` / `1` | 1 | |
319 | | CarrierNum | | String | `0` / `1` | 0 | |
320 | | LoveCode | | Number | | | |
321 | | PrintFlag | | String | `Y` / `N` | `Y` | |
322 | | TaxType | | String | `1` / `2` / `3` / `9` | `1` | |
323 | | TaxRate | | Number | | `5` | |
324 | | CustomsClearance | | Number | `1` / `2` | | |
325 | | Amt | | Number | | | 若無填寫則由套件計算 |
326 | | AmtSales | | Number | | | |
327 | | AmtZero | | Number | | | |
328 | | AmtFree | | Number | | | |
329 | | TaxAmt | | Number | | | 若無填寫則由套件計算 |
330 | | TotalAmt | ✔ | Number | | | |
331 | | ItemName | ✔ | Array | | | |
332 | | ItemCount | ✔ | Array | | | |
333 | | ItemUnit | ✔ | Array | | | |
334 | | ItemPrice | ✔ | Array | | | |
335 | | ItemTaxType | | Array | | | |
336 | | ItemAmt | | Array | | | 若無填寫則由套件計算 |
337 | | Comment | | String | | | |
338 |
339 | ##### 備註
340 | * 本套件僅提供快速串接方式,詳細稅額計算方式請務必與公司財會人員進行確認
341 |
342 | > ### send()
343 |
344 | 傳送開立發票請求到智付通
345 |
346 | ##### 回傳
347 | 詳見[智付通文件](https://inv.pay2go.com/dw_files/info_api/pay2go_gateway_electronic_invoice_api_V1_1_7.pdf)第四節之二:開立發票系統回應訊息
348 | ```
349 | {
350 | "Status": "..."
351 | "Message": "..."
352 | "Result": {...}
353 | }
354 | ```
355 |
356 | ##### 使用範例
357 | ```
358 | $res = $receipt->send();
359 | ```
360 |
361 | > ### generateTrigger ($invoiceTransNo, $orderNo, $amount)
362 |
363 | 產生智付通觸發開立電子發票必要資訊
364 |
365 | ##### 參數
366 |
367 | 1. `invoiceTransNo (String)`: 智付寶開立序號
368 | 2. `orderNo (String)`: 商店自訂編號
369 | 3. `amount (Integer)`: 發票金額
370 |
371 | ##### 回傳
372 |
373 | 1. `(Class)`: Class實體,其中getTriggerPostData() 及 getTriggerPostDataEncrypted()會回傳即將送到智付通的表單資料
374 |
375 | ##### 使用範例
376 | ```
377 | $receipt = Receipt::generateTrigger('17122817285242624', '20171121WJNBX5NNBP', 100);
378 | ```
379 |
380 | > ### sendTrigger()
381 |
382 | 送出觸發開立電子發票請求到智付通
383 |
384 | ##### 回傳
385 | 詳見[智付通文件](https://inv.pay2go.com/dw_files/info_api/pay2go_gateway_electronic_invoice_api_V1_1_7.pdf)第四節之四:觸發開立發票系統回應訊息
386 | ```
387 | {
388 | "Status": "..."
389 | "Message": "..."
390 | "Result": {...}
391 | }
392 | ```
393 |
394 | ##### 使用範例
395 | ```
396 | $res = $receipt->sendTrigger();
397 | ```
398 |
399 | > ### generateInvalid ($receiptNumber, $invalidReason)
400 |
401 | 產生智付通觸發開立電子發票必要資訊
402 |
403 | ##### 參數
404 |
405 | 1. `receiptNumber (String)`: 發票號碼
406 | 2. `receiptNumber (String)`: 作廢原因
407 |
408 | ##### 回傳
409 |
410 | 1. `(Class)`: Class實體,其中getInvalidPostData() 及 getInvalidPostDataEncrypted()會回傳即將送到智付通的表單資料
411 |
412 | ##### 使用範例
413 | ```
414 | $receipt = Receipt::generateInvalid('17122817285242624', '作廢原因');
415 | ```
416 |
417 | > ### sendInvalid()
418 |
419 | 送出觸發開立電子發票請求到智付通
420 |
421 | ##### 回傳
422 | 詳見[智付通文件](https://inv.pay2go.com/dw_files/info_api/pay2go_gateway_electronic_invoice_api_V1_1_7.pdf)第五節之二:作廢發票系統回應訊息
423 | ```
424 | {
425 | "Status": "..."
426 | "Message": "..."
427 | "Result": {...}
428 | }
429 | ```
430 |
431 | ##### 使用範例
432 | ```
433 | $res = $receipt->sendInvalid();
434 | ```
435 |
436 | > ### search($orderNo, $amount)
437 |
438 | 查詢發票
439 |
440 | ##### 參數
441 |
442 | 1. `orderNo (String)`: 商店自訂編號
443 | 2. `amount (Integer)`: 發票金額
444 |
445 | ##### 回傳
446 | 詳見[智付通文件](https://inv.pay2go.com/dw_files/info_api/pay2go_gateway_electronic_invoice_api_V1_1_7.pdf)第七節之二:查詢發票系統回應訊息
447 | ```
448 | {
449 | "Status": "..."
450 | "Message": "..."
451 | "Result": {...}
452 | }
453 | ```
454 |
455 | ##### 使用範例
456 | ```
457 | $res = $receipt->search('20171121WJNBX5NNBP', 100);
458 | ```
459 |
460 | ### 退款/取消授權
461 | 因智付通信用卡退費有尚未請款需串接取消授權API,已請款需串接退款API之規則,本功能旨在整合此一過程,降低開發人員負擔
462 | 另外也提供非即時交易退款功能
463 |
464 | #### 快速上手
465 |
466 | ```
467 | // 產生智付通退費 / 取消授權必要資訊
468 | $refund = Refund::generate('20171121WJNBX5NNBP', 100);
469 |
470 | // $refund的 postType為cacnel時,訂單準備取消授權;為refund時,訂單準備退款
471 | // $refund的 getPostData() 及 getPostDataEncrypted() 會回傳即將傳送到智付通的表單資料,可在此時紀錄log
472 |
473 | // 送出退款/取消授權申請,取得回傳結果
474 | $res = $refund->send();
475 | ```
476 |
477 | #### 可用方法
478 |
479 | > ### generate ($orderNo, $amount\[, $notifyUrl = null, $delayed = false, $params = []\])
480 |
481 | 產生智付通退費 / 取消授權必要欄位
482 |
483 | ##### 參數
484 |
485 | 1. `orderNo (String)`: 商店自訂編號
486 | 2. `amount (String)`: 訂單金額,若不想全額退款請於可選參數中傳送Amt欄位
487 | 3. `[ notifyUrl (String) ]`: 接受取消授權結果位址,於取消授權或非即時交易時才需填寫
488 | 4. `[ delayed (Boolean) ]`: 是否為非即時交易
489 | 5. `[ params (Array) ]`: 詳見下方參數表
490 |
491 | ##### 回傳
492 |
493 | 1. `(Class)`: Class實體,其中getPostData() 及 getPostDataEncrypted()包含即將送到智付通的表單資料;getPostType()為cacnel時,訂單準備取消授權,為refund時,訂單準備退款
494 |
495 | ##### 使用範例
496 | ```
497 | $refund = Refund::generate('20171121WJNBX5NNBP', 100);
498 | ```
499 |
500 | ##### 可選參數
501 | 1. 即時交易
502 |
503 | | 欄位 | 必填 | 型態 | 備註 |
504 | |-----------|:----:|:------:|------------------------------------------------|
505 | | RefundAmt | | Number | 請退款金額,若發動退費後不退全額則需傳送此參數 |
506 |
507 | 2. 非即時交易
508 |
509 | | 欄位 | 必填 | 型態 | 備註 |
510 | |-------------|:----:|:------:|-----------------------------------|
511 | | AccNo | ✔ | String | 退款金額轉入之帳號 |
512 | | BankNo | ✔ | String | 金融機構總行代號 |
513 | | SubBankCode | ✔ | String | 金融機構分行代號 |
514 | | AccName | ✔ | String | 帳戶使用名稱 |
515 | | RefundAmt | ✔ | Number | 退款金額,必須小於等於訂單金額 |
516 | | Id | + | String | 買方身分證字號,Id及UBN需擇一填寫 |
517 | | UBN | + | String | 買方統一編號,Id及UBN需擇一填寫 |
518 |
519 | > ### send()
520 |
521 | 傳送退費 / 取消授權請求到智付通
522 |
523 | ##### 回傳
524 | 取消授權:詳見[智付通文件](https://www.newebpay.com/WebSiteData/document/gateway_creditcard_deauthorize_api_V1_0_0.pdf)第五節:取消授權完成後系統回應訊息
525 |
526 | 退款:詳見[智付通文件](https://www.newebpay.com/WebSiteData/document/2.pdf)第五節:系統回應訊息
527 | ```
528 | {
529 | "Status": "..."
530 | "Message": "..."
531 | "Result": {...}
532 | }
533 | ```
534 |
535 | ##### 使用範例
536 | ```
537 | $res = $refund->send();
538 | ```
539 |
540 | ### 已約定信用卡付款
541 |
542 | #### 快速上手
543 | ```
544 | // 產生付款必要資訊
545 | $charge = Charge::generate(
546 | 100,
547 | 'email@email.com',
548 | 'itemDesc',
549 | 'xxxxxxxxxxxxxxxxxx',
550 | 'xxx',
551 | [
552 | 'MerchantOrderNo' => '20171121WJNBX5NNBP'
553 | ]
554 | );
555 |
556 | // $transfer的 getPostData() 及 getPostDataEncrypted() 會回傳即將傳送到智付通的表單資料,可在此時紀錄log
557 |
558 | // 送出扣款
559 | $res = $charge->send();
560 | ```
561 | #### 可用方法
562 |
563 | > ### generate ($amount, $email, $itemDesc, $tokenValue, $tokenTerm, $params)
564 |
565 | 產生已約定信用卡付款必要欄位
566 |
567 | ##### 參數
568 |
569 | 1. `$amount (String)`: 金額
570 | 2. `$email (String)`: 購買人 Email
571 | 3. `$itemDesc (Integer)`: 商品描述
572 | 4. `$tokenValue (Integer)`: 約定信用卡授權碼
573 | 5. `$tokenTerm ()`: 約定信用卡付款之付款人綁定資料
574 | 6. `$params ()`: 可選選項
575 |
576 | ##### 可選參數
577 |
578 | | 欄位 | 必填 | 型態 | 備註 |
579 | |-------------------|:----:|:------:|-------------------------------------------|
580 | | MerchantOrderNo | | String | 訂單編號 |
581 | | TokenSwitch | | String | 當此參數為”on”時,才會啟用約定信用卡付款授權功能 |
582 |
583 | ##### 回傳
584 |
585 | 1. `(Class)`: Class實體,其中 getPostData() 及 getPostDataEncrypted() 包含即將送到智付通的表單資料
586 |
587 | ##### 使用範例
588 | ```
589 | $charge = Charge::generate(
590 | 100,
591 | 'email@email.com',
592 | 'itemDesc',
593 | 'xxxxxxxxxxxxxxxxxx',
594 | 'xxx',
595 | [
596 | 'MerchantOrderNo' => '20171121WJNBX5NNBP'
597 | ]
598 | );
599 | ```
600 |
601 | > ### send()
602 |
603 | 傳送已約定信用卡付款請求到智付通
604 |
605 | ##### 回傳
606 | 本文件未公開,請向合作之智付通業務人員索取
607 | ```
608 | {
609 | "Status": "..."
610 | "Message": "..."
611 | "Result": {...}
612 | }
613 | ```
614 |
615 | ##### 使用範例
616 | ```
617 | $res = $transfer->send();
618 | ```
619 |
620 | ### 平台費用扣款指示
621 |
622 | #### 快速上手
623 | ```
624 | // 產生平台費用扣款指示必要資訊
625 | $transfer = Transfer::generate('20171121WJNBX5NNBP', 100, 0, 0);
626 |
627 | // $transfer的 getPostData() 及 getPostDataEncrypted() 會回傳即將傳送到智付通的表單資料,可在此時紀錄log
628 |
629 | // 送出扣款指示申請,取得扣款指示回傳結果
630 | $res = $transfer->send();
631 | ```
632 | #### 可用方法
633 |
634 | > ### generate ($merchantID, $amount, $feeType, $balanceType)
635 |
636 | 產生智付通扣款指示必要欄位
637 |
638 | ##### 參數
639 |
640 | 1. `orderNo (String)`: 商店自訂編號
641 | 2. `amount (String)`: 金額
642 | 3. `feeType (Integer)`: 費用類別
643 | 4. `balanceType (Integer)`: 交易正負值
644 |
645 | ##### 回傳
646 |
647 | 1. `(Class)`: Class實體,其中getPostData() 及 getPostDataEncrypted()包含即將送到智付通的表單資料
648 |
649 | ##### 使用範例
650 | ```
651 | $transfer = Transfer::generate('20171121WJNBX5NNBP', 100);
652 | ```
653 |
654 | > ### send()
655 |
656 | 傳送扣款指示請求到智付通
657 |
658 | ##### 回傳
659 | 本文件未公開,請向合作之智付通業務人員索取
660 | ```
661 | {
662 | "Status": "..."
663 | "Message": "..."
664 | "Result": {...}
665 | }
666 | ```
667 |
668 | ##### 使用範例
669 | ```
670 | $res = $transfer->send();
671 | ```
672 |
673 | ## 版本紀錄
674 | ### 1.1.0
675 | 1. 非信用卡退款
676 | 2. MPG交易串接增加支付寶欄位(測試功能)
677 |
678 | ### 1.0.0
679 | 1. MPG交易串接 / 查詢
680 | 2. 電子發票
681 | 3. 退款 / 取消授權
682 | 4. 平台扣款指示
683 |
684 | ## License
685 |
686 | Laravel Spgateway is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT)
687 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "leochien/laravel-spgateway",
3 | "description": "spgateway library for laravel",
4 | "keywords": ["library", "spgateway"],
5 | "type": "library",
6 | "license": "MIT",
7 | "authors": [{
8 | "name": "LeoChien",
9 | "email": "leo@hourmasters.com"
10 | }],
11 | "require": {
12 | "php": ">=7.2.5",
13 | "laravel/framework": "^7|^8",
14 | "guzzlehttp/guzzle": "^6.5.5|^7.0.1"
15 | },
16 | "autoload": {
17 | "psr-4": {
18 | "LeoChien\\Spgateway\\": "src/"
19 | }
20 | },
21 | "config": {
22 | "sort-packages": true
23 | },
24 | "extra": {
25 | "laravel": {
26 | "providers": [
27 | "LeoChien\\Spgateway\\SpgatewayServiceProvider"
28 | ]
29 | },
30 | "aliases": {
31 | "Spgateway": "LeoChien\\Spgateway\\Facades"
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "576f63844e5542dc237d5e0807f5d39a",
8 | "packages": [
9 | {
10 | "name": "guzzlehttp/guzzle",
11 | "version": "6.3.0",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/guzzle/guzzle.git",
15 | "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699",
20 | "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "guzzlehttp/promises": "^1.0",
25 | "guzzlehttp/psr7": "^1.4",
26 | "php": ">=5.5"
27 | },
28 | "require-dev": {
29 | "ext-curl": "*",
30 | "phpunit/phpunit": "^4.0 || ^5.0",
31 | "psr/log": "^1.0"
32 | },
33 | "suggest": {
34 | "psr/log": "Required for using the Log middleware"
35 | },
36 | "type": "library",
37 | "extra": {
38 | "branch-alias": {
39 | "dev-master": "6.2-dev"
40 | }
41 | },
42 | "autoload": {
43 | "files": [
44 | "src/functions_include.php"
45 | ],
46 | "psr-4": {
47 | "GuzzleHttp\\": "src/"
48 | }
49 | },
50 | "notification-url": "https://packagist.org/downloads/",
51 | "license": [
52 | "MIT"
53 | ],
54 | "authors": [
55 | {
56 | "name": "Michael Dowling",
57 | "email": "mtdowling@gmail.com",
58 | "homepage": "https://github.com/mtdowling"
59 | }
60 | ],
61 | "description": "Guzzle is a PHP HTTP client library",
62 | "homepage": "http://guzzlephp.org/",
63 | "keywords": [
64 | "client",
65 | "curl",
66 | "framework",
67 | "http",
68 | "http client",
69 | "rest",
70 | "web service"
71 | ],
72 | "time": "2017-06-22T18:50:49+00:00"
73 | },
74 | {
75 | "name": "guzzlehttp/promises",
76 | "version": "v1.3.1",
77 | "source": {
78 | "type": "git",
79 | "url": "https://github.com/guzzle/promises.git",
80 | "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
81 | },
82 | "dist": {
83 | "type": "zip",
84 | "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
85 | "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
86 | "shasum": ""
87 | },
88 | "require": {
89 | "php": ">=5.5.0"
90 | },
91 | "require-dev": {
92 | "phpunit/phpunit": "^4.0"
93 | },
94 | "type": "library",
95 | "extra": {
96 | "branch-alias": {
97 | "dev-master": "1.4-dev"
98 | }
99 | },
100 | "autoload": {
101 | "psr-4": {
102 | "GuzzleHttp\\Promise\\": "src/"
103 | },
104 | "files": [
105 | "src/functions_include.php"
106 | ]
107 | },
108 | "notification-url": "https://packagist.org/downloads/",
109 | "license": [
110 | "MIT"
111 | ],
112 | "authors": [
113 | {
114 | "name": "Michael Dowling",
115 | "email": "mtdowling@gmail.com",
116 | "homepage": "https://github.com/mtdowling"
117 | }
118 | ],
119 | "description": "Guzzle promises library",
120 | "keywords": [
121 | "promise"
122 | ],
123 | "time": "2016-12-20T10:07:11+00:00"
124 | },
125 | {
126 | "name": "guzzlehttp/psr7",
127 | "version": "1.4.2",
128 | "source": {
129 | "type": "git",
130 | "url": "https://github.com/guzzle/psr7.git",
131 | "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
132 | },
133 | "dist": {
134 | "type": "zip",
135 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
136 | "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
137 | "shasum": ""
138 | },
139 | "require": {
140 | "php": ">=5.4.0",
141 | "psr/http-message": "~1.0"
142 | },
143 | "provide": {
144 | "psr/http-message-implementation": "1.0"
145 | },
146 | "require-dev": {
147 | "phpunit/phpunit": "~4.0"
148 | },
149 | "type": "library",
150 | "extra": {
151 | "branch-alias": {
152 | "dev-master": "1.4-dev"
153 | }
154 | },
155 | "autoload": {
156 | "psr-4": {
157 | "GuzzleHttp\\Psr7\\": "src/"
158 | },
159 | "files": [
160 | "src/functions_include.php"
161 | ]
162 | },
163 | "notification-url": "https://packagist.org/downloads/",
164 | "license": [
165 | "MIT"
166 | ],
167 | "authors": [
168 | {
169 | "name": "Michael Dowling",
170 | "email": "mtdowling@gmail.com",
171 | "homepage": "https://github.com/mtdowling"
172 | },
173 | {
174 | "name": "Tobias Schultze",
175 | "homepage": "https://github.com/Tobion"
176 | }
177 | ],
178 | "description": "PSR-7 message implementation that also provides common utility methods",
179 | "keywords": [
180 | "http",
181 | "message",
182 | "request",
183 | "response",
184 | "stream",
185 | "uri",
186 | "url"
187 | ],
188 | "time": "2017-03-20T17:10:46+00:00"
189 | },
190 | {
191 | "name": "psr/http-message",
192 | "version": "1.0.1",
193 | "source": {
194 | "type": "git",
195 | "url": "https://github.com/php-fig/http-message.git",
196 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
197 | },
198 | "dist": {
199 | "type": "zip",
200 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
201 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
202 | "shasum": ""
203 | },
204 | "require": {
205 | "php": ">=5.3.0"
206 | },
207 | "type": "library",
208 | "extra": {
209 | "branch-alias": {
210 | "dev-master": "1.0.x-dev"
211 | }
212 | },
213 | "autoload": {
214 | "psr-4": {
215 | "Psr\\Http\\Message\\": "src/"
216 | }
217 | },
218 | "notification-url": "https://packagist.org/downloads/",
219 | "license": [
220 | "MIT"
221 | ],
222 | "authors": [
223 | {
224 | "name": "PHP-FIG",
225 | "homepage": "http://www.php-fig.org/"
226 | }
227 | ],
228 | "description": "Common interface for HTTP messages",
229 | "homepage": "https://github.com/php-fig/http-message",
230 | "keywords": [
231 | "http",
232 | "http-message",
233 | "psr",
234 | "psr-7",
235 | "request",
236 | "response"
237 | ],
238 | "time": "2016-08-06T14:39:51+00:00"
239 | }
240 | ],
241 | "packages-dev": [],
242 | "aliases": [],
243 | "minimum-stability": "stable",
244 | "stability-flags": [],
245 | "prefer-stable": false,
246 | "prefer-lowest": false,
247 | "platform": {
248 | "php": ">=7"
249 | },
250 | "platform-dev": []
251 | }
252 |
--------------------------------------------------------------------------------
/config/spgateway.php:
--------------------------------------------------------------------------------
1 | [
13 | 'MerchantID' => env('SPGATEWAY_MERCHANT_ID', ''),
14 | 'HashKey' => env('SPGATEWAY_HASH_KEY', ''),
15 | 'HashIV' => env('SPGATEWAY_HASH_IV', ''),
16 |
17 | 'Version' => '1.5', //串接程式版本 Varchar(5)
18 | 'RespondType' => env('SPGATEWAY_RESPOND_TYPE', 'JSON'), //回傳格式 Varchar(6) JSON 或是 String
19 | 'LangType' => env('SPGATEWAY_LANG_TYPE'), //語系 en 繁體中文版參數為 zh-tw 預設為繁體中文版, 設定的話鎖死語系 內容會自動讀取語言
20 | 'TradeLimit' => env('SPGATEWAY_TRADE_LIMIT', 300), //限制交易的秒數,當秒數倒數至 0 時,交 易當做失敗。 Int(3) 60~900
21 | 'ExpireDate' => env('SPGATEWAY_EXPIRE_DATE'), //繳費有效期限 Varchar(10) date('Ymd') 系統預設為 7 天 可接受最大值為 180 天。
22 |
23 | //支付完成 返回商店網址 Varchar(50) 交易完成後,以 Form Post 方式導回商店頁面。
24 | //若為空值,交易完成後,消費者將停留在 智付通付款或取號完成頁面。只接受 80 與 443 Port。,
25 | 'ReturnURL' => env('SPGATEWAY_RETURN_URL'),
26 |
27 | //支付通知網址 Varchar(50) 只接受 80 與 443 Port。 付款成功回傳網址
28 | 'NotifyURL' => env('SPGATEWAY_NOTIFY_URL'),
29 |
30 | //ReturnURL 與 NotifyURL 不可設定相同避免誤判 影響帳務正確性
31 |
32 | //商店取號網址 Varchar(50) 若為空值,則會顯示取號結果在智 付通頁面。
33 | 'CustomerURL' => env('SPGATEWAY_CUSTOMER_URL'),
34 |
35 | //支付取消 返回商店網址 Varchar(50) 當交易取消時,平台會出現返回鈕,使消 費者依以此參數網址返回商店指定的頁面。 2.此參數若為空值時,則無返回鈕。
36 | 'ClientBackURL' => env('SPGATEWAY_CLIENT_BACK_URL'),
37 |
38 | 'EmailModify' => env('SPGATEWAY_EMAILMODIFY'), //付款人電子信箱是否開放修改 Int(1) 付款人電子信箱欄位 是否開放讓付款人修改。1= 可修改/0= 不可修改 預設為可修改
39 | 'LoginType' => env('SPGATEWAY_LOGINTYPE'), //required 智付通會員 Int(1) 1'=>須要登入智付通會員 0'=>不須登入智付通會員
40 |
41 | //付費方式啟用
42 | 'CREDIT' => env('SPGATEWAY_CREDIT'), //信用卡 一次付清啟用 Int(1) 設定是否啟用信用卡一次付清支付方式。 1=啟用 0 或者未有此參數=不啟用
43 | 'ANDROIDPAY' => env('SPGATEWAY_ANDROIDPAY'), //google pay 1=啟用, 0 或者未有此參數=不啟用
44 | 'SAMSUNGPAY' => env('SPGATEWAY_SAMSUNGPAY'), //samsung pay 1=啟用, 0 或者未有此參數=不啟用
45 | 'InstFlag' => env('SPGATEWAY_INSTFLAG'), //信用卡 分期付款啟用 Varchar(18) 3=分 3 期功能 6=分 6 期功能 12=分 12 期功能 18=分 18 期功能 24=分 24 期功能 30=分 30 期功能 啟多期別時, 形)分隔,例如:3,6,12,代表開啟 分 3、6、12 期的功能。 欄位值=0或無值時,即代表不開啟分期。
46 | 'CreditRed' => env('SPGATEWAY_CREDITRED'), //信用卡 紅利啟用 Int(1) 是否啟用信用卡紅利支付方式。 1=啟用 0 或者未有此參數=不啟用
47 | 'UNIONPAY' => env('SPGATEWAY_UNIONPAY'), //信用卡 銀聯卡啟用 Int(1) 設定是否啟用銀聯卡支付方式。1=啟用 0 或者未有此參數=不啟用
48 | 'WEBATM' => env('SPGATEWAY_WEBATM'), //WEBATM 啟用 Int(1) 1=啟用 0 或者未有此參數=不啟用
49 | 'VACC' => env('SPGATEWAY_VACC'), //ATM 轉帳 Int(1)
50 | 'CVS' => env('SPGATEWAY_CVS'), // 超商代碼繳費 Int(1) 1=啟用, 0 或者未有此參數=不啟用 金額須大於30 小於2萬
51 | 'BARCODE' => env('SPGATEWAY_BARCODE'), //超商條碼繳費 Int(1) 1=啟用, 0 或者未有此參數=不啟用 金額須大於20 小於4萬
52 | 'P2G' => env('SPGATEWAY_P2G'), //Pay2go 電子錢 包啟用 1=啟用, 0 或者未有此參數=不啟用
53 | 'CVSCOM' => env('SPGATEWAY_CVSCOM'), //超商取貨付款 啟用 使用前,須先登入智付通會員專區啟用物 流並設定退貨門市與取貨人相關資訊。1=>超商取貨不付款 2=>超商取貨付款 3=>超商取貨不付款及超商取貨付款 0 或者未有此參數,即代表不開啟。 2.當該筆訂單金額小於 30 元或大於 2 萬元 時,即使此參數設定為啟用,MPG 付款頁 面仍不會顯示此支付方式選項。
54 | ],
55 |
56 | /*
57 | |--------------------------------------------------
58 | | For Create Merchant API
59 | |--------------------------------------------------
60 | |
61 | | 這是用來建立智付通商店的相關設定,每項皆為必填
62 | |
63 | */
64 | 'CompanyKey' => env('SPGATEWAY_COMPANY_KEY', ''),
65 | 'CompanyIV' => env('SPGATEWAY_COMPANY_IV', ''),
66 | 'PartnerID' => env('SPGATEWAY_PARTNER_ID', ''),
67 | 'MerchantIDPrefix' => env('SPGATEWAY_MERCHANT_ID_PREFIX', ''),
68 |
69 | /*
70 | |--------------------------------------------------
71 | | For Create Receipt API
72 | |--------------------------------------------------
73 | |
74 | | 這是用來開立智付通發票的相關設定,每項皆為必填
75 | |
76 | */
77 | 'receipt' => [
78 | 'HashKey' => env('SPGATEWAY_RECEIPT_KEY'),
79 | 'HashIV' => env('SPGATEWAY_RECEIPT_IV'),
80 | 'MerchantID' => env('SPGATEWAY_RECEIPT_MERCHANT_ID', ''),
81 | ],
82 | ];
83 |
--------------------------------------------------------------------------------
/resources/views/send-order.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 | 正在導向到藍新金流...
9 |
10 |
43 |
44 |
45 |
50 |
51 | 正在導向到藍新金流...
52 |
53 |
67 |
68 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/src/Charge.php:
--------------------------------------------------------------------------------
1 | apiUrl = 'https://core.newebpay.com/API/CreditCard';
18 | } else {
19 | $this->apiUrl = 'https://ccore.newebpay.com/API/CreditCard';
20 | }
21 |
22 | $this->helpers = $helpers;
23 | }
24 |
25 | /**
26 | * 產生智付通自動扣款必要資訊
27 | *
28 | * @param $amount integer 訂單金額
29 | * @param $email string 訂購人email
30 | * @param $prodDesc string 購買商品資訊
31 | * @param array $params
32 | *
33 | * @return $this|Exception
34 | */
35 | public function generate(
36 | $amount,
37 | $email,
38 | $prodDesc,
39 | $tokenValue,
40 | $tokenTerm,
41 | array $params = []
42 | ) {
43 | try {
44 | $postData = [
45 | 'TimeStamp' => time(),
46 | 'Version' => '1.0',
47 | 'MerchantOrderNo' => $params['MerchantOrderNo'] ?? $this->helpers->generateOrderNo(),
48 | 'Amt' => $amount,
49 | 'ProdDesc' => $prodDesc,
50 | 'PayerEmail' => $email,
51 | 'TokenValue' => $tokenValue,
52 | 'TokenTerm' => $tokenTerm,
53 | 'TokenSwitch' => $params['TokenSwitch'] ?? 'on',
54 | ];
55 |
56 | $postData = array_filter($postData, function ($value) {
57 | return ($value !== null && $value !== false && $value !== '');
58 | });
59 |
60 | $this->postData = $postData;
61 |
62 | return $this->encrypt();
63 | } catch (Exception $e) {
64 | return $e;
65 | }
66 | }
67 |
68 | /**
69 | * 前台送出訂單建立表單到智付通
70 | *
71 | * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
72 | */
73 | public function send($options = [])
74 | {
75 | $res = $this->helpers->sendPostRequest(
76 | $this->apiUrl,
77 | $this->postDataEncrypted,
78 | $options
79 | );
80 |
81 | $res = json_decode($res);
82 |
83 | return $res;
84 | }
85 |
86 | /**
87 | * 加密訂單資料
88 | *
89 | * @return $this
90 | */
91 | public function encrypt()
92 | {
93 | $PostData_ = $this->helpers->encryptPostData($this->postData);
94 |
95 | $this->postDataEncrypted = [
96 | 'MerchantID_' => config('spgateway.mpg.MerchantID'),
97 | 'PostData_' => $PostData_,
98 | 'Pos_' => 'JSON',
99 | ];
100 |
101 | return $this;
102 | }
103 |
104 | public function getPostData()
105 | {
106 | return $this->postData;
107 | }
108 |
109 | public function getPostDataEncrypted()
110 | {
111 | return $this->postDataEncrypted;
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/Facades/Encrypt.php:
--------------------------------------------------------------------------------
1 | client = new Client();
21 | }
22 |
23 | /**
24 | * 智付通資料加密
25 | *
26 | * @param $postData
27 | *
28 | * @param null $key
29 | * @param null $iv
30 | *
31 | * @return string
32 | */
33 | public function encryptPostData(
34 | $postData,
35 | $key = null,
36 | $iv = null
37 | ) {
38 | // 所有資料與欄位使用 = 符號組合,並用 & 符號串起字串
39 | $postData = http_build_query($postData);
40 |
41 | // 加密字串
42 | $post_data = trim(bin2hex(openssl_encrypt(
43 | $this->addPadding($postData),
44 | 'AES-256-CBC',
45 | $key ?? config('spgateway.mpg.HashKey'),
46 | OPENSSL_RAW_DATA | OPENSSL_NO_PADDING,
47 | $iv ?? config('spgateway.mpg.HashIV')
48 | )));
49 |
50 | return $post_data;
51 | }
52 |
53 | public function addPadding(
54 | $string,
55 | $blocksize = 32
56 | ) {
57 | $len = strlen($string);
58 | $pad = $blocksize - ($len % $blocksize);
59 | $string .= str_repeat(chr($pad), $pad);
60 | return $string;
61 | }
62 |
63 | public function sendPostRequest($url, $postData, $options = [])
64 | {
65 | return $this->client
66 | ->request(
67 | 'POST',
68 | $url,
69 | array_merge(['form_params' => $postData], $options)
70 | )
71 | ->getBody()
72 | ->getContents();
73 | }
74 |
75 | /**
76 | * 產生訂單編號
77 | *
78 | * @return string
79 | */
80 | public function generateOrderNo()
81 | {
82 | return date('YmdHis') . str_random(6);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/MPG.php:
--------------------------------------------------------------------------------
1 | apiUrl = [];
41 | if ('production' === config('app.env')) {
42 | $this->apiUrl['MPG_API']
43 | = 'https://core.newebpay.com/MPG/mpg_gateway';
44 | $this->apiUrl['QUERY_TRADE_INFO_API']
45 | = 'https://core.newebpay.com/API/QueryTradeInfo';
46 | } else {
47 | $this->apiUrl['MPG_API']
48 | = 'https://ccore.newebpay.com/MPG/mpg_gateway';
49 | $this->apiUrl['QUERY_TRADE_INFO_API']
50 | = 'https://ccore.newebpay.com/API/QueryTradeInfo';
51 | }
52 |
53 | $this->helpers = new Helpers();
54 | }
55 |
56 | /**
57 | * 產生智付通訂單建立必要資訊.
58 | *
59 | * @param $amount integer 訂單金額
60 | * @param $email string 訂購人email
61 | * @param $itemDesc string 商品描述
62 | *
63 | * @return MPG|Exception
64 | */
65 | public function generate(
66 | $amount,
67 | $email,
68 | $itemDesc,
69 | array $params = []
70 | ) {
71 | try {
72 | $validator = $this->formValidator(
73 | $amount,
74 | $itemDesc,
75 | $email,
76 | $params
77 | );
78 |
79 | if (true !== $validator) {
80 | throw new Exception($validator['field'] . $validator['message']);
81 | }
82 |
83 | $postData = [
84 | 'Amt' => $amount,
85 | 'ItemDesc' => $itemDesc,
86 | 'Email' => $email,
87 |
88 | 'MerchantID' => config('spgateway.mpg.MerchantID'),
89 | 'RespondType' => config('spgateway.mpg.RespondType'),
90 | 'TimeStamp' => time(),
91 | 'Version' => config('spgateway.mpg.Version'),
92 |
93 | //options
94 | 'LangType' => $params['LangType'] ?? config('spgateway.mpg.LangType'),
95 | 'MerchantOrderNo' => $params['MerchantOrderNo'] ?? $this->helpers->generateOrderNo(),
96 | 'TradeLimit' => $params['TradeLimit'] ?? config('spgateway.mpg.TradeLimit'),
97 | 'ExpireDate' => $params['ExpireDate'] ?? config('spgateway.mpg.ExpireDate'),
98 | 'ReturnURL' => $params['ReturnURL'] ?? config('spgateway.mpg.ReturnURL'),
99 | 'NotifyURL' => $params['NotifyURL'] ?? config('spgateway.mpg.NotifyURL'),
100 | 'CustomerURL' => $params['CustomerURL'] ?? config('spgateway.mpg.CustomerURL'),
101 | 'ClientBackURL' => $params['ClientBackURL'] ?? config('spgateway.mpg.ClientBackURL'),
102 | 'EmailModify' => $params['EmailModify'] ?? config('spgateway.mpg.EmailModify'),
103 | 'LoginType' => $params['LoginType'] ?? config('spgateway.mpg.LoginType'),
104 |
105 | 'OrderComment' => $params['OrderComment'] ?? null,
106 |
107 | //付款方式相關設定
108 | 'CREDIT' => $params['CREDIT'] ?? config('spgateway.mpg.CREDIT'),
109 | 'ANDROIDPAY' => $params['ANDROIDPAY'] ?? config('spgateway.mpg.ANDROIDPAY'),
110 | 'SAMSUNGPAY' => $params['SAMSUNGPAY'] ?? config('spgateway.mpg.SAMSUNGPAY'),
111 | 'InstFlag' => $params['InstFlag'] ?? config('spgateway.mpg.InstFlag'),
112 | 'CreditRed' => $params['CreditRed'] ?? config('spgateway.mpg.CreditRed'),
113 | 'UNIONPAY' => $params['UNIONPAY'] ?? config('spgateway.mpg.UNIONPAY'),
114 | 'WEBATM' => $params['WEBATM'] ?? config('spgateway.mpg.WEBATM'),
115 | 'VACC' => $params['VACC'] ?? config('spgateway.mpg.VACC'),
116 | 'CVS' => $params['CVS'] ?? config('spgateway.mpg.CVS'),
117 | 'BARCODE' => $params['BARCODE'] ?? config('spgateway.mpg.BARCODE'),
118 | 'P2G' => $params['P2G'] ?? config('spgateway.mpg.P2G'),
119 |
120 | //物流啟用相關
121 | 'CVSCOM' => $params['CVSCOM'] ?? config('spgateway.mpg.CVSCOM'),
122 |
123 | //信用卡快速結帳
124 | 'TokenTerm' => $params['TokenTerm'] ?? null, //付款人綁定資料 Varchar(20) 1.可對應付款人之資料,用於綁定付款人與 信用卡卡號時使用,例:會員編號、 Email。 2.限英、數字,「.」、「_」、「@」、「-」格 式。
125 | 'TokenTermDemand' => $params['TokenTermDemand'] ?? null, //指定付款人信用卡快速結帳必填欄位 Int(1) 1 = 必填信用卡到期日與背面末三碼 2 = 必填信用卡到期日 3 = 必填背面末三碼
126 |
127 | 'CREDITAE' => $params['BARCODE'] ?? null,
128 | 'ALIPAY' => $params['ALIPAY'] ?? null,
129 | 'TENPAY' => $params['TENPAY'] ?? null,
130 |
131 | // 信用卡授權專用欄位
132 | 'CREDITAGREEMENT' => $params['CREDITAGREEMENT'] ?? null,
133 | 'TokenLife' => $params['TokenLife'] ?? null,
134 |
135 | // 以下為支付寶 / 財付通專用欄位
136 | 'Receiver' => $params['Receiver'] ?? null,
137 | 'Tel1' => $params['Tel1'] ?? null,
138 | 'Tel2' => $params['Tel2'] ?? null,
139 | ];
140 |
141 | if (isset($params['Commodities'])) {
142 | $postData['Count'] = count($params['Commodities']);
143 | $postData = array_merge($postData, $this->parseCommodities($params['Commodities']));
144 | }
145 |
146 | $postData = array_filter($postData, function ($value) {
147 | return null !== $value && false !== $value && '' !== $value;
148 | });
149 |
150 | $this->postData = $postData;
151 |
152 | return $this->encrypt();
153 | } catch (Exception $e) {
154 | return $e;
155 | }
156 | }
157 |
158 | /**
159 | * 加密訂單資料.
160 | */
161 | public function encrypt(): MPG
162 | {
163 | $tradeInfo = $this->createMpgAesEncrypt($this->postData);
164 | $tradeSha = $this->createMpgSHA256Encrypt($tradeInfo);
165 |
166 | $this->postDataEncrypted = [
167 | 'MerchantID' => config('spgateway.mpg.MerchantID'),
168 | 'TradeInfo' => $tradeInfo,
169 | 'TradeSha' => $tradeSha,
170 | 'Version' => config('spgateway.mpg.Version'),
171 | ];
172 |
173 | return $this;
174 | }
175 |
176 | /**
177 | * 前台送出訂單建立表單到智付通.
178 | *
179 | * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
180 | */
181 | public function send()
182 | {
183 | return view(
184 | 'spgateway::send-order',
185 | [
186 | 'apiUrl' => $this->apiUrl['MPG_API'],
187 | 'order' => $this->postDataEncrypted,
188 | ]
189 | );
190 | }
191 |
192 | /**
193 | * 解析智付通交易結果回傳參數.
194 | *
195 | * @param $tradeInfo String 智付通回傳參數中的TradeInfo
196 | *
197 | * @return mixed
198 | */
199 | public function parse($tradeInfo)
200 | {
201 | $result = $this->createAES256decrypt($tradeInfo);
202 |
203 | return json_decode($result);
204 | }
205 |
206 | /**
207 | * 搜尋訂單.
208 | *
209 | * @param string $orderNo
210 | * @param int $amount
211 | *
212 | * @return mixed
213 | */
214 | public function search(
215 | $orderNo,
216 | $amount
217 | ) {
218 | $postData = [
219 | 'MerchantID' => config('spgateway.mpg.MerchantID'),
220 | 'Version' => '1.1',
221 | 'RespondType' => 'JSON',
222 | 'TimeStamp' => time(),
223 | 'MerchantOrderNo' => $orderNo,
224 | 'Amt' => $amount,
225 | ];
226 |
227 | $postData['CheckValue'] = $this->generateTradeInfoCheckValue(
228 | $orderNo,
229 | $amount
230 | );
231 |
232 | $res = $this->helpers->sendPostRequest(
233 | $this->apiUrl['QUERY_TRADE_INFO_API'],
234 | $postData
235 | );
236 |
237 | $result = json_decode($res);
238 |
239 | return $result;
240 | }
241 |
242 | /**
243 | * Get origin post data array.
244 | */
245 | public function getPostData(): array
246 | {
247 | return $this->postData;
248 | }
249 |
250 | /**
251 | * Get encrypted post data.
252 | */
253 | public function getPostDataEncrypted(): array
254 | {
255 | return $this->postDataEncrypted;
256 | }
257 |
258 | /**
259 | * 驗證表單.
260 | *
261 | * @param $amount
262 | * @param $itemDesc
263 | * @param $email
264 | * @param $params
265 | *
266 | * @return array|bool
267 | */
268 | private function formValidator(
269 | $amount,
270 | $itemDesc,
271 | $email,
272 | $params
273 | ) {
274 | if (isset($params['LangType'])) {
275 | if (!in_array($params['LangType'], ['en', 'zh-tw'])) {
276 | return $this->errorMessage(
277 | 'LangType',
278 | '英文版參數為 en,繁體中文版參數為 zh-tw'
279 | );
280 | }
281 | }
282 |
283 | if (!is_numeric($amount)) {
284 | return $this->errorMessage('Amt', '必須為大於0的整數');
285 | }
286 |
287 | if (mb_strlen($itemDesc) > 50) {
288 | return $this->errorMessage('ItemDesc', '必須小於50字');
289 | }
290 |
291 | if (isset($params['TradeLimit'])) {
292 | if ($params['TradeLimit'] < 60 || $params['TradeLimit'] > 900) {
293 | return $this->errorMessage('TradeLimit', '秒數下限為60秒,上限為900秒');
294 | }
295 | }
296 |
297 | if (isset($params['ExpireDate'])) {
298 | if (date_parse_from_format(
299 | 'Ymd',
300 | $params['ExpireDate']
301 | )['error_count']
302 | > 0
303 | ) {
304 | return $this->errorMessage(
305 | 'ExpireDate',
306 | '格式需為Ymd,如:20170101'
307 | );
308 | }
309 |
310 | if (strtotime($params['ExpireDate']) < strtotime('today')
311 | || strtotime('-180 days', strtotime($params['ExpireDate'])) > strtotime('today')
312 | ) {
313 | return $this->errorMessage('ExpireDate', '可接受最大值為 180 天');
314 | }
315 | }
316 |
317 | if (isset($params['ReturnURL'])) {
318 | if (!filter_var($params['ReturnURL'], FILTER_VALIDATE_URL)) {
319 | return $this->errorMessage('ReturnURL', '必須為合法的Url');
320 | }
321 | }
322 |
323 | if (isset($params['NotifyURL'])) {
324 | if (!filter_var($params['NotifyURL'], FILTER_VALIDATE_URL)) {
325 | return $this->errorMessage('NotifyURL', '必須為合法的Url');
326 | }
327 | }
328 |
329 | if (isset($params['CustomerURL'])) {
330 | if (!filter_var($params['CustomerURL'], FILTER_VALIDATE_URL)) {
331 | return $this->errorMessage('CustomerURL', '必須為合法的Url');
332 | }
333 | }
334 |
335 | if (isset($params['ClientBackURL'])) {
336 | if (!filter_var($params['ClientBackURL'], FILTER_VALIDATE_URL)) {
337 | return $this->errorMessage('ClientBackURL', '必須為合法的Url');
338 | }
339 | }
340 |
341 | if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
342 | return $this->errorMessage('Email', '必須為合法的Email');
343 | }
344 |
345 | if (isset($params['EmailModify'])) {
346 | if (!in_array($params['EmailModify'], [1, 0])) {
347 | return $this->errorMessage('EmailModify', '必須為0或1');
348 | }
349 | }
350 |
351 | if (isset($params['LoginType'])) {
352 | if (!in_array($params['LoginType'], [1, 0])) {
353 | return $this->errorMessage('LoginType', '必須為0或1');
354 | }
355 | }
356 |
357 | if (isset($params['OrderComment'])) {
358 | if (strlen($params['OrderComment']) > 300) {
359 | return $this->errorMessage('OrderComment', '必須小於300字');
360 | }
361 | }
362 |
363 | if (isset($params['CREDIT'])) {
364 | if (isset($params['CREDIT'])) {
365 | if (!in_array($params['CREDIT'], [1, 0])) {
366 | return $this->errorMessage('CREDIT', '必須為0或1');
367 | }
368 | }
369 | }
370 |
371 | if (isset($params['CreditRed'])) {
372 | if (isset($params['CreditRed'])) {
373 | if (!in_array($params['CreditRed'], [1, 0])) {
374 | return $this->errorMessage('CreditRed', '必須為0或1');
375 | }
376 | }
377 | }
378 |
379 | if (isset($params['InstFlag'])) {
380 | $instFlag = explode(',', $params['InstFlag']);
381 | array_walk(
382 | $instFlag,
383 | function ($val, $key) {
384 | if (!in_array($val, [1, 3, 6, 12, 18, 24])) {
385 | return $this->errorMessage(
386 | 'InstFlag',
387 | '期數必須為3、6、12、18、24'
388 | );
389 | }
390 | }
391 | );
392 | }
393 |
394 | if (isset($params['UNIONPAY'])) {
395 | if (!in_array($params['UNIONPAY'], [1, 0])) {
396 | return $this->errorMessage('UNIONPAY', '必須為0或1');
397 | }
398 | }
399 |
400 | if (isset($params['WEBATM'])) {
401 | if (!in_array($params['WEBATM'], [1, 0])) {
402 | return $this->errorMessage('WEBATM', '必須為0或1');
403 | }
404 | }
405 |
406 | if (isset($params['EmailModify'])) {
407 | if (!in_array($params['EmailModify'], [1, 0])) {
408 | return $this->errorMessage('EmailModify', '必須為0或1');
409 | }
410 | }
411 |
412 | if (isset($params['VACC'])) {
413 | if (!in_array($params['VACC'], [1, 0])) {
414 | return $this->errorMessage('VACC', '必須為0或1');
415 | }
416 | }
417 |
418 | if (isset($params['CVS'])) {
419 | if (!in_array($params['CVS'], [1, 0])) {
420 | return $this->errorMessage('CVS', '必須為0或1');
421 | }
422 | }
423 |
424 | if (isset($params['BARCODE'])) {
425 | if (!in_array($params['BARCODE'], [1, 0])) {
426 | return $this->errorMessage('BARCODE', '必須為0或1');
427 | }
428 | }
429 |
430 | return true;
431 | }
432 |
433 | /**
434 | * 回傳錯誤訊息.
435 | *
436 | * @param $field
437 | * @param $message
438 | *
439 | * @return array
440 | */
441 | private function errorMessage($field, $message)
442 | {
443 | return [
444 | 'field' => $field,
445 | 'message' => $message,
446 | ];
447 | }
448 |
449 | private function createMpgAesEncrypt($parameter = '')
450 | {
451 | $return_str = '';
452 | if (!empty($parameter)) {
453 | $return_str = http_build_query($parameter);
454 | }
455 |
456 | $key = config('spgateway.mpg.HashKey');
457 | $iv = config('spgateway.mpg.HashIV');
458 |
459 | return trim(bin2hex(openssl_encrypt(
460 | $this->helpers->addPadding($return_str),
461 | 'aes-256-cbc',
462 | $key,
463 | OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,
464 | $iv
465 | )));
466 | }
467 |
468 | private function createAES256decrypt($parameter = '')
469 | {
470 | $key = config('spgateway.mpg.HashKey');
471 | $iv = config('spgateway.mpg.HashIV');
472 |
473 | return $this->stripPadding(openssl_decrypt(
474 | hex2bin($parameter),
475 | 'aes-256-cbc',
476 | $key,
477 | OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,
478 | $iv
479 | ));
480 | }
481 |
482 | /**
483 | * SHA256 加密.
484 | *
485 | * @param string $aes
486 | *
487 | * @return string
488 | */
489 | private function createMpgSHA256Encrypt($aes)
490 | {
491 | $hashKey = config('spgateway.mpg.HashKey');
492 | $hashIv = config('spgateway.mpg.HashIV');
493 |
494 | $queryString = "HashKey={$hashKey}&{$aes}&HashIV={$hashIv}";
495 |
496 | //sha256 編碼
497 | $data = hash('sha256', $queryString);
498 |
499 | //轉大寫
500 | $tradeSha = strtoupper($data);
501 |
502 | return $tradeSha;
503 | }
504 |
505 | private function stripPadding($string)
506 | {
507 | $slast = ord(substr($string, -1));
508 | $slastc = chr($slast);
509 | if (preg_match("/$slastc{" . $slast . '}/', $string)) {
510 | $string = substr($string, 0, strlen($string) - $slast);
511 |
512 | return $string;
513 | }
514 |
515 | return false;
516 | }
517 |
518 | /**
519 | * 產生訂單查詢檢查碼
520 | *
521 | * @param $orderNo
522 | * @param $amount
523 | *
524 | * @return string
525 | */
526 | private function generateTradeInfoCheckValue($orderNo, $amount)
527 | {
528 | $data = [
529 | 'IV' => config('spgateway.mpg.HashIV'),
530 | 'Amt' => $amount,
531 | 'MerchantID' => config('spgateway.mpg.MerchantID'),
532 | 'MerchantOrderNo' => $orderNo,
533 | 'Key' => config('spgateway.mpg.HashKey'),
534 | ];
535 |
536 | $check_code_str = http_build_query($data);
537 | $checkValue = strtoupper(hash('sha256', $check_code_str));
538 |
539 | return $checkValue;
540 | }
541 |
542 | /**
543 | * 解析境外支付(支付寶/財付通)專用欄位.
544 | *
545 | * @param array $commodities
546 | *
547 | * @return array
548 | */
549 | private function parseCommodities($commodities = [])
550 | {
551 | $newCommodities = [];
552 |
553 | foreach ($commodities as $index => $commodity) {
554 | $newCommodity = [];
555 |
556 | foreach ($commodity as $key => $value) {
557 | $newCommodity[$key . ($index + 1)] = $value;
558 | }
559 |
560 | $newCommodities = array_merge($newCommodities, $newCommodity);
561 | }
562 |
563 | return $newCommodities;
564 | }
565 | }
566 |
--------------------------------------------------------------------------------
/src/Receipt.php:
--------------------------------------------------------------------------------
1 | apiUrl['CREATE_RECEIPT_API']
22 | = 'https://inv.pay2go.com/API/invoice_issue';
23 | $this->apiUrl['INVALID_RECEIPT_API']
24 | = 'https://inv.pay2go.com/API/invoice_invalid';
25 | $this->apiUrl['TRIGGER_RECEIPT_API']
26 | = 'https://inv.pay2go.com/API/invoice_touch_issue';
27 | $this->apiUrl['SEARCH_RECEIPT_API']
28 | = 'https://inv.pay2go.com/API/invoice_search';
29 | } else {
30 | $this->apiUrl['CREATE_RECEIPT_API']
31 | = 'https://cinv.pay2go.com/API/invoice_issue';
32 | $this->apiUrl['INVALID_RECEIPT_API']
33 | = 'https://cinv.pay2go.com/API/invoice_invalid';
34 | $this->apiUrl['TRIGGER_RECEIPT_API']
35 | = 'https://cinv.pay2go.com/API/invoice_touch_issue';
36 | $this->apiUrl['SEARCH_RECEIPT_API']
37 | = 'https://cinv.pay2go.com/API/invoice_search';
38 | }
39 |
40 | $this->helpers = new Helpers();
41 | }
42 |
43 | /**
44 | * 產生智付通開立電子發票必要資訊
45 | *
46 | * @param array $params
47 | *
48 | * @return $this|array
49 | */
50 | public function generate(array $params)
51 | {
52 | $params['TaxRate'] = $params['TaxRate'] ?? 5;
53 | $params['Category'] = $params['Category'] ?? 'B2C';
54 |
55 | $itemAmt = [];
56 |
57 | if ($params['Category'] === 'B2B') {
58 | $params['ItemPrice'] = array_map(function ($price) use ($params) {
59 | return $this->priceBeforeTax($price, $params['TaxRate']);
60 | }, $params['ItemPrice']);
61 | }
62 |
63 | foreach ($params['ItemCount'] as $k => $v) {
64 | $itemAmt[$k] = $params['ItemCount'][$k]
65 | * $params['ItemPrice'][$k];
66 | }
67 |
68 | $params['ItemName'] = implode('|', $params['ItemName']);
69 | $params['ItemCount'] = implode('|', $params['ItemCount']);
70 | $params['ItemUnit'] = implode('|', $params['ItemUnit']);
71 | $params['ItemPrice'] = implode('|', $params['ItemPrice']);
72 | $params['ItemAmt'] = implode('|', $itemAmt);
73 |
74 | // 智付通開立電子發票必要資訊
75 | $postData = [
76 | 'RespondType' => $params['RespondType'] ?? 'JSON',
77 | 'Version' => '1.4',
78 | 'TimeStamp' => time(),
79 | 'TransNum' => $params['TransNum'] ?? null,
80 | 'MerchantOrderNo' => $params['MerchantOrderNo'] ??
81 | $this->helpers->generateOrderNo(),
82 | 'Status' => $params['Status'] ?? '1',
83 | 'CreateStatusTime' => $params['CreateStatusTime'] ?? null,
84 | 'Category' => $params['Category'] ?? 'B2C',
85 | 'BuyerName' => $params['BuyerName'],
86 | 'BuyerUBN' => $params['BuyerUBN'] ?? null,
87 | 'BuyerAddress' => $params['BuyerAddress'] ?? null,
88 | 'BuyerEmail' => $params['BuyerEmail'],
89 | 'CarrierType' => $params['CarrierType'] ?? null,
90 | 'CarrierNum' => $params['CarrierNum'] ?? null,
91 | 'LoveCode' => $params['LoveCode'] ?? null,
92 | 'PrintFlag' => $params['PrintFlag'] ?? 'Y',
93 | 'TaxType' => $params['TaxType'] ?? '1',
94 | 'TaxRate' => $params['TaxRate'] ?? 5,
95 | 'CustomsClearance' => $params['CustomsClearance'] ?? null,
96 | 'Amt' => $this->priceBeforeTax($params['TotalAmt'],
97 | $params['TaxRate']),
98 | 'AmtSales' => $params['AmtSales'] ?? null,
99 | 'AmtZero' => $params['AmtZero'] ?? null,
100 | 'AmtFree' => $params['AmtFree'] ?? null,
101 | 'TaxAmt' => $this->calcTax($params['TotalAmt'],
102 | $params['TaxRate']),
103 | 'TotalAmt' => $params['TotalAmt'],
104 | 'ItemName' => $params['ItemName'],
105 | 'ItemCount' => $params['ItemCount'],
106 | 'ItemUnit' => $params['ItemUnit'],
107 | 'ItemPrice' => $params['ItemPrice'],
108 | 'ItemAmt' => $params['ItemAmt'],
109 | 'ItemTaxType' => $params['ItemTaxType'] ?? null,
110 | 'Comment' => $params['Comment'] ?? null,
111 | ];
112 |
113 | $this->postData = array_filter($postData, function ($value) {
114 | return ($value !== null && $value !== false && $value !== '');
115 | });
116 |
117 | return $this->encrypt();
118 | }
119 |
120 | public function priceBeforeTax($price, $tax)
121 | {
122 | return $price - $this->calcTax($price, $tax);
123 | }
124 |
125 | public function calcTax($price, $tax)
126 | {
127 | $taxRate = $tax / 100;
128 |
129 | return $price - round($price / (1 + $taxRate));
130 | }
131 |
132 | /**
133 | * 加密開立發票資料
134 | *
135 | * @return $this
136 | */
137 | private function encrypt()
138 | {
139 | $postDataEncrypted = $this->helpers->encryptPostData(
140 | $this->postData,
141 | config('spgateway.receipt.HashKey'),
142 | config('spgateway.receipt.HashIV')
143 | );
144 |
145 | $this->postDataEncrypted = [
146 | 'MerchantID_' => config('spgateway.receipt.MerchantID'),
147 | 'PostData_' => $postDataEncrypted,
148 | ];
149 |
150 | return $this;
151 | }
152 |
153 | /**
154 | * 傳送開立發票請求到智付通
155 | *
156 | * @param array $headers 自訂Headers
157 | *
158 | * @return mixed
159 | */
160 | public function send($options = [])
161 | {
162 | $res = $this->helpers->sendPostRequest(
163 | $this->apiUrl['CREATE_RECEIPT_API'],
164 | $this->postDataEncrypted,
165 | $options
166 | );
167 |
168 | $result = json_decode($res);
169 |
170 | if ($result->Status === 'SUCCESS') {
171 | $result->Result = json_decode($result->Result);
172 | }
173 |
174 | return $result;
175 | }
176 |
177 | /**
178 | * 產生智付通觸發開立電子發票必要資訊
179 | *
180 | * @param $invoiceTransNo
181 | * @param $orderNo
182 | * @param $amount
183 | * @param null $transNum
184 | *
185 | * @return $this
186 | */
187 | public function generateTrigger(
188 | $invoiceTransNo,
189 | $orderNo,
190 | $amount,
191 | $transNum = null
192 | ) {
193 | // 智付通作廢電子發票必要資訊
194 | $triggerPostData = [
195 | 'RespondType' => 'JSON',
196 | 'Version' => '1.0',
197 | 'TimeStamp' => time(),
198 | 'TransNum' => $transNum,
199 | 'InvoiceTransNo' => $invoiceTransNo,
200 | 'MerchantOrderNo' => $orderNo,
201 | 'TotalAmt' => $amount,
202 | ];
203 |
204 | $this->triggerPostData = array_filter($triggerPostData,
205 | function ($value) {
206 | return ($value !== null && $value !== false && $value !== '');
207 | });
208 |
209 | return $this->encryptTrigger();
210 | }
211 |
212 | /**
213 | * 加密觸發開立發票資料
214 | *
215 | * @return $this
216 | */
217 | private function encryptTrigger()
218 | {
219 | $postDataEncrypted = $this->helpers
220 | ->encryptPostData(
221 | $this->triggerPostData,
222 | config('spgateway.receipt.HashKey'),
223 | config('spgateway.receipt.HashIV')
224 | );
225 |
226 | $this->triggerPostDataEncrypted = [
227 | 'MerchantID_' => config('spgateway.receipt.MerchantID'),
228 | 'PostData_' => $postDataEncrypted,
229 | ];
230 |
231 | return $this;
232 | }
233 |
234 | /**
235 | * 送出觸發開立電子發票請求到智付通
236 | *
237 | * @return bool
238 | */
239 | public function sendTrigger()
240 | {
241 | $res = $this->helpers->sendPostRequest(
242 | $this->apiUrl['TRIGGER_RECEIPT_API'],
243 | $this->triggerPostDataEncrypted
244 | );
245 |
246 | $result = json_decode($res);
247 |
248 | if ($result->Status === 'SUCCESS') {
249 | $result->Result = json_decode($result->Result);
250 | }
251 |
252 | return $result;
253 | }
254 |
255 | /**
256 | * 產生智付通作廢電子發票必要資訊
257 | *
258 | * @param $receiptNumber
259 | * @param $invalidReason
260 | *
261 | * @return $this|array
262 | */
263 | public function generateInvalid(
264 | $receiptNumber,
265 | $invalidReason
266 | ) {
267 | // 智付通作廢電子發票必要資訊
268 | $this->invalidPostData = [
269 | 'RespondType' => 'JSON',
270 | 'Version' => '1.0',
271 | 'TimeStamp' => time(),
272 | 'InvoiceNumber' => $receiptNumber,
273 | 'InvalidReason' => $invalidReason,
274 | ];
275 |
276 | return $this->encryptInvalid();
277 | }
278 |
279 | /**
280 | * 加密作廢發票資料
281 | *
282 | * @return $this
283 | */
284 | private function encryptInvalid()
285 | {
286 | $postDataEncrypted
287 | = $this->helpers->encryptPostData($this->invalidPostData);
288 |
289 | $this->invalidPostDataEncrypted = [
290 | 'MerchantID_' => config('spgateway.receipt.MerchantID'),
291 | 'PostData_' => $postDataEncrypted,
292 | ];
293 |
294 | return $this;
295 | }
296 |
297 | /**
298 | * 送出作廢電子發票請求到智付通
299 | *
300 | * @return bool
301 | */
302 | public function sendInvalid()
303 | {
304 | $res = $this->helpers->sendPostRequest(
305 | $this->apiUrl['INVALID_RECEIPT_API'],
306 | $this->invalidPostDataEncrypted
307 | );
308 |
309 | $result = json_decode($res);
310 |
311 | if ($result->Status === 'SUCCESS') {
312 | $result->Result = json_decode($result->Result);
313 | }
314 |
315 | return $result;
316 | }
317 |
318 | /**
319 | * 查詢發票
320 | *
321 | * @param $orderNo
322 | * @param $amount
323 | *
324 | * @return bool
325 | */
326 | public function search($orderNo, $amount)
327 | {
328 | $postData = [
329 | 'RespondType' => 'JSON',
330 | 'Version' => '1.1',
331 | 'TimeStamp' => time(),
332 | 'SearchType' => 1,
333 | 'MerchantOrderNo' => $orderNo,
334 | 'TotalAmt' => $amount,
335 | ];
336 |
337 | $postDataEncrypted = [
338 | 'MerchantID_' => config('spgateway.receipt.MerchantID'),
339 | 'PostData_' => $this->helpers->encryptPostData($postData),
340 | ];
341 |
342 | $res = $this->helpers->sendPostRequest(
343 | $this->apiUrl['SEARCH_RECEIPT_API'],
344 | $postDataEncrypted
345 | );
346 |
347 | $result = json_decode($res);
348 |
349 | if ($result->Status === 'SUCCESS') {
350 | $result->Result = json_decode($result->Result);
351 | }
352 |
353 | return $result;
354 | }
355 |
356 | public function getPostData()
357 | {
358 | return $this->postData;
359 | }
360 |
361 | public function getPostDataEncrypted()
362 | {
363 | return $this->postDataEncrypted;
364 | }
365 |
366 | public function getTriggerPostData()
367 | {
368 | return $this->triggerPostData;
369 | }
370 |
371 | public function getTriggerPostDataEncrypted()
372 | {
373 | return $this->triggerPostDataEncrypted;
374 | }
375 |
376 | public function getInvalidPostData()
377 | {
378 | return $this->invalidPostData;
379 | }
380 |
381 | public function getInvalidPostDataEncrypted()
382 | {
383 | return $this->invalidPostDataEncrypted;
384 | }
385 | }
386 |
--------------------------------------------------------------------------------
/src/Refund.php:
--------------------------------------------------------------------------------
1 | apiUrl = [];
18 | if (config('app.env') === 'production') {
19 | $this->apiUrl['CREDIT_CARD_CANCEL_API']
20 | = 'https://core.newebpay.com/API/CreditCard/Cancel';
21 | $this->apiUrl['CREDIT_CARD_REFUND_API']
22 | = 'https://core.newebpay.com/API/CreditCard/Close';
23 | $this->apiUrl['DELAYED_REFUND_API']
24 | = 'https://core.newebpay.com/API/Refund';
25 | } else {
26 | $this->apiUrl['CREDIT_CARD_CANCEL_API']
27 | = 'https://ccore.newebpay.com/API/CreditCard/Cancel';
28 | $this->apiUrl['CREDIT_CARD_REFUND_API']
29 | = 'https://ccore.newebpay.com/API/CreditCard/Close';
30 | $this->apiUrl['DELAYED_REFUND_API']
31 | = 'https://ccore.newebpay.com/API/Refund';
32 | }
33 |
34 | $this->helpers = new Helpers();
35 | }
36 |
37 | /**
38 | * 產生智付通退費 / 取消授權必要資料
39 | *
40 | * @param $orderNo
41 | * @param $amount
42 | * @param null $notifyUrl
43 | * @param bool $delayed
44 | * @param array $params
45 | *
46 | * @return Refund|object
47 | */
48 | public function generate(
49 | $orderNo,
50 | $amount,
51 | $notifyUrl = null,
52 | $delayed = false,
53 | $params = []
54 | ) {
55 | $mpg = new MPG();
56 | $tradeInfo = $mpg->search($orderNo, $amount);
57 | $tradeInfo = $tradeInfo->Result;
58 |
59 | if ($tradeInfo->TradeStatus === "1"
60 | && $tradeInfo->PaymentType === "CREDIT"
61 | && $tradeInfo->CloseStatus === "0"
62 | ) {
63 | $this->postData = $this->generateCreditCancel(
64 | $orderNo,
65 | $amount,
66 | $notifyUrl
67 | );
68 |
69 | $this->postType = 'cancel';
70 | } elseif ($tradeInfo->TradeStatus === "1"
71 | && $tradeInfo->PaymentType === "CREDIT"
72 | && $tradeInfo->CloseStatus === "3"
73 | ) {
74 | $this->postData = $this->generateCreditRefund(
75 | $orderNo,
76 | $amount,
77 | $params
78 | );
79 |
80 | $this->postType = 'refund';
81 | } elseif ($tradeInfo->TradeStatus === "1"
82 | && $delayed === true
83 | ) {
84 | $this->postData = $this->generateDelayedRefund(
85 | $orderNo,
86 | $params
87 | );
88 |
89 | $this->postType = 'delayed';
90 | } else {
91 | return (Object)[
92 | 'Status' => false,
93 | ];
94 | }
95 |
96 | return $this->encrypt();
97 | }
98 |
99 | /**
100 | * 加密資料
101 | *
102 | * @return $this
103 | */
104 | private function encrypt()
105 | {
106 | $PostData_ = $this->helpers->encryptPostData($this->postData);
107 |
108 | $this->postDataEncrypted = [
109 | 'MerchantID_' => config('spgateway.mpg.MerchantID'),
110 | 'PostData_' => $PostData_,
111 | ];
112 |
113 | return $this;
114 | }
115 |
116 | /**
117 | * 傳送退款 / 取消授權請求到智付通
118 | *
119 | * @param array $headers 自訂Headers
120 | *
121 | * @return mixed|string
122 | */
123 | public function send($headers = [])
124 | {
125 | if ($this->postType === 'cancel') {
126 | $url = $this->apiUrl['CREDIT_CARD_CANCEL_API'];
127 | } elseif ($this->postType === 'refund') {
128 | $url = $this->apiUrl['CREDIT_CARD_REFUND_API'];
129 | } elseif ($this->postType === 'delayed') {
130 | $url = $this->apiUrl['DELAYED_REFUND_API'];
131 | }
132 |
133 | $res = $this->helpers->sendPostRequest(
134 | $url,
135 | $this->postDataEncrypted,
136 | $headers
137 | );
138 |
139 | $res = json_decode($res);
140 |
141 | return $res;
142 | }
143 |
144 | /**
145 | * 產生取消授權必要資料
146 | *
147 | * @param $MerchantOrderNo
148 | * @param $Amt
149 | * @param $notifyUrl
150 | *
151 | * @return array
152 | */
153 | private function generateCreditCancel(
154 | $MerchantOrderNo,
155 | $Amt,
156 | $notifyUrl
157 | ) {
158 | $postData = [
159 | 'RespondType' => 'JSON',
160 | 'Version' => '1.0',
161 | 'Amt' => $Amt,
162 | 'MerchantOrderNo' => $MerchantOrderNo,
163 | 'IndexType' => 1,
164 | 'TimeStamp' => time(),
165 | 'NotifyURL' => $notifyUrl,
166 | ];
167 |
168 | return $postData;
169 | }
170 |
171 | /**
172 | * 產生退費必要資料
173 | *
174 | * @param $orderNo
175 | * @param $amount
176 | * @param $params
177 | *
178 | * @return array
179 | */
180 | private function generateCreditRefund($orderNo, $amount, $params)
181 | {
182 | $postData = [
183 | 'RespondType' => 'JSON',
184 | 'Version' => '1.0',
185 | 'Amt' => $params['RefundAmt'] ?? $amount,
186 | 'MerchantOrderNo' => $orderNo,
187 | 'IndexType' => 1,
188 | 'TimeStamp' => time(),
189 | 'CloseType' => 2,
190 | ];
191 |
192 | return $postData;
193 | }
194 |
195 | /**
196 | *
197 | *
198 | * @param $orderNo
199 | * @param $params
200 | *
201 | * @return array
202 | */
203 | private function generateDelayedRefund($orderNo, $params)
204 | {
205 | $postData = [
206 | 'Version' => '1.0',
207 | 'TimeStamp' => time(),
208 | 'MerOrderNo' => $orderNo
209 | ];
210 |
211 | $postData = array_merge($postData, $params);
212 |
213 | return $postData;
214 | }
215 |
216 | public function getPostData()
217 | {
218 | return $this->postData;
219 | }
220 |
221 | public function getPostType()
222 | {
223 | return $this->postType;
224 | }
225 |
226 | public function getPostDataEncrypted()
227 | {
228 | return $this->postDataEncrypted;
229 | }
230 | }
--------------------------------------------------------------------------------
/src/SpgatewayServiceProvider.php:
--------------------------------------------------------------------------------
1 | registerConfig();
12 | $this->registerResources();
13 | }
14 |
15 | /**
16 | * Register the service provider.
17 | *
18 | * @return void
19 | */
20 | public function register()
21 | {
22 | $app = $this->app;
23 |
24 | // create image
25 | $app->singleton('mpg', function ($app) {
26 | return new MPG();
27 | });
28 |
29 | // create image
30 | $app->singleton('receipt', function ($app) {
31 | return new Receipt();
32 | });
33 |
34 | // create image
35 | $app->singleton('encrypt', function ($app) {
36 | return new EncryptLibrary();
37 | });
38 |
39 | // create image
40 | $app->singleton('refund', function ($app) {
41 | return new Refund();
42 | });
43 |
44 | // create image
45 | $app->singleton('transfer', function ($app) {
46 | return new Transfer();
47 | });
48 | }
49 |
50 | protected function registerConfig()
51 | {
52 | $this->mergeConfigFrom(
53 | __DIR__ . '/../config/spgateway.php', 'spgateway'
54 | );
55 |
56 | $this->publishes([
57 | __DIR__ . '/../config/spgateway.php' => config_path('spgateway.php'),
58 | ]);
59 | }
60 |
61 | protected function registerResources()
62 | {
63 | $this->loadViewsFrom(__DIR__ . '/../resources/views', 'spgateway');
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/Transfer.php:
--------------------------------------------------------------------------------
1 | apiUrl['CHARGE_INSTRUCT_API']
18 | = 'https://core.newebpay.com/API/ChargeInstruct';
19 | } else {
20 | $this->apiUrl['CHARGE_INSTRUCT_API']
21 | = 'https://ccore.newebpay.com/API/ChargeInstruct';
22 | }
23 |
24 | $this->helpers = new Helpers();
25 | }
26 |
27 | /**
28 | * 產生平台扣款指示必要欄位
29 | *
30 | * @param $merchantID
31 | * @param $amount
32 | * @param $feeType
33 | * @param $balanceType
34 | *
35 | * @return $this|Transfer
36 | */
37 | public function generate(
38 | $merchantID,
39 | $amount,
40 | $feeType,
41 | $balanceType
42 | ) {
43 | // 智付通平台費用扣款必要資訊
44 | $this->postData = [
45 | 'Version' => '1.0',
46 | 'TimeStamp' => time(),
47 | 'MerchantID' => $merchantID,
48 | 'Amount' => $amount,
49 | 'FeeType' => $feeType,
50 | 'BalanceType' => $balanceType,
51 | ];
52 |
53 | return $this->encrypt();
54 | }
55 |
56 | /**
57 | * 加密資料
58 | *
59 | * @return $this
60 | */
61 | public function encrypt()
62 | {
63 | $postData_ = $this->encryptPostData($this->postData);
64 |
65 | $this->postDataEncrypted = [
66 | 'PartnerID_' => config('spgateway.PartnerID'),
67 | 'PostData_' => $postData_,
68 | ];
69 |
70 | return $this;
71 | }
72 |
73 | /**
74 | * 智付通資料加密
75 | *
76 | * @param $postData
77 | *
78 | * @return string
79 | */
80 | public function encryptPostData(
81 | $postData
82 | ) {
83 | // 所有資料與欄位使用 = 符號組合,並用 & 符號串起字串
84 | $postData = http_build_query($postData);
85 |
86 | // 加密字串
87 | $post_data = trim(bin2hex(openssl_encrypt(
88 | $this->helpers->addPadding($postData),
89 | 'AES-256-CBC',
90 | config('spgateway.CompanyKey'),
91 | OPENSSL_RAW_DATA | OPENSSL_NO_PADDING,
92 | config('spgateway.CompanyIV')
93 | )));
94 |
95 | return $post_data;
96 | }
97 |
98 | /**
99 | * 傳送扣款指示要求到智付通
100 | *
101 | * @param array $headers 自訂Headers
102 | *
103 | * @return mixed
104 | */
105 | public function send($options = [])
106 | {
107 | $res = $this->helpers->sendPostRequest(
108 | $this->apiUrl['CHARGE_INSTRUCT_API'],
109 | $this->postDataEncrypted,
110 | $options
111 | );
112 |
113 | $result = json_decode($res);
114 |
115 | if ($result->Status === 'SUCCESS') {
116 | $result->Result = json_decode($result->Result);
117 | }
118 |
119 | return $result;
120 | }
121 |
122 | public function getPostData(){
123 | return $this->postData;
124 | }
125 |
126 | public function getPostDataEncrypted(){
127 | return $this->postDataEncrypted;
128 | }
129 | }
130 |
--------------------------------------------------------------------------------