├── .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 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 26 | 27 | 28 | 29 | 35 | 36 | 37 | 38 | 39 | 45 | 46 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 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 | 36 | 37 | 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 | 18 | 19 | $PROJECT_DIR$/composer.json 20 | 21 | 22 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 1525935455844 160 | 172 | 173 | 174 | 175 | 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 | 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 | [![Latest Stable Version](https://poser.pugx.org/leochien/laravel-spgateway/v/stable)](https://packagist.org/packages/leochien/laravel-spgateway) 3 | [![Total Downloads](https://poser.pugx.org/leochien/laravel-spgateway/downloads)](https://packagist.org/packages/leochien/laravel-spgateway) 4 | [![Latest Unstable Version](https://poser.pugx.org/leochien/laravel-spgateway/v/unstable)](https://packagist.org/packages/leochien/laravel-spgateway) 5 | [![License](https://poser.pugx.org/leochien/laravel-spgateway/license)](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 | 56 | 58 | 65 | 66 | 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 | --------------------------------------------------------------------------------