├── .github ├── FUNDING.yml └── workflows │ └── tests.yml ├── LICENSE ├── README.md ├── composer.json ├── config └── newebpay.php └── src ├── Concerns ├── HasEncryption.php ├── HasSender.php └── WithSessionIdKey.php ├── Contracts ├── Httpable.php └── Sender.php ├── Enums ├── Bank.php ├── CVSCOM.php ├── CreditInst.php ├── CreditRememberDemand.php ├── LgsType.php ├── NTCBLocate.php ├── PeriodStartType.php ├── PeriodStatus.php └── PeriodType.php ├── Exceptions └── NewebpayDecodeFailException.php ├── Facades └── NewebPay.php ├── Factory.php ├── NewebPay.php ├── NewebPayCancel.php ├── NewebPayClose.php ├── NewebPayCustomer.php ├── NewebPayMPG.php ├── NewebPayPeriod.php ├── NewebPayPeriodAmt.php ├── NewebPayPeriodNotify.php ├── NewebPayPeriodResult.php ├── NewebPayPeriodStatus.php ├── NewebPayQuery.php ├── NewebPayRequest.php ├── NewebPayResult.php ├── NewebPayServiceProvider.php ├── Results ├── CancelResult.php ├── CloseResult.php ├── Concerns │ └── HasVerifyCheckCode.php ├── CustomerATMResult.php ├── CustomerLgsResult.php ├── CustomerResult.php ├── CustomerStoreBarcodeResult.php ├── CustomerStoreCodeResult.php ├── MPGATMResult.php ├── MPGCreditResult.php ├── MPGEsunWalletResult.php ├── MPGEzPayResult.php ├── MPGLgsResult.php ├── MPGResult.php ├── MPGStoreBarcodeResult.php ├── MPGStoreCodeResult.php ├── MPGTaiwanPayResult.php ├── PeriodAmtResult.php ├── PeriodNotifyResult.php ├── PeriodResult.php ├── PeriodStatusResult.php ├── QueryCreditResult.php ├── QueryDigitalWalletResult.php ├── QueryLgsResult.php ├── QueryPaymentStatusResult.php ├── QueryResult.php └── Result.php └── Senders ├── BackgroundSender.php └── FrontendSender.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: ycs77 2 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: tests 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | tests: 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | fail-fast: true 14 | matrix: 15 | os: [ubuntu-latest] 16 | php: [8.1, 8.2, 8.3] 17 | laravel: [9.*, 10.*, 11.*] 18 | exclude: 19 | - php: 8.1 20 | laravel: 11.* 21 | 22 | name: P${{ matrix.php }} - L${{ matrix.laravel }} 23 | 24 | steps: 25 | - name: Checkout code 26 | uses: actions/checkout@v3 27 | 28 | - name: Setup PHP 29 | uses: shivammathur/setup-php@v2 30 | with: 31 | php-version: ${{ matrix.php }} 32 | extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, mysql, mysqli, pdo_mysql, bcmath, intl, gd, exif, iconv, imagick, fileinfo 33 | coverage: none 34 | 35 | - name: Setup problem matchers 36 | run: | 37 | echo "::add-matcher::${{ runner.tool_cache }}/php.json" 38 | echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" 39 | 40 | - name: Install dependencies 41 | run: | 42 | composer require "laravel/framework:${{ matrix.laravel }}" --no-interaction --no-update 43 | composer update --prefer-stable --prefer-dist --no-interaction 44 | 45 | - name: Execute tests 46 | run: vendor/bin/pest 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright: (c) 2020-present Lucas Yang 4 | (c) 2019 wallase 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel NewebPay - 藍新金流 2 | 3 | > Fork from [treerful/laravel-newebpay](https://bitbucket.org/pickone/laravel-newebpay) 4 | 5 | [![Latest Version on Packagist][ico-version]][link-packagist] 6 | [![Software License][ico-license]](LICENSE) 7 | [![GitHub Tests Action Status][ico-github-action]][link-github-action] 8 | [![Style CI Build Status][ico-style-ci]][link-style-ci] 9 | [![Total Downloads][ico-downloads]][link-downloads] 10 | 11 | Laravel NewebPay 為針對 Laravel 所寫的藍新金流(智付通)金流串接套件。 12 | 13 | 主要實作項目: 14 | 15 | * NewebPay MPG - 多功能收款 16 | * NewebPay Query - 單筆交易查詢 17 | * NewebPay Cancel - 信用卡取消授權 18 | * NewebPay Close - 信用卡請退款 19 | * NewebPay Period - 信用卡定期定額委託 20 | * NewebPay Period Alter Status - 修改委託狀態 21 | * NewebPay Period Alter Amt - 修改委託內容 22 | 23 | ## 版本需求 24 | 25 | * PHP 支援 8.1 以上 26 | * Laravel 版本 9 以上 27 | 28 | ## 安裝 29 | 30 | ``` 31 | composer require ycs77/laravel-newebpay 32 | ``` 33 | 34 | ### 發布設置檔案 35 | 36 | ``` 37 | php artisan vendor:publish --tag=newebpay-config 38 | ``` 39 | 40 | ## 註冊藍新金流商店 41 | 42 | 首先先到藍新金流的網站上註冊帳號 (測試時需註冊測試帳號) 和建立商店。然後在「商店資料設定」中啟用需要使用的金流功能 (測試時可以盡量全部啟用),並複製商店串接 API 的商店代號、`HashKey` 和 `HashIV`。 43 | 44 | 設定 `.env` 的商店代號和 HashKey 等: 45 | 46 | ``` 47 | NEWEBPAY_STORE_ID=... # 貼上 商店代號 (Ex: MS3311...) 48 | NEWEBPAY_STORE_HASH_KEY=... # 貼上 HashKey 49 | NEWEBPAY_STORE_HASH_IV=... # 貼上 HashIV 50 | NEWEBPAY_DEBUG=true # 測試模式 51 | ``` 52 | 53 | 更多設定需開啟 `config/newebpay.php` 修改。 54 | 55 | ## 測試用帳號 56 | 57 | 測試環境僅接受以下的測試信用卡號: 58 | 59 | * 4000-2211-1111-1111 (一次付清+分期付款) 60 | * 4003-5511-1111-1111 (紅利折抵) 61 | 62 | 測試卡號有效月年及卡片背面末三碼,可任意填寫。 63 | 64 | 更多詳細資訊請參考[藍新金流 API 文件](https://www.newebpay.com/website/Page/content/download_api)。 65 | 66 | ## MPG 多功能付款 67 | 68 | ### 發送付款請求頁面 69 | 70 | 首先先建立一個頁面,和一個「付款」按鈕: 71 | 72 | *routes/web.php* 73 | ```php 74 | Route::get('/pay', function () { 75 | return view('pay'); 76 | }); 77 | ``` 78 | 79 | *resources/views/pay.blade.php* 80 | ```html 81 |
82 | @csrf 83 | 84 |
85 | ``` 86 | 87 | Inertia.js 可以參考以下: 88 | 89 | *routes/web.php* 90 | ```php 91 | Route::get('/pay', function () { 92 | return Inertia::render('Pay', [ 93 | 'csrfToken' => csrf_token(), 94 | ]); 95 | }); 96 | ``` 97 | 98 | *resources/js/pages/Pay.vue* 99 | ```vue 100 | 106 | 107 | 112 | ``` 113 | 114 | 然後建立送出付款的路由: 115 | 116 | ```php 117 | use Ycs77\NewebPay\Facades\NewebPay; 118 | 119 | Route::post('/pay', function () { 120 | $no = 'Vanespl_ec_'.time(); // 訂單編號 121 | $amt = 120; // 交易金額 122 | $desc = '我的商品'; // 商品名稱 123 | $email = 'test@example.com'; // 付款人信箱 124 | 125 | return NewebPay::payment($no, $amt, $desc, $email)->submit(); 126 | }); 127 | ``` 128 | 129 | 基本上一般交易可直接在 `config/newebpay.php` 做設定,裡面有詳細的解說,但若遇到特殊情況,可依據個別交易設定: 130 | 131 | ```php 132 | use Ycs77\NewebPay\Facades\NewebPay; 133 | 134 | return NewebPay::payment(...) 135 | ->lang() // 語言設定 136 | ->tradeLimit() // 交易秒數限制 137 | ->expireDate() // 交易截止日 138 | ->returnUrl() // 由藍新回傳後前景畫面要接收資料顯示的網址 139 | ->notifyUrl() // 由藍新回傳後背景處理資料的接收網址 140 | ->customerUrl() // 商店取號網址 141 | ->clientBackUrl() // 付款時點擊「返回按鈕」的網址 142 | ->emailModify() // 是否開放 email 修改 143 | ->loginType() // 是否需要登入藍新金流會員 144 | ->orderComment() // 商店備註 145 | ->paymentMethod() // 付款方式 *依照 config 格式傳送* 146 | ->CVSCOM() // 物流方式 147 | ->lgsType() // 物流型態 148 | ->submit(); 149 | ``` 150 | 151 | ### 付款請求回傳結果 152 | 153 | 送出付款之後當然是要建立回傳的路由,如果是信用卡之類的付款方式,可以付款後直接跳轉回本網站的,可以只設定 callback: 154 | 155 | ```php 156 | use Illuminate\Http\Request; 157 | use Ycs77\NewebPay\Facades\NewebPay; 158 | 159 | Route::post('/pay/callback', function (Request $request) { 160 | $result = NewebPay::result($request); 161 | 162 | if ($result->isFail()) { 163 | return redirect()->to('/pay')->with('error', $result->message()); 164 | } 165 | 166 | // 訂單付款成功,處裡訂單邏輯... 167 | 168 | return redirect()->to('/pay')->with('success', '付款成功'); 169 | }); 170 | ``` 171 | 172 | 如果是 ATM 的付款方式,需要透過幕後回傳的,可以只設定 notify: 173 | 174 | ```php 175 | use Illuminate\Http\Request; 176 | use Ycs77\NewebPay\Facades\NewebPay; 177 | 178 | Route::post('/pay/notify', function (Request $request) { 179 | $result = NewebPay::result($request); 180 | 181 | if ($result->isFail()) { 182 | return; 183 | } 184 | 185 | logger('藍新金流 交易資訊 notify', ['result' => $result->data()]); 186 | 187 | // 訂單付款成功,處裡訂單邏輯... 188 | }); 189 | ``` 190 | 191 | 回傳結果可以使用各個方法來取得需要的資料: 192 | 193 | ```php 194 | $result = NewebPay::result($request); 195 | $result->data(); // 回傳完整結果 196 | $result->status(); // 交易狀態:若交易付款成功,則回傳 SUCCESS。若交易付款失敗,則回傳錯誤代碼。 197 | $result->isSuccess(); // 交易是否成功 198 | $result->isFail(); // 交易是否失敗 199 | $result->message(); // 敘述此次交易狀態 200 | $result->result(); // 回傳參數 201 | $result->merchantId(); // 藍新金流商店代號 202 | $result->amt(); // 交易金額 203 | $result->tradeNo(); // 藍新金流交易序號 204 | $result->merchantOrderNo(); // 商店訂單編號 205 | $result->respondType(); // 回傳格式 206 | $result->payTime(); // 支付完成時間 207 | $result->ip(); // 交易 IP 208 | $result->escrowBank(); // 款項保管銀行 209 | 210 | // 信用卡支付回傳(一次付清、Google Pay、Samaung Pay、國民旅遊卡、銀聯) 211 | if ($result->paymentType() === 'CREDIT') { 212 | $credit = $result->credit(); 213 | // 參考:\Ycs77\NewebPay\Results\MPGCreditResult 214 | } 215 | 216 | // WEBATM、ATM 繳費回傳 217 | if ($result->paymentType() === 'VACC' || $result->paymentType() === 'WEBATM') { 218 | $atm = $result->atm(); 219 | // 參考:\Ycs77\NewebPay\Results\MPGATMResult 220 | } 221 | 222 | // 超商代碼繳費回傳 223 | if ($result->paymentType() === 'CVS') { 224 | $storeCode = $result->storeCode(); 225 | // 參考:\Ycs77\NewebPay\Results\MPGStoreCodeResult 226 | } 227 | 228 | // 超商條碼繳費回傳 229 | if ($result->paymentType() === 'BARCODE') { 230 | $storeBarcode = $result->storeBarcode(); 231 | // 參考:\Ycs77\NewebPay\Results\MPGStoreBarcodeResult 232 | } 233 | 234 | // 超商物流回傳 235 | if ($result->paymentType() === 'CVSCOM') { 236 | $lgs = $result->lgs(); 237 | // 參考:\Ycs77\NewebPay\Results\MPGLgsResult 238 | } 239 | 240 | // 跨境支付回傳 (包含簡單付電子錢包、簡單付微信支付、簡單付支付寶) 241 | $ezPay = $result->ezPay(); 242 | if ($ezPay->isEzPay()) { 243 | // 參考:\Ycs77\NewebPay\Results\MPGEzPayResult 244 | } 245 | 246 | // 玉山 Wallet 回傳 247 | if ($result->paymentType() === 'ESUNWALLET') { 248 | $esunWallet = $result->esunWallet(); 249 | // 參考:\Ycs77\NewebPay\Results\MPGEsunWalletResult 250 | } 251 | 252 | // 台灣 Pay 回傳 253 | if ($result->paymentType() === 'TAIWANPAY') { 254 | $taiwanPay = $result->taiwanPay(); 255 | // 參考:\Ycs77\NewebPay\Results\MPGTaiwanPayResult 256 | } 257 | ``` 258 | 259 | 但如果兩個同時設定的話,進行部分交易時兩個 API 都會發送訊息,這時就要各司其職,callback 只設定返回給用戶的訊息,而 notify 只負責處理交易的邏輯: 260 | 261 | ```php 262 | use Illuminate\Http\Request; 263 | use Ycs77\NewebPay\Facades\NewebPay; 264 | 265 | Route::post('/pay/callback', function (Request $request) { 266 | $result = NewebPay::result($request); 267 | 268 | if ($result->isFail()) { 269 | return redirect()->to('/pay')->with('error', $result->message()); 270 | } 271 | 272 | return redirect()->to('/pay')->with('success', '付款成功'); 273 | }); 274 | 275 | Route::post('/pay/notify', function (Request $request) { 276 | $result = NewebPay::result($request); 277 | 278 | if ($result->isFail()) { 279 | return; 280 | } 281 | 282 | logger('藍新金流 交易資訊 notify', ['result' => $result->data()]); 283 | 284 | // 訂單付款成功,處裡訂單邏輯... 285 | }); 286 | ``` 287 | 288 | 設定好之後可以在 `config/newebpay.php` 裡設定網址: 289 | 290 | ```php 291 | return [ 292 | 293 | // 付款完成後導向頁面 294 | 'return_url' => '/pay/callback', 295 | 296 | // 付款完成後的通知連結 297 | 'notify_url' => '/pay/notify', 298 | 299 | ] 300 | ``` 301 | 302 | 還要把這些路徑排除 CSRF 檢查: 303 | 304 | *app/Http/Middleware/VerifyCsrfToken.php* 305 | ```php 306 | class VerifyCsrfToken extends Middleware 307 | { 308 | protected $except = [ 309 | '/pay/callback', 310 | '/pay/notify', 311 | ]; 312 | } 313 | ``` 314 | 315 | ## ATM/超商條碼/超商代碼取號 316 | 317 | 預設會直接導向到藍新金流的取號頁面,沒有特別需求不需要自己做。但如果要自訂取號頁面的話,也是可以自己客製調整: 318 | 319 | ```php 320 | use Ycs77\NewebPay\Facades\NewebPay; 321 | 322 | Route::post('/pay/customer', function (Request $request) { 323 | $result = NewebPay::customer($request); 324 | 325 | if ($result->isFail()) { 326 | // 取號錯誤... 327 | return; 328 | } 329 | 330 | $result = $result->result(); 331 | 332 | // 自訂取號結果頁面... 333 | }); 334 | ``` 335 | 336 | 在 `config/newebpay.php` 裡設定網址: 337 | 338 | ```php 339 | return [ 340 | 341 | // 商店取號網址 342 | 'customer_url' => '/pay/customer', 343 | 344 | ] 345 | ``` 346 | 347 | 然後要把路徑排除 CSRF 檢查: 348 | 349 | *app/Http/Middleware/VerifyCsrfToken.php* 350 | ```php 351 | class VerifyCsrfToken extends Middleware 352 | { 353 | protected $except = [ 354 | ... 355 | '/pay/customer', 356 | ]; 357 | } 358 | ``` 359 | 360 | ## 單筆交易查詢 361 | 362 | 從訂單編號和該筆交易的金額來查詢交易詳情: 363 | 364 | ```php 365 | use Ycs77\NewebPay\Facades\NewebPay; 366 | 367 | function query(Request $request) 368 | { 369 | $no = $request->input('no'); // 該筆交易的訂單編號 370 | $amt = $request->input('amt'); // 該筆交易的金額 371 | $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 372 | 373 | $result = NewebPay::query($no, $amt, $type)->submit(); 374 | 375 | if ($result->isSuccess() && $result->verify()) { 376 | // 查詢成功... 377 | 378 | return response()->json($result->result()); 379 | } 380 | 381 | return response()->json(['message' => $result->message()]); 382 | } 383 | ``` 384 | 385 | ## 信用卡取消授權 386 | 387 | 在尚未請款時可以發動取消信用卡交易: 388 | 389 | ```php 390 | use Ycs77\NewebPay\Facades\NewebPay; 391 | 392 | function cancel() 393 | { 394 | $no = $request->input('no'); // 該筆交易的訂單編號 395 | $amt = $request->input('amt'); // 該筆交易的金額 396 | $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 397 | 398 | $result = NewebPay::cancel($no, $amt, $type)->submit(); 399 | 400 | if ($result->isSuccess() && $result->verify()) { 401 | return response()->json(['message' => '取消授權成功']); 402 | } 403 | 404 | return response()->json(['message' => $result->message()]); 405 | } 406 | ``` 407 | 408 | ## 信用卡請/退款 409 | 410 | 設定信用卡請款、取消請款、退款、取消退款: 411 | 412 | ```php 413 | use Ycs77\NewebPay\Facades\NewebPay; 414 | 415 | /** 416 | * 信用卡請款 417 | */ 418 | function request() 419 | { 420 | $no = $request->input('no'); // 該筆交易的訂單編號 421 | $amt = $request->input('amt'); // 該筆交易的金額 422 | $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 423 | 424 | $result = NewebPay::request($no, $amt, $type)->submit(); 425 | 426 | if ($result->isSuccess()) { 427 | return response()->json(['message' => '信用卡請款成功']); 428 | } 429 | 430 | return response()->json(['message' => $result->message()]); 431 | } 432 | 433 | /** 434 | * 信用卡取消請款 435 | */ 436 | function cancelRequest() 437 | { 438 | $no = $request->input('no'); // 該筆交易的訂單編號 439 | $amt = $request->input('amt'); // 該筆交易的金額 440 | $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 441 | 442 | $result = NewebPay::cancelRequest($no, $amt, $type)->submit(); 443 | 444 | if ($result->isSuccess()) { 445 | return response()->json(['message' => '信用卡取消請款成功']); 446 | } 447 | 448 | return response()->json(['message' => $result->message()]); 449 | } 450 | 451 | /** 452 | * 信用卡退款 453 | */ 454 | function refund() 455 | { 456 | $no = $request->input('no'); // 該筆交易的訂單編號 457 | $amt = $request->input('amt'); // 該筆交易的金額 458 | $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 459 | 460 | $result = NewebPay::refund($no, $amt, $type)->submit(); 461 | 462 | if ($result->isSuccess()) { 463 | return response()->json(['message' => '信用卡退款成功']); 464 | } 465 | 466 | return response()->json(['message' => $result->message()]); 467 | } 468 | 469 | /** 470 | * 信用卡取消退款 471 | */ 472 | function cancelRefund() 473 | { 474 | $no = $request->input('no'); // 該筆交易的訂單編號 475 | $amt = $request->input('amt'); // 該筆交易的金額 476 | $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 477 | 478 | $result = NewebPay::cancelRefund($no, $amt, $type)->submit(); 479 | 480 | if ($result->isSuccess()) { 481 | return response()->json(['message' => '信用卡取消退款成功']); 482 | } 483 | 484 | return response()->json(['message' => $result->message()]); 485 | } 486 | ``` 487 | 488 | 或是也可以使用同一個 API 端點來執行請/退款: 489 | 490 | ```php 491 | use Ycs77\NewebPay\Facades\NewebPay; 492 | 493 | /** 494 | * 信用卡請/退款 495 | */ 496 | function close() 497 | { 498 | $no = $request->input('no'); // 該筆交易的訂單編號 499 | $amt = $request->input('amt'); // 該筆交易的金額 500 | $type = 'order'; // 可選擇是 'order' (訂單編號),或是 'trade' (藍新交易編號) 來做申請 501 | 502 | $result = NewebPay::close($no, $amt, $type) 503 | ->closeType($request->query('type')) // 設定請款或退款 504 | ->cancel($request->boolean('cancel')) // 取消請款或退款 505 | ->submit(); 506 | 507 | if ($result->isSuccess()) { 508 | return response()->json(['message' => '請求成功']); 509 | } 510 | 511 | return response()->json(['message' => $result->message()]); 512 | } 513 | ``` 514 | 515 | ## 信用卡定期定額委託 516 | 517 | ### 發送建立委託請求頁面 518 | 519 | 首先先建立一個頁面,和一個「訂閱」按鈕: 520 | 521 | *routes/web.php* 522 | ```php 523 | Route::get('/subscribe', function () { 524 | return view('subscribe'); 525 | }); 526 | ``` 527 | 528 | *resources/views/subscribe.blade.php* 529 | ```html 530 |
531 | @csrf 532 | 533 |
534 | ``` 535 | 536 | Inertia.js 可以參考以下: 537 | 538 | *routes/web.php* 539 | ```php 540 | Route::get('/subscribe', function () { 541 | return Inertia::render('Subscribe', [ 542 | 'csrfToken' => csrf_token(), 543 | ]); 544 | }); 545 | ``` 546 | 547 | *resources/js/pages/Subscribe.vue* 548 | ```vue 549 | 555 | 556 | 561 | ``` 562 | 563 | 然後建立送出付款的路由: 564 | 565 | ```php 566 | use Ycs77\NewebPay\Facades\NewebPay; 567 | 568 | Route::post('/subscribe', function () { 569 | $no = now()->timestamp; // 訂單編號 570 | $amt = 120; // 交易金額 571 | $desc = '我的訂閱制商品'; // 商品名稱 572 | $email = 'test@example.com'; // 付款人信箱 573 | 574 | return NewebPay::period($no, $amt, $desc, $email) 575 | ->everyFewDays(2) 576 | ->times(3) 577 | ->submit(); 578 | }); 579 | ``` 580 | 581 | ### 建立委託請求回傳結果 582 | 583 | 設定建立委託完成後,將頁面導向回原本的網站頁面: 584 | 585 | ```php 586 | use Illuminate\Http\Request; 587 | use Ycs77\NewebPay\Facades\NewebPay; 588 | 589 | Route::post('/pay/period/callback', function (Request $request) { 590 | $result = NewebPay::periodResult($request); 591 | 592 | if ($result->isFail()) { 593 | return redirect()->to('/pay')->with('error', $result->message()); 594 | } 595 | 596 | return redirect()->to('/pay')->with('success', '付款成功'); 597 | }); 598 | ``` 599 | 600 | 以及設定每期委託授權結果通知: 601 | 602 | ```php 603 | use Illuminate\Http\Request; 604 | use Illuminate\Support\Facades\Log; 605 | use Ycs77\NewebPay\Facades\NewebPay; 606 | 607 | Route::post('/pay/period/notify', function (Request $request) { 608 | $result = NewebPay::periodNotify($request); 609 | 610 | if ($result->isFail()) { 611 | Log::error('藍新金流 定期定額 定期交易錯誤', $result->data()); 612 | 613 | return; 614 | } 615 | 616 | // 委託授權成功,處裡訂單邏輯... 617 | }); 618 | ``` 619 | 620 | 設定好之後可以在 `config/newebpay.php` 裡設定網址: 621 | 622 | ```php 623 | return [ 624 | 625 | 'period' => [ 626 | // 建立委託完成後導向頁面 627 | 'return_url' => '/pay/period/callback', 628 | 629 | // 每期委託授權結果通知: 630 | 'notify_url' => '/pay/period/notify', 631 | ], 632 | 633 | ] 634 | ``` 635 | 636 | 記得要把這些路徑排除 CSRF 檢查: 637 | 638 | *app/Http/Middleware/VerifyCsrfToken.php* 639 | ```php 640 | class VerifyCsrfToken extends Middleware 641 | { 642 | protected $except = [ 643 | ... 644 | '/pay/period/callback', 645 | '/pay/period/notify', 646 | ]; 647 | } 648 | ``` 649 | 650 | ### 授權週期 651 | 652 | 若於週期內需授權多次,請以建立多次委託方式執行。 653 | 654 | 設定此委託於固定天期制授權,輸入數字為間隔天數 2~999。以授權日期隔日起算,以下為每隔 40 天授權一次: 655 | 656 | ```php 657 | NewebPay::period($no, $amt, $desc, $email) 658 | ->everyFewDays(40) 659 | ->times(1) 660 | ->submit(); 661 | ``` 662 | 663 | 設定此委託於每週授權,輸入數字為 1~7,代表每週一至週日。以下為每週日授權一次: 664 | 665 | ```php 666 | NewebPay::period($no, $amt, $desc, $email) 667 | ->weekly(7) 668 | ->times(1) 669 | ->submit(); 670 | ``` 671 | 672 | 設定此委託於每月授權,輸入數字為 1~31,每月的第幾天執行委託,若當月沒該日期則由該月的最後一天做為扣款日。以下為每月 20 日授權一次: 673 | 674 | ```php 675 | NewebPay::period($no, $amt, $desc, $email) 676 | ->monthly(20) 677 | ->times(1) 678 | ->submit(); 679 | ``` 680 | 681 | 設定此委託於每年授權,輸入每年的幾月幾日執行委託。以下為每年 3 月 4 日授權一次: 682 | 683 | ```php 684 | NewebPay::period($no, $amt, $desc, $email) 685 | ->yearly(3, 4) 686 | ->times(1) 687 | ->submit(); 688 | ``` 689 | 690 | ### 授權期數 691 | 692 | 設定授權委託的期數。以下為每月 4 日授權,共授權 6 次,為期 6 個月: 693 | 694 | ```php 695 | NewebPay::period($no, $amt, $desc, $email) 696 | ->monthly(4) 697 | ->times(6) 698 | ->submit(); 699 | ``` 700 | 701 | ### 立即執行十元授權 702 | 703 | 設定立即執行十元授權,以驗證信用卡: 704 | 705 | ```php 706 | 'period' => [ 707 | 'start_type' => PeriodStartType::TEN_DOLLARS_NOW, 708 | ], 709 | ``` 710 | 711 | ### 立即執行委託金額授權 712 | 713 | 設定立即執行委託金額授權: 714 | 715 | ```php 716 | 'period' => [ 717 | 'start_type' => PeriodStartType::AUTHORIZE_NOW, 718 | ], 719 | ``` 720 | 721 | ### 不檢查信用卡資訊,不授權 722 | 723 | 設定刷卡完之後,不檢查信用卡資訊,也不執行授權: 724 | 725 | ```php 726 | 'period' => [ 727 | 'start_type' => PeriodStartType::NO_AUTHORIZE, 728 | ], 729 | ``` 730 | 731 | 但需要設定首期授權日: 732 | 733 | ```php 734 | NewebPay::period($no, $amt, $desc, $email) 735 | ->everyFewDays(2) 736 | ->times(3) 737 | ->firstdate(2023, 3, 1) 738 | ->submit(); 739 | ``` 740 | 741 | ## 修改委託狀態 742 | 743 | 修改委託狀態需要傳入訂單編號、委託單號和委託狀態: 744 | 745 | ```php 746 | use Illuminate\Http\Request; 747 | use Ycs77\NewebPay\Enums\PeriodStatus; 748 | use Ycs77\NewebPay\Facades\NewebPay; 749 | 750 | Route::post('/pay/period/status', function (Request $request) { 751 | $result = NewebPay::periodStatus($request->input('no'), $request->input('periodNo'), PeriodStatus::TERMINATE) 752 | ->submit(); 753 | 754 | return $result->isSuccess() 755 | ? back()->with('success', '修改委託狀態成功') 756 | : back()->withErrors(['no' => $result->message()]); 757 | }); 758 | ``` 759 | 760 | 委託狀態可以修改成 `PeriodStatus::SUSPEND` (暫停) 和 `PeriodStatus::TERMINATE` (終止) 兩種狀態,設定成暫停之後還可以改成 `PeriodStatus::RESTART` (啟用),但只要終止委託後就無法再次啟用了。 761 | 762 | 暫停後再次啟用的委託將於最近一期開始授權。委託暫停後再啟用總期數不變,扣款時間將向後展延至期數滿期。 763 | 764 | ## 修改委託內容 765 | 766 | 修改委託內容需要傳入訂單編號、委託單號,和設定要修改成的委託觸發週期和授權次數: 767 | 768 | ```php 769 | use Illuminate\Http\Request; 770 | use Ycs77\NewebPay\Facades\NewebPay; 771 | 772 | Route::post('/pay/period/amt', function (Request $request) { 773 | $result = NewebPay::periodAmt($request->input('no'), $request->input('periodNo'), $request->input('amt')) 774 | ->everyFewDays(3) 775 | ->times(10) 776 | ->submit(); 777 | 778 | return $result->isSuccess() 779 | ? back()->with('success', '修改委託內容成功') 780 | : back()->withErrors(['no' => $result->message()]); 781 | }); 782 | ``` 783 | 784 | ## 參考 785 | 786 | [NewebPay Payment API](https://www.newebpay.com/website/Page/content/download_api#1) 787 | 788 | ## 贊助 789 | 790 | 如果我維護的套件有幫助到你,可以考慮[贊助我](https://www.patreon.com/ycs77)~ 我會很感謝你~ 而且還可以顯示您的大頭貼在我的主要專案中。 791 | 792 |

793 | 794 | 795 | 796 |

797 | 798 | 799 | Become a Patron 800 | 801 | 802 | ## License 803 | 804 | Under the [MIT LICENSE](LICENSE) 805 | 806 | [ico-version]: https://img.shields.io/packagist/v/ycs77/laravel-newebpay?style=flat-square 807 | [ico-license]: https://img.shields.io/badge/license-MIT-brightgreen?style=flat-square 808 | [ico-github-action]: https://img.shields.io/github/actions/workflow/status/ycs77/laravel-newebpay/tests.yml?branch=main&label=tests&style=flat-square 809 | [ico-style-ci]: https://github.styleci.io/repos/262404477/shield?style=flat-square 810 | [ico-downloads]: https://img.shields.io/packagist/dt/ycs77/laravel-newebpay?style=flat-square 811 | 812 | [link-packagist]: https://packagist.org/packages/ycs77/laravel-newebpay 813 | [link-github-action]: https://github.com/ycs77/laravel-newebpay/actions/workflows/tests.yml?query=branch%3Amain 814 | [link-style-ci]: https://github.styleci.io/repos/262404477 815 | [link-downloads]: https://packagist.org/packages/ycs77/laravel-newebpay 816 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ycs77/laravel-newebpay", 3 | "description": "A library of connecting newebpay's API service.", 4 | "type": "library", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "w4ll4se", 9 | "email": "wallase.huang@gmail.com" 10 | }, 11 | { 12 | "name": "Lucas Yang", 13 | "email": "yangchenshin77@gmail.com" 14 | } 15 | ], 16 | "homepage": "https://github.com/ycs77/laravel-newebpay", 17 | "require": { 18 | "php": ">=8.1", 19 | "guzzlehttp/guzzle": ">=7.2", 20 | "illuminate/config": ">=9.0", 21 | "illuminate/contracts": ">=9.0", 22 | "illuminate/log": ">=9.0", 23 | "illuminate/support": ">=9.0", 24 | "ycs77/laravel-recover-session": "^1.2" 25 | }, 26 | "require-dev": { 27 | "mockery/mockery": "^1.4", 28 | "orchestra/testbench": ">=7.0", 29 | "pestphp/pest": "^1.23 || ^2.6" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "Ycs77\\NewebPay\\": "src/" 34 | } 35 | }, 36 | "autoload-dev": { 37 | "psr-4": { 38 | "Ycs77\\NewebPay\\Tests\\": "tests/" 39 | } 40 | }, 41 | "scripts": { 42 | "post-autoload-dump": [ 43 | "@php vendor/bin/testbench package:discover --ansi" 44 | ] 45 | }, 46 | "extra": { 47 | "laravel": { 48 | "providers": [ 49 | "Ycs77\\NewebPay\\NewebPayServiceProvider" 50 | ], 51 | "aliases": { 52 | "NewebPay": "Ycs77\\NewebPay\\Facades\\NewebPay" 53 | } 54 | } 55 | }, 56 | "config": { 57 | "sort-packages": true, 58 | "allow-plugins": { 59 | "pestphp/pest-plugin": true 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /config/newebpay.php: -------------------------------------------------------------------------------- 1 | env('NEWEBPAY_DEBUG', true), 23 | 24 | /* 25 | |-------------------------------------------------------------------------- 26 | | 藍新金流商店代號和金鑰 27 | |-------------------------------------------------------------------------- 28 | | 29 | | 設定藍新金流商店代號和 HashKey、HashIV 值。 30 | | 31 | */ 32 | 33 | 'merchant_id' => env('NEWEBPAY_STORE_ID'), 34 | 'hash_key' => env('NEWEBPAY_STORE_HASH_KEY'), 35 | 'hash_iv' => env('NEWEBPAY_STORE_HASH_IV'), 36 | 37 | /* 38 | |-------------------------------------------------------------------------- 39 | | 串接版本 40 | |-------------------------------------------------------------------------- 41 | | 42 | | 設定 API 串接版本。 43 | | 44 | */ 45 | 46 | 'version' => [ 47 | 'mpg' => '2.0', 48 | 49 | 'query' => '1.3', 50 | 'credit_cancel' => '1.0', 51 | 'credit_close' => '1.1', 52 | 53 | 'period' => '1.5', 54 | 'period_status' => '1.0', 55 | 'period_amt' => '1.1', 56 | ], 57 | 58 | /* 59 | |-------------------------------------------------------------------------- 60 | | 語系 61 | |-------------------------------------------------------------------------- 62 | | 63 | | 語系可設定 "zh-tw", "en", "jp"。 64 | | 65 | */ 66 | 67 | 'lang' => 'zh-tw', 68 | 69 | /* 70 | |-------------------------------------------------------------------------- 71 | | 交易秒數限制 72 | |-------------------------------------------------------------------------- 73 | | 74 | | 預設值為 0。 75 | | 76 | | 0: 不限制 77 | | 秒數下限為 60 秒,當秒數介於 1~59 秒時,會以 60 秒計算。 78 | | 秒數上限為 900 秒,當超過 900 秒時,會 以 900 秒計算。 79 | | 80 | */ 81 | 82 | 'trade_limit' => 0, 83 | 84 | /* 85 | |-------------------------------------------------------------------------- 86 | | 繳費有效期限 87 | |-------------------------------------------------------------------------- 88 | | 89 | | 預設值為 7 天,上限為 180 天。 90 | | 91 | */ 92 | 93 | 'expire_date' => 7, 94 | 95 | /* 96 | |-------------------------------------------------------------------------- 97 | | 付款完成後導向頁面 98 | |-------------------------------------------------------------------------- 99 | | 100 | | 僅接受 port 80 或 443。 101 | | 例: /pay/callback 102 | | 103 | */ 104 | 105 | 'return_url' => null, 106 | 107 | /* 108 | |-------------------------------------------------------------------------- 109 | | 付款完成後的通知連結 110 | |-------------------------------------------------------------------------- 111 | | 112 | | 以幕後方式回傳給商店相關支付結果資料。 113 | | 114 | | 僅接受 port 80 或 443。 115 | | 例: /pay/notify 116 | | 117 | */ 118 | 119 | 'notify_url' => null, 120 | 121 | /* 122 | |-------------------------------------------------------------------------- 123 | | 商店取號網址 124 | |-------------------------------------------------------------------------- 125 | | 126 | | 如果設定為 null,則會顯示取號結果在藍新金流頁面。 127 | | 例: /pay/customer 128 | | 129 | */ 130 | 131 | 'customer_url' => null, 132 | 133 | /* 134 | |-------------------------------------------------------------------------- 135 | | 付款取消時返回商店網址 136 | |-------------------------------------------------------------------------- 137 | | 138 | | 當交易取消時,平台會出現返回鈕,使消費者依以此參數網址返回商店指定的頁面。 139 | | 140 | */ 141 | 142 | 'client_back_url' => null, 143 | 144 | /* 145 | |-------------------------------------------------------------------------- 146 | | 網址加上 Session ID 147 | |-------------------------------------------------------------------------- 148 | | 149 | | 為以 Form Post 導向回商店的網址加上加密過的 Session ID,解決重導向回網站時 150 | | 自動登出的問題。開啟時只會在 `return_url` 和 `customer_url` 網址加上。 151 | | 152 | */ 153 | 154 | 'with_session_id' => true, 155 | 156 | /* 157 | |-------------------------------------------------------------------------- 158 | | 付款人電子信箱是否開放修改 159 | |-------------------------------------------------------------------------- 160 | | 161 | | 設定付款人電子信箱是否開放修改。 162 | | 163 | */ 164 | 165 | 'email_modify' => true, 166 | 167 | /* 168 | |-------------------------------------------------------------------------- 169 | | 登入藍新金流會員 170 | |-------------------------------------------------------------------------- 171 | | 172 | | 是否需要登入藍新金流會員。 173 | | 174 | */ 175 | 176 | 'login_type' => false, 177 | 178 | /* 179 | |-------------------------------------------------------------------------- 180 | | 商店備註 181 | |-------------------------------------------------------------------------- 182 | | 183 | | 1. 商店備註限制長度為 300 字。 184 | | 2. 若有輸入此參數,將會於 MPG 頁面呈現商店備註內容。 185 | | 186 | */ 187 | 188 | 'order_comment' => null, 189 | 190 | /* 191 | |-------------------------------------------------------------------------- 192 | | 支付方式 193 | |-------------------------------------------------------------------------- 194 | | 195 | | 設定商店需要使用的支付方式。 196 | | 197 | */ 198 | 199 | 'payment_methods' => [ 200 | 201 | /** 202 | * 信用卡支付 (default: true) 203 | * enabled: 是否啟用信用卡支付 204 | * red: 是否啟用紅利 205 | * inst: 分期 206 | * CreditInst::NONE 不啟用 207 | * CreditInst::ALL 啟用全部分期 208 | * CreditInst::P3 分 3 期 209 | * CreditInst::P6 分 6 期 210 | * CreditInst::P12 分 12 期 211 | * CreditInst::P18 分 18 期 212 | * CreditInst::P24 分 24 期 213 | * 使用陣列開啟多種分期,例如:[CreditInst::P3, CreditInst::P6] 214 | */ 215 | 'credit' => [ 216 | 'enabled' => true, 217 | 'red' => false, 218 | 'inst' => CreditInst::NONE, 219 | ], 220 | 221 | /** 222 | * 信用卡記憶卡號 (default: false) 223 | * enabled: 是否啟用信用卡記憶卡號 224 | * demand: 指定付款人信用卡快速結帳必填欄位 225 | * CreditInst::EXPIRATION_DATE_AND_CVC 必填信用卡到期日與背面末三碼 226 | * CreditInst::EXPIRATION_DATE 必填信用卡到期日 227 | * CreditInst::CVC 必填背面末三碼 228 | */ 229 | 'credit_remember' => [ 230 | 'enabled' => false, 231 | 'demand' => CreditRememberDemand::EXPIRATION_DATE_AND_CVC, 232 | ], 233 | 234 | /** WebATM 支付 (default: false) */ 235 | 'webATM' => false, 236 | 237 | /** ATM 轉帳 (default: false) */ 238 | 'VACC' => false, 239 | 240 | /** 241 | * 金融機構 242 | * Bank::BOT 台灣銀行 243 | * Bank::HNCB 華南銀行 244 | * Bank::FirstBank 第一銀行 245 | * 使用陣列指定 1 個以上的銀行,例如:[Bank::BOT, Bank::HNCB] 246 | * 247 | * 此為 WebATM 與 ATM 轉帳 可供付款人選擇轉帳銀行,將顯示於 MPG 頁上。為共用此參數值,無法個別分開指定。 248 | * 249 | * 每日的 00:00:00-01:00:00 為第一銀行例行 250 | * 維護時間,在此時間區間內,將不會顯示[第一銀行]的選項,若商店在此時間區間僅 251 | * 指定第一銀行一家銀行,將會回應[MPG01027]的錯誤代碼 252 | */ 253 | 'bank' => Bank::ALL, 254 | 255 | /** 256 | * 信用卡 國民旅遊卡 (default: false) 257 | * enabled: 是否啟用 國民旅遊卡 交易 258 | * locate: 旅遊地區,可使用地區請參考 \Ycs77\NewebPay\Enums\NTCBLocate 類別 259 | * start_date: 國民旅遊卡起始日期 260 | * end_date: 國民旅遊卡結束日期 261 | */ 262 | 'NTCB' => [ 263 | 'enabled' => false, 264 | 'locate' => NTCBLocate::TaipeiCity, 265 | 'start_date' => '2015-01-01', 266 | 'end_date' => '2015-01-01', 267 | ], 268 | 269 | /** Google Pay (default: false) */ 270 | 'googlePay' => false, 271 | 272 | /** Samsung Pay (default: false) */ 273 | 'samsungPay' => false, 274 | 275 | /** 276 | * LINE Pay (default: false) 277 | * enabled: 是否啟用 LINE Pay 支付 278 | * 產品圖檔連結網址 279 | * 此連結的圖檔將顯示於 LINE Pay 付款前的產品圖片區,若無產品圖檔連結網址,會使用藍新系統預設圖檔。 280 | * 圖片尺寸建議使用 84*84 像素。 281 | */ 282 | 'linePay' => [ 283 | 'enabled' => false, 284 | // 'image_url' => 'http://example.com/your-image-url', 285 | ], 286 | 287 | /** 銀聯卡支付 (default: false) */ 288 | 'unionPay' => false, 289 | 290 | /** 玉山 Walle (default: false) */ 291 | 'esunWallet' => false, 292 | 293 | /** 台灣 Pay (default: false) */ 294 | 'taiwanPay' => false, 295 | 296 | /** 簡單付電子錢包 (default: false) */ 297 | 'ezPay' => false, 298 | 299 | /** 簡單付微信支付 (default: false) */ 300 | 'ezpWeChat' => false, 301 | 302 | /** 簡單付支付寶 (default: false) */ 303 | 'ezpAlipay' => false, 304 | 305 | /** 超商代碼繳費支付 (default: false) */ 306 | 'CVS' => false, 307 | 308 | /** 條碼繳費支付 (default: false) */ 309 | 'barcode' => false, 310 | ], 311 | 312 | /* 313 | |-------------------------------------------------------------------------- 314 | | 物流搭配付款方式 315 | |-------------------------------------------------------------------------- 316 | | 317 | | CVSCOM::NOT_PAY 啟用超商取貨不付款 318 | | CVSCOM::PAY 啟用超商取貨付款 319 | | CVSCOM::NOT_PAY_AND_PAY 啟用超商取貨不付款 及 超商取貨付款 320 | | CVSCOM::NONE 不開啟 321 | | 322 | */ 323 | 324 | 'CVSCOM' => CVSCOM::NONE, 325 | 326 | /* 327 | |-------------------------------------------------------------------------- 328 | | 物流型態 329 | |-------------------------------------------------------------------------- 330 | | 331 | | LgsType::B2C 超商大宗寄倉(目前僅支援統㇐超商) 332 | | LgsType::C2C 超商店到店(目前僅支援全家) 333 | | LgsType::DEFAULT 預設 334 | | 335 | | 預設值情況說明: 336 | | 1. 系統優先啟用[B2C 大宗寄倉]。 337 | | 2. 若商店設定中未啟用[B2C 大宗寄倉],則系統將會啟用[C2C 店到店]。 338 | | 3. 若商店設定中,[B2C 大宗寄倉]與[C2C 店到店]皆未啟用,則支付頁面中將不會出現物流選項。 339 | | 340 | */ 341 | 342 | 'lgs_type' => LgsType::DEFAULT, 343 | 344 | /* 345 | |-------------------------------------------------------------------------- 346 | | 信用卡定期定額委託 347 | |-------------------------------------------------------------------------- 348 | | 349 | | 和信用卡定期定額委託相關的設定。 350 | | 351 | */ 352 | 353 | 'period' => [ 354 | 355 | /** 356 | * 交易模式 357 | * 委託成立後,是否立即進行信用卡授權交易,作為檢查信用卡之有效性 358 | * PeriodStartType::TEN_DOLLARS_NOW 立即執行十元授權 359 | * PeriodStartType::AUTHORIZE_NOW 立即執行委託金額授權 360 | * PeriodStartType::NO_AUTHORIZE 不檢查信用卡資訊,不授權 361 | */ 362 | 'start_type' => PeriodStartType::AUTHORIZE_NOW, 363 | 364 | /** 365 | * 是否開啟付款人資訊 366 | * 於付款人填寫此委託時,是否需顯示付款人資訊填寫欄位。 367 | * 付款人資訊填寫欄位包含付款人姓名、付款人電話、付款人手機。 368 | */ 369 | 'payment_info' => false, 370 | 371 | /** 372 | * 是否開啟收件人資訊 373 | * 於付款人填寫此委託時,是否需顯示收件人資訊填寫欄位。 374 | * 收件人資訊填寫欄位包含收件人姓名、收件人電話、收件人手機、收件人地址。 375 | */ 376 | 'order_info' => false, 377 | 378 | /** 379 | * 返回商店網址 380 | * 1. 當付款人首次執行信用卡授權交易完成後,以 Form Post 方式導回商店頁。 381 | * 2. 若此欄位為空值,交易完成後,付款人將停留在藍新金流交易完成頁面。 382 | */ 383 | 'return_url' => null, 384 | 385 | /** 386 | * 每期授權結果通知 387 | * 1. 當付款人每期執行信用卡授權交易完成後,以幕後 Post 方式通知商店授權結果。 388 | * 2. 若此欄位為空值,則不通知商店授權結果。 389 | */ 390 | 'notify_url' => null, 391 | 392 | /** 393 | * 取消交易時返回商店的網址 394 | */ 395 | 'back_url' => null, 396 | ], 397 | 398 | ]; 399 | -------------------------------------------------------------------------------- /src/Concerns/HasEncryption.php: -------------------------------------------------------------------------------- 1 | addPadding($postDataStr), 'AES-256-CBC', $hashKey, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $hashIV))); 17 | } 18 | 19 | protected function decryptDataByAES(string $parameter, string $hashKey, string $hashIV): string|false 20 | { 21 | return $this->stripPadding(openssl_decrypt(hex2bin($parameter), 'AES-256-CBC', $hashKey, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $hashIV)); 22 | } 23 | 24 | protected function encryptDataBySHA(string $parameter, string $hashKey, string $hashIV): string 25 | { 26 | $hashs = 'HashKey='.$hashKey.'&'.$parameter.'&HashIV='.$hashIV; 27 | 28 | return strtoupper(hash('sha256', $hashs)); 29 | } 30 | 31 | protected function queryCheckValue(array $parameter, string $hashKey, string $hashIV): string 32 | { 33 | ksort($parameter); 34 | $checkStr = http_build_query($parameter); 35 | $hashs = 'IV='.$hashIV.'&'.$checkStr.'&Key='.$hashKey; 36 | 37 | return strtoupper(hash('sha256', $hashs)); 38 | } 39 | 40 | protected function addPadding(string $string, int $blocksize = 32): string 41 | { 42 | $len = strlen($string); 43 | $pad = $blocksize - ($len % $blocksize); 44 | $string .= str_repeat(chr($pad), $pad); 45 | 46 | return $string; 47 | } 48 | 49 | protected function stripPadding(string $string): string|false 50 | { 51 | $slast = ord(substr($string, -1)); 52 | $slastc = chr($slast); 53 | 54 | if (preg_match('/'.$slastc.'{'.$slast.'}/', $string)) { 55 | $string = substr($string, 0, strlen($string) - $slast); 56 | 57 | return $string; 58 | } 59 | 60 | return false; 61 | } 62 | 63 | /** 64 | * 解碼加密字串 65 | * 66 | * @throws \Ycs77\NewebPay\Exceptions\NewebpayDecodeFailException 67 | */ 68 | protected function decode(string $encryptString): mixed 69 | { 70 | try { 71 | $decryptString = $this->decryptDataByAES($encryptString, $this->hashKey, $this->hashIV); 72 | 73 | return json_decode($decryptString, true); 74 | } catch (Throwable $e) { 75 | throw new NewebpayDecodeFailException($e, $encryptString); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Concerns/HasSender.php: -------------------------------------------------------------------------------- 1 | sender = $sender; 21 | 22 | return $this; 23 | } 24 | 25 | public function getSender(): Sender 26 | { 27 | return $this->sender; 28 | } 29 | 30 | public function setFrontendSender() 31 | { 32 | $this->setSender(new FrontendSender()); 33 | 34 | return $this; 35 | } 36 | 37 | public function setBackgroundSender() 38 | { 39 | $this->setSender(new BackgroundSender($this->createHttp())); 40 | 41 | return $this; 42 | } 43 | 44 | public function setMockHttp(MockHandler|Response $mockResponse) 45 | { 46 | if ($this->sender instanceof Httpable) { 47 | if ($mockResponse instanceof Response) { 48 | $mockHandler = new MockHandler([$mockResponse]); 49 | } 50 | 51 | $this->sender->setHttp($this->createHttp($mockHandler)); 52 | } 53 | 54 | return $this; 55 | } 56 | 57 | protected function createHttp(MockHandler $mockHttpHandler = null): Client 58 | { 59 | $attributes = []; 60 | 61 | if ($mockHttpHandler) { 62 | $attributes['handler'] = HandlerStack::create($mockHttpHandler); 63 | } 64 | 65 | return new Client($attributes); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Concerns/WithSessionIdKey.php: -------------------------------------------------------------------------------- 1 | config->get('newebpay.with_session_id') && $url) { 16 | $urlSessionIdKey = $this->config->get('recover-session.session_id_key'); 17 | 18 | $key = RecoverSession::preserve(Request::instance()); 19 | 20 | $delimiter = str_contains($url, '?') ? '&' : '?'; 21 | 22 | return $url.$delimiter.$urlSessionIdKey.'='.$key; 23 | } 24 | 25 | return $url; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Contracts/Httpable.php: -------------------------------------------------------------------------------- 1 | config, $this->session); 36 | 37 | return $newebPay->order($no, $amt, $desc, $email); 38 | } 39 | 40 | /** 41 | * MPG 交易回應結果 42 | */ 43 | public function result(Request $request): MPGResult 44 | { 45 | $result = new NewebPayResult($this->config, $this->session); 46 | 47 | return $result->result($request); 48 | } 49 | 50 | /** 51 | * MPG 付款取號 52 | * 53 | * 適用交易類別:超商代碼、超商條碼、超商取貨付款、ATM 54 | */ 55 | public function customer(Request $request): CustomerResult 56 | { 57 | $result = new NewebPayCustomer($this->config, $this->session); 58 | 59 | return $result->result($request); 60 | } 61 | 62 | /** 63 | * 單筆交易查詢 64 | * 65 | * @param string $no 訂單編號 66 | * @param int $amt 訂單金額 67 | */ 68 | public function query(string $no, int $amt): NewebPayQuery 69 | { 70 | $newebPay = new NewebPayQuery($this->config, $this->session); 71 | 72 | return $newebPay->query($no, $amt); 73 | } 74 | 75 | /** 76 | * 取消信用卡授權 77 | * 78 | * @param string $no 訂單編號 79 | * @param int $amt 訂單金額 80 | * @param string $type 編號類型 81 | * * **order**: 使用商店訂單編號追蹤 82 | * * **trade**: 使用藍新金流交易序號追蹤 83 | */ 84 | public function cancel(string $no, int $amt, string $type = 'order'): NewebPayCancel 85 | { 86 | $newebPay = new NewebPayCancel($this->config, $this->session); 87 | 88 | return $newebPay->cancelOrder($no, $amt, $type); 89 | } 90 | 91 | /** 92 | * 信用卡請/退款 93 | * 94 | * @param string $no 訂單編號 95 | * @param int $amt 訂單金額 96 | * @param string $type 編號類型 97 | * * **order**: 使用商店訂單編號追蹤 98 | * * **trade**: 使用藍新金流交易序號追蹤 99 | */ 100 | public function close(string $no, int $amt, string $type = 'order'): NewebPayClose 101 | { 102 | $newebPay = new NewebPayClose($this->config, $this->session); 103 | 104 | return $newebPay->closeOrder($no, $amt, $type); 105 | } 106 | 107 | /** 108 | * 信用卡請款 109 | * 110 | * @param string $no 訂單編號 111 | * @param int $amt 訂單金額 112 | * @param string $type 編號類型 113 | * * **order**: 使用商店訂單編號追蹤 114 | * * **trade**: 使用藍新金流交易序號追蹤 115 | */ 116 | public function request(string $no, int $amt, string $type = 'order'): NewebPayClose 117 | { 118 | return $this 119 | ->close($no, $amt, $type) 120 | ->pay(); 121 | } 122 | 123 | /** 124 | * 取消信用卡請款 125 | * 126 | * @param string $no 訂單編號 127 | * @param int $amt 訂單金額 128 | * @param string $type 編號類型 129 | * * **order**: 使用商店訂單編號追蹤 130 | * * **trade**: 使用藍新金流交易序號追蹤 131 | */ 132 | public function cancelRequest(string $no, int $amt, string $type = 'order'): NewebPayClose 133 | { 134 | return $this 135 | ->close($no, $amt, $type) 136 | ->pay() 137 | ->cancel(); 138 | } 139 | 140 | /** 141 | * 信用卡退款 142 | * 143 | * @param string $no 訂單編號 144 | * @param int $amt 訂單金額 145 | * @param string $type 編號類型 146 | * * **order**: 使用商店訂單編號追蹤 147 | * * **trade**: 使用藍新金流交易序號追蹤 148 | */ 149 | public function refund(string $no, int $amt, string $type = 'order'): NewebPayClose 150 | { 151 | return $this 152 | ->close($no, $amt, $type) 153 | ->refund(); 154 | } 155 | 156 | /** 157 | * 取消信用卡退款 158 | * 159 | * @param string $no 訂單編號 160 | * @param int $amt 訂單金額 161 | * @param string $type 編號類型 162 | * * **order**: 使用商店訂單編號追蹤 163 | * * **trade**: 使用藍新金流交易序號追蹤 164 | */ 165 | public function cancelRefund(string $no, int $amt, string $type = 'order'): NewebPayClose 166 | { 167 | return $this 168 | ->close($no, $amt, $type) 169 | ->refund() 170 | ->cancel(); 171 | } 172 | 173 | /** 174 | * 建立信用卡定期定額委託 175 | * 176 | * @param string $no 訂單編號 177 | * @param int $amt 委託金額 178 | * @param string $desc 產品名稱 179 | * @param string $email 聯絡信箱 180 | */ 181 | public function period(string $no, int $amt, string $desc, string $email): NewebPayPeriod 182 | { 183 | $newebPay = new NewebPayPeriod($this->config, $this->session); 184 | 185 | return $newebPay->periodOrder($no, $amt, $desc, $email); 186 | } 187 | 188 | /** 189 | * 建立定期定額委託回傳結果 190 | */ 191 | public function periodResult(Request $request): PeriodResult 192 | { 193 | $result = new NewebPayPeriodResult($this->config, $this->session); 194 | 195 | return $result->result($request); 196 | } 197 | 198 | /** 199 | * 定期定額每期委託完成回傳結果 200 | */ 201 | public function periodNotify(Request $request): PeriodNotifyResult 202 | { 203 | $result = new NewebPayPeriodNotify($this->config, $this->session); 204 | 205 | return $result->result($request); 206 | } 207 | 208 | /** 209 | * 修改信用卡定期定額委託狀態 210 | * 211 | * @param string $no 訂單編號 212 | * @param string $periodNo 委託單號 213 | * @param \Ycs77\NewebPay\Enums\PeriodStatus $status 委託狀態 214 | * 1. 終止委託後無法再次啟用 215 | * 2. 暫停後再次啟用的委託將於最近一期開始授權 216 | * 3. 委託暫停後再啟用總期數不變,扣款時間將向後展延至期數滿期 217 | */ 218 | public function periodStatus(string $no, string $periodNo, PeriodStatus $status): NewebPayPeriodStatus 219 | { 220 | $newebPay = new NewebPayPeriodStatus($this->config, $this->session); 221 | 222 | return $newebPay->alterStatus($no, $periodNo, $status); 223 | } 224 | 225 | /** 226 | * 修改信用卡定期定額委託內容 227 | * 228 | * @param string $no 訂單編號 229 | * @param string $periodNo 委託單號 230 | * @param int $amt 委託金額 231 | */ 232 | public function periodAmt(string $no, string $periodNo, int $amt): NewebPayPeriodAmt 233 | { 234 | $newebPay = new NewebPayPeriodAmt($this->config, $this->session); 235 | 236 | return $newebPay->alter($no, $periodNo, $amt); 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /src/NewebPay.php: -------------------------------------------------------------------------------- 1 | merchantID = $this->config->get('newebpay.merchant_id'); 41 | $this->hashKey = $this->config->get('newebpay.hash_key'); 42 | $this->hashIV = $this->config->get('newebpay.hash_iv'); 43 | 44 | $this->setTimestamp(); 45 | $this->boot(); 46 | } 47 | 48 | /** 49 | * The newebpay boot hook. 50 | */ 51 | public function boot(): void 52 | { 53 | // 54 | } 55 | 56 | /** 57 | * Set now timestamp. 58 | */ 59 | public function setTimestamp() 60 | { 61 | $this->timestamp = Carbon::now()->timestamp; 62 | 63 | return $this; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/NewebPayCancel.php: -------------------------------------------------------------------------------- 1 | setBackgroundSender(); 20 | 21 | $this->postData['TimeStamp'] = $this->timestamp; 22 | $this->postData['Version'] = $this->config->get('newebpay.version.credit_cancel'); 23 | $this->postData['RespondType'] = 'JSON'; 24 | 25 | $this->apiPath('/API/CreditCard/Cancel'); 26 | } 27 | 28 | /** 29 | * 設定取消授權的模式 30 | * 31 | * @param string $no 訂單編號 32 | * @param int $amt 訂單金額 33 | * @param string $type 編號類型 34 | * * **order**: 使用商店訂單編號追蹤 35 | * * **trade**: 使用藍新金流交易序號追蹤 36 | */ 37 | public function cancelOrder(string $no, int $amt, string $type = 'order') 38 | { 39 | if ($type === 'order') { 40 | $this->postData['MerchantOrderNo'] = $no; 41 | $this->postData['IndexType'] = 1; 42 | } elseif ($type === 'trade') { 43 | $this->postData['TradeNo'] = $no; 44 | $this->postData['IndexType'] = 2; 45 | } 46 | 47 | $this->postData['Amt'] = $amt; 48 | 49 | return $this; 50 | } 51 | 52 | /** 53 | * Get the newebpay post data. 54 | */ 55 | public function postData(): array 56 | { 57 | return $this->postData; 58 | } 59 | 60 | /** 61 | * Get request data. 62 | */ 63 | public function requestData(): array 64 | { 65 | $postData = $this->encryptDataByAES($this->postData, $this->hashKey, $this->hashIV); 66 | 67 | return [ 68 | 'MerchantID_' => $this->merchantID, 69 | 'PostData_' => $postData, 70 | ]; 71 | } 72 | 73 | /** 74 | * Submit data to newebpay API. 75 | */ 76 | public function submit(): CancelResult 77 | { 78 | return new CancelResult(parent::submit(), $this->hashKey, $this->hashIV); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/NewebPayClose.php: -------------------------------------------------------------------------------- 1 | setBackgroundSender(); 20 | 21 | $this->postData['TimeStamp'] = $this->timestamp; 22 | $this->postData['Version'] = $this->config->get('newebpay.version.credit_close'); 23 | $this->postData['RespondType'] = 'JSON'; 24 | 25 | $this->apiPath('/API/CreditCard/Close'); 26 | } 27 | 28 | /** 29 | * 設定請退款的訂單內容 30 | * 31 | * @param string $no 訂單編號 32 | * @param int $amt 訂單金額 33 | * @param string $type 編號類型 34 | * * **order**: 使用商店訂單編號追蹤 35 | * * **trade**: 使用藍新金流交易序號追蹤 36 | */ 37 | public function closeOrder(string $no, int $amt, string $type = 'order') 38 | { 39 | if ($type === 'order') { 40 | $this->postData['MerchantOrderNo'] = $no; 41 | $this->postData['IndexType'] = 1; 42 | } elseif ($type === 'trade') { 43 | $this->postData['TradeNo'] = $no; 44 | $this->postData['IndexType'] = 2; 45 | } 46 | 47 | $this->postData['Amt'] = $amt; 48 | 49 | return $this; 50 | } 51 | 52 | /** 53 | * 設定請款 54 | */ 55 | public function pay() 56 | { 57 | return $this->closeType('pay'); 58 | } 59 | 60 | /** 61 | * 設定退款 62 | */ 63 | public function refund() 64 | { 65 | return $this->closeType('refund'); 66 | } 67 | 68 | /** 69 | * 設定請款或退款 70 | * 71 | * @param string $type 類型 72 | * * **pay**: 請款 73 | * * **refund**: 退款 74 | */ 75 | public function closeType(string $type) 76 | { 77 | if ($type === 'pay') { 78 | $this->postData['CloseType'] = 1; 79 | } elseif ($type === 'refund') { 80 | $this->postData['CloseType'] = 2; 81 | } 82 | 83 | return $this; 84 | } 85 | 86 | /** 87 | * 取消請款或退款 88 | */ 89 | public function cancel(bool $isCancel = true) 90 | { 91 | if ($isCancel) { 92 | $this->postData['Cancel'] = 1; 93 | } 94 | 95 | return $this; 96 | } 97 | 98 | /** 99 | * Get the newebpay post data. 100 | */ 101 | public function postData(): array 102 | { 103 | return $this->postData; 104 | } 105 | 106 | /** 107 | * Get request data. 108 | */ 109 | public function requestData(): array 110 | { 111 | $postData = $this->encryptDataByAES($this->postData, $this->hashKey, $this->hashIV); 112 | 113 | return [ 114 | 'MerchantID_' => $this->merchantID, 115 | 'PostData_' => $postData, 116 | ]; 117 | } 118 | 119 | /** 120 | * Submit data to newebpay API. 121 | */ 122 | public function submit(): CloseResult 123 | { 124 | return new CloseResult(parent::submit()); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/NewebPayCustomer.php: -------------------------------------------------------------------------------- 1 | only( 18 | 'Status', 'MerchantID', 'TradeInfo', 'TradeSha', 'Version', 'EncryptType' 19 | ); 20 | 21 | $data['TradeInfo'] = $this->decode($data['TradeInfo']); 22 | 23 | return new CustomerResult($data); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/NewebPayMPG.php: -------------------------------------------------------------------------------- 1 | setFrontendSender(); 27 | 28 | $this->tradeData['MerchantID'] = $this->merchantID; 29 | $this->tradeData['TimeStamp'] = $this->timestamp; 30 | $this->tradeData['Version'] = $this->config->get('newebpay.version.mpg'); 31 | $this->tradeData['RespondType'] = 'JSON'; 32 | 33 | $this->apiPath('/MPG/mpg_gateway'); 34 | $this->lang(); 35 | $this->tradeLimit(); 36 | $this->expireDate(); 37 | $this->returnUrl(); 38 | $this->notifyUrl(); 39 | $this->customerUrl(); 40 | $this->clientBackUrl(); 41 | $this->emailModify(); 42 | $this->loginType(); 43 | $this->orderComment(); 44 | $this->paymentMethods(); 45 | $this->cvscom(); 46 | $this->lgsType(); 47 | } 48 | 49 | /** 50 | * 語系 51 | * 52 | * 語系可設定 "zh-tw", "en", "jp"。 53 | */ 54 | public function lang(string $lang = null) 55 | { 56 | $this->tradeData['LangType'] = $lang ?? $this->config->get('newebpay.lang'); 57 | 58 | return $this; 59 | } 60 | 61 | /** 62 | * 交易秒數限制 63 | * 64 | * * **0**: 不限制 65 | * * 秒數下限為 60 秒,當秒數介於 1~59 秒時,會以 60 秒計算。 66 | * * 秒數上限為 900 秒,當超過 900 秒時,會 以 900 秒計算。 67 | */ 68 | public function tradeLimit(int $limit = null) 69 | { 70 | $this->tradeData['TradeLimit'] = $limit !== null 71 | ? $limit 72 | : $this->config->get('newebpay.trade_limit'); 73 | 74 | return $this; 75 | } 76 | 77 | /** 78 | * 繳費有效期限 79 | * 80 | * 預設值為 7 天,上限為 180 天。 81 | */ 82 | public function expireDate(int $day = null) 83 | { 84 | $day = $day !== null ? $day : $this->config->get('newebpay.expire_date'); 85 | 86 | $this->tradeData['ExpireDate'] = Carbon::now()->addDays($day)->format('Ymd'); 87 | 88 | return $this; 89 | } 90 | 91 | /** 92 | * 付款完成後導向頁面 93 | * 94 | * 僅接受 port 80 或 443。 95 | */ 96 | public function returnUrl(string $url = null) 97 | { 98 | if ($url = $url ?? $this->config->get('newebpay.return_url')) { 99 | $this->tradeData['ReturnURL'] = $this->WithSessionIdKey( 100 | $this->formatCallbackUrl($url) 101 | ); 102 | } 103 | 104 | return $this; 105 | } 106 | 107 | /** 108 | * 付款完成後的通知連結 109 | * 110 | * 1. 以幕後方式回傳給商店相關支付結果資料 111 | * 2. 僅接受 port 80 或 443。 112 | */ 113 | public function notifyUrl(string $url = null) 114 | { 115 | if ($url = $url ?? $this->config->get('newebpay.notify_url')) { 116 | $this->tradeData['NotifyURL'] = $this->formatCallbackUrl($url); 117 | } 118 | 119 | return $this; 120 | } 121 | 122 | /** 123 | * 商店取號網址 124 | * 125 | * 如果設定為 null,則會顯示取號結果在藍新金流頁面。 126 | */ 127 | public function customerUrl(string $url = null) 128 | { 129 | if ($url = $url ?? $this->config->get('newebpay.customer_url')) { 130 | $this->tradeData['CustomerURL'] = $this->WithSessionIdKey( 131 | $this->formatCallbackUrl($url) 132 | ); 133 | } 134 | 135 | return $this; 136 | } 137 | 138 | /** 139 | * 付款時點擊「返回按鈕」的網址 140 | * 141 | * 當交易中平台會出現返回鈕,使消費者依以此參數網址返回商店指定的頁面。 142 | */ 143 | public function clientBackUrl(string $url = null) 144 | { 145 | if ($url = $url ?? $this->config->get('newebpay.client_back_url')) { 146 | $this->tradeData['ClientBackURL'] = $this->formatCallbackUrl($url); 147 | } 148 | 149 | return $this; 150 | } 151 | 152 | /** 153 | * 付款人電子信箱是否開放修改 154 | */ 155 | public function emailModify(bool $isModify = null) 156 | { 157 | if (! ($isModify ?? $this->config->get('newebpay.email_modify'))) { 158 | $this->tradeData['EmailModify'] = 0; 159 | } 160 | 161 | return $this; 162 | } 163 | 164 | /** 165 | * 是否需要登入藍新金流會員 166 | */ 167 | public function loginType(bool $isLogin = false) 168 | { 169 | if ($isLogin ?? $this->config->get('newebpay.login_type')) { 170 | $this->tradeData['LoginType'] = 1; 171 | } 172 | 173 | return $this; 174 | } 175 | 176 | /** 177 | * 商店備註 178 | * 179 | * 1. 商店備註限制長度為 300 字。 180 | * 2. 若有輸入此參數,將會於 MPG 頁面呈現商店備註內容。 181 | */ 182 | public function orderComment(string $comment = null) 183 | { 184 | $this->tradeData['OrderComment'] = $comment !== null 185 | ? $comment 186 | : $this->config->get('newebpay.order_comment'); 187 | 188 | return $this; 189 | } 190 | 191 | /** 192 | * 設定商店需要使用的支付方式 193 | */ 194 | public function paymentMethods(array $paymentMethods = []) 195 | { 196 | $paymentMethods = array_merge($this->config->get('newebpay.payment_methods'), $paymentMethods); 197 | 198 | if ($paymentMethods['credit']['enabled']) { 199 | $this->tradeData['CREDIT'] = 1; 200 | 201 | if ($paymentMethods['credit']['red']) { 202 | $this->tradeData['CreditRed'] = 1; 203 | } 204 | 205 | if ($paymentMethods['credit']['inst'] instanceof CreditInst && 206 | $paymentMethods['credit']['inst'] !== CreditInst::NONE || 207 | is_array($paymentMethods['credit']['inst']) 208 | ) { 209 | $this->tradeData['InstFlag'] = collect($paymentMethods['credit']['inst']) 210 | ->map(fn (CreditInst $inst) => $inst->value) 211 | ->join(','); 212 | } elseif (is_numeric($paymentMethods['credit']['inst']) || is_string($paymentMethods['credit']['inst'])) { 213 | $this->tradeData['InstFlag'] = $paymentMethods['credit']['inst']; 214 | } 215 | } 216 | if ($paymentMethods['webATM']) { 217 | $this->tradeData['WEBATM'] = 1; 218 | } 219 | if ($paymentMethods['VACC']) { 220 | $this->tradeData['VACC'] = 1; 221 | } 222 | if ($paymentMethods['bank'] instanceof Bank && 223 | $paymentMethods['bank'] !== Bank::ALL || 224 | is_array($paymentMethods['bank']) 225 | ) { 226 | $this->tradeData['BankType'] = collect($paymentMethods['bank']) 227 | ->map(fn (Bank $inst) => $inst->value) 228 | ->join(','); 229 | } elseif (is_string($paymentMethods['bank'])) { 230 | $this->tradeData['BankType'] = $paymentMethods['bank']; 231 | } 232 | if ($paymentMethods['NTCB']['enabled']) { 233 | $this->tradeData['NTCB'] = 1; 234 | /** @see \Ycs77\NewebPay\Enums\NTCBLocate */ 235 | $this->tradeData['NTCBLocate'] = $paymentMethods['NTCB']['locate']->value; 236 | $this->tradeData['NTCBStartDate'] = $paymentMethods['NTCB']['start_date']; 237 | $this->tradeData['NTCBEndDate'] = $paymentMethods['NTCB']['end_date']; 238 | } 239 | 240 | if ($paymentMethods['googlePay']) { 241 | $this->tradeData['ANDROIDPAY'] = 1; 242 | } 243 | if ($paymentMethods['samsungPay']) { 244 | $this->tradeData['SAMSUNGPAY'] = 1; 245 | } 246 | if (is_array($paymentMethods['linePay']) && $paymentMethods['linePay']['enabled'] || 247 | $paymentMethods['linePay'] === true 248 | ) { 249 | $this->tradeData['LINEPAY'] = 1; 250 | if (isset($paymentMethods['linePay']['image_url'])) { 251 | $this->tradeData['ImageUrl'] = $paymentMethods['linePay']['image_url']; 252 | } 253 | } 254 | if ($paymentMethods['unionPay']) { 255 | $this->tradeData['UNIONPAY'] = 1; 256 | } 257 | if ($paymentMethods['esunWallet']) { 258 | $this->tradeData['ESUNWALLET'] = 1; 259 | } 260 | if ($paymentMethods['taiwanPay']) { 261 | $this->tradeData['TAIWANPAY'] = 1; 262 | } 263 | if ($paymentMethods['ezPay']) { 264 | $this->tradeData['EZPAY'] = 1; 265 | } 266 | if ($paymentMethods['ezpWeChat']) { 267 | $this->tradeData['EZPWECHAT'] = 1; 268 | } 269 | if ($paymentMethods['ezpAlipay']) { 270 | $this->tradeData['EZPALIPAY'] = 1; 271 | } 272 | 273 | if ($paymentMethods['CVS']) { 274 | $this->tradeData['CVS'] = 1; 275 | } 276 | if ($paymentMethods['barcode']) { 277 | $this->tradeData['BARCODE'] = 1; 278 | } 279 | 280 | return $this; 281 | } 282 | 283 | /** 284 | * 信用卡記憶卡號 285 | * 286 | * @param string $identifier 287 | * * 可對應付款人之資料,用於綁定付款人與信用卡卡號時使用 288 | * * 例:會員編號、Email。 289 | * * 限英、數字,「.」、「_」、「@」、「-」格式。 290 | * @param \Ycs77\NewebPay\Enums\CreditRememberDemand $demand 指定付款人信用卡快速結帳必填欄位 291 | * * **CreditRememberDemand::EXPIRATION_DATE_AND_CVC** 必填信用卡到期日與背面末三碼 292 | * * **CreditRememberDemand::EXPIRATION_DATE** 必填信用卡到期日 293 | * * **CreditRememberDemand::CVC** 必填背面末三碼 294 | */ 295 | public function creditRemember(string $identifier, CreditRememberDemand $demand = null) 296 | { 297 | $creditRemember = $this->config->get('newebpay.payment_methods.credit_remember'); 298 | 299 | if ($creditRemember['enabled']) { 300 | $this->tradeData['TokenTerm'] = $identifier; 301 | $this->tradeData['TokenTermDemand'] = $demand 302 | ? $demand->value 303 | : $creditRemember['demand']->value; 304 | } 305 | 306 | return $this; 307 | } 308 | 309 | /** 310 | * 物流搭配付款方式 311 | * 312 | * @param \Ycs77\NewebPay\Enums\CVSCOM $cvscom 313 | * * **CVSCOM::NOT_PAY** 啟用超商取貨不付款 314 | * * **CVSCOM::PAY** 啟用超商取貨付款 315 | * * **CVSCOM::NOT_PAY_AND_PAY** 啟用超商取貨不付款 及 超商取貨付款 316 | * * **CVSCOM::NONE** 不開啟 317 | */ 318 | public function cvscom(CVSCOM $cvscom = null) 319 | { 320 | $cvscom = $cvscom ?? $this->config->get('newebpay.CVSCOM') ?? CVSCOM::NONE; 321 | 322 | if ($cvscom !== CVSCOM::NONE) { 323 | $this->tradeData['CVSCOM'] = $cvscom->value; 324 | } 325 | 326 | return $this; 327 | } 328 | 329 | /** 330 | * 物流型態 331 | * 332 | * @param \Ycs77\NewebPay\Enums\LgsType $lgsType 333 | * * **LgsType::B2C** 超商大宗寄倉(目前僅支援統㇐超商) 334 | * * **LgsType::C2C** 超商店到店(目前僅支援全家) 335 | * * **LgsType::DEFAULT** 預設 336 | * 337 | * 預設值情況說明: 338 | * 1. 系統優先啟用[B2C 大宗寄倉]。 339 | * 2. 若商店設定中未啟用[B2C 大宗寄倉],則系統將會啟用[C2C 店到店]。 340 | * 3. 若商店設定中,[B2C 大宗寄倉]與[C2C 店到店]皆未啟用,則支付頁面中將不會出現物流選項。 341 | */ 342 | public function lgsType(LgsType $lgsType = null) 343 | { 344 | $lgsType = $lgsType ?? $this->config->get('newebpay.lgs_type'); 345 | 346 | if ($lgsType !== LgsType::DEFAULT) { 347 | $this->tradeData['LgsType'] = $lgsType->value; 348 | } 349 | 350 | return $this; 351 | } 352 | 353 | /** 354 | * Set the order detail data. 355 | */ 356 | public function order(string $no, int $amt, string $desc, string $email) 357 | { 358 | $this->tradeData['MerchantOrderNo'] = $no; 359 | $this->tradeData['Amt'] = $amt; 360 | $this->tradeData['ItemDesc'] = $desc; 361 | $this->tradeData['Email'] = $email; 362 | 363 | return $this; 364 | } 365 | 366 | /** 367 | * Get the newebpay trade data. 368 | */ 369 | public function tradeData(): array 370 | { 371 | return $this->tradeData; 372 | } 373 | 374 | /** 375 | * Get request data. 376 | */ 377 | public function requestData(): array 378 | { 379 | $tradeInfo = $this->encryptDataByAES($this->tradeData, $this->hashKey, $this->hashIV); 380 | $tradeSha = $this->encryptDataBySHA($tradeInfo, $this->hashKey, $this->hashIV); 381 | 382 | return [ 383 | 'MerchantID' => $this->merchantID, 384 | 'TradeInfo' => $tradeInfo, 385 | 'TradeSha' => $tradeSha, 386 | 'Version' => $this->tradeData['Version'], 387 | ]; 388 | } 389 | } 390 | -------------------------------------------------------------------------------- /src/NewebPayPeriod.php: -------------------------------------------------------------------------------- 1 | setFrontendSender(); 23 | 24 | $this->postData['TimeStamp'] = $this->timestamp; 25 | $this->postData['Version'] = $this->config->get('newebpay.version.period'); 26 | $this->postData['RespondType'] = 'JSON'; 27 | 28 | $this->apiPath('/MPG/period'); 29 | $this->lang(); 30 | $this->returnUrl(); 31 | $this->notifyUrl(); 32 | $this->backUrl(); 33 | $this->emailModify(); 34 | $this->paymentInfo(); 35 | $this->orderInfo(); 36 | $this->unionPay(); 37 | $this->periodStartType(); 38 | } 39 | 40 | /** 41 | * 語系 42 | * 43 | * 語系可設定 "zh-Tw", "en"。 44 | */ 45 | public function lang(string $lang = null) 46 | { 47 | $lang = $lang ?? $this->config->get('newebpay.lang'); 48 | 49 | if (is_string($lang) && strtolower($lang) !== 'zh-tw') { 50 | $this->postData['LangType'] = $lang; 51 | } 52 | 53 | return $this; 54 | } 55 | 56 | /** 57 | * 首次付款完成後返回商店網址 58 | * 59 | * 1. 當付款人首次執行信用卡授權交易完成後,以 Form Post 方式導回商店頁。 60 | * 2. 若此欄位為空值,交易完成後,付款人將停留在藍新金流交易完成頁面。 61 | */ 62 | public function returnUrl(string $url = null) 63 | { 64 | if ($url = $url ?? $this->config->get('newebpay.period.return_url')) { 65 | $this->postData['ReturnURL'] = $this->WithSessionIdKey( 66 | $this->formatCallbackUrl($url) 67 | ); 68 | } 69 | 70 | return $this; 71 | } 72 | 73 | /** 74 | * 每期授權結果通知網址 75 | * 76 | * 1. 當付款人每期執行信用卡授權交易完成後,以幕後 Post 方式通知商店授權結果。 77 | * 2. 若此欄位為空值,則不通知商店授權結果。 78 | */ 79 | public function notifyUrl(string $url = null) 80 | { 81 | if ($url = $url ?? $this->config->get('newebpay.period.notify_url')) { 82 | $this->postData['NotifyURL'] = $this->formatCallbackUrl($url); 83 | } 84 | 85 | return $this; 86 | } 87 | 88 | /** 89 | * 取消交易時返回商店的網址 90 | */ 91 | public function backUrl(string $url = null) 92 | { 93 | if ($url = $url ?? $this->config->get('newebpay.period.back_url')) { 94 | $this->postData['BackURL'] = $this->formatCallbackUrl($url); 95 | } 96 | 97 | return $this; 98 | } 99 | 100 | /** 101 | * 付款人電子信箱是否開放修改 102 | */ 103 | public function emailModify(bool $isModify = null) 104 | { 105 | if (! ($isModify ?? $this->config->get('newebpay.email_modify'))) { 106 | $this->postData['EmailModify'] = 0; 107 | } 108 | 109 | return $this; 110 | } 111 | 112 | /** 113 | * 是否開啟付款人資訊 114 | * 115 | * * 於付款人填寫此委託時,是否需顯示付款人資訊填寫欄位。 116 | * * 付款人資訊填寫欄位包含付款人姓名、付款人電話、付款人手機。 117 | */ 118 | public function paymentInfo(bool $show = null) 119 | { 120 | if (! ($show ?? $this->config->get('newebpay.period.payment_info'))) { 121 | $this->postData['PaymentInfo'] = 'N'; 122 | } 123 | 124 | return $this; 125 | } 126 | 127 | /** 128 | * 是否開啟收件人資訊 129 | * 130 | * * 於付款人填寫此委託時,是否需顯示收件人資訊填寫欄位。 131 | * * 收件人資訊填寫欄位包含收件人姓名、收件人電話、收件人手機、收件人地址。 132 | */ 133 | public function orderInfo(bool $show = null) 134 | { 135 | if (! ($show ?? $this->config->get('newebpay.period.order_info'))) { 136 | $this->postData['OrderInfo'] = 'N'; 137 | } 138 | 139 | return $this; 140 | } 141 | 142 | /** 143 | * 設定是否啟用銀聯卡支付方式 144 | * 145 | * * 銀聯卡僅支援幕後非 3D 交易 146 | */ 147 | public function unionPay(bool $enabled = null) 148 | { 149 | if ($enabled) { 150 | $this->postData['UNIONPAY'] = 1; 151 | } 152 | 153 | return $this; 154 | } 155 | 156 | /** 157 | * 建立信用卡定期定額委託 158 | * 159 | * @param string $no 訂單編號 160 | * @param int $amt 委託金額 161 | * @param string $desc 產品名稱 162 | * @param string $email 聯絡信箱 163 | */ 164 | public function periodOrder(string $no, int $amt, string $desc, string $email) 165 | { 166 | $this->postData['MerOrderNo'] = $no; 167 | $this->postData['PeriodAmt'] = $amt; 168 | $this->postData['ProdDesc'] = $desc; 169 | $this->postData['PayerEmail'] = $email; 170 | 171 | return $this; 172 | } 173 | 174 | /** 175 | * 設定此委託於週期間,執行信用卡授權交易的時間點 176 | */ 177 | public function periodType(PeriodType $type, string $point) 178 | { 179 | $this->postData['PeriodType'] = $type->value; 180 | $this->postData['PeriodPoint'] = $point; 181 | 182 | return $this; 183 | } 184 | 185 | /** 186 | * 設定此委託於固定天期制觸發 187 | * 188 | * @param int $day 執行委託的間隔天數 189 | * * 為數字 2~999,以授權日期隔日起算。 190 | * * 例:數值為 2,則表示每隔兩天會執行一次委託 191 | */ 192 | public function everyFewDays(int $day) 193 | { 194 | $this->periodType(PeriodType::EVERY_FEW_DAYS, (string) $day); 195 | 196 | return $this; 197 | } 198 | 199 | /** 200 | * 設定此委託於每週觸發 201 | * 202 | * @param int $weekday 在週幾執行委託 203 | * * 為數字 1 ~ 7,代表每週一至週日。 204 | * * 例:每週日執行授權,則此欄位值為 7;若週日與週一皆需執行授權,請分別建立 2 張委託 205 | */ 206 | public function weekly(int $weekday) 207 | { 208 | $this->periodType(PeriodType::WEEKLY, (string) $weekday); 209 | 210 | return $this; 211 | } 212 | 213 | /** 214 | * 設定此委託於每月觸發 215 | * 216 | * @param int $day 在每月的第幾天執行委託 217 | * * 為數字 1 ~ 31,代表每月 1 號 ~ 31 號。若當月沒該日期則由該月的最後一天做為扣款日 218 | * * 例:每月1號執行授權,則此欄位值為1;若於1個月內需授權多次,請以建立多次委託方式執行。 219 | */ 220 | public function monthly(int $day) 221 | { 222 | $this->periodType(PeriodType::MONTHLY, str_pad((string) $day, 2, '0', STR_PAD_LEFT)); 223 | 224 | return $this; 225 | } 226 | 227 | /** 228 | * 設定此委託於每年觸發 229 | * 230 | * 若於 1 年內需授權多次,請以建立多次委託方式執行 231 | */ 232 | public function yearly(int $month, int $day) 233 | { 234 | $month = str_pad((string) $month, 2, '0', STR_PAD_LEFT); 235 | $day = str_pad((string) $day, 2, '0', STR_PAD_LEFT); 236 | $this->periodType(PeriodType::YEARLY, $month.$day); 237 | 238 | return $this; 239 | } 240 | 241 | /** 242 | * 授權期數 243 | * 244 | * @param int $times 授權委託的期數 245 | * * 為數字 1~99 246 | */ 247 | public function times(int $times) 248 | { 249 | $this->postData['PeriodTimes'] = $times; 250 | 251 | return $this; 252 | } 253 | 254 | /** 255 | * 交易模式 256 | * 257 | * 委託成立後,是否立即進行信用卡授權交易,作為檢查信用卡之有效性 258 | * 259 | * * PeriodStartType::TEN_DOLLARS_NOW 立即執行十元授權 260 | * * PeriodStartType::AUTHORIZE_NOW 立即執行委託金額授權 261 | * * PeriodStartType::NO_AUTHORIZE 不檢查信用卡資訊,不授權 262 | */ 263 | public function periodStartType(PeriodStartType $startType = null) 264 | { 265 | $startType = $startType ?? $this->config->get('newebpay.period.start_type'); 266 | 267 | $this->postData['PeriodStartType'] = $startType->value; 268 | 269 | return $this; 270 | } 271 | 272 | /** 273 | * 首期授權日 274 | */ 275 | public function firstdate(int $year, int $month, int $day) 276 | { 277 | $month = str_pad((string) $month, 2, '0', STR_PAD_LEFT); 278 | $day = str_pad((string) $day, 2, '0', STR_PAD_LEFT); 279 | $this->postData['PeriodFirstdate'] = $year.'/'.$month.'/'.$day; 280 | 281 | return $this; 282 | } 283 | 284 | /** 285 | * 委託備註說明 286 | */ 287 | public function memo(string $memo) 288 | { 289 | $this->postData['PeriodMemo'] = $memo; 290 | 291 | return $this; 292 | } 293 | 294 | /** 295 | * Get the newebpay post data. 296 | */ 297 | public function postData(): array 298 | { 299 | return $this->postData; 300 | } 301 | 302 | /** 303 | * Get request data. 304 | */ 305 | public function requestData(): array 306 | { 307 | $postData = $this->encryptDataByAES($this->postData, $this->hashKey, $this->hashIV); 308 | 309 | return [ 310 | 'MerchantID_' => $this->merchantID, 311 | 'PostData_' => $postData, 312 | ]; 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /src/NewebPayPeriodAmt.php: -------------------------------------------------------------------------------- 1 | setBackgroundSender(); 21 | 22 | $this->postData['TimeStamp'] = $this->timestamp; 23 | $this->postData['Version'] = $this->config->get('newebpay.version.period_amt'); 24 | $this->postData['RespondType'] = 'JSON'; 25 | 26 | $this->apiPath('/MPG/period/AlterAmt'); 27 | } 28 | 29 | /** 30 | * 修改定期定額委託內容 31 | * 32 | * @param string $no 訂單編號 33 | * @param string $periodNo 委託單號 34 | * @param int $amt 委託金額 35 | */ 36 | public function alter(string $no, string $periodNo, int $amt) 37 | { 38 | $this->postData['MerOrderNo'] = $no; 39 | $this->postData['PeriodNo'] = $periodNo; 40 | $this->postData['AlterAmt'] = $amt; 41 | 42 | return $this; 43 | } 44 | 45 | /** 46 | * 設定此委託於週期間,執行信用卡授權交易的時間點 47 | */ 48 | public function periodType(PeriodType $type, string $point) 49 | { 50 | $this->postData['PeriodType'] = $type->value; 51 | $this->postData['PeriodPoint'] = $point; 52 | 53 | return $this; 54 | } 55 | 56 | /** 57 | * 設定此委託於固定天期制觸發 58 | * 59 | * @param int $day 執行委託的間隔天數 60 | * * 為數字 2~999,以授權日期隔日起算。 61 | * * 例:數值為 2,則表示每隔兩天會執行一次委託 62 | */ 63 | public function everyFewDays(int $day) 64 | { 65 | $this->periodType(PeriodType::EVERY_FEW_DAYS, (string) $day); 66 | 67 | return $this; 68 | } 69 | 70 | /** 71 | * 設定此委託於每週觸發 72 | * 73 | * @param int $weekday 在週幾執行委託 74 | * * 為數字 1 ~ 7,代表每週一至週日。 75 | * * 例:每週日執行授權,則此欄位值為 7;若週日與週一皆需執行授權,請分別建立 2 張委託 76 | */ 77 | public function weekly(int $weekday) 78 | { 79 | $this->periodType(PeriodType::WEEKLY, (string) $weekday); 80 | 81 | return $this; 82 | } 83 | 84 | /** 85 | * 設定此委託於每月觸發 86 | * 87 | * @param int $day 在每月的第幾天執行委託 88 | * * 為數字 1 ~ 31,代表每月 1 號 ~ 31 號。若當月沒該日期則由該月的最後一天做為扣款日 89 | * * 例:每月1號執行授權,則此欄位值為1;若於1個月內需授權多次,請以建立多次委託方式執行。 90 | */ 91 | public function monthly(int $day) 92 | { 93 | $this->periodType(PeriodType::MONTHLY, str_pad((string) $day, 2, '0', STR_PAD_LEFT)); 94 | 95 | return $this; 96 | } 97 | 98 | /** 99 | * 設定此委託於每年觸發 100 | * 101 | * 若於 1 年內需授權多次,請以建立多次委託方式執行 102 | */ 103 | public function yearly(int $month, int $day) 104 | { 105 | $month = str_pad((string) $month, 2, '0', STR_PAD_LEFT); 106 | $day = str_pad((string) $day, 2, '0', STR_PAD_LEFT); 107 | $this->periodType(PeriodType::YEARLY, $month.$day); 108 | 109 | return $this; 110 | } 111 | 112 | /** 113 | * 授權期數 114 | * 115 | * @param int $times 授權委託的期數 116 | * * 為數字 1~99 117 | */ 118 | public function times(int $times) 119 | { 120 | $this->postData['PeriodTimes'] = $times; 121 | 122 | return $this; 123 | } 124 | 125 | /** 126 | * 調整信用卡到期日 127 | */ 128 | public function creditExpiredAt(int $month, int $day) 129 | { 130 | $month = str_pad((string) $month, 2, '0', STR_PAD_LEFT); 131 | $day = str_pad((string) $day, 2, '0', STR_PAD_LEFT); 132 | $this->postData['Extday'] = $month.$day; 133 | 134 | return $this; 135 | } 136 | 137 | /** 138 | * Get the newebpay post data. 139 | */ 140 | public function postData(): array 141 | { 142 | return $this->postData; 143 | } 144 | 145 | /** 146 | * Get request data. 147 | */ 148 | public function requestData(): array 149 | { 150 | $postData = $this->encryptDataByAES($this->postData, $this->hashKey, $this->hashIV); 151 | 152 | return [ 153 | 'MerchantID_' => $this->merchantID, 154 | 'PostData_' => $postData, 155 | ]; 156 | } 157 | 158 | /** 159 | * Submit data to newebpay API. 160 | */ 161 | public function submit(): PeriodAmtResult 162 | { 163 | return new PeriodAmtResult($this->decode(parent::submit()['period'])); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/NewebPayPeriodNotify.php: -------------------------------------------------------------------------------- 1 | decode($request->input('Period')); 18 | 19 | return new PeriodNotifyResult($data); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/NewebPayPeriodResult.php: -------------------------------------------------------------------------------- 1 | decode($request->input('Period')); 18 | 19 | return new PeriodResult($data); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/NewebPayPeriodStatus.php: -------------------------------------------------------------------------------- 1 | setBackgroundSender(); 21 | 22 | $this->postData['TimeStamp'] = $this->timestamp; 23 | $this->postData['Version'] = $this->config->get('newebpay.version.period_status'); 24 | $this->postData['RespondType'] = 'JSON'; 25 | 26 | $this->apiPath('/MPG/period/AlterStatus'); 27 | } 28 | 29 | /** 30 | * 修改定期定額委託狀態 31 | * 32 | * @param string $no 訂單編號 33 | * @param string $periodNo 委託單號 34 | * @param \Ycs77\NewebPay\Enums\PeriodStatus $status 委託狀態 35 | * 1. 終止委託後無法再次啟用 36 | * 2. 暫停後再次啟用的委託將於最近一期開始授權 37 | * 3. 委託暫停後再啟用總期數不變,扣款時間將向後展延至期數滿期 38 | */ 39 | public function alterStatus(string $no, string $periodNo, PeriodStatus $status) 40 | { 41 | $this->postData['MerOrderNo'] = $no; 42 | $this->postData['PeriodNo'] = $periodNo; 43 | $this->postData['AlterType'] = $status->value; 44 | 45 | return $this; 46 | } 47 | 48 | /** 49 | * Get the newebpay post data. 50 | */ 51 | public function postData(): array 52 | { 53 | return $this->postData; 54 | } 55 | 56 | /** 57 | * Get request data. 58 | */ 59 | public function requestData(): array 60 | { 61 | $postData = $this->encryptDataByAES($this->postData, $this->hashKey, $this->hashIV); 62 | 63 | return [ 64 | 'MerchantID_' => $this->merchantID, 65 | 'PostData_' => $postData, 66 | ]; 67 | } 68 | 69 | /** 70 | * Submit data to newebpay API. 71 | */ 72 | public function submit(): PeriodStatusResult 73 | { 74 | return new PeriodStatusResult($this->decode(parent::submit()['period'])); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/NewebPayQuery.php: -------------------------------------------------------------------------------- 1 | setBackgroundSender(); 25 | 26 | $this->checkValues['MerchantID'] = $this->merchantID; 27 | 28 | $this->apiPath('/API/QueryTradeInfo'); 29 | } 30 | 31 | /** 32 | * 單筆交易查詢 33 | * 34 | * @param string $no 訂單編號 35 | * @param int $amt 訂單金額 36 | */ 37 | public function query(string $no, int $amt) 38 | { 39 | $this->checkValues['MerchantOrderNo'] = $no; 40 | $this->checkValues['Amt'] = $amt; 41 | 42 | return $this; 43 | } 44 | 45 | /** 46 | * 資料來源 47 | * 48 | * 設定此參數會查詢 複合式商店旗下對應商店的訂單。 49 | * 50 | * 若為複合式商店(MS5 開頭),此欄位為必填,且要固定填入:"Composite"。 51 | * 若沒有帶[Gateway]或是帶入其他參數值,則查詢一般商店代號。 52 | */ 53 | public function gateway(string $gateway = null) 54 | { 55 | $this->gateway = $gateway; 56 | 57 | return $this; 58 | } 59 | 60 | /** 61 | * Get request data. 62 | */ 63 | public function requestData(): array 64 | { 65 | $CheckValue = $this->queryCheckValue($this->checkValues, $this->hashKey, $this->hashIV); 66 | 67 | return [ 68 | 'MerchantID' => $this->merchantID, 69 | 'Version' => $this->config->get('newebpay.version.query'), 70 | 'RespondType' => 'JSON', 71 | 'CheckValue' => $CheckValue, 72 | 'TimeStamp' => $this->timestamp, 73 | 'MerchantOrderNo' => $this->checkValues['MerchantOrderNo'], 74 | 'Amt' => $this->checkValues['Amt'], 75 | 'Gateway' => $this->gateway, 76 | ]; 77 | } 78 | 79 | /** 80 | * Submit data to newebpay API. 81 | */ 82 | public function submit(): QueryResult 83 | { 84 | return new QueryResult(parent::submit(), $this->hashKey, $this->hashIV); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/NewebPayRequest.php: -------------------------------------------------------------------------------- 1 | url; 30 | } 31 | 32 | /** 33 | * Set the newebpay API path. 34 | */ 35 | public function apiPath(string $path) 36 | { 37 | $this->url = ($this->config->get('newebpay.debug') ? $this->testUrl : $this->productionUrl).$path; 38 | 39 | return $this; 40 | } 41 | 42 | protected function formatCallbackUrl(string $path) 43 | { 44 | if (! filter_var($path, FILTER_VALIDATE_URL)) { 45 | $path = $this->config->get('app.url').$path; 46 | } 47 | 48 | return $path; 49 | } 50 | 51 | /** 52 | * Get request data. 53 | */ 54 | abstract public function requestData(): array; 55 | 56 | /** 57 | * Submit data to newebpay API. 58 | */ 59 | public function submit(): mixed 60 | { 61 | return $this->sender->send($this->requestData(), $this->url); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/NewebPayResult.php: -------------------------------------------------------------------------------- 1 | only( 18 | 'Status', 'MerchantID', 'TradeInfo', 'TradeSha', 'Version', 'EncryptType' 19 | ); 20 | 21 | $data['TradeInfo'] = $this->decode($data['TradeInfo']); 22 | 23 | return new MPGResult($data); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/NewebPayServiceProvider.php: -------------------------------------------------------------------------------- 1 | mergeConfigFrom(__DIR__.'/../config/newebpay.php', 'newebpay'); 16 | 17 | $this->app->singleton(Factory::class, function (Application $app) { 18 | return new Factory( 19 | $app->make('config'), 20 | $app->make('session.store') 21 | ); 22 | }); 23 | } 24 | 25 | /** 26 | * Bootstrap service for package. 27 | */ 28 | public function boot(): void 29 | { 30 | $this->publishes([ 31 | __DIR__.'/../config/newebpay.php' => config_path('newebpay.php'), 32 | ], 'newebpay-config'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Results/CancelResult.php: -------------------------------------------------------------------------------- 1 | data = $this->transformData($data); 22 | $this->hashKey = $hashKey; 23 | $this->hashIV = $hashIV; 24 | } 25 | 26 | /** 27 | * 交易狀態 28 | * 29 | * 1. 若交易付款成功,則回傳 SUCCESS。 30 | * 2. 若交易付款失敗,則回傳錯誤代碼。 31 | */ 32 | public function status(): string 33 | { 34 | return $this->data['Status']; 35 | } 36 | 37 | /** 38 | * 交易是否成功 39 | */ 40 | public function isSuccess(): bool 41 | { 42 | return $this->status() === 'SUCCESS'; 43 | } 44 | 45 | /** 46 | * 交易是否失敗 47 | */ 48 | public function isFail(): bool 49 | { 50 | return $this->status() !== 'SUCCESS'; 51 | } 52 | 53 | /** 54 | * 敘述此次交易狀態 55 | */ 56 | public function message(): string 57 | { 58 | return $this->data['Message']; 59 | } 60 | 61 | /** 62 | * 回傳參數 63 | */ 64 | public function result(): array 65 | { 66 | return $this->data['Result'] ?? []; 67 | } 68 | 69 | /** 70 | * 藍新金流商店代號 71 | */ 72 | public function merchantId(): string 73 | { 74 | return $this->result()['MerchantID']; 75 | } 76 | 77 | /** 78 | * 交易金額 79 | */ 80 | public function amt(): int 81 | { 82 | return $this->result()['Amt']; 83 | } 84 | 85 | /** 86 | * 藍新金流交易序號 87 | */ 88 | public function tradeNo(): string 89 | { 90 | return $this->result()['TradeNo']; 91 | } 92 | 93 | /** 94 | * 商店訂單編號 95 | */ 96 | public function merchantOrderNo(): string 97 | { 98 | return $this->result()['MerchantOrderNo']; 99 | } 100 | 101 | /** 102 | * 檢核碼 103 | */ 104 | public function checkCode() 105 | { 106 | return $this->result()['CheckCode']; 107 | } 108 | 109 | /** 110 | * 驗證資料有沒有被竄改 111 | */ 112 | public function verify(): bool 113 | { 114 | return $this->verifyCheckCode($this->checkCode(), [ 115 | 'MerchantID' => $this->merchantId(), 116 | 'Amt' => $this->amt(), 117 | 'MerchantOrderNo' => $this->merchantOrderNo(), 118 | 'TradeNo' => $this->tradeNo(), 119 | ], $this->hashKey, $this->hashIV); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/Results/CloseResult.php: -------------------------------------------------------------------------------- 1 | data['Status']; 16 | } 17 | 18 | /** 19 | * 交易是否成功 20 | */ 21 | public function isSuccess(): bool 22 | { 23 | return $this->status() === 'SUCCESS'; 24 | } 25 | 26 | /** 27 | * 交易是否失敗 28 | */ 29 | public function isFail(): bool 30 | { 31 | return $this->status() !== 'SUCCESS'; 32 | } 33 | 34 | /** 35 | * 敘述此次交易狀態 36 | */ 37 | public function message(): string 38 | { 39 | return $this->data['Message']; 40 | } 41 | 42 | /** 43 | * 回傳參數 44 | */ 45 | public function result(): array 46 | { 47 | return $this->data['Result'] ?? []; 48 | } 49 | 50 | /** 51 | * 藍新金流商店代號 52 | */ 53 | public function merchantId(): string 54 | { 55 | return $this->result()['MerchantID']; 56 | } 57 | 58 | /** 59 | * 交易金額 60 | */ 61 | public function amt(): int 62 | { 63 | return $this->result()['Amt']; 64 | } 65 | 66 | /** 67 | * 藍新金流交易序號 68 | */ 69 | public function tradeNo(): string 70 | { 71 | return $this->result()['TradeNo']; 72 | } 73 | 74 | /** 75 | * 商店訂單編號 76 | */ 77 | public function merchantOrderNo(): string 78 | { 79 | return $this->result()['MerchantOrderNo']; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Results/Concerns/HasVerifyCheckCode.php: -------------------------------------------------------------------------------- 1 | $parameter['MerchantID'], 11 | 'Amt' => $parameter['Amt'], 12 | 'MerchantOrderNo' => $parameter['MerchantOrderNo'], 13 | 'TradeNo' => $parameter['TradeNo'], 14 | ]; 15 | 16 | ksort($parameter); 17 | $checkStr = http_build_query($parameter); 18 | $hashs = 'HashIV='.$hashIV.'&'.$checkStr.'&HashKey='.$hashKey.''; 19 | $hashCode = strtoupper(hash('sha256', $hashs)); 20 | 21 | return $checkCode === $hashCode; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Results/CustomerATMResult.php: -------------------------------------------------------------------------------- 1 | data['BankCode']; 13 | } 14 | 15 | /** 16 | * 繳費代碼 17 | */ 18 | public function codeNo(): string 19 | { 20 | return $this->data['CodeNo']; 21 | } 22 | 23 | /** 24 | * Define the data keys. 25 | */ 26 | protected function dataKeys(): array 27 | { 28 | return [ 29 | 'BankCode', 30 | 'CodeNo', 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Results/CustomerLgsResult.php: -------------------------------------------------------------------------------- 1 | data['StoreCode']; 13 | } 14 | 15 | /** 16 | * 取貨門市中文名稱 17 | */ 18 | public function storeName(): string 19 | { 20 | return $this->data['StoreName']; 21 | } 22 | 23 | /** 24 | * 超商類別名稱 25 | * 26 | * * **全家** 27 | * * **7-ELEVEN** 28 | * * **萊爾富** 29 | * * **OK mart** 30 | */ 31 | public function storeType(): string 32 | { 33 | return $this->data['StoreType']; 34 | } 35 | 36 | /** 37 | * 超商門市地址 38 | */ 39 | public function storeAddr(): string 40 | { 41 | return $this->data['StoreAddr']; 42 | } 43 | 44 | /** 45 | * 取件交易方式 46 | * 47 | * * **1**: 取貨付款 48 | * * **3**: 取貨不付款 49 | */ 50 | public function tradeType(): int 51 | { 52 | return $this->data['TradeType']; 53 | } 54 | 55 | /** 56 | * 取貨人姓名 57 | */ 58 | public function cvscomName(): string 59 | { 60 | return $this->data['CVSCOMName']; 61 | } 62 | 63 | /** 64 | * 取貨人手機號碼 65 | */ 66 | public function cvscomPhone(): string 67 | { 68 | return $this->data['CVSCOMPhone']; 69 | } 70 | 71 | /** 72 | * 物流寄件單號 73 | */ 74 | public function lgsNo(): string 75 | { 76 | return $this->data['LgsNo']; 77 | } 78 | 79 | /** 80 | * 物流型態 81 | * 82 | * * **B2C**: 大宗寄倉 83 | * * **C2C**: 店到店 84 | */ 85 | public function lgsType(): string 86 | { 87 | return $this->data['LgsType']; 88 | } 89 | 90 | /** 91 | * Define the data keys. 92 | */ 93 | protected function dataKeys(): array 94 | { 95 | return [ 96 | 'StoreCode', 97 | 'StoreName', 98 | 'StoreType', 99 | 'StoreAddr', 100 | 'TradeType', 101 | 'CVSCOMName', 102 | 'CVSCOMPhone', 103 | 'LgsNo', 104 | 'LgsType', 105 | ]; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/Results/CustomerResult.php: -------------------------------------------------------------------------------- 1 | data['Status']; 16 | } 17 | 18 | /** 19 | * 取號是否成功 20 | */ 21 | public function isSuccess(): bool 22 | { 23 | return $this->status() === 'SUCCESS'; 24 | } 25 | 26 | /** 27 | * 取號是否失敗 28 | */ 29 | public function isFail(): bool 30 | { 31 | return $this->status() !== 'SUCCESS'; 32 | } 33 | 34 | /** 35 | * 敘述此次交易狀態 36 | */ 37 | public function message(): string 38 | { 39 | return $this->data['TradeInfo']['Message']; 40 | } 41 | 42 | /** 43 | * 回傳參數 44 | */ 45 | public function result(): array 46 | { 47 | return $this->data['TradeInfo']['Result'] ?? []; 48 | } 49 | 50 | /** 51 | * 藍新金流商店代號 52 | */ 53 | public function merchantId(): string 54 | { 55 | return $this->result()['MerchantID']; 56 | } 57 | 58 | /** 59 | * 交易金額 60 | */ 61 | public function amt(): int 62 | { 63 | return $this->result()['Amt']; 64 | } 65 | 66 | /** 67 | * 藍新金流交易序號 68 | */ 69 | public function tradeNo(): string 70 | { 71 | return $this->result()['TradeNo']; 72 | } 73 | 74 | /** 75 | * 商店訂單編號 76 | */ 77 | public function merchantOrderNo(): string 78 | { 79 | return $this->result()['MerchantOrderNo']; 80 | } 81 | 82 | /** 83 | * 支付方式 84 | * 85 | * * **VACC**: 銀行 ATM 轉帳付款 86 | * * **BARCODE**: 超商條碼繳費 87 | * * **CVS**: 超商代碼繳費 88 | * * **CVSCOM**: 超商取貨付款 89 | */ 90 | public function paymentType(): string 91 | { 92 | return $this->result()['PaymentType']; 93 | } 94 | 95 | /** 96 | * 繳費截止日期 97 | */ 98 | public function expireDate(): string 99 | { 100 | return $this->result()['ExpireDate']; 101 | } 102 | 103 | /** 104 | * 繳費截止時間 105 | */ 106 | public function expireTime(): string 107 | { 108 | return $this->result()['ExpireTime']; 109 | } 110 | 111 | /** 112 | * ATM 繳費回傳 113 | */ 114 | public function atm(): CustomerATMResult 115 | { 116 | return new CustomerATMResult($this->result()); 117 | } 118 | 119 | /** 120 | * 超商代碼繳費回傳 121 | */ 122 | public function storeCode(): CustomerStoreCodeResult 123 | { 124 | return new CustomerStoreCodeResult($this->result()); 125 | } 126 | 127 | /** 128 | * 超商條碼繳費回傳 129 | */ 130 | public function storeBarcode(): CustomerStoreBarcodeResult 131 | { 132 | return new CustomerStoreBarcodeResult($this->result()); 133 | } 134 | 135 | /** 136 | * 超商物流回傳 137 | */ 138 | public function lgs(): CustomerLgsResult 139 | { 140 | return new CustomerLgsResult($this->result()); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/Results/CustomerStoreBarcodeResult.php: -------------------------------------------------------------------------------- 1 | data['Barcode_1']; 13 | } 14 | 15 | /** 16 | * 繳費條碼第二段條碼 17 | */ 18 | public function barcode2(): string 19 | { 20 | return $this->data['Barcode_2']; 21 | } 22 | 23 | /** 24 | * 繳費條碼第三段條碼 25 | */ 26 | public function barcode3(): string 27 | { 28 | return $this->data['Barcode_3']; 29 | } 30 | 31 | /** 32 | * Define the data keys. 33 | */ 34 | protected function dataKeys(): array 35 | { 36 | return [ 37 | 'Barcode_1', 38 | 'Barcode_2', 39 | 'Barcode_3', 40 | ]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Results/CustomerStoreCodeResult.php: -------------------------------------------------------------------------------- 1 | data['CodeNo']; 13 | } 14 | 15 | /** 16 | * Define the data keys. 17 | */ 18 | protected function dataKeys(): array 19 | { 20 | return [ 21 | 'CodeNo', 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Results/MPGATMResult.php: -------------------------------------------------------------------------------- 1 | data['PayBankCode'] ?? null; 13 | } 14 | 15 | /** 16 | * 付款人金融機構帳號末五碼 17 | */ 18 | public function payerAccount5Code(): ?string 19 | { 20 | return $this->data['PayerAccount5Code'] ?? null; 21 | } 22 | 23 | /** 24 | * Define the data keys. 25 | */ 26 | protected function dataKeys(): array 27 | { 28 | return [ 29 | 'PayBankCode', 30 | 'PayerAccount5Code', 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Results/MPGCreditResult.php: -------------------------------------------------------------------------------- 1 | '台灣發卡機構核發之信用卡', 12 | 'FOREIGN' => '國外發卡機構核發之卡', 13 | 'UNIONPAY' => '銀聯卡', 14 | 'GOOGLEPAY' => 'GooglePay', 15 | 'SAMSUNGPAY' => 'SamsungPay', 16 | 'DCC' => '動態貨幣轉換', 17 | ]; 18 | 19 | /** 20 | * 收單金融機構中英文名稱對照 21 | */ 22 | protected $authBanks = [ 23 | 'Esun' => '玉山銀行', 24 | 'Taishin' => '台新銀行', 25 | 'CTBC' => '中國信託銀行', 26 | 'NCCC' => '聯合信用卡中心', 27 | 'CathayBK' => '國泰世華銀行', 28 | 'Citibank' => '花旗銀行', 29 | 'UBOT' => '聯邦銀行', 30 | 'SKBank' => '新光銀行', 31 | 'Fubon' => '富邦銀行', 32 | 'FirstBank' => '第一銀行', 33 | ]; 34 | 35 | /** 36 | * 收單金融機構 37 | * 38 | * * **Esun**: 玉山銀行 39 | * * **Taishin**: 台新銀行 40 | * * **CTBC**: 中國信託銀行 41 | * * **NCCC**: 聯合信用卡中心 42 | * * **CathayBK**: 國泰世華銀行 43 | * * **Citibank**: 花旗銀行 44 | * * **UBOT**: 聯邦銀行 45 | * * **SKBank**: 新光銀行 46 | * * **Fubon**: 富邦銀行 47 | * * **FirstBank**: 第一銀行 48 | */ 49 | public function authBank(): string 50 | { 51 | return $this->data['AuthBank']; 52 | } 53 | 54 | /** 55 | * 收單金融機構中文名稱 56 | */ 57 | public function authBankName(): string 58 | { 59 | return $this->authBanks[$this->data['AuthBank']] ?? $this->data['AuthBank']; 60 | } 61 | 62 | /** 63 | * 金融機構回應碼 64 | */ 65 | public function respondCode(): ?string 66 | { 67 | return $this->data['RespondCode'] ?? null; 68 | } 69 | 70 | /** 71 | * 授權碼 72 | */ 73 | public function auth(): ?string 74 | { 75 | return $this->data['Auth'] ?? null; 76 | } 77 | 78 | /** 79 | * 卡號前六碼 80 | */ 81 | public function card6No(): ?string 82 | { 83 | return $this->data['Card6No'] ?? null; 84 | } 85 | 86 | /** 87 | * 卡號末四碼 88 | */ 89 | public function card4No(): ?string 90 | { 91 | return $this->data['Card4No'] ?? null; 92 | } 93 | 94 | /** 95 | * 分期-期別 96 | */ 97 | public function inst(): int 98 | { 99 | return $this->data['Inst']; 100 | } 101 | 102 | /** 103 | * 分期-首期金額 104 | */ 105 | public function instFirst(): int 106 | { 107 | return $this->data['InstFirst']; 108 | } 109 | 110 | /** 111 | * 分期-每期金額 112 | */ 113 | public function instEach(): int 114 | { 115 | return $this->data['InstEach']; 116 | } 117 | 118 | /** 119 | * ECI 值 120 | * 121 | * 3D 回傳值 eci=1,2,5,6,代表為 3D 交易。 122 | */ 123 | public function ECI(): ?string 124 | { 125 | return $this->data['ECI'] ?? null; 126 | } 127 | 128 | /** 129 | * 信用卡快速結帳使用狀態 130 | * 131 | * * **0**: 該筆交易為非使用信用卡快速結帳功能。 132 | * * **1**: 該筆交易為首次設定信用卡快速結帳功能。 133 | * * **2**: 該筆交易為使用信用卡快速結帳功能。 134 | * * **9**: 該筆交易為取消信用卡快速結帳功能功能。 135 | */ 136 | public function tokenUseStatus(): int 137 | { 138 | return $this->data['TokenUseStatus']; 139 | } 140 | 141 | /** 142 | * 紅利折抵後實際金額 143 | * 144 | * 1. 扣除紅利交易折抵後的實際授權金額。 145 | * 例:1000 元之交易,紅利折抵 60 元,則紅利折抵後實際金額為 940 元。 146 | * 2. 若紅利點數不足,會有以下狀況: 147 | * 2-1. 紅利折抵交易失敗,回傳參數數值為 0。 148 | * 2-2. 紅利折抵交易成功,回傳參數數值為訂單金額。 149 | * 2-3. 紅利折抵交易是否成功,視該銀行之設定為準。 150 | * 3. 僅有使用紅利折抵交易時才會回傳此參數。 151 | * 4. 若紅利折抵掉全部金額,則此欄位回傳參數數值也會是 0,交易成功或交易失敗,請依回傳參數[Status]回覆為準。 152 | */ 153 | public function redAmt(): ?int 154 | { 155 | return $this->data['RedAmt'] ?? null; 156 | } 157 | 158 | /** 159 | * 交易類別 160 | * 161 | * * **CREDIT**: 台灣發卡機構核發之信用卡 162 | * * **FOREIGN**: 國外發卡機構核發之卡 163 | * * **UNIONPAY**: 銀聯卡 164 | * * **GOOGLEPAY**: GooglePay 165 | * * **SAMSUNGPAY**: SamsungPay 166 | * * **DCC**: 動態貨幣轉換 (註:僅支援台新銀行一次付清之代收商店。) 167 | */ 168 | public function paymentMethod(): string 169 | { 170 | return $this->data['PaymentMethod']; 171 | } 172 | 173 | /** 174 | * 交易類別中文名稱 175 | */ 176 | public function paymentMethodName(): string 177 | { 178 | return $this->paymentMethods[$this->data['PaymentMethod']] ?? $this->data['PaymentMethod']; 179 | } 180 | 181 | /** 182 | * 外幣金額 183 | * 184 | * * DCC 動態貨幣轉換交易才會回傳的參數 185 | * * 註:僅支援台新銀行一次付清之代收商店。 186 | */ 187 | public function dccAmt(): ?float 188 | { 189 | return $this->data['DCC_Amt'] ?? null; 190 | } 191 | 192 | /** 193 | * 匯率 194 | * 195 | * * DCC 動態貨幣轉換交易才會回傳的參數 196 | * * 註:僅支援台新銀行一次付清之代收商店。 197 | */ 198 | public function dccRate(): ?float 199 | { 200 | return $this->data['DCC_Rate'] ?? null; 201 | } 202 | 203 | /** 204 | * 風險匯率 205 | * 206 | * * DCC 動態貨幣轉換交易才會回傳的參數 207 | * * 註:僅支援台新銀行一次付清之代收商店。 208 | */ 209 | public function dccMarkup(): ?float 210 | { 211 | return $this->data['DCC_Markup'] ?? null; 212 | } 213 | 214 | /** 215 | * 幣別 216 | * 217 | * 例如:USD、JPY、MOP... 218 | * 219 | * * DCC 動態貨幣轉換交易才會回傳的參數 220 | * * 註:僅支援台新銀行一次付清之代收商店。 221 | */ 222 | public function dccCurrency(): ?string 223 | { 224 | return $this->data['DCC_Currency'] ?? null; 225 | } 226 | 227 | /** 228 | * 幣別代碼 229 | * 230 | * 例如:MOP = 446... 231 | * 232 | * * DCC 動態貨幣轉換交易才會回傳的參數 233 | * * 註:僅支援台新銀行一次付清之代收商店。 234 | */ 235 | public function dccCurrencyCode(): ?int 236 | { 237 | return $this->data['DCC_Currency_Code'] ?? null; 238 | } 239 | 240 | /** 241 | * Define the data keys. 242 | */ 243 | protected function dataKeys(): array 244 | { 245 | return [ 246 | 'AuthBank', 247 | 'RespondCode', 248 | 'Auth', 249 | 'Card6No', 250 | 'Card4No', 251 | 'Inst', 252 | 'InstFirst', 253 | 'InstEach', 254 | 'ECI', 255 | 'TokenUseStatus', 256 | 'RedAmt', 257 | 'PaymentMethod', 258 | 'DCC_Amt', 259 | 'DCC_Rate', 260 | 'DCC_Markup', 261 | 'DCC_Currency', 262 | 'DCC_Currency_Code', 263 | ]; 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /src/Results/MPGEsunWalletResult.php: -------------------------------------------------------------------------------- 1 | data['PayAmt']; 13 | } 14 | 15 | /** 16 | * 紅利折抵金額 17 | */ 18 | public function redDisAmt(): ?int 19 | { 20 | return $this->data['RedDisAmt'] ?? null; 21 | } 22 | 23 | /** 24 | * Define the data keys. 25 | */ 26 | protected function dataKeys(): array 27 | { 28 | return [ 29 | 'PayAmt', 30 | 'RedDisAmt', 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Results/MPGEzPayResult.php: -------------------------------------------------------------------------------- 1 | '支付寶', 12 | 'WECHATPAY' => '微信支付', 13 | 'ACCLINK' => '約定連結帳戶', 14 | 'CREDIT' => '信用卡', 15 | 'CVS' => '超商代碼', 16 | 'P2GEACC' => '簡單付電子帳戶轉帳', 17 | 'VACC' => 'ATM 轉帳', 18 | 'WEBATM' => 'WebATM 轉帳', 19 | ]; 20 | 21 | /** 22 | * 確認這筆交易是來自 ezPay 的交易 23 | */ 24 | public function isEzPay() 25 | { 26 | return is_string($this->channelId()) && in_array($this->channelId(), array_keys($this->channels)); 27 | } 28 | 29 | /** 30 | * 跨境通路類型 31 | * 32 | * 該筆交易之跨境收款通路。 33 | * 34 | * * **ALIPAY**: 支付寶 35 | * * **WECHATPAY**: 微信支付 36 | * * **ACCLINK**: 約定連結帳戶 37 | * * **CREDIT**: 信用卡 38 | * * **CVS**: 超商代碼 39 | * * **P2GEACC**: 簡單付電子帳戶轉帳 40 | * * **VACC**: ATM 轉帳 41 | * * **WEBATM**: WebATM 轉帳 42 | */ 43 | public function channelId(): ?string 44 | { 45 | return $this->data['ChannelID'] ?? null; 46 | } 47 | 48 | /** 49 | * 跨境通路中文名稱 50 | */ 51 | public function channelName(): ?string 52 | { 53 | return $this->channels[$this->data['ChannelID']] ?? $this->data['ChannelID']; 54 | } 55 | 56 | /** 57 | * 跨境通路交易序號 58 | */ 59 | public function channelNo(): ?string 60 | { 61 | return $this->data['ChannelNo'] ?? null; 62 | } 63 | 64 | /** 65 | * Define the data keys. 66 | */ 67 | protected function dataKeys(): array 68 | { 69 | return [ 70 | 'ChannelID', 71 | 'ChannelNo', 72 | ]; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Results/MPGLgsResult.php: -------------------------------------------------------------------------------- 1 | data['StoreCode']; 13 | } 14 | 15 | /** 16 | * 取貨門市中文名稱 17 | */ 18 | public function storeName(): string 19 | { 20 | return $this->data['StoreName']; 21 | } 22 | 23 | /** 24 | * 超商類別名稱 25 | * 26 | * [全家]、[7-ELEVEN]、[萊爾富]、[OK mart] 27 | */ 28 | public function storeType(): string 29 | { 30 | return $this->data['StoreType']; 31 | } 32 | 33 | /** 34 | * 超商門市地址 35 | */ 36 | public function storeAddr(): string 37 | { 38 | return $this->data['StoreAddr']; 39 | } 40 | 41 | /** 42 | * 取件交易方式 43 | * 44 | * * **1**: 取貨付款 45 | * * **3**: 取貨不付款 46 | */ 47 | public function tradeType(): int 48 | { 49 | return $this->data['TradeType']; 50 | } 51 | 52 | /** 53 | * 取貨人姓名 54 | */ 55 | public function cvscomName(): string 56 | { 57 | return $this->data['CVSCOMName']; 58 | } 59 | 60 | /** 61 | * 取貨人手機號碼 62 | */ 63 | public function cvscomPhone(): string 64 | { 65 | return $this->data['CVSCOMPhone']; 66 | } 67 | 68 | /** 69 | * 物流寄件單號 70 | */ 71 | public function lgsNo(): string 72 | { 73 | return $this->data['LgsNo']; 74 | } 75 | 76 | /** 77 | * 物流型態 78 | * 79 | * B2C、C2C 80 | */ 81 | public function lgsType(): string 82 | { 83 | return $this->data['LgsType']; 84 | } 85 | 86 | /** 87 | * Define the data keys. 88 | */ 89 | protected function dataKeys(): array 90 | { 91 | return [ 92 | 'StoreCode', 93 | 'StoreName', 94 | 'StoreType', 95 | 'StoreAddr', 96 | 'TradeType', 97 | 'CVSCOMName', 98 | 'CVSCOMPhone', 99 | 'LgsNo', 100 | 'LgsType', 101 | ]; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/Results/MPGResult.php: -------------------------------------------------------------------------------- 1 | data['Status']; 16 | } 17 | 18 | /** 19 | * 交易是否成功 20 | */ 21 | public function isSuccess(): bool 22 | { 23 | return $this->status() === 'SUCCESS'; 24 | } 25 | 26 | /** 27 | * 交易是否失敗 28 | */ 29 | public function isFail(): bool 30 | { 31 | return $this->status() !== 'SUCCESS'; 32 | } 33 | 34 | /** 35 | * 敘述此次交易狀態 36 | */ 37 | public function message(): string 38 | { 39 | return $this->data['TradeInfo']['Message'] ?? ''; 40 | } 41 | 42 | /** 43 | * 回傳參數 44 | */ 45 | public function result(): array 46 | { 47 | return $this->data['TradeInfo']['Result'] ?? []; 48 | } 49 | 50 | /** 51 | * 藍新金流商店代號 52 | */ 53 | public function merchantId(): string 54 | { 55 | return $this->result()['MerchantID']; 56 | } 57 | 58 | /** 59 | * 交易金額 60 | */ 61 | public function amt(): int 62 | { 63 | return $this->result()['Amt']; 64 | } 65 | 66 | /** 67 | * 藍新金流交易序號 68 | */ 69 | public function tradeNo(): string 70 | { 71 | return $this->result()['TradeNo']; 72 | } 73 | 74 | /** 75 | * 商店訂單編號 76 | */ 77 | public function merchantOrderNo(): string 78 | { 79 | return $this->result()['MerchantOrderNo']; 80 | } 81 | 82 | /** 83 | * 支付方式 84 | * 85 | * * **CREDIT**: 信用卡付款 86 | * * **VACC**: 銀行 ATM 轉帳付款 87 | * * **WEBATM**: 網路銀行轉帳付款 88 | * * **BARCODE**: 超商條碼繳費 89 | * * **CVS**: 超商代碼繳費 90 | * * **LINEPAY**: LINE Pay 付款 91 | * * **ESUNWALLET**: 玉山 Wallet 92 | * * **TAIWANPAY**: 台灣 Pay 93 | * * **CVSCOM**: 超商取貨付款 94 | */ 95 | public function paymentType(): string 96 | { 97 | return $this->result()['PaymentType']; 98 | } 99 | 100 | /** 101 | * 回傳格式 102 | * 103 | * JSON 格式 104 | */ 105 | public function respondType(): string 106 | { 107 | return $this->result()['RespondType']; 108 | } 109 | 110 | /** 111 | * 支付完成時間 112 | * 113 | * 當使用超商取貨服務時,本欄位的值會以空值回傳 114 | */ 115 | public function payTime(): ?string 116 | { 117 | return $this->result()['PayTime'] ?? null; 118 | } 119 | 120 | /** 121 | * 交易 IP 122 | */ 123 | public function ip(): string 124 | { 125 | return $this->result()['IP']; 126 | } 127 | 128 | /** 129 | * 款項保管銀行 130 | * 131 | * 如商店是直接與收單機構簽約的閘道模式如:支付寶-玉山銀行、ezPay 電子錢包、LINE Pay, 132 | * 當使用信用卡支付時,本欄位的值會以空值回傳。 133 | */ 134 | public function escrowBank(): ?string 135 | { 136 | return $this->result()['EscrowBank'] ?? null; 137 | } 138 | 139 | /** 140 | * 信用卡支付回傳(一次付清、Google Pay、Samaung Pay、國民旅遊卡、銀聯) 141 | */ 142 | public function credit(): MPGCreditResult 143 | { 144 | return new MPGCreditResult($this->result()); 145 | } 146 | 147 | /** 148 | * WEBATM、ATM 繳費回傳 149 | */ 150 | public function atm(): MPGATMResult 151 | { 152 | return new MPGATMResult($this->result()); 153 | } 154 | 155 | /** 156 | * 超商代碼繳費回傳 157 | */ 158 | public function storeCode(): MPGStoreCodeResult 159 | { 160 | return new MPGStoreCodeResult($this->result()); 161 | } 162 | 163 | /** 164 | * 超商條碼繳費回傳 165 | */ 166 | public function storeBarcode(): MPGStoreBarcodeResult 167 | { 168 | return new MPGStoreBarcodeResult($this->result()); 169 | } 170 | 171 | /** 172 | * 超商物流回傳 173 | */ 174 | public function lgs(): MPGLgsResult 175 | { 176 | return new MPGLgsResult($this->result()); 177 | } 178 | 179 | /** 180 | * 跨境支付回傳 (包含簡單付電子錢包、簡單付微信支付、簡單付支付寶) 181 | */ 182 | public function ezPay(): MPGEzPayResult 183 | { 184 | return new MPGEzPayResult($this->result()); 185 | } 186 | 187 | /** 188 | * 玉山 Wallet 回傳 189 | */ 190 | public function esunWallet(): MPGEsunWalletResult 191 | { 192 | return new MPGEsunWalletResult($this->result()); 193 | } 194 | 195 | /** 196 | * 台灣 Pay 回傳 197 | */ 198 | public function taiwanPay(): MPGTaiwanPayResult 199 | { 200 | return new MPGTaiwanPayResult($this->result()); 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /src/Results/MPGStoreBarcodeResult.php: -------------------------------------------------------------------------------- 1 | '7-11', 12 | 'FAMILY' => '全家', 13 | 'OK' => 'OK', 14 | 'HILIFE' => '萊爾富', 15 | ]; 16 | 17 | /** 18 | * 繳費條碼第一段條碼 19 | */ 20 | public function barcode1(): string 21 | { 22 | return $this->data['Barcode_1']; 23 | } 24 | 25 | /** 26 | * 繳費條碼第二段條碼 27 | */ 28 | public function barcode2(): string 29 | { 30 | return $this->data['Barcode_2']; 31 | } 32 | 33 | /** 34 | * 繳費條碼第三段條碼 35 | */ 36 | public function barcode3(): string 37 | { 38 | return $this->data['Barcode_3']; 39 | } 40 | 41 | /** 42 | * 付款次數 43 | */ 44 | public function repayTimes(): int 45 | { 46 | return $this->data['RepayTimes']; 47 | } 48 | 49 | /** 50 | * 繳費超商 51 | * 52 | * 收款超商的代碼 53 | * * **SEVEN**: 7-11 54 | * * **FAMILY**: 全家 55 | * * **OK**: OK 56 | * * **HILIFE**: 萊爾富 57 | */ 58 | public function payStore(): string 59 | { 60 | return $this->data['PayStore']; 61 | } 62 | 63 | /** 64 | * 繳費超商中文名稱 65 | */ 66 | public function payStoreName(): string 67 | { 68 | return $this->payStores[$this->data['PayStore']] ?? $this->data['PayStore']; 69 | } 70 | 71 | /** 72 | * Define the data keys. 73 | */ 74 | protected function dataKeys(): array 75 | { 76 | return [ 77 | 'Barcode_1', 78 | 'Barcode_2', 79 | 'Barcode_3', 80 | 'RepayTimes', 81 | 'PayStore', 82 | ]; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Results/MPGStoreCodeResult.php: -------------------------------------------------------------------------------- 1 | '7-11', 12 | 2 => '全家', 13 | 3 => 'OK', 14 | 4 => '萊爾富', 15 | ]; 16 | 17 | /** 18 | * 繳費代碼 19 | */ 20 | public function codeNo(): string 21 | { 22 | return $this->data['CodeNo']; 23 | } 24 | 25 | /** 26 | * 繳費門市類別 27 | * 28 | * * **1**: 7-11 29 | * * **2**: 全家 30 | * * **3**: OK 31 | * * **4**: 萊爾富 32 | */ 33 | public function storeType(): int 34 | { 35 | return $this->data['StoreType']; 36 | } 37 | 38 | /** 39 | * 繳費超商中文名稱 40 | */ 41 | public function storeTypeName(): string 42 | { 43 | return $this->storeTypes[$this->data['StoreType']] ?? $this->data['StoreType']; 44 | } 45 | 46 | /** 47 | * 繳費門市代號 48 | * 49 | * 全家回傳門市中文名稱 50 | */ 51 | public function storeId(): string 52 | { 53 | return $this->data['StoreID']; 54 | } 55 | 56 | /** 57 | * Define the data keys. 58 | */ 59 | protected function dataKeys(): array 60 | { 61 | return [ 62 | 'CodeNo', 63 | 'StoreType', 64 | 'StoreID', 65 | ]; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Results/MPGTaiwanPayResult.php: -------------------------------------------------------------------------------- 1 | data['PayAmt']; 13 | } 14 | 15 | /** 16 | * Define the data keys. 17 | */ 18 | protected function dataKeys(): array 19 | { 20 | return [ 21 | 'PayAmt', 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Results/PeriodAmtResult.php: -------------------------------------------------------------------------------- 1 | data['Status']; 18 | } 19 | 20 | /** 21 | * 交易是否成功 22 | */ 23 | public function isSuccess(): bool 24 | { 25 | return $this->status() === 'SUCCESS'; 26 | } 27 | 28 | /** 29 | * 交易是否失敗 30 | */ 31 | public function isFail(): bool 32 | { 33 | return $this->status() !== 'SUCCESS'; 34 | } 35 | 36 | /** 37 | * 敘述此次交易狀態 38 | */ 39 | public function message(): string 40 | { 41 | return $this->data['Message']; 42 | } 43 | 44 | /** 45 | * 回傳參數 46 | */ 47 | public function result(): array 48 | { 49 | return $this->data['Result'] ?? []; 50 | } 51 | 52 | /** 53 | * 商店訂單編號 54 | */ 55 | public function merchantOrderNo(): string 56 | { 57 | return $this->result()['MerOrderNo']; 58 | } 59 | 60 | /** 61 | * 委託單號 62 | */ 63 | public function periodNo(): string 64 | { 65 | return $this->result()['PeriodNo']; 66 | } 67 | 68 | /** 69 | * 委託金額 70 | */ 71 | public function amt(): int 72 | { 73 | return $this->result()['AlterAmt']; 74 | } 75 | 76 | /** 77 | * 週期類別 78 | */ 79 | public function periodType(): PeriodType 80 | { 81 | return PeriodType::from($this->result()['PeriodType']); 82 | } 83 | 84 | /** 85 | * 交易週期授權時間 86 | */ 87 | public function periodPoint(): string 88 | { 89 | return $this->result()['PeriodPoint']; 90 | } 91 | 92 | /** 93 | * 委託下一次授權金額 94 | */ 95 | public function newNextAmt(): int 96 | { 97 | return $this->result()['NewNextAmt']; 98 | } 99 | 100 | /** 101 | * 委託下一次授權日期 102 | */ 103 | public function newNextTime(): string 104 | { 105 | return $this->result()['NewNextTime']; 106 | } 107 | 108 | /** 109 | * 授權期數 110 | */ 111 | public function periodTimes(): int 112 | { 113 | return $this->result()['PeriodTimes']; 114 | } 115 | 116 | /** 117 | * 信用卡到期日 118 | * 119 | * 格式為月年 120 | */ 121 | public function creditExpiredAt(): string 122 | { 123 | return $this->result()['Extday']; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/Results/PeriodNotifyResult.php: -------------------------------------------------------------------------------- 1 | '玉山銀行', 12 | 'Taishin' => '台新銀行', 13 | 'NCCC' => '聯合信用卡中心', 14 | 'CathayBK' => '國泰世華銀行', 15 | 'CTBC' => '中國信託銀行', 16 | 'UBOT' => '聯邦銀行', 17 | ]; 18 | 19 | /** 20 | * 交易狀態 21 | * 22 | * 1. 若交易付款成功,則回傳 SUCCESS。 23 | * 2. 若交易付款失敗,則回傳錯誤代碼。 24 | */ 25 | public function status(): string 26 | { 27 | return $this->data['Status']; 28 | } 29 | 30 | /** 31 | * 交易是否成功 32 | */ 33 | public function isSuccess(): bool 34 | { 35 | return $this->status() === 'SUCCESS'; 36 | } 37 | 38 | /** 39 | * 交易是否失敗 40 | */ 41 | public function isFail(): bool 42 | { 43 | return $this->status() !== 'SUCCESS'; 44 | } 45 | 46 | /** 47 | * 敘述此次交易狀態 48 | */ 49 | public function message(): string 50 | { 51 | return $this->data['Message']; 52 | } 53 | 54 | /** 55 | * 回傳參數 56 | */ 57 | public function result(): array 58 | { 59 | return $this->data['Result'] ?? []; 60 | } 61 | 62 | /** 63 | * 藍新金流商店代號 64 | */ 65 | public function merchantId(): string 66 | { 67 | return $this->result()['MerchantID']; 68 | } 69 | 70 | /** 71 | * 商店訂單編號 72 | */ 73 | public function merchantOrderNo(): string 74 | { 75 | return $this->result()['MerchantOrderNo']; 76 | } 77 | 78 | /** 79 | * 自訂單號 80 | * 81 | * 格式為:商店訂單編號_期數 82 | */ 83 | public function orderNo(): string 84 | { 85 | return $this->result()['OrderNo']; 86 | } 87 | 88 | /** 89 | * 藍新金流交易序號 90 | */ 91 | public function tradeNo(): string 92 | { 93 | return $this->result()['TradeNo']; 94 | } 95 | 96 | /** 97 | * 委託之本期授權時間 (Y-m-d h:i:s) 98 | */ 99 | public function authDate(): string 100 | { 101 | return $this->result()['AuthDate']; 102 | } 103 | 104 | /** 105 | * 委託之總授權期數 106 | */ 107 | public function totalTimes(): int 108 | { 109 | return $this->result()['TotalTimes']; 110 | } 111 | 112 | /** 113 | * 委託之已授權期數,包含授權失敗期數 114 | */ 115 | public function alreadyTimes(): int 116 | { 117 | return $this->result()['AlreadyTimes']; 118 | } 119 | 120 | /** 121 | * 委託單本期授權金額 122 | */ 123 | public function authAmt(): int 124 | { 125 | return $this->result()['AuthAmt']; 126 | } 127 | 128 | /** 129 | * 授權碼 130 | */ 131 | public function authCode(): string 132 | { 133 | return $this->result()['AuthCode']; 134 | } 135 | 136 | /** 137 | * 款項保管銀行 138 | * 139 | * 如商店是直接與銀行簽約的信用卡特約商店,當使用信用卡支付時,本欄位會回傳空值 140 | * 141 | * * **HNCB**: 華南銀行 142 | */ 143 | public function escrowBank(): ?string 144 | { 145 | return $this->result()['EscrowBank'] ?? null; 146 | } 147 | 148 | /** 149 | * 收單金融機構 150 | * 151 | * * **Esun**: 玉山銀行 152 | * * **Taishin**: 台新銀行 153 | * * **NCCC**: 聯合信用卡中心 154 | * * **CathayBK**: 國泰世華銀行 155 | * * **CTBC**: 中國信託銀行 156 | * * **UBOT**: 聯邦銀行 157 | */ 158 | public function authBank(): string 159 | { 160 | return $this->result()['AuthBank']; 161 | } 162 | 163 | /** 164 | * 收單金融機構中文名稱 165 | */ 166 | public function authBankName(): string 167 | { 168 | return $this->authBanks[$this->result()['AuthBank']] ?? $this->result()['AuthBank']; 169 | } 170 | 171 | /** 172 | * 下期委託授權日期 (Y-m-d) 173 | * 174 | * 授權當期若為最後一期,則回覆該期日期 175 | */ 176 | public function nextAuthDate(): string 177 | { 178 | return $this->result()['NextAuthDate']; 179 | } 180 | 181 | /** 182 | * 委託單號 183 | */ 184 | public function periodNo(): string 185 | { 186 | return $this->result()['PeriodNo']; 187 | } 188 | 189 | // TODO: 在初次授權時,notify 有幾個欄位沒有回傳 190 | // MerchantID 191 | // MerchantOrderNo 192 | // // OrderNo 193 | // TradeNo 194 | // // AuthDate 195 | // // TotalTimes 196 | // // AlreadyTimes 197 | // // AuthAmt 198 | // AuthCode 199 | // EscrowBank 200 | // AuthBank 201 | // // NextAuthDate 202 | // PeriodNo 203 | } 204 | -------------------------------------------------------------------------------- /src/Results/PeriodResult.php: -------------------------------------------------------------------------------- 1 | '台灣發卡機構核發之信用卡', 14 | 'UNIONPAY' => '銀聯卡', 15 | ]; 16 | 17 | /** 18 | * 收單金融機構中英文名稱對照 19 | */ 20 | protected $authBanks = [ 21 | 'Esun' => '玉山銀行', 22 | 'Taishin' => '台新銀行', 23 | 'NCCC' => '聯合信用卡中心', 24 | 'CathayBK' => '國泰世華銀行', 25 | 'CTBC' => '中國信託銀行', 26 | 'UBOT' => '聯邦銀行', 27 | ]; 28 | 29 | /** 30 | * 交易狀態 31 | * 32 | * 1. 若交易付款成功,則回傳 SUCCESS。 33 | * 2. 若交易付款失敗,則回傳錯誤代碼。 34 | */ 35 | public function status(): string 36 | { 37 | return $this->data['Status']; 38 | } 39 | 40 | /** 41 | * 交易是否成功 42 | */ 43 | public function isSuccess(): bool 44 | { 45 | return $this->status() === 'SUCCESS'; 46 | } 47 | 48 | /** 49 | * 交易是否失敗 50 | */ 51 | public function isFail(): bool 52 | { 53 | return $this->status() !== 'SUCCESS'; 54 | } 55 | 56 | /** 57 | * 敘述此次交易狀態 58 | */ 59 | public function message(): string 60 | { 61 | return $this->data['Message']; 62 | } 63 | 64 | /** 65 | * 回傳參數 66 | */ 67 | public function result(): array 68 | { 69 | return $this->data['Result'] ?? []; 70 | } 71 | 72 | /** 73 | * 藍新金流商店代號 74 | */ 75 | public function merchantId(): string 76 | { 77 | return $this->result()['MerchantID']; 78 | } 79 | 80 | /** 81 | * 商店訂單編號 82 | */ 83 | public function merchantOrderNo(): string 84 | { 85 | return $this->result()['MerchantOrderNo']; 86 | } 87 | 88 | /** 89 | * 委託週期類別 90 | */ 91 | public function periodType(): PeriodType 92 | { 93 | return PeriodType::from($this->result()['PeriodType']); 94 | } 95 | 96 | /** 97 | * 此委託總授權期數 98 | */ 99 | public function authTimes(): int 100 | { 101 | return $this->result()['AuthTimes']; 102 | } 103 | 104 | /** 105 | * 委託所有授權日期排程 106 | */ 107 | public function dateArray(): array 108 | { 109 | return explode(',', $this->result()['DateArray']); 110 | } 111 | 112 | /** 113 | * 委託每期金額 114 | */ 115 | public function periodAmt(): int 116 | { 117 | return $this->result()['PeriodAmt']; 118 | } 119 | 120 | /** 121 | * 委託單號 122 | */ 123 | public function periodNo(): string 124 | { 125 | return $this->result()['PeriodNo']; 126 | } 127 | 128 | /** 129 | * 每期授權時間 130 | * 131 | * 交易模式為 **立即執行十元授權** 或 **立即執行委託金額授權** 時回傳的參數。 132 | */ 133 | public function authTime(): string 134 | { 135 | return $this->result()['AuthTime']; 136 | } 137 | 138 | /** 139 | * 藍新金流交易序號 140 | * 141 | * 交易模式為 **立即執行十元授權** 或 **立即執行委託金額授權** 時回傳的參數。 142 | */ 143 | public function tradeNo(): string 144 | { 145 | return $this->result()['TradeNo']; 146 | } 147 | 148 | /** 149 | * 卡號前六與後四碼 150 | * 151 | * 交易模式為 **立即執行十元授權** 或 **立即執行委託金額授權** 時回傳的參數。 152 | */ 153 | public function cardNo(): string 154 | { 155 | return $this->result()['CardNo']; 156 | } 157 | 158 | /** 159 | * 授權碼 160 | * 161 | * 交易模式為 **立即執行十元授權** 或 **立即執行委託金額授權** 時回傳的參數。 162 | */ 163 | public function authCode(): string 164 | { 165 | return $this->result()['AuthCode']; 166 | } 167 | 168 | /** 169 | * 銀行回應碼 170 | * 171 | * 00 代表刷卡成功,其餘為刷卡失敗。 172 | * 173 | * 交易模式為 **立即執行十元授權** 或 **立即執行委託金額授權** 時回傳的參數。 174 | */ 175 | public function respondCode(): string 176 | { 177 | return $this->result()['RespondCode']; 178 | } 179 | 180 | /** 181 | * 刷卡是否成功 182 | */ 183 | public function creditSuccessfully(): bool 184 | { 185 | return $this->respondCode() === '00'; 186 | } 187 | 188 | /** 189 | * 款項保管銀行 190 | * 191 | * 如商店是直接與銀行簽約的信用卡特約商店,當使用信用卡支付時,本欄位會回傳空值 192 | * 193 | * * **HNCB**: 華南銀行 194 | * 195 | * 交易模式為 **立即執行十元授權** 或 **立即執行委託金額授權** 時回傳的參數。 196 | */ 197 | public function escrowBank(): ?string 198 | { 199 | return $this->result()['EscrowBank'] ?? null; 200 | } 201 | 202 | /** 203 | * 收單金融機構 204 | * 205 | * * **Esun**: 玉山銀行 206 | * * **Taishin**: 台新銀行 207 | * * **NCCC**: 聯合信用卡中心 208 | * * **CathayBK**: 國泰世華銀行 209 | * * **CTBC**: 中國信託銀行 210 | * * **UBOT**: 聯邦銀行 211 | * 212 | * 交易模式為 **立即執行十元授權** 或 **立即執行委託金額授權** 時回傳的參數。 213 | */ 214 | public function authBank(): string 215 | { 216 | return $this->result()['AuthBank']; 217 | } 218 | 219 | /** 220 | * 收單金融機構中文名稱 221 | */ 222 | public function authBankName(): string 223 | { 224 | return $this->authBanks[$this->result()['AuthBank']] ?? $this->result()['AuthBank']; 225 | } 226 | 227 | /** 228 | * 交易類別 229 | * 230 | * * **CREDIT**: 台灣發卡機構核發之信用卡 231 | * * **UNIONPAY**: 銀聯卡 232 | * 233 | * 交易模式為 **立即執行十元授權** 或 **立即執行委託金額授權** 時回傳的參數。 234 | */ 235 | public function paymentMethod(): string 236 | { 237 | return $this->result()['PaymentMethod']; 238 | } 239 | 240 | /** 241 | * 交易類別中文名稱 242 | */ 243 | public function paymentMethodName(): string 244 | { 245 | return $this->paymentMethods[$this->result()['PaymentMethod']] ?? $this->result()['PaymentMethod']; 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /src/Results/PeriodStatusResult.php: -------------------------------------------------------------------------------- 1 | data['Status']; 18 | } 19 | 20 | /** 21 | * 交易是否成功 22 | */ 23 | public function isSuccess(): bool 24 | { 25 | return $this->status() === 'SUCCESS'; 26 | } 27 | 28 | /** 29 | * 交易是否失敗 30 | */ 31 | public function isFail(): bool 32 | { 33 | return $this->status() !== 'SUCCESS'; 34 | } 35 | 36 | /** 37 | * 敘述此次交易狀態 38 | */ 39 | public function message(): string 40 | { 41 | return $this->data['Message']; 42 | } 43 | 44 | /** 45 | * 回傳參數 46 | */ 47 | public function result(): array 48 | { 49 | return $this->data['Result'] ?? []; 50 | } 51 | 52 | /** 53 | * 商店訂單編號 54 | */ 55 | public function merchantOrderNo(): string 56 | { 57 | return $this->result()['MerOrderNo']; 58 | } 59 | 60 | /** 61 | * 委託單號 62 | */ 63 | public function periodNo(): string 64 | { 65 | return $this->result()['PeriodNo']; 66 | } 67 | 68 | /** 69 | * 委託狀態 70 | */ 71 | public function periodStatus(): PeriodStatus 72 | { 73 | return PeriodStatus::from($this->result()['AlterType']); 74 | } 75 | 76 | /** 77 | * 委託下一次授權日期 78 | */ 79 | public function newNextTime(): string 80 | { 81 | return $this->result()['NewNextTime']; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Results/QueryCreditResult.php: -------------------------------------------------------------------------------- 1 | '台灣發卡機構核發之信用卡', 12 | 'FOREIGN' => '國外發卡機構核發之卡', 13 | 'NTCB' => '國民旅遊卡', 14 | 'UNIONPAY' => '銀聯卡', 15 | 'APPLEPAY' => 'ApplePay', 16 | 'GOOGLEPAY' => 'GooglePay', 17 | 'SAMSUNGPAY' => 'SamsungPay', 18 | ]; 19 | 20 | /** 21 | * 收單金融機構中英文名稱對照 22 | */ 23 | protected $authBanks = [ 24 | 'Esun' => '玉山銀行', 25 | 'Taishin' => '台新銀行', 26 | 'CTBC' => '中國信託銀行', 27 | 'NCCC' => '聯合信用卡中心', 28 | 'CathayBK' => '國泰世華銀行', 29 | 'Citibank' => '花旗銀行', 30 | 'UBOT' => '聯邦銀行', 31 | 'SKBank' => '新光銀行', 32 | 'Fubon' => '富邦銀行', 33 | 'FirstBank' => '第一銀行', 34 | ]; 35 | 36 | /** 37 | * 金融機構回應碼 38 | */ 39 | public function respondCode(): ?string 40 | { 41 | return $this->data['RespondCode'] ?? null; 42 | } 43 | 44 | /** 45 | * 授權碼 46 | */ 47 | public function auth(): ?string 48 | { 49 | return $this->data['Auth'] ?? null; 50 | } 51 | 52 | /** 53 | * ECI 值 54 | * 55 | * 3D 回傳值 eci=1,2,5,6,代表為 3D 交易。 56 | */ 57 | public function ECI(): ?string 58 | { 59 | return $this->data['ECI'] ?? null; 60 | } 61 | 62 | /** 63 | * 請款金額 64 | */ 65 | public function closeAmt(): int 66 | { 67 | return $this->data['CloseAmt']; 68 | } 69 | 70 | /** 71 | * 請款狀態 72 | * 73 | * * **0**: 未請款 74 | * * **1**: 等待提送請款至收單機構 75 | * * **2**: 請款處理中 76 | * * **3**: 請款完成 77 | */ 78 | public function closeStatus(): int 79 | { 80 | return $this->data['CloseStatus']; 81 | } 82 | 83 | /** 84 | * 可退款餘額 85 | * 86 | * 1. 若此筆交易未發動退款,則本欄位回傳值為可退款金額 87 | * 2. 若此筆交易已發動退款,則本欄位回傳值為可退款餘額 88 | */ 89 | public function backBalance(): int 90 | { 91 | return $this->data['BackBalance']; 92 | } 93 | 94 | /** 95 | * 退款狀態 96 | * 97 | * * **0**: 未退款 98 | * * **1**: 等待提送退款至收單機構 99 | * * **2**: 退款處理中 100 | * * **3**: 退款完成 101 | */ 102 | public function backStatus(): int 103 | { 104 | return $this->data['BackStatus']; 105 | } 106 | 107 | /** 108 | * 授權結果訊息 109 | * 110 | * 銀行回覆此次信用卡授權結果狀態 111 | */ 112 | public function respondMsg(): string 113 | { 114 | return $this->data['RespondMsg']; 115 | } 116 | 117 | /** 118 | * 分期-期別 119 | */ 120 | public function inst(): int 121 | { 122 | return $this->data['Inst']; 123 | } 124 | 125 | /** 126 | * 分期-首期金額 127 | */ 128 | public function instFirst(): int 129 | { 130 | return $this->data['InstFirst']; 131 | } 132 | 133 | /** 134 | * 分期-每期金額 135 | */ 136 | public function instEach(): int 137 | { 138 | return $this->data['InstEach']; 139 | } 140 | 141 | /** 142 | * 交易類別 143 | * 144 | * * **CREDIT**: 台灣發卡機構核發之信用卡 145 | * * **FOREIGN**: 國外發卡機構核發之卡 146 | * * **NTCB**: 國民旅遊卡 147 | * * **UNIONPAY**: 銀聯卡 148 | * * **APPLEPAY**: ApplePay 149 | * * **GOOGLEPAY**: GooglePay 150 | * * **SAMSUNGPAY**: SamsungPay 151 | */ 152 | public function paymentMethod(): string 153 | { 154 | return $this->data['PaymentMethod']; 155 | } 156 | 157 | /** 158 | * 交易類別中文名稱 159 | */ 160 | public function paymentMethodName(): string 161 | { 162 | return $this->paymentMethods[$this->data['PaymentMethod']] ?? $this->data['PaymentMethod']; 163 | } 164 | 165 | /** 166 | * 卡號前六碼 167 | */ 168 | public function card6No(): string 169 | { 170 | return $this->data['Card6No']; 171 | } 172 | 173 | /** 174 | * 卡號末四碼 175 | */ 176 | public function card4No(): string 177 | { 178 | return $this->data['Card4No']; 179 | } 180 | 181 | /** 182 | * 收單金融機構 183 | * 184 | * * **Esun**: 玉山銀行 185 | * * **Taishin**: 台新銀行 186 | * * **CTBC**: 中國信託銀行 187 | * * **NCCC**: 聯合信用卡中心 188 | * * **CathayBK**: 國泰世華銀行 189 | * * **Citibank**: 花旗銀行 190 | * * **UBOT**: 聯邦銀行 191 | * * **SKBank**: 新光銀行 192 | * * **Fubon**: 富邦銀行 193 | * * **FirstBank**: 第一銀行 194 | */ 195 | public function authBank(): string 196 | { 197 | return $this->data['AuthBank']; 198 | } 199 | 200 | /** 201 | * 收單金融機構中文名稱 202 | */ 203 | public function authBankName(): string 204 | { 205 | return $this->authBanks[$this->data['AuthBank']] ?? $this->data['AuthBank']; 206 | } 207 | 208 | /** 209 | * Define the data keys. 210 | */ 211 | protected function dataKeys(): array 212 | { 213 | return [ 214 | 'RespondCode', 215 | 'Auth', 216 | 'ECI', 217 | 'CloseAmt', 218 | 'CloseStatus', 219 | 'BackBalance', 220 | 'BackStatus', 221 | 'RespondMsg', 222 | 'Inst', 223 | 'InstFirst', 224 | 'InstEach', 225 | 'PaymentMethod', 226 | 'Card6No', 227 | 'Card4No', 228 | 'AuthBank', 229 | ]; 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /src/Results/QueryDigitalWalletResult.php: -------------------------------------------------------------------------------- 1 | 'LINE Pay 付款', 12 | 'ESUNWALLET' => '玉山 Wallet', 13 | 'TAIWANPAY' => '台灣 Pay ', 14 | ]; 15 | 16 | /** 17 | * 收單金融機構中英文名稱對照 18 | */ 19 | protected $authBanks = [ 20 | 'Linepay' => 'LINE Pay', 21 | 'Esun' => '玉山銀行', 22 | ]; 23 | 24 | /** 25 | * 金融機構回應碼 26 | */ 27 | public function respondCode(): ?string 28 | { 29 | return $this->data['RespondCode'] ?? null; 30 | } 31 | 32 | /** 33 | * 請款金額 34 | */ 35 | public function closeAmt(): int 36 | { 37 | return $this->data['CloseAmt']; 38 | } 39 | 40 | /** 41 | * 請款狀態 42 | * 43 | * * **0**: 未請款 44 | * * **1**: 請款申請中 (等待提送請款檔至收單機構) 45 | * * **2**: 請款處理中 46 | * * **3**: 請款完成 47 | * * **4**: 請款失敗 48 | */ 49 | public function closeStatus(): string 50 | { 51 | return $this->data['CloseStatus']; 52 | } 53 | 54 | /** 55 | * 可退款餘額 56 | * 57 | * 1. 若此筆交易未發動退款,則本欄位回傳值為可退款金額 58 | * 2. 若此筆交易已發動退款,則本欄位回傳值為可退款餘額 59 | * 3. 目前不支援 LINE Pay 60 | */ 61 | public function backBalance(): int 62 | { 63 | return $this->data['BackBalance']; 64 | } 65 | 66 | /** 67 | * 退款狀態 68 | * 69 | * * **0**: 未退款 70 | * * **1**: 退款申請中 (等待提送退款至收單機構) 71 | * * **2**: 退款處理中 72 | * * **3**: 退款完成 73 | * * **4**: 退款失敗 74 | */ 75 | public function backStatus(): string 76 | { 77 | return $this->data['BackStatus']; 78 | } 79 | 80 | /** 81 | * 授權結果訊息 82 | * 83 | * 銀行回覆此次電子錢包授權結果狀態 84 | */ 85 | public function respondMsg(): string 86 | { 87 | return $this->data['RespondMsg']; 88 | } 89 | 90 | /** 91 | * 交易類別 92 | * 93 | * * **LINEPAY**: LINE Pay 付款 94 | * * **ESUNWALLET**: 玉山 Wallet 95 | * * **TAIWANPAY**: 台灣 Pay 96 | */ 97 | public function paymentMethod(): string 98 | { 99 | return $this->data['PaymentMethod']; 100 | } 101 | 102 | /** 103 | * 交易類別中文名稱 104 | */ 105 | public function paymentMethodName(): string 106 | { 107 | return $this->paymentMethods[$this->data['PaymentMethod']] ?? $this->data['PaymentMethod']; 108 | } 109 | 110 | /** 111 | * 收單金融機構 112 | * 113 | * * **Linepay**: LINE Pay 114 | * * **Esun**: 玉山銀行 115 | */ 116 | public function authBank(): string 117 | { 118 | return $this->data['AuthBank']; 119 | } 120 | 121 | /** 122 | * 收單金融機構中文名稱 123 | */ 124 | public function authBankName(): string 125 | { 126 | return $this->authBanks[$this->data['AuthBank']] ?? $this->data['AuthBank']; 127 | } 128 | 129 | /** 130 | * Define the data keys. 131 | */ 132 | protected function dataKeys(): array 133 | { 134 | return [ 135 | 'RespondCode', 136 | 'CloseAmt', 137 | 'CloseStatus', 138 | 'BackBalance', 139 | 'BackStatus', 140 | 'RespondMsg', 141 | 'PaymentMethod', 142 | 'AuthBank', 143 | ]; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/Results/QueryLgsResult.php: -------------------------------------------------------------------------------- 1 | data['StoreCode']; 13 | } 14 | 15 | /** 16 | * 取貨門市中文名稱 17 | */ 18 | public function storeName() 19 | { 20 | return $this->data['StoreName']; 21 | } 22 | 23 | /** 24 | * 超商類別名稱 25 | * 26 | * * **全家** 27 | * * **統一** 28 | * * **萊爾富** 29 | * * **OK mart** 30 | */ 31 | public function storeType() 32 | { 33 | return $this->data['StoreType']; 34 | } 35 | 36 | /** 37 | * 物流訂單編號 38 | */ 39 | public function lgsNo() 40 | { 41 | return $this->data['LgsNo']; 42 | } 43 | 44 | /** 45 | * 物流型態 46 | * 47 | * * **B2C**: 大宗寄倉 48 | * * **C2C**: 店到店 49 | */ 50 | public function lgsType() 51 | { 52 | return $this->data['LgsType']; 53 | } 54 | 55 | /** 56 | * Define the data keys. 57 | */ 58 | protected function dataKeys(): array 59 | { 60 | return [ 61 | 'StoreType', 62 | 'StoreCode', 63 | 'StoreName', 64 | 'LgsNo', 65 | 'LgsType', 66 | ]; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Results/QueryPaymentStatusResult.php: -------------------------------------------------------------------------------- 1 | data['PayInfo']; 17 | } 18 | 19 | /** 20 | * 繳費有效期限 21 | */ 22 | public function ExpireDate(): string 23 | { 24 | return $this->data['ExpireDate']; 25 | } 26 | 27 | /** 28 | * 交易狀態 29 | * 30 | * * **0**: 未付款 31 | * * **1**: 已付款 32 | * * **2**: 訂單失敗 33 | * * **3**: 訂單取消 34 | * * **6**: 已退款 35 | * * **9**: 付款中,待銀行確認 36 | */ 37 | public function OrderStatus(): int 38 | { 39 | return $this->data['OrderStatus']; 40 | } 41 | 42 | /** 43 | * Define the data keys. 44 | */ 45 | protected function dataKeys(): array 46 | { 47 | return [ 48 | 'PayInfo', 49 | 'ExpireDate', 50 | 'OrderStatus', 51 | ]; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Results/QueryResult.php: -------------------------------------------------------------------------------- 1 | data = $this->transformData($data); 22 | $this->hashKey = $hashKey; 23 | $this->hashIV = $hashIV; 24 | } 25 | 26 | /** 27 | * 查詢狀態 28 | * 29 | * 1. 若查詢成功,則回傳 SUCCESS。 30 | * 2. 若查詢失敗,則回傳錯誤代碼。 31 | */ 32 | public function status(): string 33 | { 34 | return $this->data['Status']; 35 | } 36 | 37 | /** 38 | * 查詢是否成功 39 | */ 40 | public function isSuccess(): bool 41 | { 42 | return $this->status() === 'SUCCESS'; 43 | } 44 | 45 | /** 46 | * 查詢是否失敗 47 | */ 48 | public function isFail(): bool 49 | { 50 | return $this->status() !== 'SUCCESS'; 51 | } 52 | 53 | /** 54 | * 敘述此次查詢狀態 55 | */ 56 | public function message(): string 57 | { 58 | return $this->data['Message']; 59 | } 60 | 61 | /** 62 | * 回傳參數 63 | */ 64 | public function result(): array 65 | { 66 | return $this->data['Result'] ?? []; 67 | } 68 | 69 | /** 70 | * 藍新金流商店代號 71 | */ 72 | public function merchantId(): string 73 | { 74 | return $this->result()['MerchantID']; 75 | } 76 | 77 | /** 78 | * 交易金額 79 | */ 80 | public function amt(): int 81 | { 82 | return $this->result()['Amt']; 83 | } 84 | 85 | /** 86 | * 藍新金流交易序號 87 | */ 88 | public function tradeNo(): string 89 | { 90 | return $this->result()['TradeNo']; 91 | } 92 | 93 | /** 94 | * 商店訂單編號 95 | */ 96 | public function merchantOrderNo(): string 97 | { 98 | return $this->result()['MerchantOrderNo']; 99 | } 100 | 101 | /** 102 | * 支付狀態 103 | * 104 | * * **0**: 未付款 105 | * * **1**: 付款成功 106 | * * **2**: 付款失敗 107 | * * **3**: 取消付款 108 | * * **6**: 退款 109 | */ 110 | public function tradeStatus(): string 111 | { 112 | return $this->result()['TradeStatus']; 113 | } 114 | 115 | /** 116 | * 支付方式 117 | * 118 | * * **CREDIT**: 信用卡付款 119 | * * **VACC**: 銀行 ATM 轉帳付款 120 | * * **WEBATM**: 網路銀行轉帳付款 121 | * * **BARCODE**: 超商條碼繳費 122 | * * **CVS**: 超商代碼繳費 123 | * * **LINEPAY**: LINE Pay 付款 124 | * * **ESUNWALLET**: 玉山 Wallet 125 | * * **TAIWANPAY**: 台灣 Pay 126 | * * **CVSCOM**: 超商取貨付款 127 | */ 128 | public function paymentType(): string 129 | { 130 | return $this->result()['PaymentType']; 131 | } 132 | 133 | /** 134 | * 交易建立時間 135 | */ 136 | public function createTime(): string 137 | { 138 | return $this->result()['CreateTime']; 139 | } 140 | 141 | /** 142 | * 支付完成時間 143 | */ 144 | public function payTime(): string 145 | { 146 | return $this->result()['PayTime']; 147 | } 148 | 149 | /** 150 | * 檢核碼 151 | */ 152 | public function checkCode() 153 | { 154 | return $this->result()['CheckCode']; 155 | } 156 | 157 | /** 158 | * 驗證資料有沒有被竄改 159 | */ 160 | public function verify(): bool 161 | { 162 | return $this->verifyCheckCode($this->checkCode(), [ 163 | 'MerchantID' => $this->merchantId(), 164 | 'Amt' => $this->amt(), 165 | 'MerchantOrderNo' => $this->merchantOrderNo(), 166 | 'TradeNo' => $this->tradeNo(), 167 | ], $this->hashKey, $this->hashIV); 168 | } 169 | 170 | /** 171 | * 預計撥款日 172 | */ 173 | public function fundTime(): string 174 | { 175 | return $this->result()['FundTime']; 176 | } 177 | 178 | /** 179 | * 實際交易商店代號 180 | */ 181 | public function shopMerchantId(): ?string 182 | { 183 | return $this->result()['ShopMerchantID'] ?? null; 184 | } 185 | 186 | /** 187 | * 信用卡交易回傳(國外卡、國旅卡、ApplePay、GooglePay、SamsungPay) 188 | */ 189 | public function credit(): QueryCreditResult 190 | { 191 | return new QueryCreditResult($this->result()); 192 | } 193 | 194 | /** 195 | * 超商代碼、超商條碼、超商取貨付款、LINE Pay、ATM、WebATM 回傳 196 | */ 197 | public function paymentStatus(): QueryPaymentStatusResult 198 | { 199 | return new QueryPaymentStatusResult($this->result()); 200 | } 201 | 202 | /** 203 | * 超商取貨付款回傳 204 | */ 205 | public function lgs(): QueryLgsResult 206 | { 207 | return new QueryLgsResult($this->result()); 208 | } 209 | 210 | /** 211 | * 電子錢包(LINE Pay、玉山 Wallet、台灣 Pay) 212 | */ 213 | public function digitalWallet(): QueryDigitalWalletResult 214 | { 215 | return new QueryDigitalWalletResult($this->result()); 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /src/Results/Result.php: -------------------------------------------------------------------------------- 1 | data = $this->transformData($data); 15 | } 16 | 17 | /** 18 | * The result data. 19 | */ 20 | public function data(): array 21 | { 22 | return $this->data; 23 | } 24 | 25 | /** 26 | * Transform the input data. 27 | */ 28 | protected function transformData(array $data): array 29 | { 30 | $keys = $this->dataKeys(); 31 | 32 | if (count($keys)) { 33 | return collect($data) 34 | ->only($keys) 35 | ->all(); 36 | } 37 | 38 | return $data; 39 | } 40 | 41 | /** 42 | * Define the data keys. 43 | */ 44 | protected function dataKeys(): array 45 | { 46 | return []; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Senders/BackgroundSender.php: -------------------------------------------------------------------------------- 1 | $data, 23 | 'verify' => false, 24 | ]; 25 | 26 | $result = json_decode($this->http->post($url, $parameter)->getBody(), true); 27 | 28 | return $result; 29 | } 30 | 31 | /** 32 | * Set the http client instance. 33 | */ 34 | public function setHttp(Client $client) 35 | { 36 | $this->http = $client; 37 | 38 | return $this; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Senders/FrontendSender.php: -------------------------------------------------------------------------------- 1 |
'; 15 | 16 | foreach ($request as $key => $value) { 17 | $result .= ''; 18 | } 19 | 20 | $result .= '
'; 21 | 22 | return $result; 23 | } 24 | } 25 | --------------------------------------------------------------------------------