├── .gitignore
├── .styleci.yml
├── src
├── Contracts
│ ├── HTTPClient.php
│ └── HTTPSender.php
├── Sender
│ ├── Sync.php
│ └── Async.php
├── NewebPayQuery.php
├── NewebPayMPG.php
├── NewebPayCancel.php
├── NewebPayClose.php
├── Traits
│ ├── HasSender.php
│ ├── Encryption.php
│ └── Trade.php
├── BaseNewebPay.php
└── NewebPay.php
├── composer.json
├── LICENSE
├── tests
├── NewebPayCloseTest.php
├── NewebPayCancelTest.php
├── NewebPayQueryTest.php
├── TestCase.php
├── NewebPayMPGTest.php
└── NewebPayTest.php
├── README.md
└── README-en.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .phpunit.result.cache
3 | example
4 | composer.lock
5 | /vendor
6 | .DS_Store
7 | /.vscode
8 | /build/coverage-report
9 | phpunit.xml
10 | *.cache
--------------------------------------------------------------------------------
/.styleci.yml:
--------------------------------------------------------------------------------
1 | risky: false
2 | version: 8.1
3 | preset: recommended
4 | finder:
5 | exclude:
6 | - "modules"
7 | - "node_modules"
8 | - "nova"
9 | - "nova-components"
10 | - "storage"
11 | - "spark"
12 | - "vendor"
13 | name: "*.php"
14 | not-name:
15 | - "*.blade.php"
16 | - "_ide_helper.php"
--------------------------------------------------------------------------------
/src/Contracts/HTTPClient.php:
--------------------------------------------------------------------------------
1 | ';
20 |
21 | foreach ($request as $key => $value) {
22 | $result .= '';
23 | }
24 |
25 | $result .= '';
26 |
27 | return $result;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "xup6m6fu04/newebpay-sdk-php",
3 | "description": "A library of connecting newebpay API service.",
4 | "type": "library",
5 | "authors": [
6 | {
7 | "name": "xup6m6fu04",
8 | "email": "sarah82529@gmail.com"
9 | }
10 | ],
11 | "require": {
12 | "php": "^7.2.5 || ^8.0",
13 | "guzzlehttp/guzzle": "^7.5",
14 | "nesbot/carbon": "^2.66",
15 | "ext-openssl": "*",
16 | "ext-json": "*"
17 | },
18 | "require-dev": {
19 | "phpunit/phpunit": ">=8"
20 | },
21 | "license": "MIT",
22 | "autoload": {
23 | "psr-4": {
24 | "Xup6m6fu04\\NewebPay\\": "src/"
25 | }
26 | },
27 | "autoload-dev": {
28 | "psr-4": {
29 | "Xup6m6fu04\\NewebPay\\Tests\\": "tests/"
30 | }
31 | },
32 | "config": {
33 | "platform-check": false
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright: (c) 2020-present Lucas Yang
4 | (c) 2019 wallase
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
--------------------------------------------------------------------------------
/src/NewebPayQuery.php:
--------------------------------------------------------------------------------
1 | setApiPath('API/QueryTradeInfo');
17 | $this->setAsyncSender();
18 |
19 | $this->CheckValues['MerchantID'] = $this->MerchantID;
20 | }
21 |
22 | public function setQuery($no, $amt): NewebPayQuery
23 | {
24 | $this->CheckValues['MerchantOrderNo'] = $no;
25 | $this->CheckValues['Amt'] = $amt;
26 |
27 | return $this;
28 | }
29 |
30 | /**
31 | * Get request data.
32 | *
33 | * @return array
34 | */
35 | public function getRequestData(): array
36 | {
37 | $CheckValue = $this->queryCheckValue($this->CheckValues, $this->HashKey, $this->HashIV);
38 |
39 | return [
40 | 'MerchantID' => $this->MerchantID,
41 | 'Version' => $this->configs['Version'],
42 | 'RespondType' => $this->configs['RespondType'],
43 | 'CheckValue' => $CheckValue,
44 | 'TimeStamp' => $this->timestamp,
45 | 'MerchantOrderNo' => $this->CheckValues['MerchantOrderNo'],
46 | 'Amt' => $this->CheckValues['Amt'],
47 | ];
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Sender/Async.php:
--------------------------------------------------------------------------------
1 | http = $client;
29 | }
30 |
31 | /**
32 | * Send the data to API.
33 | *
34 | * @param array $request
35 | * @param string $url
36 | *
37 | * @throws GuzzleException
38 | *
39 | * @return mixed
40 | */
41 | public function send(array $request, string $url)
42 | {
43 | $parameter = [
44 | 'form_params' => $request,
45 | 'verify' => false,
46 | ];
47 |
48 | return json_decode($this->http->post($url, $parameter)->getBody(), true);
49 | }
50 |
51 | /**
52 | * Set mock http client instance.
53 | *
54 | * @param Client $client
55 | *
56 | * @return $this
57 | */
58 | public function setHttp(Client $client): Async
59 | {
60 | $this->http = $client;
61 |
62 | return $this;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/NewebPayMPG.php:
--------------------------------------------------------------------------------
1 | setApiPath('MPG/mpg_gateway');
15 | $this->setSyncSender();
16 |
17 | $this->setLangType();
18 | $this->setTradeLimit();
19 | $this->setExpireDate();
20 | $this->setReturnURL();
21 | $this->setNotifyURL();
22 | $this->setCustomerURL();
23 | $this->setClientBackURL();
24 | $this->setEmailModify();
25 | $this->setLoginType();
26 | $this->setOrderComment();
27 | $this->setPaymentMethod();
28 | $this->setTokenTerm();
29 | $this->setCVSCOM();
30 | $this->setLgsType();
31 |
32 | $this->TradeData['MerchantID'] = $this->MerchantID;
33 | }
34 |
35 | /**
36 | * Get request data.
37 | *
38 | * @return array
39 | */
40 | public function getRequestData(): array
41 | {
42 | $tradeInfo = $this->encryptDataByAES($this->TradeData, $this->HashKey, $this->HashIV);
43 | $tradeSha = $this->encryptDataBySHA($tradeInfo, $this->HashKey, $this->HashIV);
44 |
45 | return [
46 | 'MerchantID' => $this->MerchantID,
47 | 'TradeInfo' => $tradeInfo,
48 | 'TradeSha' => $tradeSha,
49 | 'Version' => $this->TradeData['Version'],
50 | ];
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/NewebPayCancel.php:
--------------------------------------------------------------------------------
1 | setApiPath('API/CreditCard/Cancel');
15 | $this->setAsyncSender();
16 |
17 | $this->setNotifyURL();
18 | }
19 |
20 | /**
21 | * 設定取消授權的模式.
22 | *
23 | * @param string $no
24 | * @param int $amt
25 | * @param string $type
26 | * 'order': 使用商店訂單編號
27 | * 'trade': 使用藍新金流交易序號
28 | *
29 | * @return $this
30 | */
31 | public function setCancelOrder(
32 | string $no,
33 | int $amt,
34 | string $type = 'order'
35 | ): NewebPayCancel {
36 | if ($type === 'order') {
37 | $this->TradeData['MerchantOrderNo'] = $no;
38 | $this->TradeData['IndexType'] = 1;
39 | } elseif ($type === 'trade') {
40 | $this->TradeData['TradeNo'] = $no;
41 | $this->TradeData['IndexType'] = 2;
42 | }
43 |
44 | $this->TradeData['Amt'] = $amt;
45 |
46 | return $this;
47 | }
48 |
49 | /**
50 | * Get request data.
51 | *
52 | * @return array
53 | */
54 | public function getRequestData(): array
55 | {
56 | $postData = $this->encryptDataByAES(
57 | $this->TradeData,
58 | $this->HashKey,
59 | $this->HashIV
60 | );
61 |
62 | return [
63 | 'MerchantID_' => $this->MerchantID,
64 | 'PostData_' => $postData,
65 | ];
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/tests/NewebPayCloseTest.php:
--------------------------------------------------------------------------------
1 | createMockConfig());
14 |
15 | $this->assertEquals('https://ccore.newebpay.com/API/CreditCard/Close', $newebpay->getUrl());
16 | }
17 |
18 | public function testNewebPayCloseSenderIsSync()
19 | {
20 | $newebpay = new NewebPayClose($this->createMockConfig());
21 |
22 | $this->assertInstanceOf(Async::class, $newebpay->getSender());
23 | }
24 |
25 | public function testNewebPayCloseGetRequestData()
26 | {
27 | $this->setTestNow();
28 |
29 | $newebpay = new NewebPayClose($this->createMockConfig());
30 |
31 | $requestData = $newebpay->getRequestData();
32 |
33 | $this->assertEquals('TestMerchantID1234', $requestData['MerchantID_']);
34 | $this->assertEquals('e88e33cc07d106bcba1c1bd02d5d421fa9f86ef5a1469c0e801b3813b360f8333fd9fef8bf7312a3e5e66e1f6b5601b6c2ad3875eb127ca33809ddd77de94550', $requestData['PostData_']);
35 | }
36 |
37 | public function testNewebPayCloseSubmit()
38 | {
39 | $this->setTestNow();
40 |
41 | $newebpay = new NewebPayClose($this->createMockConfig());
42 |
43 | $result = $newebpay
44 | ->setCloseOrder('TestNo123456', 100, 'order')
45 | ->setMockHttp([
46 | new Response(200, [], '{"Status":"Code001","Message":"Test message.","Result":[]}'),
47 | ])
48 | ->submit();
49 |
50 | $this->assertEquals([
51 | 'Status' => 'Code001',
52 | 'Message' => 'Test message.',
53 | 'Result' => [],
54 | ], $result);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tests/NewebPayCancelTest.php:
--------------------------------------------------------------------------------
1 | createMockConfig());
14 |
15 | $this->assertEquals('https://ccore.newebpay.com/API/CreditCard/Cancel', $newebpay->getUrl());
16 | }
17 |
18 | public function testNewebPayCancelSenderIsSync()
19 | {
20 | $newebpay = new NewebPayCancel($this->createMockConfig());
21 |
22 | $this->assertInstanceOf(Async::class, $newebpay->getSender());
23 | }
24 |
25 | public function testNewebPayCancelGetRequestData()
26 | {
27 | $this->setTestNow();
28 |
29 | $newebpay = new NewebPayCancel($this->createMockConfig());
30 |
31 | $requestData = $newebpay->getRequestData();
32 |
33 | $this->assertEquals('TestMerchantID1234', $requestData['MerchantID_']);
34 | $this->assertEquals('e88e33cc07d106bcba1c1bd02d5d421fa9f86ef5a1469c0e801b3813b360f8333fd9fef8bf7312a3e5e66e1f6b5601b6c2ad3875eb127ca33809ddd77de94550', $requestData['PostData_']);
35 | }
36 |
37 | public function testNewebPayCancelSubmit()
38 | {
39 | $this->setTestNow();
40 |
41 | $newebpay = new NewebPayCancel($this->createMockConfig());
42 |
43 | $result = $newebpay
44 | ->setCancelOrder('TestNo123456', 100, 'order')
45 | ->setMockHttp([
46 | new Response(200, [], '{"Status":"Code001","Message":"Test message.","Result":[]}'),
47 | ])
48 | ->submit();
49 |
50 | $this->assertEquals([
51 | 'Status' => 'Code001',
52 | 'Message' => 'Test message.',
53 | 'Result' => [],
54 | ], $result);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 藍新科技金流 API 專用 PHP SDK
2 |
3 | > Fork from [ycs77/laravel-newebpay](https://github.com/ycs77/laravel-newebpay)
4 |
5 | [](https://app.fossa.com/projects/git%2Bgithub.com%2Fxup6m6fu04%2Fnewebpay-sdk-php?ref=badge_small)
6 | [](https://github.styleci.io/repos/596413768?branch=master)
7 | [](https://opensource.org/licenses/MIT)
8 |
9 |
10 | ## 重要
11 |
12 | ### 此處為簡易文件說明,要閱讀完整的使用說明及範例詳細講解請參考
13 | https://github.com/xup6m6fu04/newebpay-example
14 |
15 | ## 說明
16 |
17 | 調整項目
18 | - 不限制於 Laravel 中使用
19 | - 更新支援至藍新金流最新版本
20 | - 搭配猴子都能懂的完整詳細說明
21 |
22 | 藍新金流官方文件:https://www.newebpay.com/website/Page/content/download_api
23 |
24 | 目前支援藍新金流 API 程式碼版本號:2.0
25 |
26 | 文件版本號:NDNF-1.0.6
27 |
28 | 目前支援功能
29 | - MPG 交易
30 | - 信用卡請款
31 | - 信用卡取消授權
32 | - 信用卡退款
33 | - 信用卡取消請款
34 | - 信用卡取消退款
35 |
36 | ## 需求
37 |
38 | 至少需要 PHP 7.2.5 或以上版本,也支援 PHP 8 以上版本
39 |
40 | ## 安裝 ##
41 |
42 | ```sh
43 | $ composer require xup6m6fu04/newebpay-sdk-php
44 | ```
45 |
46 | ## 簡易範例 ##
47 |
48 | ```php
49 | payment(
63 | $_POST['MerchantOrderNo'], // 訂單編號
64 | $_POST['Amt'], // 訂單金額
65 | $_POST['ItemDesc'], // 商品名稱
66 | $_POST['Email'] // 付款人電子信箱
67 | );
68 |
69 | // 要更改設定用 ->set + 屬性名稱 (ex: setReturnURL)
70 | $newebpay->setReturnURL(....); // 設定交易完成後的返回網址
71 |
72 | // 送出表單
73 | echo $newebpay->submit();
74 | ```
75 |
76 | ## Versioning
77 | This project respects semantic versioning.
78 |
79 | See http://semver.org/
80 |
81 | ## License
82 |
83 | [](https://app.fossa.com/projects/git%2Bgithub.com%2Fxup6m6fu04%2Fnewebpay-sdk-php?ref=badge_large)
84 |
--------------------------------------------------------------------------------
/tests/NewebPayQueryTest.php:
--------------------------------------------------------------------------------
1 | createMockConfig());
14 |
15 | $this->assertEquals('https://ccore.newebpay.com/API/QueryTradeInfo', $newebpay->getUrl());
16 | }
17 |
18 | public function testNewebPayQuerySenderIsSync()
19 | {
20 | $newebpay = new NewebPayQuery($this->createMockConfig());
21 |
22 | $this->assertInstanceOf(Async::class, $newebpay->getSender());
23 | }
24 |
25 | public function testNewebPayQueryGetRequestData()
26 | {
27 | $this->setTestNow();
28 |
29 | $newebpay = new NewebPayQuery($this->createMockConfig());
30 |
31 | $requestData = $newebpay
32 | ->setQuery('TestNo123456', 100)
33 | ->getRequestData();
34 |
35 | $this->assertEquals('TestMerchantID1234', $requestData['MerchantID']);
36 | $this->assertEquals('1.5', $requestData['Version']);
37 | $this->assertEquals('JSON', $requestData['RespondType']);
38 | $this->assertEquals('A314C865681049301D80A33318E5043B51425EAC58736E9ACF4FAC5854ABD59F', $requestData['CheckValue']);
39 | $this->assertEquals(1577836800, $requestData['TimeStamp']);
40 | $this->assertEquals('TestNo123456', $requestData['MerchantOrderNo']);
41 | $this->assertEquals(100, $requestData['Amt']);
42 | }
43 |
44 | public function testNewebPayQuerySubmit()
45 | {
46 | $this->setTestNow();
47 |
48 | $newebpay = new NewebPayQuery($this->createMockConfig());
49 |
50 | $result = $newebpay
51 | ->setQuery('TestNo123456', 100)
52 | ->setMockHttp([
53 | new Response(200, [], '{"Status":"Code001","Message":"Test message.","Result":[]}'),
54 | ])
55 | ->submit();
56 |
57 | $this->assertEquals([
58 | 'Status' => 'Code001',
59 | 'Message' => 'Test message.',
60 | 'Result' => [],
61 | ], $result);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/NewebPayClose.php:
--------------------------------------------------------------------------------
1 | setApiPath('API/CreditCard/Close');
15 | $this->setAsyncSender();
16 |
17 | $this->setNotifyURL();
18 | }
19 |
20 | /**
21 | * 設定請退款的模式.
22 | *
23 | * @param string $no
24 | * @param int $amt
25 | * @param string $type
26 | * 'order': 使用商店訂單編號
27 | * 'trade': 使用藍新金流交易序號
28 | *
29 | * @return $this
30 | */
31 | public function setCloseOrder(
32 | string $no,
33 | int $amt,
34 | string $type = 'order'
35 | ): NewebPayClose {
36 | if ($type === 'order') {
37 | $this->TradeData['MerchantOrderNo'] = $no;
38 | $this->TradeData['IndexType'] = 1;
39 | } elseif ($type === 'trade') {
40 | $this->TradeData['TradeNo'] = $no;
41 | $this->TradeData['IndexType'] = 2;
42 | }
43 |
44 | $this->TradeData['Amt'] = $amt;
45 |
46 | return $this;
47 | }
48 |
49 | /**
50 | * 設定請款或退款.
51 | *
52 | * @param string $type
53 | * 'pay': 請款
54 | * 'refund': 退款
55 | *
56 | * @return $this
57 | */
58 | public function setCloseType(string $type = 'pay'): NewebPayClose
59 | {
60 | if ($type === 'pay') {
61 | $this->TradeData['CloseType'] = 1;
62 | } elseif ($type === 'refund') {
63 | $this->TradeData['CloseType'] = 2;
64 | }
65 |
66 | return $this;
67 | }
68 |
69 | public function setCancel($isCancel = false): NewebPayClose
70 | {
71 | $this->TradeData['Cancel'] = $isCancel;
72 |
73 | return $this;
74 | }
75 |
76 | /**
77 | * Get request data.
78 | *
79 | * @return array
80 | */
81 | public function getRequestData(): array
82 | {
83 | $postData = $this->encryptDataByAES(
84 | $this->TradeData,
85 | $this->HashKey,
86 | $this->HashIV
87 | );
88 |
89 | return [
90 | 'MerchantID_' => $this->MerchantID,
91 | 'PostData_' => $postData,
92 | ];
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | mockConfigValues();
23 |
24 | return $this->config;
25 | }
26 |
27 | /**
28 | * @param $key
29 | * @param $returnValue
30 | */
31 | public function mockSetConfig($key, $returnValue)
32 | {
33 | $this->config[$key] = $returnValue;
34 | }
35 |
36 | public function mockConfigValues()
37 | {
38 | $this->mockSetConfig('Debug', true);
39 | $this->mockSetConfig('MerchantID', 'TestMerchantID1234');
40 | $this->mockSetConfig('HashKey', 'TestHashKey123456789');
41 | $this->mockSetConfig('HashIV', '17ef14e533ed1c18'); // Generate with `bin2hex(openssl_random_pseudo_bytes(8));`
42 | $this->mockSetConfig('Version', '1.5');
43 | $this->mockSetConfig('RespondType', 'JSON');
44 | $this->mockSetConfig('LangType', 'zh-tw');
45 | $this->mockSetConfig('TradeLimit', 0);
46 | $this->mockSetConfig('ExpireDate', 7);
47 | $this->mockSetConfig('ReturnURL', null);
48 | $this->mockSetConfig('NotifyURL', null);
49 | $this->mockSetConfig('CustomerURL', null);
50 | $this->mockSetConfig('ClientBackURL', null);
51 | $this->mockSetConfig('EmailModify', false);
52 | $this->mockSetConfig('LoginType', false);
53 | $this->mockSetConfig('OrderComment', null);
54 | $this->mockSetConfig('PaymentMethod', [
55 | 'CREDIT' => [
56 | 'Enable' => true,
57 | 'CreditRed' => false,
58 | 'InstFlag' => 0,
59 | ],
60 | 'ANDROIDPAY' => false,
61 | 'SAMSUNGPAY' => false,
62 | 'LINEPAY' => false,
63 | 'UNIONPAY' => false,
64 | 'WEBATM' => false,
65 | 'VACC' => false,
66 | 'CVS' => false,
67 | 'BARCODE' => false,
68 | 'ESUNWALLET' => false,
69 | 'TAIWANPAY' => false,
70 | 'EZPAY' => false,
71 | 'EZPWECHAT' => false,
72 | 'EZPALIPAY' => false,
73 | ]);
74 | $this->mockSetConfig('CVSCOM', null);
75 | $this->mockSetConfig('LgsType', null);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/Traits/HasSender.php:
--------------------------------------------------------------------------------
1 | sender = $sender;
32 |
33 | return $this;
34 | }
35 |
36 | /**
37 | * Get the sender instance.
38 | *
39 | * @return HTTPSender
40 | */
41 | public function getSender(): HTTPSender
42 | {
43 | return $this->sender;
44 | }
45 |
46 | /**
47 | * Set sync sender.
48 | *
49 | * @return $this
50 | */
51 | public function setSyncSender()
52 | {
53 | $this->setSender(new Sync());
54 |
55 | return $this;
56 | }
57 |
58 | /**
59 | * Set async sender.
60 | *
61 | * @return $this
62 | */
63 | public function setAsyncSender()
64 | {
65 | $this->setSender(new Async($this->createHttp()));
66 |
67 | return $this;
68 | }
69 |
70 | /**
71 | * Set mock http instance.
72 | *
73 | * @param $mockResponse
74 | *
75 | * @return $this
76 | */
77 | public function setMockHttp($mockResponse)
78 | {
79 | if ($this->sender instanceof HTTPClient) {
80 | if (!$mockResponse instanceof MockHandler) {
81 | $mockHandler = new MockHandler($mockResponse);
82 | }
83 |
84 | $this->sender->setHttp($this->createHttp($mockHandler));
85 | }
86 |
87 | return $this;
88 | }
89 |
90 | /**
91 | * Create http instance.
92 | *
93 | * @param MockHandler|null $mockHttpHandler
94 | *
95 | * @return Client
96 | */
97 | protected function createHttp(MockHandler $mockHttpHandler = null): Client
98 | {
99 | $attributes = [
100 | 'handler' => $mockHttpHandler ? HandlerStack::create($mockHttpHandler) : null,
101 | ];
102 |
103 | $attributes = array_filter($attributes, function ($value) {
104 | return $value !== null;
105 | });
106 |
107 | return new Client($attributes);
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/README-en.md:
--------------------------------------------------------------------------------
1 | # NewebPay Payment API PHP SDK
2 |
3 | > Forked from [ycs77/laravel-newebpay](https://github.com/ycs77/laravel-newebpay)
4 |
5 | [](https://app.fossa.com/projects/git%2Bgithub.com%2Fxup6m6fu04%2Fnewebpay-sdk-php?ref=badge_small)
6 | [](https://github.styleci.io/repos/596413768?branch=master)
7 | [](https://opensource.org/licenses/MIT)
8 |
9 |
10 | ## Important
11 |
12 | ### This document provides a brief overview. For a complete usage guide and detailed examples, please refer to:
13 | https://github.com/xup6m6fu04/newebpay-example
14 |
15 | ## Description
16 |
17 | Adjusted Items
18 | - Not restricted for use within Laravel
19 | - Updated to support the latest version of NewebPay
20 | - Comes with a detailed explanation that's easy to understand
21 |
22 | Official NewebPay Documentation: https://www.newebpay.com/website/Page/content/download_api
23 |
24 | Currently supports NewebPay API version: 2.0
25 |
26 | Document version: NDNF-1.0.6
27 |
28 | Currently supported features
29 | - MPG Transaction
30 | - Credit Card Billing
31 | - Credit Card Authorization Cancellation
32 | - Credit Card Refund
33 | - Credit Card Billing Cancellation
34 | - Credit Card Refund Cancellation
35 |
36 | ## Requirements
37 |
38 | Requires at least PHP 7.2.5 or above, also supports PHP 8 and above
39 |
40 | ## Installation
41 |
42 | ```sh
43 | $ composer require xup6m6fu04/newebpay-sdk-php
44 | ```
45 | ## Simple Example
46 |
47 | ```php
48 | payment(
62 | $_POST['MerchantOrderNo'], // Order Number
63 | $_POST['Amt'], // Order Amount
64 | $_POST['ItemDesc'], // Product Name
65 | $_POST['Email'] // Payer's Email
66 | );
67 |
68 | // To change the settings, use ->set + property name (ex: setReturnURL)
69 | $newebpay->setReturnURL(....); // Set the return URL after the transaction is completed
70 |
71 | // Submit the form
72 | echo $newebpay->submit();
73 | ```
74 |
75 |
76 | ## Versioning
77 | This project respects semantic versioning.
78 |
79 | See http://semver.org/
80 |
81 | ## License
82 |
83 | [](https://app.fossa.com/projects/git%2Bgithub.com%2Fxup6m6fu04%2Fnewebpay-sdk-php?ref=badge_large)
84 |
--------------------------------------------------------------------------------
/src/Traits/Encryption.php:
--------------------------------------------------------------------------------
1 | addPadding($postDataStr), 'AES-256-CBC', $hashKey, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $hashIV)));
21 | }
22 |
23 | /**
24 | * Decrypt data with AES.
25 | *
26 | * @param string $parameter
27 | * @param string $hashKey
28 | * @param string $hashIV
29 | *
30 | * @return string|false
31 | */
32 | protected function decryptDataByAES(string $parameter, string $hashKey, string $hashIV)
33 | {
34 | return $this->stripPadding(openssl_decrypt(hex2bin($parameter), 'AES-256-CBC', $hashKey, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $hashIV));
35 | }
36 |
37 | /**
38 | * Encrypt data with SHA.
39 | *
40 | * @param string $parameter
41 | * @param string $hashKey
42 | * @param string $hashIV
43 | *
44 | * @return string
45 | */
46 | protected function encryptDataBySHA(string $parameter, string $hashKey, string $hashIV): string
47 | {
48 | $postDataStr = 'HashKey='.$hashKey.'&'.$parameter.'&HashIV='.$hashIV;
49 |
50 | return strtoupper(hash('sha256', $postDataStr));
51 | }
52 |
53 | /**
54 | * Query check value.
55 | *
56 | * @param array $parameter
57 | * @param string $hashKey
58 | * @param string $hashIV
59 | *
60 | * @return string
61 | */
62 | protected function queryCheckValue(array $parameter, string $hashKey, string $hashIV): string
63 | {
64 | ksort($parameter);
65 | $checkStr = http_build_query($parameter);
66 | $postDataStr = 'IV='.$hashIV.'&'.$checkStr.'&Key='.$hashKey;
67 |
68 | return strtoupper(hash('sha256', $postDataStr));
69 | }
70 |
71 | /**
72 | * Add padding.
73 | *
74 | * @param string $string
75 | * @param int $blocksize
76 | *
77 | * @return string
78 | */
79 | protected function addPadding(string $string, int $blocksize = 32): string
80 | {
81 | $len = strlen($string);
82 | $pad = $blocksize - ($len % $blocksize);
83 | $string .= str_repeat(chr($pad), $pad);
84 |
85 | return $string;
86 | }
87 |
88 | /**
89 | * Strip padding.
90 | *
91 | * @param string $string
92 | *
93 | * @return string|false
94 | */
95 | protected function stripPadding(string $string)
96 | {
97 | $slast = ord(substr($string, -1));
98 | $slastc = chr($slast);
99 | $pcheck = substr($string, -$slast);
100 |
101 | if (preg_match('/'.$slastc.'{'.$slast.'}/', $string)) {
102 | $string = substr($string, 0, strlen($string) - $slast);
103 |
104 | return $string;
105 | }
106 |
107 | return false;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/BaseNewebPay.php:
--------------------------------------------------------------------------------
1 | configs = $configs;
77 | $this->MerchantID = $configs['MerchantID'];
78 | $this->HashKey = $configs['HashKey'];
79 | $this->HashIV = $configs['HashIV'];
80 |
81 | $this->setTimestamp();
82 | $this->tradeDataBoot();
83 | $this->boot();
84 | }
85 |
86 | /**
87 | * The newebpay boot hook.
88 | *
89 | * @return void
90 | */
91 | public function boot()
92 | {
93 | //
94 | }
95 |
96 | /**
97 | * Generate the newebpay full URL.
98 | *
99 | * @param string $path
100 | *
101 | * @return string
102 | */
103 | public function generateUrl(string $path): string
104 | {
105 | return ($this->configs['Debug'] ? $this->testUrl : $this->productionUrl)
106 | .$path;
107 | }
108 |
109 | /**
110 | * Get the newebpay full URL.
111 | *
112 | * @return string
113 | */
114 | public function getUrl(): string
115 | {
116 | return $this->url;
117 | }
118 |
119 | /**
120 | * Set the newebpay API path.
121 | *
122 | * @param string $path
123 | *
124 | * @return $this
125 | */
126 | public function setApiPath(string $path): BaseNewebPay
127 | {
128 | $this->url = $this->generateUrl($path);
129 |
130 | return $this;
131 | }
132 |
133 | /**
134 | * Set now timestamp.
135 | *
136 | * @return $this
137 | */
138 | public function setTimestamp(): BaseNewebPay
139 | {
140 | $this->timestamp = Carbon::now()->timestamp;
141 |
142 | return $this;
143 | }
144 |
145 | /**
146 | * Get request data.
147 | *
148 | * @return array
149 | */
150 | public function getRequestData(): array
151 | {
152 | return [];
153 | }
154 |
155 | /**
156 | * Submit data to newebpay API.
157 | *
158 | * @return mixed
159 | */
160 | public function submit()
161 | {
162 | return $this->sender->send($this->getRequestData(), $this->url);
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/tests/NewebPayMPGTest.php:
--------------------------------------------------------------------------------
1 | createMockConfig());
13 |
14 | $this->assertEquals('https://ccore.newebpay.com/MPG/mpg_gateway', $newebpay->getUrl());
15 | }
16 |
17 | public function testNewebPayMPGSenderIsSync()
18 | {
19 | $newebpay = new NewebPayMPG($this->createMockConfig());
20 |
21 | $this->assertInstanceOf(Sync::class, $newebpay->getSender());
22 | }
23 |
24 | public function testNewebPayMPGGetRequestData()
25 | {
26 | $this->setTestNow();
27 |
28 | $newebpay = new NewebPayMPG($this->createMockConfig());
29 |
30 | $requestData = $newebpay->getRequestData();
31 |
32 | $this->assertEquals('TestMerchantID1234', $requestData['MerchantID']);
33 | $this->assertEquals('e88e33cc07d106bcba1c1bd02d5d421fa9f86ef5a1469c0e801b3813b360f8333fd9fef8bf7312a3e5e66e1f6b5601b633b2b337c5dc2f6001d3f14dcb80df6cfc4ffe7a624838789bc47fcdd438db49a5f3e2b48d1740160d307a1bf6f27190b8825723f59d0cdf4071229db0a7bb6b2ef12ce7be24b0467db60a4185908770e1b5238444fb00fa24bb7693f9fb8d8c38577702e5ef0cab44b8d25e86f43e4599ca40b486efe32aae055626ca86d322055b161886fd13884252afbf7604ba739af778f00bdff9166f51143e5c5bd7326129fa1289fac0d1d66d0d41b9937058a69f5bb0f312ad4f1045aa8b74f354f5f8b260fed32f386bcec3e973f9c631fee1a8c0479fc45054c91e7eeaecbc692ae67561e71f31bb61964a5d51a7b6cb987d5bff4e838b2dfe02d1c2d83c2c0c34027ade4dc4dbbfe1644dcfc79d99944c5cff4e0cd95992114542a59c3240f4b498bc5cf4411614a310fb5ee126c28ac8', $requestData['TradeInfo']);
34 | $this->assertEquals('2E9E19F4BD2B1005BF1552267EAE9EE7D3A5DBBA7FE291CB4EBD8C29E91C0060', $requestData['TradeSha']);
35 | $this->assertEquals('1.5', $requestData['Version']);
36 | }
37 |
38 | public function testNewebPayMPGSubmit()
39 | {
40 | $this->setTestNow();
41 |
42 | $newebpay = new NewebPayMPG($this->createMockConfig());
43 |
44 | $result = $newebpay
45 | ->setOrder('TestNo123456', 100, '測試商品', 'test@email.com')
46 | ->submit();
47 |
48 | $this->assertEquals('', $result);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/tests/NewebPayTest.php:
--------------------------------------------------------------------------------
1 | setTestNow();
13 |
14 | $newebPay = new NewebPay($this->createMockConfig());
15 | $result = $newebPay
16 | ->payment('TestNo123456', 100, '測試商品', 'test@email.com')
17 | ->submit();
18 |
19 | $this->assertEquals('', $result);
20 | }
21 |
22 | public function testNewebPayCreditCardCancelAuthorization()
23 | {
24 | $this->setTestNow();
25 |
26 | $newebpay = new NewebPay($this->createMockConfig());
27 |
28 | $result = $newebpay
29 | ->creditCardCancelAuthorization('TestNo123456', 100, 'order')
30 | ->setMockHttp([
31 | new Response(200, [], '{"Status":"Code001","Message":"Test message.","Result":[]}'),
32 | ])
33 | ->submit();
34 |
35 | $this->assertEquals([
36 | 'Status' => 'Code001',
37 | 'Message' => 'Test message.',
38 | 'Result' => [],
39 | ], $result);
40 | }
41 |
42 | public function testNewebPayCreditCardChargeback()
43 | {
44 | $this->setTestNow();
45 |
46 | $newebpay = new NewebPay($this->createMockConfig());
47 |
48 | $result = $newebpay
49 | ->creditCardChargeback('TestNo123456', 100, 'order')
50 | ->setMockHttp([
51 | new Response(200, [], '{"Status":"Code001","Message":"Test message.","Result":[]}'),
52 | ])
53 | ->submit();
54 |
55 | $this->assertEquals([
56 | 'Status' => 'Code001',
57 | 'Message' => 'Test message.',
58 | 'Result' => [],
59 | ], $result);
60 | }
61 |
62 | public function testNewebPayCancelCreditCardChargeback()
63 | {
64 | $this->setTestNow();
65 |
66 | $newebpay = new NewebPay($this->createMockConfig());
67 |
68 | $result = $newebpay
69 | ->cancelCreditCardChargeback('TestNo123456', 100, 'order')
70 | ->setMockHttp([
71 | new Response(200, [], '{"Status":"Code001","Message":"Test message.","Result":[]}'),
72 | ])
73 | ->submit();
74 |
75 | $this->assertEquals([
76 | 'Status' => 'Code001',
77 | 'Message' => 'Test message.',
78 | 'Result' => [],
79 | ], $result);
80 | }
81 |
82 | public function testNewebPayCreditCardRefund()
83 | {
84 | $this->setTestNow();
85 |
86 | $newebpay = new NewebPay($this->createMockConfig());
87 |
88 | $result = $newebpay
89 | ->creditCardRefund('TestNo123456', 100, 'order')
90 | ->setMockHttp([
91 | new Response(200, [], '{"Status":"Code001","Message":"Test message.","Result":[]}'),
92 | ])
93 | ->submit();
94 |
95 | $this->assertEquals([
96 | 'Status' => 'Code001',
97 | 'Message' => 'Test message.',
98 | 'Result' => [],
99 | ], $result);
100 | }
101 |
102 | public function testNewebPayCancelCreditCardRefund()
103 | {
104 | $this->setTestNow();
105 |
106 | $newebpay = new NewebPay($this->createMockConfig());
107 |
108 | $result = $newebpay
109 | ->cancelCreditCardRefund('TestNo123456', 100, 'order')
110 | ->setMockHttp([
111 | new Response(200, [], '{"Status":"Code001","Message":"Test message.","Result":[]}'),
112 | ])
113 | ->submit();
114 |
115 | $this->assertEquals([
116 | 'Status' => 'Code001',
117 | 'Message' => 'Test message.',
118 | 'Result' => [],
119 | ], $result);
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/NewebPay.php:
--------------------------------------------------------------------------------
1 | configs);
22 | $newebPay->setOrder($no, $amt, $desc, $email);
23 |
24 | return $newebPay;
25 | }
26 |
27 | /**
28 | * 取消授權.
29 | *
30 | * @param string $no 訂單編號
31 | * @param int $amt 訂單金額
32 | * @param string $type 編號類型
33 | * 'order' => 使用商店訂單編號追蹤
34 | * 'trade' => 使用藍新金流交易序號追蹤
35 | *
36 | * @return NewebPayCancel
37 | */
38 | public function creditCardCancelAuthorization(
39 | string $no,
40 | int $amt,
41 | string $type = 'order'
42 | ): NewebPayCancel {
43 | $newebPay = new NewebPayCancel($this->configs);
44 | $newebPay->setCancelOrder($no, $amt, $type);
45 |
46 | return $newebPay;
47 | }
48 |
49 | /**
50 | * 信用卡請款.
51 | *
52 | * @param string $no 訂單編號
53 | * @param int $amt 訂單金額
54 | * @param string $type 編號類型
55 | * 'order' => 使用商店訂單編號追蹤
56 | * 'trade' => 使用藍新金流交易序號追蹤
57 | *
58 | * @return NewebPayClose
59 | */
60 | public function creditCardChargeback(
61 | string $no,
62 | int $amt,
63 | string $type = 'order'
64 | ): NewebPayClose {
65 | $newebPay = new NewebPayClose($this->configs);
66 | $newebPay->setCloseOrder($no, $amt, $type);
67 | $newebPay->setCloseType('pay');
68 |
69 | return $newebPay;
70 | }
71 |
72 | /**
73 | * 信用卡取消請款.
74 | *
75 | * @param string $no 訂單編號
76 | * @param int $amt 訂單金額
77 | * @param string $type 編號類型
78 | * 'order' => 使用商店訂單編號追蹤
79 | * 'trade' => 使用藍新金流交易序號追蹤
80 | *
81 | * @return NewebPayClose
82 | */
83 | public function cancelCreditCardChargeback(
84 | string $no,
85 | int $amt,
86 | string $type = 'order'
87 | ): NewebPayClose {
88 | $newebPay = new NewebPayClose($this->configs);
89 | $newebPay->setCloseOrder($no, $amt, $type);
90 | $newebPay->setCloseType('pay');
91 | $newebPay->setCancel(true);
92 |
93 | return $newebPay;
94 | }
95 |
96 | /**
97 | * 信用卡退款.
98 | *
99 | * @param string $no 訂單編號
100 | * @param int $amt 訂單金額
101 | * @param string $type 編號類型
102 | * 'order' => 使用商店訂單編號追蹤
103 | * 'trade' => 使用藍新金流交易序號追蹤
104 | *
105 | * @return NewebPayClose
106 | */
107 | public function creditCardRefund(
108 | string $no,
109 | int $amt,
110 | string $type = 'order'
111 | ): NewebPayClose {
112 | $newebPay = new NewebPayClose($this->configs);
113 | $newebPay->setCloseOrder($no, $amt, $type);
114 | $newebPay->setCloseType('refund');
115 |
116 | return $newebPay;
117 | }
118 |
119 | /**
120 | * 信用卡取消退款.
121 | *
122 | * @param string $no 訂單編號
123 | * @param int $amt 訂單金額
124 | * @param string $type 編號類型
125 | * 'order' => 使用商店訂單編號追蹤
126 | * 'trade' => 使用藍新金流交易序號追蹤
127 | *
128 | * @return NewebPayClose
129 | */
130 | public function cancelCreditCardRefund(
131 | string $no,
132 | int $amt,
133 | string $type = 'order'
134 | ): NewebPayClose {
135 | $newebPay = new NewebPayClose($this->configs);
136 | $newebPay->setCloseOrder($no, $amt, $type);
137 | $newebPay->setCloseType('refund');
138 | $newebPay->setCancel(true);
139 |
140 | return $newebPay;
141 | }
142 |
143 | /**
144 | * 查詢.
145 | *
146 | * @param string $no 訂單編號
147 | * @param int $amt 訂單金額
148 | *
149 | * @return NewebPayQuery
150 | */
151 | public function query(
152 | string $no,
153 | int $amt
154 | ): NewebPayQuery {
155 | $newebPay = new NewebPayQuery($this->configs);
156 | $newebPay->setQuery($no, $amt);
157 |
158 | return $newebPay;
159 | }
160 |
161 | /**
162 | * 解碼加密字串.
163 | *
164 | * @param string $encryptString
165 | *
166 | * @throws Exception
167 | *
168 | * @return mixed
169 | */
170 | public function decode(string $encryptString)
171 | {
172 | try {
173 | $decryptString = $this->decryptDataByAES(
174 | $encryptString,
175 | $this->HashKey,
176 | $this->HashIV
177 | );
178 |
179 | return json_decode($decryptString, true);
180 | } catch (Exception $e) {
181 | throw new Exception($e, $encryptString);
182 | }
183 | }
184 |
185 | /**
186 | * 驗證來源.
187 | *
188 | * @param string $trade
189 | * @param $sha
190 | *
191 | * @return bool
192 | */
193 | public function verify(string $trade, $sha): bool
194 | {
195 | return $sha === $this->encryptDataBySHA($trade, $this->HashKey, $this->HashIV);
196 | }
197 |
198 | /**
199 | * 從 request 取得解碼加密字串.
200 | *
201 | * @throws Exception
202 | *
203 | * @return mixed
204 | */
205 | public function decodeFromRequest($post)
206 | {
207 | if (!$this->verify($post['TradeInfo'], $post['TradeSha'])) {
208 | throw new Exception('TradeSha is not match');
209 | }
210 |
211 | $tradeInfo = $this->decode($post['TradeInfo']);
212 | $post['TradeInfo'] = $tradeInfo;
213 |
214 | return $post;
215 | }
216 | }
217 |
--------------------------------------------------------------------------------
/src/Traits/Trade.php:
--------------------------------------------------------------------------------
1 | TradeData['TimeStamp'] = $this->timestamp;
24 | $this->setVersion();
25 | $this->setRespondType();
26 | }
27 |
28 | /**
29 | * Get the newebpay TradeData.
30 | *
31 | * @return array
32 | */
33 | public function getTradeData(): array
34 | {
35 | return $this->TradeData;
36 | }
37 |
38 | /**
39 | * 串接版本.
40 | *
41 | * @param string|null $version
42 | *
43 | * @return $this
44 | */
45 | public function setVersion(string $version = null)
46 | {
47 | $this->TradeData['Version'] = $version ?? $this->configs['Version'];
48 |
49 | return $this;
50 | }
51 |
52 | /**
53 | * 回傳格式.
54 | *
55 | * Support types: "JSON", "String"
56 | *
57 | * @param string|null $type
58 | *
59 | * @return $this
60 | */
61 | public function setRespondType(string $type = null)
62 | {
63 | $this->TradeData['RespondType'] = $type ?? $this->configs['RespondType'];
64 |
65 | return $this;
66 | }
67 |
68 | /**
69 | * 語系.
70 | *
71 | * Support types: "zh-tw", "en"
72 | *
73 | * @param string|null $lang
74 | *
75 | * @return $this
76 | */
77 | public function setLangType(string $lang = null)
78 | {
79 | $this->TradeData['LangType'] = $lang ?? $this->configs['LangType'];
80 |
81 | return $this;
82 | }
83 |
84 | /**
85 | * 交易秒數限制.
86 | *
87 | * 0: 不限制
88 | * 秒數下限為 60 秒,當秒數介於 1~59 秒時,會以 60 秒計算。
89 | * 秒數上限為 900 秒,當超過 900 秒時,會 以 900 秒計算。
90 | *
91 | * @param int|null $limit
92 | *
93 | * @return $this
94 | */
95 | public function setTradeLimit(int $limit = null)
96 | {
97 | $this->TradeData['TradeLimit'] = $limit !== null ? $limit : $this->configs['TradeLimit'];
98 |
99 | return $this;
100 | }
101 |
102 | /**
103 | * 繳費有效期限.
104 | *
105 | * @param int|null $day
106 | *
107 | * @return $this
108 | */
109 | public function setExpireDate(int $day = null)
110 | {
111 | $day = $day !== null ? $day : $this->configs['ExpireDate'];
112 |
113 | $this->TradeData['ExpireDate'] = Carbon::now()->addDays($day)->format('Ymd');
114 |
115 | return $this;
116 | }
117 |
118 | /**
119 | * 付款完成後導向頁面.
120 | *
121 | * 僅接受 port 80 or 443
122 | *
123 | * @param string|null $url
124 | *
125 | * @return $this
126 | */
127 | public function setReturnURL(string $url = null)
128 | {
129 | $this->TradeData['ReturnURL'] = $url ?? $this->configs['ReturnURL'];
130 |
131 | return $this;
132 | }
133 |
134 | /**
135 | * 付款完成後的通知連結.
136 | *
137 | * 以幕後方式回傳給商店相關支付結果資料
138 | * 僅接受 port 80 or 443
139 | *
140 | * @param string|null $url
141 | *
142 | * @return $this
143 | */
144 | public function setNotifyURL(string $url = null)
145 | {
146 | $this->TradeData['NotifyURL'] = $url ?? $this->configs['NotifyURL'];
147 |
148 | return $this;
149 | }
150 |
151 | /**
152 | * 商店取號網址
153 | *
154 | * 此參數若為空值,則會顯示取號結果在藍新金流頁面。
155 | *
156 | * @param string|null $url
157 | *
158 | * @return $this
159 | */
160 | public function setCustomerURL(string $url = null)
161 | {
162 | $this->TradeData['CustomerURL'] = $url ?? $this->configs['CustomerURL'];
163 |
164 | return $this;
165 | }
166 |
167 | /**
168 | * 付款取消-返回商店網址
169 | *
170 | * 當交易取消時,平台會出現返回鈕,使消費者依以此參數網址返回商店指定的頁面
171 | *
172 | * @param string|null $url
173 | *
174 | * @return $this
175 | */
176 | public function setClientBackURL(string $url = null)
177 | {
178 | $this->TradeData['ClientBackURL'] = $url ?? $this->configs['ClientBackURL'];
179 |
180 | return $this;
181 | }
182 |
183 | /**
184 | * 付款人電子信箱是否開放修改.
185 | *
186 | * @param bool|null $isModify
187 | *
188 | * @return $this
189 | */
190 | public function setEmailModify(bool $isModify = null)
191 | {
192 | $this->TradeData['EmailModify'] = ($isModify !== null ? $isModify : $this->configs['EmailModify']) ? 1 : 0;
193 |
194 | return $this;
195 | }
196 |
197 | /**
198 | * 是否需要登入藍新金流會員
199 | *
200 | * @param bool|null $isLogin
201 | *
202 | * @return $this
203 | */
204 | public function setLoginType(bool $isLogin = false)
205 | {
206 | $this->TradeData['LoginType'] = ($isLogin !== null ? $isLogin : $this->configs['LoginType']) ? 1 : 0;
207 |
208 | return $this;
209 | }
210 |
211 | /**
212 | * 商店備註.
213 | *
214 | * 1.限制長度為 300 字。
215 | * 2.若有提供此參數,將會於 MPG 頁面呈現商店備註內容。
216 | *
217 | * @param string|null $comment
218 | *
219 | * @return $this
220 | */
221 | public function setOrderComment(string $comment = null)
222 | {
223 | $this->TradeData['OrderComment'] = $comment !== null ? $comment : $this->configs['OrderComment'];
224 |
225 | return $this;
226 | }
227 |
228 | /**
229 | * 支付方式.
230 | *
231 | * @param array $paymentMethod
232 | *
233 | * @return $this
234 | */
235 | public function setPaymentMethod(array $paymentMethod = [])
236 | {
237 | $paymentMethod = array_merge($this->configs['PaymentMethod'], $paymentMethod);
238 |
239 | $this->TradeData['CREDIT'] = $paymentMethod['CREDIT']['Enable'] ? 1 : 0;
240 | $this->TradeData['ANDROIDPAY'] = $paymentMethod['ANDROIDPAY'] ? 1 : 0;
241 | $this->TradeData['SAMSUNGPAY'] = $paymentMethod['SAMSUNGPAY'] ? 1 : 0;
242 | $this->TradeData['LINEPAY'] = isset($paymentMethod['LINEPAY']) && $paymentMethod['LINEPAY'] ? 1 : 0;
243 | $this->TradeData['ImageUrl'] = isset($paymentMethod['ImageUrl']) && $paymentMethod['ImageUrl'] ? 1 : 0;
244 | $this->TradeData['InstFlag'] = ($paymentMethod['CREDIT']['Enable'] && $paymentMethod['CREDIT']['InstFlag']) ? $paymentMethod['CREDIT']['InstFlag'] : 0;
245 | $this->TradeData['CreditRed'] = ($paymentMethod['CREDIT']['Enable'] && $paymentMethod['CREDIT']['CreditRed']) ? 1 : 0;
246 | $this->TradeData['UNIONPAY'] = $paymentMethod['UNIONPAY'] ? 1 : 0;
247 | $this->TradeData['WEBATM'] = $paymentMethod['WEBATM'] ? 1 : 0;
248 | $this->TradeData['VACC'] = $paymentMethod['VACC'] ? 1 : 0;
249 | $this->TradeData['CVS'] = $paymentMethod['CVS'] ? 1 : 0;
250 | $this->TradeData['BARCODE'] = $paymentMethod['BARCODE'] ? 1 : 0;
251 | $this->TradeData['ESUNWALLET'] = isset($paymentMethod['ESUNWALLET']) && $paymentMethod['ESUNWALLET'] ? 1 : 0;
252 | $this->TradeData['TAIWANPAY'] = isset($paymentMethod['TAIWANPAY']) && $paymentMethod['TAIWANPAY'] ? 1 : 0;
253 | $this->TradeData['EZPAY'] = isset($paymentMethod['EZPAY']) && $paymentMethod['EZPAY'] ? 1 : 0;
254 | $this->TradeData['EZPWECHAT'] = isset($paymentMethod['EZPWECHAT']) && $paymentMethod['EZPWECHAT'] ? 1 : 0;
255 | $this->TradeData['EZPALIPAY'] = isset($paymentMethod['EZPALIPAY']) && $paymentMethod['EZPALIPAY'] ? 1 : 0;
256 |
257 | return $this;
258 | }
259 |
260 | /**
261 | * 付款方式-物流啟用.
262 | *
263 | * 1 = 啟用超商取貨不付款
264 | * 2 = 啟用超商取貨付款
265 | * 3 = 啟用超商取貨不付款及超商取貨付款
266 | * null = 不開啟
267 | *
268 | * @param int|null $cvscom
269 | *
270 | * @return $this
271 | */
272 | public function setCVSCOM(int $cvscom = null)
273 | {
274 | $this->TradeData['CVSCOM'] = $cvscom !== null ? $cvscom : $this->configs['CVSCOM'];
275 |
276 | return $this;
277 | }
278 |
279 | /**
280 | * 物流型態.
281 | *
282 | * B2C = 超商大宗寄倉(目前僅支援統㇐超商)
283 | * C2C = 超商店到店(目前僅支援全家)
284 | * null = 預設
285 | *
286 | * 預設值情況說明:
287 | * a.系統優先啟用[B2C 大宗寄倉]。
288 | * b.若商店設定中未啟用[B2C 大宗寄倉],則系統將會啟用[C2C 店到店]。
289 | * c.若商店設定中,[B2C 大宗寄倉]與[C2C 店到店]皆未啟用,則支付頁面中將不會出現物流選項。
290 | *
291 | * @param string|null $lgsType
292 | *
293 | * @return $this
294 | */
295 | public function setLgsType(string $lgsType = null)
296 | {
297 | $this->TradeData['LgsType'] = $lgsType !== null ? $lgsType : $this->configs['LgsType'];
298 |
299 | return $this;
300 | }
301 |
302 | /**
303 | * Set TokenTerm.
304 | *
305 | * @param string $token
306 | *
307 | * @return $this
308 | */
309 | public function setTokenTerm(string $token = '')
310 | {
311 | $this->TradeData['TokenTerm'] = $token;
312 |
313 | return $this;
314 | }
315 |
316 | /**
317 | * Set Order.
318 | *
319 | * @param string $no
320 | * @param int $amt
321 | * @param string $desc
322 | * @param string $email
323 | *
324 | * @return $this
325 | */
326 | public function setOrder(string $no, int $amt, string $desc, string $email)
327 | {
328 | $this->TradeData['MerchantOrderNo'] = $no;
329 | $this->TradeData['Amt'] = $amt;
330 | $this->TradeData['ItemDesc'] = $desc;
331 | $this->TradeData['Email'] = $email;
332 |
333 | return $this;
334 | }
335 | }
336 |
--------------------------------------------------------------------------------