├── .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 | [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fxup6m6fu04%2Fnewebpay-sdk-php.svg?type=small)](https://app.fossa.com/projects/git%2Bgithub.com%2Fxup6m6fu04%2Fnewebpay-sdk-php?ref=badge_small) 6 | [![StyleCI](https://github.styleci.io/repos/596413768/shield?branch=master)](https://github.styleci.io/repos/596413768?branch=master) 7 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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 | [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fxup6m6fu04%2Fnewebpay-sdk-php.svg?type=large)](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 | [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fxup6m6fu04%2Fnewebpay-sdk-php.svg?type=small)](https://app.fossa.com/projects/git%2Bgithub.com%2Fxup6m6fu04%2Fnewebpay-sdk-php?ref=badge_small) 6 | [![StyleCI](https://github.styleci.io/repos/596413768/shield?branch=master)](https://github.styleci.io/repos/596413768?branch=master) 7 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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 | [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fxup6m6fu04%2Fnewebpay-sdk-php.svg?type=large)](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 | --------------------------------------------------------------------------------