├── .github
├── FUNDING.yml
└── workflows
│ └── tests.yml
├── src
├── Contracts
│ ├── Sender.php
│ └── Httpable.php
├── Enums
│ ├── PeriodStatus.php
│ ├── PeriodStartType.php
│ ├── Bank.php
│ ├── CreditRememberDemand.php
│ ├── PeriodType.php
│ ├── CVSCOM.php
│ ├── CreditInst.php
│ ├── LgsType.php
│ └── NTCBLocate.php
├── Results
│ ├── MPGTaiwanPayResult.php
│ ├── CustomerStoreCodeResult.php
│ ├── CustomerATMResult.php
│ ├── MPGEsunWalletResult.php
│ ├── MPGATMResult.php
│ ├── Concerns
│ │ └── HasVerifyCheckCode.php
│ ├── CustomerStoreBarcodeResult.php
│ ├── Result.php
│ ├── QueryPaymentStatusResult.php
│ ├── QueryLgsResult.php
│ ├── MPGStoreCodeResult.php
│ ├── CloseResult.php
│ ├── PeriodStatusResult.php
│ ├── MPGEzPayResult.php
│ ├── MPGStoreBarcodeResult.php
│ ├── MPGLgsResult.php
│ ├── CustomerLgsResult.php
│ ├── PeriodAmtResult.php
│ ├── CancelResult.php
│ ├── CustomerResult.php
│ ├── QueryDigitalWalletResult.php
│ ├── PeriodNotifyResult.php
│ ├── MPGResult.php
│ ├── QueryResult.php
│ ├── QueryCreditResult.php
│ ├── PeriodResult.php
│ └── MPGCreditResult.php
├── Exceptions
│ └── NewebpayDecodeFailException.php
├── NewebPayPeriodResult.php
├── NewebPayPeriodNotify.php
├── NewebPayResult.php
├── NewebPayCustomer.php
├── Concerns
│ ├── WithSessionIdKey.php
│ ├── HasSender.php
│ └── HasEncryption.php
├── Senders
│ ├── FrontendSender.php
│ └── BackgroundSender.php
├── NewebPayServiceProvider.php
├── NewebPay.php
├── NewebPayRequest.php
├── Facades
│ └── NewebPay.php
├── NewebPayCancel.php
├── NewebPayPeriodStatus.php
├── NewebPayQuery.php
├── NewebPayClose.php
├── NewebPayPeriodAmt.php
├── Factory.php
├── NewebPayPeriod.php
└── NewebPayMPG.php
├── LICENSE
├── composer.json
├── config
└── newebpay.php
└── README.md
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | patreon: ycs77
2 |
--------------------------------------------------------------------------------
/src/Contracts/Sender.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/Enums/LgsType.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/Exceptions/NewebpayDecodeFailException.php:
--------------------------------------------------------------------------------
1 | decode($request->input('Period'));
18 |
19 | return new PeriodResult($data);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/NewebPayPeriodNotify.php:
--------------------------------------------------------------------------------
1 | decode($request->input('Period'));
18 |
19 | return new PeriodNotifyResult($data);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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/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/Senders/FrontendSender.php:
--------------------------------------------------------------------------------
1 |
';
21 |
22 | return $result;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/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/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/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/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 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 wallase
4 | Copyright (c) 2020-present Lucas Yang
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 |
--------------------------------------------------------------------------------
/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/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/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/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/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/Enums/NTCBLocate.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 |
--------------------------------------------------------------------------------
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
1 | name: tests
2 |
3 | on:
4 | push:
5 | branches: [1.x]
6 | pull_request:
7 | branches: [1.x]
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, 8.4]
17 | laravel: [9.*, 10.*, 11.*, 12.*]
18 | exclude:
19 | - php: 8.3
20 | laravel: 9.*
21 | - php: 8.4
22 | laravel: 9.*
23 | - php: 8.4
24 | laravel: 10.*
25 | - php: 8.1
26 | laravel: 11.*
27 | - php: 8.1
28 | laravel: 12.*
29 |
30 | name: P${{ matrix.php }} - L${{ matrix.laravel }}
31 |
32 | steps:
33 | - name: Checkout code
34 | uses: actions/checkout@v4
35 |
36 | - name: Setup PHP
37 | uses: shivammathur/setup-php@v2
38 | with:
39 | php-version: ${{ matrix.php }}
40 | extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, mysql, mysqli, pdo_mysql, bcmath, intl, gd, exif, iconv, imagick, fileinfo
41 | coverage: none
42 |
43 | - name: Setup problem matchers
44 | run: |
45 | echo "::add-matcher::${{ runner.tool_cache }}/php.json"
46 | echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
47 |
48 | - name: Install dependencies
49 | run: |
50 | composer require "laravel/framework:${{ matrix.laravel }}" --no-interaction --no-update
51 | composer update --prefer-stable --prefer-dist --no-interaction
52 |
53 | - name: Execute tests
54 | run: vendor/bin/pest
55 |
--------------------------------------------------------------------------------
/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/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/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/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 |
--------------------------------------------------------------------------------
/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.36.0 || ^3.8.2"
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 |
--------------------------------------------------------------------------------
/src/Facades/NewebPay.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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/Factory.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/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 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 |
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 |
101 |
105 |
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 |
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 |
550 |
554 |
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 |
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=1.x&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%3A1.x
814 | [link-style-ci]: https://github.styleci.io/repos/262404477
815 | [link-downloads]: https://packagist.org/packages/ycs77/laravel-newebpay
816 |
--------------------------------------------------------------------------------