├── .gitignore ├── .phpstorm.meta.php ├── .travis.yml ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml ├── src ├── .phpstorm.meta.php │ └── voicetube.taiwan.payment.gateway.phpstorm.meta.php ├── AllPayPaymentGateway.php ├── AllPayPaymentResponse.php ├── Common │ ├── AbstractGateway.php │ ├── AbstractResponse.php │ ├── AbstractUtility.php │ ├── GatewayInterface.php │ ├── OrderBag.php │ └── ResponseInterface.php ├── EcAllPayUtility.php ├── EcPayPaymentGateway.php ├── EcPayPaymentResponse.php ├── SpGatewayPaymentGateway.php ├── SpGatewayPaymentResponse.php ├── TaiwanPaymentGateway.php └── TaiwanPaymentResponse.php └── tests ├── TaiwanPaymentGateway ├── AllPayPaymentGatewayTest.php ├── AllPayPaymentResponseTest.php ├── EcPayPaymentGatewayTest.php ├── EcPayPaymentResponseTest.php ├── SpGatewayPaymentGatewayTest.php ├── SpGatewayPaymentResponseTest.php ├── TaiwanPaymentGatewayTest.php └── TaiwanPaymentResponseTest.php └── bootstrap.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | composer.lock 3 | .DS_Store 4 | .idea/ 5 | test*.* 6 | report/ 7 | build/ -------------------------------------------------------------------------------- /.phpstorm.meta.php: -------------------------------------------------------------------------------- 1 | [ 11 | '' == '@', 12 | "SpGateway" instanceof \VoiceTube\TaiwanPaymentGateway\SpGatewayPaymentGateway, 13 | "AllPay" instanceof \VoiceTube\TaiwanPaymentGateway\AllPayPaymentGateway, 14 | "EcPay" instanceof \VoiceTube\TaiwanPaymentGateway\EcPayPaymentGateway, 15 | ], 16 | \VoiceTube\TaiwanPaymentGateway\TaiwanPaymentResponse::create('') => [ 17 | '' == '@', 18 | "SpGateway" instanceof \VoiceTube\TaiwanPaymentGateway\SpGatewayPaymentResponse, 19 | "AllPay" instanceof \VoiceTube\TaiwanPaymentGateway\AllPayPaymentResponse, 20 | "EcPay" instanceof \VoiceTube\TaiwanPaymentGateway\EcPayPaymentResponse, 21 | ] 22 | ]; -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - '5.5' 4 | - '5.6' 5 | - '7.0' 6 | - '7.1' 7 | - hhvm 8 | - nightly 9 | 10 | env: 11 | global: 12 | - setup=basic 13 | 14 | matrix: 15 | include: 16 | - php: 5.5 17 | env: setup=lowest 18 | - php: 7.0 19 | env: setup=stable 20 | 21 | 22 | sudo: false 23 | 24 | addons: 25 | code_climate: 26 | repo_token: $cc_token 27 | 28 | before_install: 29 | - travis_retry composer self-update 30 | 31 | install: 32 | - if [[ $setup = 'basic' ]]; then travis_retry composer install --no-interaction --prefer-dist; fi 33 | - if [[ $setup = 'stable' ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-stable; fi 34 | - if [[ $setup = 'lowest' ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-lowest --prefer-stable; fi 35 | 36 | script: vendor/bin/phpcs --standard=PSR2 src && vendor/bin/phpunit --coverage-text 37 | 38 | after_success: 39 | - vendor/bin/test-reporter -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Merik-VT 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Taiwan Payment Gateway 2 | ========================= 3 | 4 | #### A payment gateway library for Taiwan. 5 | 6 | Created by [VoiceTube](https://www.voicetube.com/) 7 | 8 | [![Build Status](https://travis-ci.org/merik-chen/Taiwan-Payment-Gateway.svg?branch=master)](https://travis-ci.org/merik-chen/Taiwan-Payment-Gateway) 9 | [![Test Coverage](https://codeclimate.com/repos/58f2e68ab05ce9025a0023ca/badges/78424a612ed55896c86d/coverage.svg)](https://codeclimate.com/repos/58f2e68ab05ce9025a0023ca/coverage) 10 | [![Code Climate](https://codeclimate.com/repos/58f2e68ab05ce9025a0023ca/badges/78424a612ed55896c86d/gpa.svg)](https://codeclimate.com/repos/58f2e68ab05ce9025a0023ca/feed) 11 | 12 | Features 13 | -------- 14 | 15 | * Create / Process order 16 | * Unit-Testing with PHPUnit 17 | * PSR-4 auto-loading compliant structure 18 | * Support PHPStorm meta for auto-completion 19 | * Easy to use to any framework or even a plain php file 20 | 21 | Todo 22 | ---- 23 | 24 | * Payment status 25 | * E-Invoice features 26 | * Credit Card cancel / refund API 27 | 28 | Available Gateway 29 | ----------------- 30 | 31 | * [智付通 Spgateway](https://www.spgateway.com) 32 | * [歐付寶 allPay](https://www.allpay.com.tw/) 33 | * [綠界 ECPay](https://www.ecpay.com.tw) 34 | 35 | 36 | 37 | How to use 38 | ---------- 39 | 40 | #### Accept payment method. 41 | 42 | * WebATM 43 | * BarCode 44 | * TenPay (AllPay only) 45 | * TopUp (AllPay only) 46 | * Credit 47 | * ATM 48 | * CVS 49 | * ALL (AllPay, EcPay only) 50 | 51 | #### Load the library 52 | 53 | ```php 54 | require_once 'vendor/autoload.php'; 55 | 56 | use VoiceTube\TaiwanPaymentGateway; 57 | ``` 58 | 59 | #### Initial the gateway 60 | 61 | ```php 62 | 63 | /** 64 | * Use factory to create gateway or directly new the gateway 65 | */ 66 | 67 | $gw = TaiwanPaymentGateway\TaiwanPaymentGateway::create('SpGateway', [ 68 | 'hashKey' => 'c7fe1bfba42369ec1add502c9917e14d', 69 | 'hashIV' => '245a49c8fb5151f0', 70 | 'merchantId' => 'MS1234567', 71 | 'version' => '1.2', 72 | 'actionUrl' => 'https://ccore.spgateway.com/MPG/mpg_gateway', 73 | 'returnUrl' => 'https://localhost/payment/confirm', 74 | 'notifyUrl' => 'https://localhost/payment/notify', 75 | 'clientBackUrl' => 'https://localhost/payment/return', 76 | 'paymentInfoUrl'=> 'https://localhost/payment/information', 77 | ]); 78 | 79 | 80 | $sp = new TaiwanPaymentGateway\SpGatewayPaymentGateway([ 81 | 'hashKey' => 'c7fe1bfba42369ec1add502c9917e14d', 82 | 'hashIV' => '245a49c8fb5151f0', 83 | 'merchantId' => 'MS1234567', 84 | 'version' => '1.2', 85 | 'actionUrl' => 'https://ccore.spgateway.com/MPG/mpg_gateway', 86 | 'returnUrl' => 'https://localhost/payment/confirm', 87 | 'notifyUrl' => 'https://localhost/payment/notify', 88 | 'clientBackUrl' => 'https://localhost/payment/return', 89 | 'paymentInfoUrl'=> 'https://localhost/payment/information', 90 | ]); 91 | 92 | $ec = new TaiwanPaymentGateway\EcPayPaymentGateway([ 93 | 'hashKey' => '5294y06JbISpM5x9', 94 | 'hashIV' => 'v77hoKGq4kWxNNIS', 95 | 'merchantId' => '2000132', 96 | 'version' => 'V4', 97 | 'actionUrl' => 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/', 98 | 'returnUrl' => 'https://localhost/payment/confirm', 99 | 'clientBackUrl' => 'https://localhost/payment/return', 100 | 'paymentInfoUrl'=> 'https://localhost/payment/information', 101 | ]); 102 | 103 | $ap = new TaiwanPaymentGateway\AllPayPaymentGateway([ 104 | 'hashKey' => '5294y06JbISpM5x9', 105 | 'hashIV' => 'v77hoKGq4kWxNNIS', 106 | 'merchantId' => '2000132', 107 | 'version' => 'V2', 108 | 'actionUrl' => 'https://payment-stage.allpay.com.tw/Cashier/AioCheckOut/', 109 | 'returnUrl' => 'https://localhost/payment/confirm', 110 | 'clientBackUrl' => 'https://localhost/payment/return', 111 | 'paymentInfoUrl'=> 'https://localhost/payment/information', 112 | ]); 113 | ``` 114 | 115 | #### New order 116 | ##### !! All order settings must called after create new order, or the `$gw->newOrder()` function will erase all previously order data. 117 | 118 | ```php 119 | // create new order 120 | // $respond_type: 121 | // SpGateway: `POST` or `JSON` (default to 'JSON') 122 | // AllPay, EcPay: `POST` only 123 | $gw->newOrder( 124 | required:$merchant_order_no, 125 | required:$amount, 126 | required:$item_describe, 127 | required:$order_comment, 128 | optional:$respond_type, 129 | optional:$timestamp 130 | ); 131 | 132 | // Available payment method 133 | $gw->useBarCode(); 134 | $gw->useWebATM(); 135 | $gw->useCredit(); 136 | $gw->useTenPay(); // AllPay only 137 | $gw->useTopUp(); // AllPay only 138 | $gw->useATM(); 139 | $gw->useCVS(); 140 | $gw->useALL(); // AllPay, EcPay only 141 | 142 | // spgateway only settings 143 | $gw->setEmail('bonjour@voicetube.com'); // setting user email 144 | $gw->triggerEmailModify(optional:boolean); // allow user update email address later. 145 | $gw->onlyLoginMemberCanPay(optional:boolean); // force user must to be login later. 146 | 147 | // Order settings 148 | $gw->setUnionPay(); 149 | $gw->needExtraPaidInfo(); 150 | $gw->setCreditInstallment(required:$months, optional:$total_amount); 151 | $gw->setOrderExpire(required:$expire_Date); 152 | 153 | // It can be using like this 154 | 155 | $rId = sprintf("VT%s", time()); 156 | $gw->newOrder($rId, 100, rId, $rId) 157 | ->useCredit() 158 | ->setUnionPay() 159 | ->needExtraPaidInfo(); 160 | 161 | // generate post form 162 | $gw->genForm(optional:$auto_submit = true); 163 | 164 | ``` 165 | 166 | #### Process order result/information 167 | 168 | ##### Initial the gateway 169 | 170 | ```php 171 | /** 172 | * Use factory to create response or directly new the response 173 | */ 174 | 175 | $gwr = TaiwanPaymentGateway\TaiwanPaymentResponse::create('SpGateway', [ 176 | 'hashKey' => 'c7fe1bfba42369ec1add502c9917e14d', 177 | 'hashIV' => '245a49c8fb5151f0', 178 | ]); 179 | 180 | $spr = new TaiwanPaymentGateway\SpGatewayPaymentResponse([ 181 | 'hashKey' => 'c7fe1bfba42369ec1add502c9917e14d', 182 | 'hashIV' => '245a49c8fb5151f0', 183 | ]); 184 | 185 | $ecr = new TaiwanPaymentGateway\EcPayPaymentResponse([ 186 | 'hashKey' => '5294y06JbISpM5x9', 187 | 'hashIV' => 'v77hoKGq4kWxNNIS', 188 | ]); 189 | 190 | $apr = new TaiwanPaymentGateway\AllPayPaymentResponse([ 191 | 'hashKey' => '5294y06JbISpM5x9', 192 | 'hashIV' => 'v77hoKGq4kWxNNIS', 193 | ]); 194 | ``` 195 | 196 | ##### Check the payment response 197 | 198 | ```php 199 | // processOrder will catch $_POST fields and clean it 200 | // SpGateway: `POST` or `JSON` 201 | // AllPay, EcPay: `POST` only 202 | $result = $spr->processOrder(optional:$type='POST or JSON'); 203 | 204 | // dump the result 205 | array(22) { 206 | ["Status"]=> 207 | string(7) "SUCCESS" 208 | ["Message"]=> 209 | string(12) "授權成功" 210 | ["MerchantID"]=> 211 | string(9) "MS1234567" 212 | ["Amt"]=> 213 | int(1200) 214 | ["TradeNo"]=> 215 | string(17) "17032311330952317" 216 | ["MerchantOrderNo"]=> 217 | string(15) "1703230034715" 218 | ["PaymentType"]=> 219 | string(6) "CREDIT" 220 | ["RespondType"]=> 221 | string(6) "String" 222 | ["CheckCode"]=> 223 | string(64) "4B3DDA5FE88966928FEB903D6037B06A1A929087046E5E8D7A8CB2778A30D67C" 224 | ["PayTime"]=> 225 | string(19) "2017-03-23 11:33:09" 226 | ["IP"]=> 227 | string(12) "XXX.XXX.XXX.XXX" 228 | ["EscrowBank"]=> 229 | string(3) "KGI" 230 | ["TokenUseStatus"]=> 231 | int(0) 232 | ["RespondCode"]=> 233 | string(2) "00" 234 | ["Auth"]=> 235 | string(6) "930637" 236 | ["Card6No"]=> 237 | string(6) "400022" 238 | ["Card4No"]=> 239 | string(4) "1111" 240 | ["Inst"]=> 241 | int(0) 242 | ["InstFirst"]=> 243 | int(1200) 244 | ["InstEach"]=> 245 | int(0) 246 | ["ECI"]=> 247 | string(0) "" 248 | ["matched"]=> 249 | bool(true) 250 | } 251 | 252 | // after processing, check the `matched` field. 253 | 254 | // for allpay and ecpay, you will need to call `rspOk` or `rspError`. 255 | $ecr->rspOk(); 256 | // or 257 | $apr->rspError(optinal:'Custom error msg'); 258 | 259 | ``` 260 | 261 | #### Ref. 262 | 263 | * [[PDF] SpGateway](https://www.spgateway.com/dw_files/info_api/spgateway_gateway_MPGapi_V1_0_3.pdf) 264 | * [[PDF] AllPay](https://www.allpay.com.tw/Content/files/allpay_011.pdf) 265 | * [[PDF] EcPay](https://www.ecpay.com.tw/Content/files/ecpay_011.pdf) 266 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "voicetube/taiwan-payment-gateway", 3 | "description": "A payment gateway library for Taiwan.", 4 | "keywords": ["VoiceTube", "payment", "gateway", "Taiwan"], 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Merik Chen", 9 | "email": "merik@voicetube.com" 10 | } 11 | ], 12 | "type": "project", 13 | "require": { 14 | "php": ">=5.5" 15 | }, 16 | "require-dev": { 17 | "phpunit/phpunit": "4.8.*", 18 | "squizlabs/php_codesniffer": "^2.8", 19 | "codeclimate/php-test-reporter": "^0.4.4", 20 | "phpmd/phpmd": "^2.6" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "VoiceTube\\TaiwanPaymentGateway\\": "src/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests 14 | 15 | 16 | 17 | 18 | ./src 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/.phpstorm.meta.php/voicetube.taiwan.payment.gateway.phpstorm.meta.php: -------------------------------------------------------------------------------- 1 | \VoiceTube\TaiwanPaymentGateway\SpGatewayPaymentGateway::class, 15 | "AllPay" => \VoiceTube\TaiwanPaymentGateway\AllPayPaymentGateway::class, 16 | "EcPay" => \VoiceTube\TaiwanPaymentGateway\EcPayPaymentGateway::class, 17 | ] 18 | )); 19 | 20 | override(\VoiceTube\TaiwanPaymentGateway\TaiwanPaymentResponse::create(''), map( 21 | [ 22 | '' == '@', 23 | "SpGateway" => \VoiceTube\TaiwanPaymentGateway\SpGatewayPaymentResponse::class, 24 | "AllPay" => \VoiceTube\TaiwanPaymentGateway\AllPayPaymentResponse::class, 25 | "EcPay" => \VoiceTube\TaiwanPaymentGateway\EcPayPaymentResponse::class, 26 | ] 27 | )); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/AllPayPaymentGateway.php: -------------------------------------------------------------------------------- 1 | actionUrl)) { 20 | $this->actionUrl = 'https://payment.allpay.com.tw/Cashier/AioCheckOut/'; 21 | } 22 | if (empty($this->version)) { 23 | $this->version = 'V2'; 24 | } 25 | 26 | return $this; 27 | } 28 | 29 | /** 30 | * @return AllPayPaymentGateway 31 | */ 32 | public function useBarCode() 33 | { 34 | $this->order['ChoosePayment'] = 'BARCODE'; 35 | $this->order['PaymentInfoURL'] = $this->paymentInfoUrl; 36 | return $this; 37 | } 38 | 39 | /** 40 | * @return AllPayPaymentGateway 41 | */ 42 | public function useWebATM() 43 | { 44 | $this->order['ChoosePayment'] = 'WebATM'; 45 | return $this; 46 | } 47 | 48 | /** 49 | * @return AllPayPaymentGateway 50 | */ 51 | public function useCredit() 52 | { 53 | $this->order['ChoosePayment'] = 'Credit'; 54 | return $this; 55 | } 56 | 57 | /** 58 | * @return AllPayPaymentGateway 59 | */ 60 | public function useTenPay() 61 | { 62 | $this->order['ChoosePayment'] = 'Tenpay'; 63 | return $this; 64 | } 65 | 66 | /** 67 | * @return AllPayPaymentGateway 68 | */ 69 | public function useTopUp() 70 | { 71 | $this->order['ChoosePayment'] = 'TopUpUsed'; 72 | return $this; 73 | } 74 | 75 | /** 76 | * @return AllPayPaymentGateway 77 | */ 78 | public function useATM() 79 | { 80 | $this->order['ChoosePayment'] = 'ATM'; 81 | $this->order['PaymentInfoURL'] = $this->paymentInfoUrl; 82 | return $this; 83 | } 84 | 85 | /** 86 | * @return AllPayPaymentGateway 87 | */ 88 | public function useCVS() 89 | { 90 | $this->order['ChoosePayment'] = 'CVS'; 91 | $this->order['PaymentInfoURL'] = $this->paymentInfoUrl; 92 | return $this; 93 | } 94 | 95 | /** 96 | * @return AllPayPaymentGateway 97 | */ 98 | public function useALL() 99 | { 100 | $this->order['ChoosePayment'] = 'ALL'; 101 | $this->order['PaymentInfoURL'] = $this->paymentInfoUrl; 102 | return $this; 103 | } 104 | 105 | /** 106 | * @return AllPayPaymentGateway 107 | */ 108 | public function needExtraPaidInfo() 109 | { 110 | $this->order['NeedExtraPaidInfo'] = 'Y'; 111 | return $this; 112 | } 113 | 114 | /** 115 | * @param integer $months 116 | * @param integer|float $totalAmount 117 | * @return AllPayPaymentGateway 118 | */ 119 | public function setCreditInstallment($months, $totalAmount = 0) 120 | { 121 | $this->order['CreditInstallment'] = $months; 122 | if ($totalAmount) { 123 | $this->order['InstallmentAmount'] = $totalAmount; 124 | } 125 | return $this; 126 | } 127 | 128 | /** 129 | * @param int|string $expireDate 130 | * @return AllPayPaymentGateway 131 | */ 132 | public function setOrderExpire($expireDate) 133 | { 134 | if (is_numeric($expireDate)) { 135 | $expireDate = intval($expireDate); 136 | } 137 | 138 | switch ($this->order['ChoosePayment']) { 139 | case 'ATM': 140 | $this->order['ExpireDate'] = $expireDate; 141 | break; 142 | case 'Tenpay': 143 | case 'CVS': 144 | $this->order['StoreExpireDate'] = mktime( 145 | 23, 146 | 59, 147 | 59, 148 | date('m'), 149 | date('d') + $expireDate, 150 | date('Y') 151 | ) - time(); 152 | break; 153 | case 'BARCODE': 154 | $this->order['StoreExpireDate'] = $expireDate; 155 | break; 156 | } 157 | return $this; 158 | } 159 | 160 | /** 161 | * @return AllPayPaymentGateway 162 | */ 163 | public function setUnionPay() 164 | { 165 | $this->order['UnionPay'] = 1; 166 | return $this; 167 | } 168 | 169 | /** 170 | * @return array 171 | */ 172 | public function getOrder() 173 | { 174 | return $this->order; 175 | } 176 | 177 | /** 178 | * @param string $merchantOrderNo 179 | * @param float|int $amount 180 | * @param string $itemDescribe 181 | * @param string $orderComment 182 | * @param string $respondType 183 | * @param int $timestamp 184 | * @throws \InvalidArgumentException 185 | * @return AllPayPaymentGateway 186 | */ 187 | public function newOrder( 188 | $merchantOrderNo, 189 | $amount, 190 | $itemDescribe, 191 | $orderComment, 192 | $respondType = 'POST', 193 | $timestamp = 0 194 | ) { 195 | 196 | $this->argumentChecker(); 197 | 198 | $timestamp = empty($timestamp) ? time() : $timestamp; 199 | 200 | $this->clearOrder(); 201 | 202 | $this->order['PaymentType'] = 'aio'; 203 | $this->order['MerchantID'] = $this->merchantId; 204 | $this->order['MerchantTradeDate'] = date("Y/m/d H:i:s", $timestamp); 205 | $this->order['MerchantTradeNo'] = $merchantOrderNo; 206 | $this->order['TotalAmount'] = intval($amount); 207 | $this->order['ItemName'] = $itemDescribe; 208 | $this->order['TradeDesc'] = $orderComment; 209 | $this->order['EncryptType'] = 1; 210 | 211 | if (!empty($this->returnUrl)) { 212 | $this->order['ReturnURL'] = $this->returnUrl; 213 | } 214 | if (!empty($this->clientBackUrl)) { 215 | $this->order['ClientBackURL'] = $this->clientBackUrl; 216 | } 217 | 218 | return $this; 219 | } 220 | 221 | /** 222 | * @return string 223 | */ 224 | public function genCheckValue() 225 | { 226 | uksort($this->order, 'strcasecmp'); 227 | 228 | $merArray = array_merge(['HashKey' => $this->hashKey], $this->order, ['HashIV' => $this->hashIV]); 229 | 230 | $checkMerStr = urldecode(http_build_query($merArray)); 231 | 232 | foreach ($this->urlEncodeMapping as $key => $value) { 233 | $checkMerStr = str_replace($key, $value, $checkMerStr); 234 | } 235 | 236 | $checkMerStr = strtolower(urlencode($checkMerStr)); 237 | 238 | return strtoupper(hash('sha256', $checkMerStr)); 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /src/AllPayPaymentResponse.php: -------------------------------------------------------------------------------- 1 | processOrderPost(); 13 | } 14 | 15 | /** 16 | * @return bool|array 17 | */ 18 | public function processOrderPost() 19 | { 20 | if (!isset($_POST)) { 21 | return false; 22 | } 23 | if (empty($_POST)) { 24 | return false; 25 | } 26 | 27 | $post = filter_var_array($_POST, [ 28 | 'MerchantID' => FILTER_SANITIZE_STRING, 29 | 'MerchantTradeNo' => FILTER_SANITIZE_STRING, 30 | 'RtnCode' => FILTER_VALIDATE_INT, 31 | 'TradeAmt' => FILTER_VALIDATE_INT, 32 | 'RtnMsg' => FILTER_SANITIZE_STRING, 33 | 'TradeNo' => FILTER_SANITIZE_STRING, 34 | 'PaymentDate' => FILTER_SANITIZE_STRING, 35 | 'PaymentType' => FILTER_SANITIZE_STRING, 36 | 'PaymentTypeChargeFee' => FILTER_VALIDATE_INT, 37 | 'TradeDate' => FILTER_SANITIZE_STRING, 38 | 'SimulatePaid' => FILTER_VALIDATE_INT, 39 | 'CheckMacValue' => FILTER_SANITIZE_STRING, 40 | 'PeriodType' => FILTER_SANITIZE_STRING, 41 | 'Frequency' => FILTER_VALIDATE_INT, 42 | 'ExecTimes' => FILTER_VALIDATE_INT, 43 | 'amount' => FILTER_VALIDATE_INT, 44 | 'gwsr' => FILTER_VALIDATE_INT, 45 | 'stage' => FILTER_VALIDATE_INT, 46 | 'stast' => FILTER_VALIDATE_INT, 47 | 'eci' => FILTER_VALIDATE_INT, 48 | 'staed' => FILTER_VALIDATE_INT, 49 | 'red_dan' => FILTER_VALIDATE_INT, 50 | 'red_yet' => FILTER_VALIDATE_INT, 51 | 'red_de_amt' => FILTER_VALIDATE_INT, 52 | 'red_ok_amt' => FILTER_VALIDATE_INT, 53 | 'PeriodAmount' => FILTER_VALIDATE_INT, 54 | 'TotalSuccessTimes' => FILTER_VALIDATE_INT, 55 | 'FirstAuthAmount' => FILTER_VALIDATE_INT, 56 | 'TotalSuccessAmount' => FILTER_VALIDATE_INT, 57 | 'process_date' => FILTER_SANITIZE_STRING, 58 | 'auth_code' => FILTER_SANITIZE_STRING, 59 | 'WebATMAccBank' => FILTER_SANITIZE_STRING, 60 | 'WebATMAccNo' => FILTER_SANITIZE_STRING, 61 | 'WebATMBankName' => FILTER_SANITIZE_STRING, 62 | 'ATMAccBank' => FILTER_SANITIZE_STRING, 63 | 'ATMAccNo' => FILTER_SANITIZE_STRING, 64 | 'PaymentNo' => FILTER_SANITIZE_STRING, 65 | 'PayFrom' => FILTER_SANITIZE_STRING, 66 | 'card4no' => FILTER_SANITIZE_STRING, 67 | 'card6no' => FILTER_SANITIZE_STRING, 68 | ], false); 69 | 70 | if (!$post['RtnCode']) { 71 | return false; 72 | } 73 | 74 | $post['matched'] = $this->matchCheckCode($post); 75 | 76 | return $post; 77 | } 78 | 79 | public function matchCheckCode(array $payload = []) 80 | { 81 | $post = $_POST; 82 | 83 | $checkMacValue = $post['CheckMacValue']; 84 | 85 | unset($post['CheckMacValue']); 86 | 87 | uksort($post, 'strcasecmp'); 88 | 89 | $merArray = array_merge(['HashKey' => $this->hashKey], $post, ['HashIV' => $this->hashIV]); 90 | 91 | $checkMerStr = urldecode(http_build_query($merArray)); 92 | 93 | foreach ($this->urlEncodeMapping as $key => $value) { 94 | $checkMerStr = str_replace($key, $value, $checkMerStr); 95 | } 96 | 97 | $checkMerStr = strtolower(urlencode($checkMerStr)); 98 | 99 | return $checkMacValue == strtoupper(hash('sha256', $checkMerStr)); 100 | } 101 | 102 | public function rspOk() 103 | { 104 | echo "1|OK"; 105 | return true; 106 | } 107 | 108 | public function rspError($msg = 'Error') 109 | { 110 | echo "0|$msg"; 111 | return true; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/Common/AbstractGateway.php: -------------------------------------------------------------------------------- 1 | setArrayConfig($config); 12 | } 13 | } 14 | 15 | public function clearOrder() 16 | { 17 | $this->order = []; 18 | } 19 | 20 | /** 21 | * @throws \InvalidArgumentException 22 | */ 23 | protected function argumentChecker() 24 | { 25 | /** 26 | * Argument Check 27 | */ 28 | if (!isset($this->hashIV)) { 29 | throw new \InvalidArgumentException('HashIV not set'); 30 | } 31 | if (!isset($this->hashKey)) { 32 | throw new \InvalidArgumentException('HashKey not set'); 33 | } 34 | if (!isset($this->merchantId)) { 35 | throw new \InvalidArgumentException('MerchantID not set'); 36 | } 37 | 38 | if (!isset($this->returnUrl)) { 39 | throw new \InvalidArgumentException('ReturnURL not set'); 40 | } 41 | if (empty($this->actionUrl)) { 42 | throw new \InvalidArgumentException('ActionURL not set'); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Common/AbstractResponse.php: -------------------------------------------------------------------------------- 1 | setArrayConfig($config); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Common/AbstractUtility.php: -------------------------------------------------------------------------------- 1 | $value) { 13 | $this->setConfig($key, $value); 14 | } 15 | 16 | $this->urlEncodeMapping = [ 17 | '%2D' => '-', 18 | '%5F' => '_', 19 | '%2E' => '.', 20 | '%21' => '!', 21 | '%2A' => '*', 22 | '%2d' => '-', 23 | '%5f' => '_', 24 | '%2e' => '.', 25 | '%2a' => '*', 26 | '%28' => '(', 27 | '%29' => ')', 28 | '%20' => '+']; 29 | } 30 | 31 | private function isExists($key) 32 | { 33 | return property_exists(self::class, $key); 34 | } 35 | 36 | /** 37 | * @param $key 38 | * @param $value 39 | * @throws \InvalidArgumentException 40 | * @return mixed 41 | */ 42 | public function setConfig($key, $value) 43 | { 44 | $key = trim($key); 45 | 46 | if ($this->isExists($key)) { 47 | $this->$key = $value; 48 | 49 | return $value; 50 | } 51 | 52 | throw new \InvalidArgumentException('config key not exists.'); 53 | } 54 | 55 | /** 56 | * @param $key 57 | * @throws \InvalidArgumentException 58 | * @return mixed 59 | */ 60 | public function getConfig($key) 61 | { 62 | $key = trim($key); 63 | 64 | if ($this->isExists($key)) { 65 | return $this->$key; 66 | } 67 | throw new \InvalidArgumentException('config key not exists.'); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Common/GatewayInterface.php: -------------------------------------------------------------------------------- 1 | autoSubmit = !!$autoSubmit; 21 | 22 | if (!isset($this->order['ChoosePayment'])) { 23 | throw new \InvalidArgumentException('Payment method not set'); 24 | } 25 | 26 | if ($this->order['ChoosePayment'] == 'BARCODE' || 27 | $this->order['ChoosePayment'] == 'ATM' || 28 | $this->order['ChoosePayment'] == 'CVS' 29 | ) { 30 | if (empty($this->paymentInfoUrl)) { 31 | throw new \InvalidArgumentException('PaymentInfoURL not set'); 32 | } 33 | } 34 | 35 | $this->order['CheckMacValue'] = $this->genCheckValue(); 36 | 37 | $formId = sprintf("PG_ALLPAY_FORM_GO_%s", sha1(time())); 38 | 39 | $html = sprintf( 40 | ""; 48 | 49 | if ($this->autoSubmit) { 50 | $html .= sprintf("", $formId); 51 | } 52 | 53 | return $html; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/EcPayPaymentGateway.php: -------------------------------------------------------------------------------- 1 | actionUrl)) { 20 | $this->actionUrl = 'https://payment.ecpay.com.tw/Cashier/AioCheckOut/'; 21 | } 22 | if (empty($this->version)) { 23 | $this->version = 'V4'; 24 | } 25 | 26 | return $this; 27 | } 28 | 29 | /** 30 | * @return EcPayPaymentGateway 31 | */ 32 | public function useBarCode() 33 | { 34 | $this->order['ChoosePayment'] = 'BARCODE'; 35 | $this->order['PaymentInfoURL'] = $this->paymentInfoUrl; 36 | return $this; 37 | } 38 | 39 | /** 40 | * @return EcPayPaymentGateway 41 | */ 42 | public function useWebATM() 43 | { 44 | $this->order['ChoosePayment'] = 'WebATM'; 45 | return $this; 46 | } 47 | 48 | /** 49 | * @return EcPayPaymentGateway 50 | */ 51 | public function useCredit() 52 | { 53 | $this->order['ChoosePayment'] = 'Credit'; 54 | return $this; 55 | } 56 | 57 | /** 58 | * @return EcPayPaymentGateway 59 | */ 60 | public function useATM() 61 | { 62 | $this->order['ChoosePayment'] = 'ATM'; 63 | $this->order['PaymentInfoURL'] = $this->paymentInfoUrl; 64 | return $this; 65 | } 66 | 67 | /** 68 | * @return EcPayPaymentGateway 69 | */ 70 | public function useCVS() 71 | { 72 | $this->order['ChoosePayment'] = 'CVS'; 73 | $this->order['PaymentInfoURL'] = $this->paymentInfoUrl; 74 | return $this; 75 | } 76 | 77 | /** 78 | * @return EcPayPaymentGateway 79 | */ 80 | public function useALL() 81 | { 82 | $this->order['ChoosePayment'] = 'ALL'; 83 | $this->order['PaymentInfoURL'] = $this->paymentInfoUrl; 84 | return $this; 85 | } 86 | 87 | /** 88 | * @return EcPayPaymentGateway 89 | */ 90 | public function needExtraPaidInfo() 91 | { 92 | $this->order['NeedExtraPaidInfo'] = 'Y'; 93 | return $this; 94 | } 95 | 96 | /** 97 | * @param integer $months 98 | * @param integer|float $totalAmount 99 | * @return EcPayPaymentGateway 100 | */ 101 | public function setCreditInstallment($months, $totalAmount = 0) 102 | { 103 | $this->order['CreditInstallment'] = $months; 104 | if ($totalAmount) { 105 | $this->order['InstallmentAmount'] = $totalAmount; 106 | } 107 | return $this; 108 | } 109 | 110 | /** 111 | * @param int|string $expireDate 112 | * @return EcPayPaymentGateway 113 | */ 114 | public function setOrderExpire($expireDate) 115 | { 116 | if (is_numeric($expireDate)) { 117 | $expireDate = intval($expireDate); 118 | } 119 | 120 | switch ($this->order['ChoosePayment']) { 121 | case 'ATM': 122 | $this->order['ExpireDate'] = $expireDate; 123 | break; 124 | case 'CVS': 125 | $this->order['StoreExpireDate'] = mktime( 126 | 23, 127 | 59, 128 | 59, 129 | date('m'), 130 | date('d') + $expireDate, 131 | date('Y') 132 | ) - time(); 133 | break; 134 | case 'BARCODE': 135 | $this->order['StoreExpireDate'] = $expireDate; 136 | break; 137 | } 138 | return $this; 139 | } 140 | 141 | /** 142 | * @return EcPayPaymentGateway 143 | */ 144 | public function setUnionPay() 145 | { 146 | $this->order['UnionPay'] = 1; 147 | return $this; 148 | } 149 | 150 | /** 151 | * @return array 152 | */ 153 | public function getOrder() 154 | { 155 | return $this->order; 156 | } 157 | 158 | /** 159 | * @param string $merchantOrderNo 160 | * @param float|int $amount 161 | * @param string $itemDescribe 162 | * @param string $orderComment 163 | * @param string $respondType 164 | * @param int $timestamp 165 | * @throws \InvalidArgumentException 166 | * @return EcPayPaymentGateway 167 | */ 168 | public function newOrder( 169 | $merchantOrderNo, 170 | $amount, 171 | $itemDescribe, 172 | $orderComment, 173 | $respondType = 'POST', 174 | $timestamp = 0 175 | ) { 176 | 177 | $this->argumentChecker(); 178 | 179 | $timestamp = empty($timestamp) ? time() : $timestamp; 180 | 181 | $this->clearOrder(); 182 | 183 | $this->order['PaymentType'] = 'aio'; 184 | $this->order['MerchantID'] = $this->merchantId; 185 | $this->order['MerchantTradeDate'] = date("Y/m/d H:i:s", $timestamp); 186 | $this->order['MerchantTradeNo'] = $merchantOrderNo; 187 | $this->order['TotalAmount'] = intval($amount); 188 | $this->order['ItemName'] = $itemDescribe; 189 | $this->order['TradeDesc'] = $orderComment; 190 | $this->order['EncryptType'] = 1; 191 | 192 | if (!empty($this->returnUrl)) { 193 | $this->order['ReturnURL'] = $this->returnUrl; 194 | } 195 | if (!empty($this->clientBackUrl)) { 196 | $this->order['ClientBackURL'] = $this->clientBackUrl; 197 | } 198 | 199 | return $this; 200 | } 201 | 202 | /** 203 | * @return string 204 | */ 205 | public function genCheckValue() 206 | { 207 | uksort($this->order, 'strcasecmp'); 208 | 209 | $merArray = array_merge(['HashKey' => $this->hashKey], $this->order, ['HashIV' => $this->hashIV]); 210 | 211 | $checkMerStr = urldecode(http_build_query($merArray)); 212 | 213 | foreach ($this->urlEncodeMapping as $key => $value) { 214 | $checkMerStr = str_replace($key, $value, $checkMerStr); 215 | } 216 | 217 | $checkMerStr = strtolower(urlencode($checkMerStr)); 218 | 219 | return strtoupper(hash('sha256', $checkMerStr)); 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /src/EcPayPaymentResponse.php: -------------------------------------------------------------------------------- 1 | processOrderPost(); 13 | } 14 | 15 | /** 16 | * @return bool|array 17 | */ 18 | public function processOrderPost() 19 | { 20 | if (!isset($_POST)) { 21 | return false; 22 | } 23 | if (empty($_POST)) { 24 | return false; 25 | } 26 | 27 | $post = filter_var_array($_POST, [ 28 | 'MerchantID' => FILTER_SANITIZE_STRING, 29 | 'MerchantTradeNo' => FILTER_SANITIZE_STRING, 30 | 'RtnCode' => FILTER_VALIDATE_INT, 31 | 'TradeAmt' => FILTER_VALIDATE_INT, 32 | 'RtnMsg' => FILTER_SANITIZE_STRING, 33 | 'TradeNo' => FILTER_SANITIZE_STRING, 34 | 'PaymentDate' => FILTER_SANITIZE_STRING, 35 | 'PaymentType' => FILTER_SANITIZE_STRING, 36 | 'PaymentTypeChargeFee' => FILTER_VALIDATE_INT, 37 | 'TradeDate' => FILTER_SANITIZE_STRING, 38 | 'SimulatePaid' => FILTER_VALIDATE_INT, 39 | 'CheckMacValue' => FILTER_SANITIZE_STRING, 40 | 'PeriodType' => FILTER_SANITIZE_STRING, 41 | 'Frequency' => FILTER_VALIDATE_INT, 42 | 'ExecTimes' => FILTER_VALIDATE_INT, 43 | 'amount' => FILTER_VALIDATE_INT, 44 | 'gwsr' => FILTER_VALIDATE_INT, 45 | 'stage' => FILTER_VALIDATE_INT, 46 | 'stast' => FILTER_VALIDATE_INT, 47 | 'eci' => FILTER_VALIDATE_INT, 48 | 'staed' => FILTER_VALIDATE_INT, 49 | 'red_dan' => FILTER_VALIDATE_INT, 50 | 'red_yet' => FILTER_VALIDATE_INT, 51 | 'red_de_amt' => FILTER_VALIDATE_INT, 52 | 'red_ok_amt' => FILTER_VALIDATE_INT, 53 | 'PeriodAmount' => FILTER_VALIDATE_INT, 54 | 'TotalSuccessTimes' => FILTER_VALIDATE_INT, 55 | 'FirstAuthAmount' => FILTER_VALIDATE_INT, 56 | 'TotalSuccessAmount' => FILTER_VALIDATE_INT, 57 | 'process_date' => FILTER_SANITIZE_STRING, 58 | 'auth_code' => FILTER_SANITIZE_STRING, 59 | 'WebATMAccBank' => FILTER_SANITIZE_STRING, 60 | 'WebATMAccNo' => FILTER_SANITIZE_STRING, 61 | 'WebATMBankName' => FILTER_SANITIZE_STRING, 62 | 'ATMAccBank' => FILTER_SANITIZE_STRING, 63 | 'ATMAccNo' => FILTER_SANITIZE_STRING, 64 | 'PaymentNo' => FILTER_SANITIZE_STRING, 65 | 'PayFrom' => FILTER_SANITIZE_STRING, 66 | 'card4no' => FILTER_SANITIZE_STRING, 67 | 'card6no' => FILTER_SANITIZE_STRING, 68 | ], false); 69 | 70 | if (!$post['RtnCode']) { 71 | return false; 72 | } 73 | 74 | $post['matched'] = $this->matchCheckCode($post); 75 | 76 | return $post; 77 | } 78 | 79 | public function matchCheckCode(array $payload = []) 80 | { 81 | $checkMacValue = $_POST['CheckMacValue']; 82 | 83 | unset($_POST['CheckMacValue']); 84 | 85 | uksort($_POST, 'strcasecmp'); 86 | 87 | $merArray = array_merge(['HashKey' => $this->hashKey], $_POST, ['HashIV' => $this->hashIV]); 88 | 89 | $checkMerStr = urldecode(http_build_query($merArray)); 90 | 91 | foreach ($this->urlEncodeMapping as $key => $value) { 92 | $checkMerStr = str_replace($key, $value, $checkMerStr); 93 | } 94 | 95 | $checkMerStr = strtolower(urlencode($checkMerStr)); 96 | 97 | return $checkMacValue == strtoupper(hash('sha256', $checkMerStr)); 98 | } 99 | 100 | public function rspOk() 101 | { 102 | echo "1|OK"; 103 | return true; 104 | } 105 | 106 | public function rspError($msg = 'Error') 107 | { 108 | echo "0|$msg"; 109 | return true; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/SpGatewayPaymentGateway.php: -------------------------------------------------------------------------------- 1 | actionUrl)) { 20 | $this->actionUrl = 'https://core.spgateway.com/MPG/mpg_gateway'; 21 | } 22 | if (empty($this->version)) { 23 | $this->version = '1.2'; 24 | } 25 | 26 | return $this; 27 | } 28 | 29 | /** 30 | * @return SpGatewayPaymentGateway 31 | */ 32 | public function useBarCode() 33 | { 34 | $this->order['BARCODE'] = 1; 35 | return $this; 36 | } 37 | 38 | /** 39 | * @return SpGatewayPaymentGateway 40 | */ 41 | public function useWebATM() 42 | { 43 | $this->order['WEBATM'] = 1; 44 | return $this; 45 | } 46 | 47 | /** 48 | * @return SpGatewayPaymentGateway 49 | */ 50 | public function useCredit() 51 | { 52 | $this->order['CREDIT'] = 1; 53 | return $this; 54 | } 55 | 56 | /** 57 | * @return SpGatewayPaymentGateway 58 | */ 59 | public function useATM() 60 | { 61 | $this->order['VACC'] = 1; 62 | return $this; 63 | } 64 | 65 | /** 66 | * @return SpGatewayPaymentGateway 67 | */ 68 | public function useCVS() 69 | { 70 | $this->order['CVS'] = 1; 71 | return $this; 72 | } 73 | 74 | /** 75 | * @param bool $mode 76 | * @return SpGatewayPaymentGateway 77 | */ 78 | public function triggerEmailModify($mode) 79 | { 80 | $this->order['EmailModify'] = (!!$mode) ? 1 : 0; 81 | return $this; 82 | } 83 | 84 | /** 85 | * @param bool $mode 86 | * @return SpGatewayPaymentGateway 87 | */ 88 | public function onlyLoginMemberCanPay($mode) 89 | { 90 | $this->order['LoginType'] = (!!$mode) ? 1 : 0; 91 | return $this; 92 | } 93 | 94 | /** 95 | * @param integer $months 96 | * @return SpGatewayPaymentGateway 97 | */ 98 | public function setCreditInstallment($months) 99 | { 100 | $this->order['InstFlag'] = $months; 101 | return $this; 102 | } 103 | 104 | /** 105 | * @param int|string $expireDate 106 | * @return SpGatewayPaymentGateway 107 | */ 108 | public function setOrderExpire($expireDate) 109 | { 110 | if (is_numeric($expireDate)) { 111 | $expireDate = intval($expireDate); 112 | } 113 | if (is_string($expireDate)) { 114 | $expireDate = intval(strtotime($expireDate)); 115 | } 116 | 117 | $this->order['ExpireDate'] = date('Ymd', $expireDate); 118 | return $this; 119 | } 120 | 121 | /** 122 | * @return SpGatewayPaymentGateway 123 | */ 124 | public function setUnionPay() 125 | { 126 | $this->order['UNIONPAY'] = 1; 127 | if (isset($this->order['CREDIT'])) { 128 | unset($this->order['CREDIT']); 129 | } 130 | return $this; 131 | } 132 | 133 | /** 134 | * @param string $email 135 | * @throws \InvalidArgumentException 136 | * @return SpGatewayPaymentGateway 137 | */ 138 | public function setEmail($email) 139 | { 140 | $email = filter_var($email, FILTER_VALIDATE_EMAIL); 141 | 142 | if ($email === false) { 143 | throw new \InvalidArgumentException('Invalid email format'); 144 | } 145 | 146 | $this->order['Email'] = $email; 147 | return $this; 148 | } 149 | 150 | /** 151 | * @return array 152 | */ 153 | public function getOrder() 154 | { 155 | return $this->order; 156 | } 157 | 158 | /** 159 | * @param string $merchantOrderNo 160 | * @param float|int $amount 161 | * @param string $itemDescribe 162 | * @param string $orderComment 163 | * @param string $respondType 164 | * @param int $timestamp 165 | * @throws \InvalidArgumentException 166 | * @return SpGatewayPaymentGateway 167 | */ 168 | public function newOrder( 169 | $merchantOrderNo, 170 | $amount, 171 | $itemDescribe, 172 | $orderComment, 173 | $respondType = 'JSON', 174 | $timestamp = 0 175 | ) { 176 | 177 | /** 178 | * Argument Check 179 | */ 180 | $this->argumentChecker(); 181 | 182 | if (!isset($this->notifyUrl)) { 183 | throw new \InvalidArgumentException('NotifyURL not set'); 184 | } 185 | 186 | $timestamp = empty($timestamp) ? time() : $timestamp; 187 | 188 | $this->clearOrder(); 189 | 190 | $this->order['Amt'] = intval($amount); 191 | $this->order['Version'] = $this->version; 192 | $this->order['LangType'] = 'zh-tw'; 193 | $this->order['TimeStamp'] = $timestamp; 194 | $this->order['MerchantID'] = $this->merchantId; 195 | $this->order['RespondType'] = $respondType; 196 | 197 | $this->order['MerchantOrderNo'] = $merchantOrderNo; 198 | 199 | $this->order['ItemDesc'] = $itemDescribe; 200 | $this->order['OrderComment'] = $orderComment; 201 | 202 | if (!empty($this->returnUrl)) { 203 | $this->order['ReturnURL'] = $this->returnUrl; 204 | } 205 | if (!empty($this->notifyUrl)) { 206 | $this->order['NotifyURL'] = $this->notifyUrl; 207 | } 208 | if (!empty($this->paymentInfoUrl)) { 209 | $this->order['CustomerURL'] = $this->paymentInfoUrl; 210 | } 211 | if (!empty($this->clientBackUrl)) { 212 | $this->order['ClientBackURL'] = $this->clientBackUrl; 213 | } 214 | 215 | return $this; 216 | } 217 | 218 | protected function isPaymentMethodSelected() 219 | { 220 | if (!isset($this->order['UNIONPAY']) && 221 | !isset($this->order['BARCODE']) && 222 | !isset($this->order['CREDIT']) && 223 | !isset($this->order['WEBATM']) && 224 | !isset($this->order['VACC']) && 225 | !isset($this->order['CVS']) 226 | ) { 227 | throw new \InvalidArgumentException('Payment method not set'); 228 | } 229 | } 230 | 231 | /** 232 | * @param bool $autoSubmit 233 | * @return string 234 | */ 235 | public function genForm($autoSubmit) 236 | { 237 | $this->autoSubmit = !!$autoSubmit; 238 | 239 | $this->isPaymentMethodSelected(); 240 | 241 | if (isset($this->order['BARCODE']) || 242 | isset($this->order['VACC']) || 243 | isset($this->order['CVS']) 244 | ) { 245 | if (empty($this->paymentInfoUrl)) { 246 | throw new \InvalidArgumentException('PaymentInfoURL not set'); 247 | } 248 | } 249 | 250 | if (!isset($this->order['LoginType'])) { 251 | $this->order['LoginType'] = 0; 252 | } 253 | if (!isset($this->order['EmailModify'])) { 254 | $this->order['EmailModify'] = 0; 255 | } 256 | 257 | $this->order['CheckValue'] = $this->genCheckValue(); 258 | 259 | $formId = sprintf("PG_SPGATEWAY_FORM_GO_%s", sha1(time())); 260 | 261 | $html = sprintf( 262 | ""; 270 | 271 | if ($this->autoSubmit) { 272 | $html .= sprintf("", $formId); 273 | } 274 | 275 | return $html; 276 | } 277 | 278 | /** 279 | * @return string 280 | */ 281 | public function genCheckValue() 282 | { 283 | $merArray = [ 284 | 'MerchantOrderNo' => $this->order['MerchantOrderNo'], 285 | 'MerchantID' => $this->merchantId, 286 | 'TimeStamp' => $this->order['TimeStamp'], 287 | 'Version' => $this->version, 288 | 'Amt' => $this->order['Amt'], 289 | ]; 290 | 291 | ksort($merArray); 292 | 293 | $merArray = array_merge(['HashKey' => $this->hashKey], $merArray, ['HashIV' => $this->hashIV]); 294 | 295 | $checkMerStr = http_build_query($merArray); 296 | 297 | return strtoupper(hash("sha256", $checkMerStr)); 298 | } 299 | } 300 | -------------------------------------------------------------------------------- /src/SpGatewayPaymentResponse.php: -------------------------------------------------------------------------------- 1 | processOrderJson(); 14 | break; 15 | case 'POST': 16 | default: 17 | return $this->processOrderPost(); 18 | break; 19 | } 20 | } 21 | 22 | /** 23 | * @return bool|array 24 | */ 25 | public function processOrderJson() 26 | { 27 | if (!isset($_POST['JSONData'])) { 28 | return false; 29 | } 30 | 31 | $post = json_decode($_POST['JSONData'], true); 32 | 33 | if ($post['Status'] !== 'SUCCESS') { 34 | return false; 35 | } 36 | 37 | $result = json_decode($post['Result'], true); 38 | 39 | $result['matched'] = $this->matchCheckCode($result); 40 | 41 | return $result; 42 | } 43 | 44 | /** 45 | * @return bool|array 46 | */ 47 | public function processOrderPost() 48 | { 49 | if (!isset($_POST)) { 50 | return false; 51 | } 52 | if (empty($_POST)) { 53 | return false; 54 | } 55 | 56 | $post = filter_var_array($_POST, [ 57 | 'Status' => FILTER_SANITIZE_STRING, 58 | 'Message' => FILTER_SANITIZE_STRING, 59 | 'MerchantID' => FILTER_SANITIZE_STRING, 60 | 'Amt' => FILTER_VALIDATE_INT, 61 | 'TradeNo' => FILTER_SANITIZE_STRING, 62 | 'MerchantOrderNo' => FILTER_SANITIZE_STRING, 63 | 'PaymentType' => FILTER_SANITIZE_STRING, 64 | 'RespondType' => FILTER_SANITIZE_STRING, 65 | 'CheckCode' => FILTER_SANITIZE_STRING, 66 | 'PayTime' => FILTER_SANITIZE_STRING, 67 | 'IP' => FILTER_VALIDATE_IP, 68 | 'EscrowBank' => FILTER_SANITIZE_STRING, 69 | 'TokenUseStatus' => FILTER_VALIDATE_INT, 70 | 'RespondCode' => FILTER_SANITIZE_STRING, 71 | 'Auth' => FILTER_SANITIZE_STRING, 72 | 'Card6No' => FILTER_SANITIZE_STRING, 73 | 'Card4No' => FILTER_SANITIZE_STRING, 74 | 'Inst' => FILTER_VALIDATE_INT, 75 | 'InstFirst' => FILTER_VALIDATE_INT, 76 | 'InstEach' => FILTER_VALIDATE_INT, 77 | 'ECI' => FILTER_SANITIZE_STRING, 78 | 'PayBankCode' => FILTER_SANITIZE_STRING, 79 | 'PayerAccount5Code' => FILTER_SANITIZE_STRING, 80 | 'CodeNo' => FILTER_SANITIZE_STRING, 81 | 'Barcode_1' => FILTER_SANITIZE_STRING, 82 | 'Barcode_2' => FILTER_SANITIZE_STRING, 83 | 'Barcode_3' => FILTER_SANITIZE_STRING, 84 | 'PayStore' => FILTER_SANITIZE_STRING 85 | ], false); 86 | 87 | if ($post['Status'] !== 'SUCCESS') { 88 | return false; 89 | } 90 | 91 | $post['matched'] = $this->matchCheckCode($post); 92 | 93 | return $post; 94 | } 95 | 96 | public function matchCheckCode(array $payload = []) 97 | { 98 | $matchedCode = $payload['CheckCode']; 99 | 100 | $checkCode = [ 101 | "Amt" => $payload['Amt'], 102 | "TradeNo" => $payload['TradeNo'], 103 | "MerchantID" => $payload['MerchantID'], 104 | "MerchantOrderNo" => $payload['MerchantOrderNo'], 105 | ]; 106 | 107 | ksort($checkCode); 108 | 109 | $checkCode = array_merge(['HashIV' => $this->hashIV], $checkCode, ['HashKey' => $this->hashKey]); 110 | 111 | $checkStr = http_build_query($checkCode); 112 | 113 | return $matchedCode == strtoupper(hash("sha256", $checkStr)); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/TaiwanPaymentGateway.php: -------------------------------------------------------------------------------- 1 | "VT-TPG-TEST", 18 | 'amount' => 100, 19 | 'itemDesc' => 'VT-TPG-TEST-ITEM-DESC', 20 | 'orderComment' => 'VT-TPG-TEST-ITEM-DESC', 21 | 'ts' => 1492287995 22 | ]; 23 | 24 | 25 | protected $config = [ 26 | 'hashKey' => '5294y06JbISpM5x9', 27 | 'hashIV' => 'v77hoKGq4kWxNNIS', 28 | 'merchantId' => '2000132', 29 | 'version' => 'V2', 30 | 'actionUrl' => 'https://ccore.spgateway.com/MPG/mpg_gateway', 31 | 'returnUrl' => 'https://localhost/tpg/confirm', 32 | 'notifyUrl' => '', 33 | 'clientBackUrl' => 'https://localhost/tpg/return', 34 | ]; 35 | 36 | function __construct($name = null, array $data = [], $dataName = '') 37 | { 38 | parent::__construct($name, $data, $dataName); 39 | $this->gw = new AllPayPaymentGateway($this->config); 40 | } 41 | 42 | public function testConstruct() 43 | { 44 | 45 | $config = $this->config; 46 | 47 | unset($config['version']); 48 | unset($config['actionUrl']); 49 | 50 | $this->gw = new AllPayPaymentGateway($config); 51 | $this->assertInstanceOf(AllPayPaymentGateway::class, $this->gw); 52 | } 53 | 54 | public function testGetNonExistsConfig() 55 | { 56 | try { 57 | $this->gw->getConfig('NonExists'); 58 | } catch (\InvalidArgumentException $e) { 59 | $this->assertEquals('config key not exists.', $e->getMessage()); 60 | } 61 | } 62 | 63 | public function testSetNonExistsConfig() 64 | { 65 | try { 66 | $this->gw->setConfig('NonExists', sha1(time())); 67 | } catch (\InvalidArgumentException $e) { 68 | $this->assertEquals('config key not exists.', $e->getMessage()); 69 | } 70 | } 71 | 72 | public function testNewOrder() 73 | { 74 | $this->gw->newOrder( 75 | $this->order['mid'], 76 | $this->order['amount'], 77 | $this->order['itemDesc'], 78 | $this->order['orderComment'], 79 | 'POST', 80 | $this->order['ts'] 81 | ); 82 | 83 | $this->assertNotEmpty($this->gw->getOrder()); 84 | } 85 | 86 | public function testGenOrderForm() 87 | { 88 | $this->testNewOrder(); 89 | 90 | $this->gw->useCredit()->needExtraPaidInfo()->setCreditInstallment(3, $this->order['amount']); 91 | $this->assertNotEmpty($this->gw->genForm(false)); 92 | } 93 | 94 | public function testUnionPay() 95 | { 96 | $this->testNewOrder(); 97 | $this->gw->useCredit()->setUnionPay(); 98 | $this->assertNotEmpty($this->gw->genForm(true)); 99 | } 100 | 101 | public function testPaymentMethodNotSet() 102 | { 103 | try{ 104 | $this->testNewOrder(); 105 | $this->assertNotEmpty($this->gw->genForm(true)); 106 | } catch (\Exception $e) { 107 | $this->assertEquals('Payment method not set', $e->getMessage()); 108 | } 109 | } 110 | public function testPaymentInfoUrlNotSet() 111 | { 112 | try{ 113 | $this->testNewOrder(); 114 | $this->gw->useBarCode()->setConfig('paymentInfoUrl', 0); 115 | $this->gw->genForm(true); 116 | } catch (\Exception $e) { 117 | $this->assertEquals('PaymentInfoURL not set', $e->getMessage()); 118 | } 119 | } 120 | 121 | public function testUseWebAtm() 122 | { 123 | $this->testNewOrder(); 124 | $this->gw 125 | ->useWebATM() 126 | ->setConfig('paymentInfoUrl', 'https://localhost/payment/information'); 127 | } 128 | 129 | public function testUseTopUp() 130 | { 131 | $this->testNewOrder(); 132 | $this->gw 133 | ->useTopUp(); 134 | } 135 | 136 | public function testUseAtm() 137 | { 138 | $this->testNewOrder(); 139 | $this->gw 140 | ->useATM() 141 | ->setOrderExpire(mktime(23, 59, 59, date('m'), date('d') + 3, date('Y'))) 142 | ->setConfig('paymentInfoUrl', 'https://localhost/payment/information'); 143 | } 144 | 145 | public function testUseCvs() 146 | { 147 | $this->testNewOrder(); 148 | $this->gw 149 | ->useCVS() 150 | ->setOrderExpire(7) 151 | ->setConfig('paymentInfoUrl', 'https://localhost/payment/information'); 152 | } 153 | 154 | public function testUseTenPay() 155 | { 156 | $this->testNewOrder(); 157 | $this->gw 158 | ->useTenPay() 159 | ->setOrderExpire(7); 160 | } 161 | 162 | public function testUseBarCode() 163 | { 164 | $this->testNewOrder(); 165 | $this->gw 166 | ->useBarCode() 167 | ->setOrderExpire(mktime(23, 59, 59, date('m'), date('d') + 7, date('Y'))) 168 | ->setConfig('paymentInfoUrl', 'https://localhost/payment/information'); 169 | } 170 | 171 | public function testUseAll() 172 | { 173 | $this->testNewOrder(); 174 | $this->gw 175 | ->useALL() 176 | ->setConfig('paymentInfoUrl', 'https://localhost/payment/information'); 177 | } 178 | 179 | public function testNewOrderNoHashIv() 180 | { 181 | try { 182 | $config = $this->config; 183 | 184 | unset($config['hashIV']); 185 | 186 | $gw = new AllPayPaymentGateway($config); 187 | 188 | $gw->newOrder($this->order['mid'], 189 | $this->order['amount'], 190 | $this->order['itemDesc'], 191 | $this->order['orderComment'], 192 | 'JSON', 193 | $this->order['ts'] 194 | ); 195 | } catch (\InvalidArgumentException $e) { 196 | $this->assertEquals('HashIV not set', $e->getMessage()); 197 | } 198 | 199 | } 200 | 201 | public function testNewOrderNoHashKey() 202 | { 203 | try { 204 | 205 | $config = $this->config; 206 | 207 | unset($config['hashKey']); 208 | 209 | $gw = new AllPayPaymentGateway($config); 210 | 211 | $gw->newOrder($this->order['mid'], 212 | $this->order['amount'], 213 | $this->order['itemDesc'], 214 | $this->order['orderComment'], 215 | 'JSON', 216 | $this->order['ts'] 217 | ); 218 | } catch (\InvalidArgumentException $e) { 219 | $this->assertEquals('HashKey not set', $e->getMessage()); 220 | } 221 | 222 | } 223 | 224 | public function testNewOrderNoMerchantID() 225 | { 226 | try { 227 | $config = $this->config; 228 | 229 | unset($config['merchantId']); 230 | 231 | $gw = new AllPayPaymentGateway($config); 232 | 233 | $gw->newOrder($this->order['mid'], 234 | $this->order['amount'], 235 | $this->order['itemDesc'], 236 | $this->order['orderComment'], 237 | 'JSON', 238 | $this->order['ts'] 239 | ); 240 | } catch (\InvalidArgumentException $e) { 241 | $this->assertEquals('MerchantID not set', $e->getMessage()); 242 | } 243 | 244 | } 245 | 246 | public function testNewOrderNoReturnURL() 247 | { 248 | try { 249 | $config = $this->config; 250 | 251 | unset($config['returnUrl']); 252 | 253 | $gw = new AllPayPaymentGateway($config); 254 | 255 | $gw->newOrder($this->order['mid'], 256 | $this->order['amount'], 257 | $this->order['itemDesc'], 258 | $this->order['orderComment'], 259 | 'JSON', 260 | $this->order['ts'] 261 | ); 262 | } catch (\InvalidArgumentException $e) { 263 | $this->assertEquals('ReturnURL not set', $e->getMessage()); 264 | } 265 | 266 | } 267 | 268 | public function testNewOrderSetNotifyURL() 269 | { 270 | $config = $this->config; 271 | 272 | $config['notifyUrl'] = 'https://localhost/tpg/notify'; 273 | 274 | $gw = new AllPayPaymentGateway($config); 275 | 276 | $gw->newOrder($this->order['mid'], 277 | $this->order['amount'], 278 | $this->order['itemDesc'], 279 | $this->order['orderComment'], 280 | 'JSON', 281 | $this->order['ts'] 282 | ); 283 | 284 | } 285 | 286 | public function testNewOrderNoNotifyUrl() 287 | { 288 | try { 289 | $config = $this->config; 290 | 291 | unset($config['notifyUrl']); 292 | 293 | $gw = new AllPayPaymentGateway($config); 294 | 295 | $gw->newOrder($this->order['mid'], 296 | $this->order['amount'], 297 | $this->order['itemDesc'], 298 | $this->order['orderComment'], 299 | 'JSON', 300 | $this->order['ts'] 301 | ); 302 | } catch (\InvalidArgumentException $e) { 303 | $this->assertEquals('NotifyURL not set', $e->getMessage()); 304 | } 305 | 306 | } 307 | 308 | public function testNewOrderNoActionURL() 309 | { 310 | try { 311 | $gw = new AllPayPaymentGateway($this->config); 312 | 313 | $gw->setConfig('actionUrl', 0); 314 | 315 | $gw->newOrder($this->order['mid'], 316 | $this->order['amount'], 317 | $this->order['itemDesc'], 318 | $this->order['orderComment'], 319 | 'JSON', 320 | $this->order['ts'] 321 | )->useBarCode(); 322 | } catch (\InvalidArgumentException $e) { 323 | $this->assertEquals('ActionURL not set', $e->getMessage()); 324 | } 325 | 326 | } 327 | 328 | public function testNewOrderSetPaymentInfoURL() 329 | { 330 | $gw = new AllPayPaymentGateway($this->config); 331 | 332 | $gw->setConfig('paymentInfoUrl', 'https://localhost/tpg/info'); 333 | 334 | $gw->newOrder($this->order['mid'], 335 | $this->order['amount'], 336 | $this->order['itemDesc'], 337 | $this->order['orderComment'], 338 | 'JSON', 339 | $this->order['ts'] 340 | ); 341 | } 342 | } 343 | -------------------------------------------------------------------------------- /tests/TaiwanPaymentGateway/AllPayPaymentResponseTest.php: -------------------------------------------------------------------------------- 1 | '5294y06JbISpM5x9', 17 | 'hashIV' => 'v77hoKGq4kWxNNIS', 18 | 'merchantId' => '2000132', 19 | 'version' => 'V2', 20 | ]; 21 | 22 | public function testConstruct() 23 | { 24 | $gwr = new AllPayPaymentResponse($this->config); 25 | 26 | $this->assertInstanceOf(AllPayPaymentResponse::class, $gwr); 27 | } 28 | 29 | public function testProcessOrder() 30 | { 31 | $gwr = new AllPayPaymentResponse($this->config); 32 | 33 | $_POST = [ 34 | 'AlipayID' => '', 35 | 'AlipayTradeNo' => '', 36 | 'amount' => '100', 37 | 'ATMAccBank' => '', 38 | 'ATMAccNo' => '', 39 | 'auth_code' => '777777', 40 | 'card4no' => '2222', 41 | 'card6no' => '431195', 42 | 'eci' => '0', 43 | 'ExecTimes' => '', 44 | 'Frequency' => '', 45 | 'gwsr' => '10541521', 46 | 'MerchantID' => '2000132', 47 | 'MerchantTradeNo' => 'VT1490265603', 48 | 'PayFrom' => '', 49 | 'PaymentDate' => '2017/03/23 18:41:19', 50 | 'PaymentNo' => '', 51 | 'PaymentType' => 'Credit_CreditCard', 52 | 'PaymentTypeChargeFee' => '1', 53 | 'PeriodAmount' => '', 54 | 'PeriodType' => '', 55 | 'process_date' => '2017/03/23 18:41:19', 56 | 'red_dan' => '0', 57 | 'red_de_amt' => '0', 58 | 'red_ok_amt' => '0', 59 | 'red_yet' => '0', 60 | 'RtnCode' => '1', 61 | 'RtnMsg' => '交易成功', 62 | 'SimulatePaid' => '0', 63 | 'staed' => '0', 64 | 'stage' => '0', 65 | 'stast' => '0', 66 | 'TenpayTradeNo' => '', 67 | 'TotalSuccessAmount' => '', 68 | 'TotalSuccessTimes' => '', 69 | 'TradeAmt' => '100', 70 | 'TradeDate' => '2017/03/23 18:40:20', 71 | 'TradeNo' => '1703231840205732', 72 | 'WebATMAccBank' => '', 73 | 'WebATMAccNo' => '', 74 | 'WebATMBankName' => '', 75 | 'CheckMacValue' => 'C65E91444C43934C9E363D9EBCD72BB5BA88600E6EB5DA4034BACF99A2663263', 76 | ]; 77 | 78 | $result = $gwr->processOrder(); 79 | 80 | $this->assertEquals(true, $result['matched']); 81 | 82 | if ($result['matched']) { 83 | $gwr->rspOk(); 84 | } else { 85 | $gwr->rspError(); 86 | } 87 | 88 | } 89 | 90 | public function testProcessOrderWrongPOST() 91 | { 92 | $gwr = new AllPayPaymentResponse([ 93 | 'hashKey' => 'fyjEf9sLkim7RdDvGeZZfVcLef5jDyWT', 94 | 'hashIV' => '6fxmp07KjuRaHvFo', 95 | 'merchantId' => 'MS3606763', 96 | 'version' => '1.2', 97 | ]); 98 | 99 | $_POST = array( 100 | 'RtnCode' => '0', 101 | ); 102 | 103 | $result = $gwr->processOrder('POST'); 104 | 105 | $this->assertEquals(false, $result); 106 | 107 | $_POST = []; 108 | 109 | $result = $gwr->processOrder('POST'); 110 | 111 | $this->assertEquals(false, $result); 112 | 113 | unset($_POST); 114 | 115 | $result = $gwr->processOrder('POST'); 116 | 117 | $this->assertEquals(false, $result); 118 | 119 | if ($result['matched']) { 120 | $gwr->rspOk(); 121 | } else { 122 | $gwr->rspError('Failed'); 123 | } 124 | 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /tests/TaiwanPaymentGateway/EcPayPaymentGatewayTest.php: -------------------------------------------------------------------------------- 1 | "VT-TPG-TEST", 18 | 'amount' => 100, 19 | 'itemDesc' => 'VT-TPG-TEST-ITEM-DESC', 20 | 'orderComment' => 'VT-TPG-TEST-ITEM-DESC', 21 | 'ts' => 1492287995 22 | ]; 23 | 24 | function __construct($name = null, array $data = [], $dataName = '') 25 | { 26 | parent::__construct($name, $data, $dataName); 27 | $this->gw = new EcPayPaymentGateway([ 28 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 29 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 30 | 'merchantId' => 'MS11434419', 31 | 'version' => '1.2', 32 | 'actionUrl' => 'https://ccore.spgateway.com/MPG/mpg_gateway', 33 | 'returnUrl' => 'https://localhost/tpg/confirm', 34 | 'notifyUrl' => '', 35 | 'clientBackUrl' => 'https://localhost/tpg/return', 36 | ]); 37 | } 38 | 39 | public function testConstruct() 40 | { 41 | $this->gw = new EcPayPaymentGateway([ 42 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 43 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 44 | 'merchantId' => 'MS11434419', 45 | 'version' => '1.2', 46 | 'actionUrl' => 'https://ccore.spgateway.com/MPG/mpg_gateway', 47 | 'returnUrl' => 'https://localhost/tpg/confirm', 48 | 'notifyUrl' => '', 49 | 'clientBackUrl' => 'https://localhost/tpg/return', 50 | ]); 51 | $this->assertInstanceOf(EcPayPaymentGateway::class, $this->gw); 52 | } 53 | 54 | public function testGetNonExistsConfig() 55 | { 56 | try { 57 | $this->gw->getConfig('NonExists'); 58 | } catch (\InvalidArgumentException $e) { 59 | $this->assertEquals('config key not exists.', $e->getMessage()); 60 | } 61 | } 62 | 63 | public function testSetNonExistsConfig() 64 | { 65 | try { 66 | $this->gw->setConfig('NonExists', sha1(time())); 67 | } catch (\InvalidArgumentException $e) { 68 | $this->assertEquals('config key not exists.', $e->getMessage()); 69 | } 70 | } 71 | 72 | public function testNewOrder() 73 | { 74 | $this->gw->newOrder( 75 | $this->order['mid'], 76 | $this->order['amount'], 77 | $this->order['itemDesc'], 78 | $this->order['orderComment'], 79 | 'POST', 80 | $this->order['ts'] 81 | ); 82 | 83 | $this->assertNotEmpty($this->gw->getOrder()); 84 | } 85 | 86 | public function testGenOrderForm() 87 | { 88 | $this->testNewOrder(); 89 | $this->gw->useCredit()->needExtraPaidInfo()->setCreditInstallment(3, $this->order['amount']); 90 | $this->assertNotEmpty($this->gw->genForm(false)); 91 | } 92 | 93 | public function testUnionPay() 94 | { 95 | $this->testNewOrder(); 96 | $this->gw->useCredit()->setUnionPay(); 97 | $this->assertNotEmpty($this->gw->genForm(true)); 98 | } 99 | 100 | public function testPaymentMethodNotSet() 101 | { 102 | try{ 103 | $this->testNewOrder(); 104 | $this->assertNotEmpty($this->gw->genForm(true)); 105 | } catch (\Exception $e) { 106 | $this->assertEquals('Payment method not set', $e->getMessage()); 107 | } 108 | } 109 | public function testPaymentInfoUrlNotSet() 110 | { 111 | try{ 112 | $this->testNewOrder(); 113 | $this->gw->useBarCode()->setConfig('paymentInfoUrl', 0); 114 | $this->gw->genForm(true); 115 | } catch (\Exception $e) { 116 | $this->assertEquals('PaymentInfoURL not set', $e->getMessage()); 117 | } 118 | } 119 | 120 | public function testUseWebAtm() 121 | { 122 | $this->testNewOrder(); 123 | $this->gw 124 | ->useWebATM() 125 | ->setConfig('paymentInfoUrl', 'https://localhost/payment/information'); 126 | } 127 | 128 | public function testUseAtm() 129 | { 130 | $this->testNewOrder(); 131 | $this->gw 132 | ->useATM() 133 | ->setOrderExpire(mktime(23, 59, 59, date('m'), date('d') + 3, date('Y'))) 134 | ->setConfig('paymentInfoUrl', 'https://localhost/payment/information'); 135 | } 136 | 137 | public function testUseCvs() 138 | { 139 | $this->testNewOrder(); 140 | $this->gw 141 | ->useCVS() 142 | ->setOrderExpire(7) 143 | ->setConfig('paymentInfoUrl', 'https://localhost/payment/information'); 144 | } 145 | 146 | public function testUseBarCode() 147 | { 148 | $this->testNewOrder(); 149 | $this->gw 150 | ->useBarCode() 151 | ->setOrderExpire(mktime(23, 59, 59, date('m'), date('d') + 7, date('Y'))) 152 | ->setConfig('paymentInfoUrl', 'https://localhost/payment/information'); 153 | } 154 | 155 | public function testUseAll() 156 | { 157 | $this->testNewOrder(); 158 | $this->gw 159 | ->useALL() 160 | ->setConfig('paymentInfoUrl', 'https://localhost/payment/information'); 161 | } 162 | 163 | public function testNewOrderNoHashIv() 164 | { 165 | try { 166 | $gw = new EcPayPaymentGateway([ 167 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 168 | 'hashIV' => null, //'KHQ49UsmwMZJk6D1', 169 | 'merchantId' => 'MS11434419', 170 | 'returnUrl' => 'https://localhost/tpg/confirm', 171 | 'notifyUrl' => '', 172 | 'clientBackUrl' => 'https://localhost/tpg/return', 173 | ]); 174 | 175 | $gw->newOrder($this->order['mid'], 176 | $this->order['amount'], 177 | $this->order['itemDesc'], 178 | $this->order['orderComment'], 179 | 'JSON', 180 | $this->order['ts'] 181 | ); 182 | } catch (\InvalidArgumentException $e) { 183 | $this->assertEquals('HashIV not set', $e->getMessage()); 184 | } 185 | 186 | } 187 | 188 | public function testNewOrderNoHashKey() 189 | { 190 | try { 191 | $gw = new EcPayPaymentGateway([ 192 | 'hashKey' => null, //'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 193 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 194 | 'merchantId' => 'MS11434419', 195 | 'returnUrl' => 'https://localhost/tpg/confirm', 196 | 'notifyUrl' => '', 197 | 'clientBackUrl' => 'https://localhost/tpg/return', 198 | ]); 199 | 200 | $gw->newOrder($this->order['mid'], 201 | $this->order['amount'], 202 | $this->order['itemDesc'], 203 | $this->order['orderComment'], 204 | 'JSON', 205 | $this->order['ts'] 206 | ); 207 | } catch (\InvalidArgumentException $e) { 208 | $this->assertEquals('HashKey not set', $e->getMessage()); 209 | } 210 | 211 | } 212 | 213 | public function testNewOrderNoMerchantID() 214 | { 215 | try { 216 | $gw = new EcPayPaymentGateway([ 217 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 218 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 219 | 'merchantId' => null, //'MS11434419', 220 | 'returnUrl' => 'https://localhost/tpg/confirm', 221 | 'notifyUrl' => '', 222 | 'clientBackUrl' => 'https://localhost/tpg/return', 223 | ]); 224 | 225 | $gw->newOrder($this->order['mid'], 226 | $this->order['amount'], 227 | $this->order['itemDesc'], 228 | $this->order['orderComment'], 229 | 'JSON', 230 | $this->order['ts'] 231 | ); 232 | } catch (\InvalidArgumentException $e) { 233 | $this->assertEquals('MerchantID not set', $e->getMessage()); 234 | } 235 | 236 | } 237 | 238 | public function testNewOrderNoReturnURL() 239 | { 240 | try { 241 | $gw = new EcPayPaymentGateway([ 242 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 243 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 244 | 'merchantId' => 'MS11434419', 245 | 'returnUrl' => null, //'https://localhost/tpg/confirm', 246 | 'notifyUrl' => '', 247 | 'clientBackUrl' => 'https://localhost/tpg/return', 248 | ]); 249 | 250 | $gw->newOrder($this->order['mid'], 251 | $this->order['amount'], 252 | $this->order['itemDesc'], 253 | $this->order['orderComment'], 254 | 'JSON', 255 | $this->order['ts'] 256 | ); 257 | } catch (\InvalidArgumentException $e) { 258 | $this->assertEquals('ReturnURL not set', $e->getMessage()); 259 | } 260 | 261 | } 262 | 263 | public function testNewOrderSetNotifyURL() 264 | { 265 | $gw = new EcPayPaymentGateway([ 266 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 267 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 268 | 'merchantId' => 'MS11434419', 269 | 'returnUrl' => 'https://localhost/tpg/confirm', 270 | 'notifyUrl' => 'https://localhost/tpg/notify', 271 | 'clientBackUrl' => 'https://localhost/tpg/return', 272 | ]); 273 | 274 | $gw->newOrder($this->order['mid'], 275 | $this->order['amount'], 276 | $this->order['itemDesc'], 277 | $this->order['orderComment'], 278 | 'JSON', 279 | $this->order['ts'] 280 | ); 281 | 282 | } 283 | 284 | public function testNewOrderNoNotifyUrl() 285 | { 286 | try { 287 | $gw = new EcPayPaymentGateway([ 288 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 289 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 290 | 'merchantId' => 'MS11434419', 291 | 'returnUrl' => 'https://localhost/tpg/confirm', 292 | 'notifyUrl' => null, 293 | 'clientBackUrl' => 'https://localhost/tpg/return', 294 | ]); 295 | 296 | $gw->setConfig('paymentInfoUrl', 'https://localhost/tpg/info'); 297 | 298 | $gw->newOrder($this->order['mid'], 299 | $this->order['amount'], 300 | $this->order['itemDesc'], 301 | $this->order['orderComment'], 302 | 'JSON', 303 | $this->order['ts'] 304 | ); 305 | } catch (\InvalidArgumentException $e) { 306 | $this->assertEquals('NotifyURL not set', $e->getMessage()); 307 | } 308 | 309 | } 310 | 311 | public function testNewOrderNoActionURL() 312 | { 313 | try { 314 | $gw = new EcPayPaymentGateway([ 315 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 316 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 317 | 'merchantId' => 'MS11434419', 318 | 'returnUrl' => 'https://localhost/tpg/confirm', 319 | 'notifyUrl' => '', 320 | 'clientBackUrl' => 'https://localhost/tpg/return', 321 | ]); 322 | 323 | $gw->setConfig('actionUrl', 0); 324 | 325 | $gw->newOrder($this->order['mid'], 326 | $this->order['amount'], 327 | $this->order['itemDesc'], 328 | $this->order['orderComment'], 329 | 'JSON', 330 | $this->order['ts'] 331 | )->useBarCode(); 332 | } catch (\InvalidArgumentException $e) { 333 | $this->assertEquals('ActionURL not set', $e->getMessage()); 334 | } 335 | 336 | } 337 | 338 | public function testNewOrderSetPaymentInfoURL() 339 | { 340 | $gw = new EcPayPaymentGateway([ 341 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 342 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 343 | 'merchantId' => 'MS11434419', 344 | 'returnUrl' => 'https://localhost/tpg/confirm', 345 | 'notifyUrl' => '', 346 | 'clientBackUrl' => 'https://localhost/tpg/return', 347 | ]); 348 | 349 | $gw->setConfig('paymentInfoUrl', 'https://localhost/tpg/info'); 350 | 351 | $gw->newOrder($this->order['mid'], 352 | $this->order['amount'], 353 | $this->order['itemDesc'], 354 | $this->order['orderComment'], 355 | 'JSON', 356 | $this->order['ts'] 357 | ); 358 | } 359 | } 360 | -------------------------------------------------------------------------------- /tests/TaiwanPaymentGateway/EcPayPaymentResponseTest.php: -------------------------------------------------------------------------------- 1 | '5294y06JbISpM5x9', 17 | 'hashIV' => 'v77hoKGq4kWxNNIS', 18 | 'merchantId' => '2000132', 19 | 'version' => 'V2', 20 | ]; 21 | 22 | public function testConstruct() 23 | { 24 | $gwr = new EcPayPaymentResponse($this->config); 25 | 26 | $this->assertInstanceOf(EcPayPaymentResponse::class, $gwr); 27 | } 28 | 29 | public function testProcessOrder() 30 | { 31 | $gwr = new EcPayPaymentResponse($this->config); 32 | 33 | $_POST = [ 34 | 'AlipayID' => '', 35 | 'AlipayTradeNo' => '', 36 | 'amount' => '100', 37 | 'ATMAccBank' => '', 38 | 'ATMAccNo' => '', 39 | 'auth_code' => '777777', 40 | 'card4no' => '2222', 41 | 'card6no' => '431195', 42 | 'eci' => '0', 43 | 'ExecTimes' => '', 44 | 'Frequency' => '', 45 | 'gwsr' => '10541521', 46 | 'MerchantID' => '2000132', 47 | 'MerchantTradeNo' => 'VT1490265603', 48 | 'PayFrom' => '', 49 | 'PaymentDate' => '2017/03/23 18:41:19', 50 | 'PaymentNo' => '', 51 | 'PaymentType' => 'Credit_CreditCard', 52 | 'PaymentTypeChargeFee' => '1', 53 | 'PeriodAmount' => '', 54 | 'PeriodType' => '', 55 | 'process_date' => '2017/03/23 18:41:19', 56 | 'red_dan' => '0', 57 | 'red_de_amt' => '0', 58 | 'red_ok_amt' => '0', 59 | 'red_yet' => '0', 60 | 'RtnCode' => '1', 61 | 'RtnMsg' => '交易成功', 62 | 'SimulatePaid' => '0', 63 | 'staed' => '0', 64 | 'stage' => '0', 65 | 'stast' => '0', 66 | 'TenpayTradeNo' => '', 67 | 'TotalSuccessAmount' => '', 68 | 'TotalSuccessTimes' => '', 69 | 'TradeAmt' => '100', 70 | 'TradeDate' => '2017/03/23 18:40:20', 71 | 'TradeNo' => '1703231840205732', 72 | 'WebATMAccBank' => '', 73 | 'WebATMAccNo' => '', 74 | 'WebATMBankName' => '', 75 | 'CheckMacValue' => 'C65E91444C43934C9E363D9EBCD72BB5BA88600E6EB5DA4034BACF99A2663263', 76 | ]; 77 | 78 | $result = $gwr->processOrder(); 79 | 80 | $this->assertEquals(true, $result['matched']); 81 | 82 | if ($result['matched']) { 83 | $gwr->rspOk(); 84 | } else { 85 | $gwr->rspError(); 86 | } 87 | 88 | } 89 | 90 | public function testProcessOrderWrongPOST() 91 | { 92 | $gwr = new EcPayPaymentResponse([ 93 | 'hashKey' => 'fyjEf9sLkim7RdDvGeZZfVcLef5jDyWT', 94 | 'hashIV' => '6fxmp07KjuRaHvFo', 95 | 'merchantId' => 'MS3606763', 96 | 'version' => '1.2', 97 | ]); 98 | 99 | $_POST = array( 100 | 'RtnCode' => '0', 101 | ); 102 | 103 | $result = $gwr->processOrder('POST'); 104 | 105 | $this->assertEquals(false, $result); 106 | 107 | $_POST = []; 108 | 109 | $result = $gwr->processOrder('POST'); 110 | 111 | $this->assertEquals(false, $result); 112 | 113 | unset($_POST); 114 | 115 | $result = $gwr->processOrder('POST'); 116 | 117 | $this->assertEquals(false, $result); 118 | 119 | if ($result['matched']) { 120 | $gwr->rspOk(); 121 | } else { 122 | $gwr->rspError('Failed'); 123 | } 124 | 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /tests/TaiwanPaymentGateway/SpGatewayPaymentGatewayTest.php: -------------------------------------------------------------------------------- 1 | "VT-TPG-TEST", 18 | 'amount' => 100, 19 | 'itemDesc' => 'VT-TPG-TEST-ITEM-DESC', 20 | 'orderComment' => 'VT-TPG-TEST-ITEM-DESC', 21 | 'ts' => 1492287995 22 | ]; 23 | 24 | function __construct($name = null, array $data = [], $dataName = '') 25 | { 26 | parent::__construct($name, $data, $dataName); 27 | $this->gw = new SpGatewayPaymentGateway([ 28 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 29 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 30 | 'merchantId' => 'MS11434419', 31 | 'version' => '1.2', 32 | 'actionUrl' => 'https://ccore.spgateway.com/MPG/mpg_gateway', 33 | 'returnUrl' => 'https://localhost/tpg/confirm', 34 | 'notifyUrl' => '', 35 | 'clientBackUrl' => 'https://localhost/tpg/return', 36 | ]); 37 | } 38 | 39 | public function testConstruct() 40 | { 41 | $this->gw = new SpGatewayPaymentGateway([ 42 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 43 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 44 | 'merchantId' => 'MS11434419', 45 | 'returnUrl' => 'https://localhost/tpg/confirm', 46 | 'notifyUrl' => '', 47 | 'clientBackUrl' => 'https://localhost/tpg/return', 48 | ]); 49 | $this->assertInstanceOf(SpGatewayPaymentGateway::class, $this->gw); 50 | } 51 | 52 | public function testGetExistsConfig() 53 | { 54 | $this->assertEquals('a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', $this->gw->getConfig('hashKey')); 55 | } 56 | 57 | public function testGetNonExistsConfig() 58 | { 59 | try { 60 | $this->gw->getConfig('NonExists'); 61 | } catch (\InvalidArgumentException $e) { 62 | $this->assertEquals('config key not exists.', $e->getMessage()); 63 | } 64 | } 65 | 66 | public function testSetNonExistsConfig() 67 | { 68 | try { 69 | $this->gw->setConfig('NonExists', sha1(time())); 70 | } catch (\InvalidArgumentException $e) { 71 | $this->assertEquals('config key not exists.', $e->getMessage()); 72 | } 73 | } 74 | 75 | public function testNewOrderJSON() 76 | { 77 | $this->gw->newOrder( 78 | $this->order['mid'], 79 | $this->order['amount'], 80 | $this->order['itemDesc'], 81 | $this->order['orderComment'], 82 | 'JSON', 83 | $this->order['ts'] 84 | ); 85 | 86 | $this->assertNotEmpty($this->gw->getOrder()); 87 | } 88 | 89 | public function testNewOrderPOST() 90 | { 91 | $this->gw->newOrder( 92 | $this->order['mid'], 93 | $this->order['amount'], 94 | $this->order['itemDesc'], 95 | $this->order['orderComment'], 96 | 'POST', 97 | $this->order['ts'] 98 | ); 99 | 100 | $this->assertNotEmpty($this->gw->getOrder()); 101 | } 102 | 103 | public function testGenOrderForm() 104 | { 105 | $this->testNewOrderJSON(); 106 | $this->gw->useCredit()->setCreditInstallment(3); 107 | $this->assertNotEmpty($this->gw->genForm(false)); 108 | } 109 | 110 | public function testUnionPay() 111 | { 112 | $this->testNewOrderJSON(); 113 | $this->gw->useCredit()->setUnionPay(); 114 | $this->assertNotEmpty($this->gw->genForm(true)); 115 | } 116 | 117 | public function testUserCanModifyEmail() 118 | { 119 | $this->testNewOrderJSON(); 120 | $this->gw->useCredit()->triggerEmailModify(true); 121 | $this->assertNotEmpty($this->gw->genForm(false)); 122 | } 123 | 124 | public function testUserCantModifyEmail() 125 | { 126 | $this->testNewOrderJSON(); 127 | $this->gw->useCredit()->triggerEmailModify(false); 128 | $this->assertNotEmpty($this->gw->genForm(false)); 129 | } 130 | 131 | public function testOnlyGatewayMemberCanPay() 132 | { 133 | $this->testNewOrderJSON(); 134 | $this->gw->useCredit()->onlyLoginMemberCanPay(true); 135 | $this->assertNotEmpty($this->gw->genForm(false)); 136 | } 137 | 138 | public function testNotOnlyGatewayMemberCanPay() 139 | { 140 | $this->testNewOrderJSON(); 141 | $this->gw->useCredit()->onlyLoginMemberCanPay(false); 142 | $this->assertNotEmpty($this->gw->genForm(false)); 143 | } 144 | 145 | public function testPaymentMethodNotSet() 146 | { 147 | try{ 148 | $this->testNewOrderJSON(); 149 | $this->assertNotEmpty($this->gw->genForm(true)); 150 | } catch (\Exception $e) { 151 | $this->assertEquals('Payment method not set', $e->getMessage()); 152 | } 153 | } 154 | 155 | public function testPaymentInfoUrlNotSet() 156 | { 157 | try{ 158 | $this->testNewOrderJSON(); 159 | $this->gw->useBarCode()->setConfig('paymentInfoUrl', 0); 160 | $this->gw->setEmail('abc@test.com')->genForm(true); 161 | } catch (\Exception $e) { 162 | $this->assertEquals('PaymentInfoURL not set', $e->getMessage()); 163 | } 164 | } 165 | 166 | public function testWrongEmailAddress() 167 | { 168 | try{ 169 | $this->testNewOrderJSON(); 170 | $this->gw->useBarCode()->setConfig('paymentInfoUrl', 0); 171 | $this->gw->setEmail('abc@test')->genForm(true); 172 | } catch (\Exception $e) { 173 | $this->assertEquals('Invalid email format', $e->getMessage()); 174 | } 175 | } 176 | 177 | public function testUseWebAtm() 178 | { 179 | $this->testNewOrderJSON(); 180 | $this->gw 181 | ->useWebATM() 182 | ->setOrderExpire(mktime(23, 59, 59, date('m'), date('d') + 3, date('Y'))) 183 | ->setConfig('paymentInfoUrl', 'https://localhost/payment/information'); 184 | } 185 | 186 | public function testUseAtm() 187 | { 188 | $this->testNewOrderJSON(); 189 | $this->gw 190 | ->useATM() 191 | ->setOrderExpire(date('Y/m/d H:i:s', mktime(23, 59, 59, date('m'), date('d') + 3, date('Y')))) 192 | ->setConfig('paymentInfoUrl', 'https://localhost/payment/information'); 193 | } 194 | 195 | public function testUseCvs() 196 | { 197 | $this->testNewOrderJSON(); 198 | $this->gw->useCVS()->setConfig('paymentInfoUrl', 'https://localhost/payment/information'); 199 | } 200 | 201 | public function testNewOrderNoHashIv() 202 | { 203 | try { 204 | $gw = new SpGatewayPaymentGateway([ 205 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 206 | 'hashIV' => null, //'KHQ49UsmwMZJk6D1', 207 | 'merchantId' => 'MS11434419', 208 | 'returnUrl' => 'https://localhost/tpg/confirm', 209 | 'notifyUrl' => '', 210 | 'clientBackUrl' => 'https://localhost/tpg/return', 211 | ]); 212 | 213 | $gw->newOrder($this->order['mid'], 214 | $this->order['amount'], 215 | $this->order['itemDesc'], 216 | $this->order['orderComment'], 217 | 'JSON', 218 | $this->order['ts'] 219 | ); 220 | } catch (\InvalidArgumentException $e) { 221 | $this->assertEquals('HashIV not set', $e->getMessage()); 222 | } 223 | 224 | } 225 | 226 | public function testNewOrderNoHashKey() 227 | { 228 | try { 229 | $gw = new SpGatewayPaymentGateway([ 230 | 'hashKey' => null, //'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 231 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 232 | 'merchantId' => 'MS11434419', 233 | 'returnUrl' => 'https://localhost/tpg/confirm', 234 | 'notifyUrl' => '', 235 | 'clientBackUrl' => 'https://localhost/tpg/return', 236 | ]); 237 | 238 | $gw->newOrder($this->order['mid'], 239 | $this->order['amount'], 240 | $this->order['itemDesc'], 241 | $this->order['orderComment'], 242 | 'JSON', 243 | $this->order['ts'] 244 | ); 245 | } catch (\InvalidArgumentException $e) { 246 | $this->assertEquals('HashKey not set', $e->getMessage()); 247 | } 248 | 249 | } 250 | 251 | public function testNewOrderNoMerchantID() 252 | { 253 | try { 254 | $gw = new SpGatewayPaymentGateway([ 255 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 256 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 257 | 'merchantId' => null, //'MS11434419', 258 | 'returnUrl' => 'https://localhost/tpg/confirm', 259 | 'notifyUrl' => '', 260 | 'clientBackUrl' => 'https://localhost/tpg/return', 261 | ]); 262 | 263 | $gw->newOrder($this->order['mid'], 264 | $this->order['amount'], 265 | $this->order['itemDesc'], 266 | $this->order['orderComment'], 267 | 'JSON', 268 | $this->order['ts'] 269 | ); 270 | } catch (\InvalidArgumentException $e) { 271 | $this->assertEquals('MerchantID not set', $e->getMessage()); 272 | } 273 | 274 | } 275 | 276 | public function testNewOrderNoReturnURL() 277 | { 278 | try { 279 | $gw = new SpGatewayPaymentGateway([ 280 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 281 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 282 | 'merchantId' => 'MS11434419', 283 | 'returnUrl' => null, //'https://localhost/tpg/confirm', 284 | 'notifyUrl' => '', 285 | 'clientBackUrl' => 'https://localhost/tpg/return', 286 | ]); 287 | 288 | $gw->newOrder($this->order['mid'], 289 | $this->order['amount'], 290 | $this->order['itemDesc'], 291 | $this->order['orderComment'], 292 | 'JSON', 293 | $this->order['ts'] 294 | ); 295 | } catch (\InvalidArgumentException $e) { 296 | $this->assertEquals('ReturnURL not set', $e->getMessage()); 297 | } 298 | 299 | } 300 | 301 | public function testNewOrderSetNotifyURL() 302 | { 303 | $gw = new SpGatewayPaymentGateway([ 304 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 305 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 306 | 'merchantId' => 'MS11434419', 307 | 'returnUrl' => 'https://localhost/tpg/confirm', 308 | 'notifyUrl' => 'https://localhost/tpg/notify', 309 | 'clientBackUrl' => 'https://localhost/tpg/return', 310 | ]); 311 | 312 | $gw->newOrder($this->order['mid'], 313 | $this->order['amount'], 314 | $this->order['itemDesc'], 315 | $this->order['orderComment'], 316 | 'JSON', 317 | $this->order['ts'] 318 | ); 319 | 320 | } 321 | 322 | public function testNewOrderNoNotifyUrl() 323 | { 324 | try { 325 | $gw = new SpGatewayPaymentGateway([ 326 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 327 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 328 | 'merchantId' => 'MS11434419', 329 | 'returnUrl' => 'https://localhost/tpg/confirm', 330 | 'notifyUrl' => null, 331 | 'clientBackUrl' => 'https://localhost/tpg/return', 332 | ]); 333 | 334 | $gw->setConfig('paymentInfoUrl', 'https://localhost/tpg/info'); 335 | 336 | $gw->newOrder($this->order['mid'], 337 | $this->order['amount'], 338 | $this->order['itemDesc'], 339 | $this->order['orderComment'], 340 | 'JSON', 341 | $this->order['ts'] 342 | ); 343 | } catch (\InvalidArgumentException $e) { 344 | $this->assertEquals('NotifyURL not set', $e->getMessage()); 345 | } 346 | 347 | } 348 | 349 | public function testNewOrderNoActionURL() 350 | { 351 | try { 352 | $gw = new SpGatewayPaymentGateway([ 353 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 354 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 355 | 'merchantId' => 'MS11434419', 356 | 'returnUrl' => 'https://localhost/tpg/confirm', 357 | 'notifyUrl' => '', 358 | 'clientBackUrl' => 'https://localhost/tpg/return', 359 | ]); 360 | 361 | $gw->setConfig('actionUrl', null); 362 | 363 | $gw->newOrder($this->order['mid'], 364 | $this->order['amount'], 365 | $this->order['itemDesc'], 366 | $this->order['orderComment'], 367 | 'JSON', 368 | $this->order['ts'] 369 | ); 370 | } catch (\InvalidArgumentException $e) { 371 | $this->assertEquals('ActionURL not set', $e->getMessage()); 372 | } 373 | 374 | } 375 | 376 | public function testNewOrderSetPaymentInfoURL() 377 | { 378 | $gw = new SpGatewayPaymentGateway([ 379 | 'hashKey' => 'a73rjr4ocBjDcy6UGltXINJBw2NcdCEo', 380 | 'hashIV' => 'KHQ49UsmwMZJk6D1', 381 | 'merchantId' => 'MS11434419', 382 | 'returnUrl' => 'https://localhost/tpg/confirm', 383 | 'notifyUrl' => '', 384 | 'clientBackUrl' => 'https://localhost/tpg/return', 385 | ]); 386 | 387 | $gw->setConfig('paymentInfoUrl', 'https://localhost/tpg/info'); 388 | 389 | $gw->newOrder($this->order['mid'], 390 | $this->order['amount'], 391 | $this->order['itemDesc'], 392 | $this->order['orderComment'], 393 | 'JSON', 394 | $this->order['ts'] 395 | ); 396 | } 397 | } 398 | -------------------------------------------------------------------------------- /tests/TaiwanPaymentGateway/SpGatewayPaymentResponseTest.php: -------------------------------------------------------------------------------- 1 | 'fyjEf9sLkim7RdDvGeZZfVcLef5jDyWT', 21 | 'hashIV' => '6fxmp07KjuRaHvFo', 22 | 'merchantId' => 'MS3606763', 23 | 'version' => '1.2', 24 | ]); 25 | 26 | $this->assertInstanceOf(SpGatewayPaymentResponse::class, $gwr); 27 | } 28 | 29 | public function testProcessOrder() 30 | { 31 | $gwr = new SpGatewayPaymentResponse([ 32 | 'hashKey' => 'fyjEf9sLkim7RdDvGeZZfVcLef5jDyWT', 33 | 'hashIV' => '6fxmp07KjuRaHvFo', 34 | 'merchantId' => 'MS3606763', 35 | 'version' => '1.2', 36 | ]); 37 | $_POST = array( 38 | "JSONData" =>"{\"Status\":\"SUCCESS\",\"Message\":\"\\u6388\\u6b0a\\u6210\\u529f\",\"Result\":\"{\\\"MerchantID\\\":\\\"MS3606763\\\",\\\"Amt\\\":1200,\\\"TradeNo\\\":\\\"17032212162728251\\\",\\\"MerchantOrderNo\\\":\\\"170322VT0034651\\\",\\\"RespondType\\\":\\\"JSON\\\",\\\"CheckCode\\\":\\\"B79A8F7171CDA95468FF8B091458124E55CA687242BD2848511052F40394256A\\\",\\\"IP\\\":\\\"1.34.194.146\\\",\\\"EscrowBank\\\":\\\"KGI\\\",\\\"PaymentType\\\":\\\"CREDIT\\\",\\\"RespondCode\\\":\\\"00\\\",\\\"Auth\\\":\\\"930637\\\",\\\"Card6No\\\":\\\"400022\\\",\\\"Card4No\\\":\\\"1111\\\",\\\"Exp\\\":\\\"2203\\\",\\\"TokenUseStatus\\\":\\\"0\\\",\\\"InstFirst\\\":1200,\\\"InstEach\\\":0,\\\"Inst\\\":0,\\\"ECI\\\":\\\"\\\",\\\"PayTime\\\":\\\"2017-03-22 12:16:27\\\"}\"}" 39 | ); 40 | 41 | $result = $gwr->processOrder(); 42 | 43 | $this->assertEquals(true, $result['matched']); 44 | 45 | } 46 | 47 | public function testProcessOrderWrongJSON() 48 | { 49 | $gwr = new SpGatewayPaymentResponse([ 50 | 'hashKey' => 'fyjEf9sLkim7RdDvGeZZfVcLef5jDyWT', 51 | 'hashIV' => '6fxmp07KjuRaHvFo', 52 | 'merchantId' => 'MS3606763', 53 | 'version' => '1.2', 54 | ]); 55 | $_POST = array( 56 | "JSONDataWrong" =>"{\"Status\":\"SUCCESS\",\"Message\":\"\\u6388\\u6b0a\\u6210\\u529f\",\"Result\":\"{\\\"MerchantID\\\":\\\"MS3606763\\\",\\\"Amt\\\":1200,\\\"TradeNo\\\":\\\"17032212162728251\\\",\\\"MerchantOrderNo\\\":\\\"170322VT0034651\\\",\\\"RespondType\\\":\\\"JSON\\\",\\\"CheckCode\\\":\\\"B79A8F7171CDA95468FF8B091458124E55CA687242BD2848511052F40394256A\\\",\\\"IP\\\":\\\"1.34.194.146\\\",\\\"EscrowBank\\\":\\\"KGI\\\",\\\"PaymentType\\\":\\\"CREDIT\\\",\\\"RespondCode\\\":\\\"00\\\",\\\"Auth\\\":\\\"930637\\\",\\\"Card6No\\\":\\\"400022\\\",\\\"Card4No\\\":\\\"1111\\\",\\\"Exp\\\":\\\"2203\\\",\\\"TokenUseStatus\\\":\\\"0\\\",\\\"InstFirst\\\":1200,\\\"InstEach\\\":0,\\\"Inst\\\":0,\\\"ECI\\\":\\\"\\\",\\\"PayTime\\\":\\\"2017-03-22 12:16:27\\\"}\"}" 57 | ); 58 | 59 | $result = $gwr->processOrder(); 60 | 61 | $this->assertEquals(false, $result); 62 | 63 | } 64 | 65 | public function testProcessOrderFailedJSON() 66 | { 67 | $gwr = new SpGatewayPaymentResponse([ 68 | 'hashKey' => 'fyjEf9sLkim7RdDvGeZZfVcLef5jDyWT', 69 | 'hashIV' => '6fxmp07KjuRaHvFo', 70 | 'merchantId' => 'MS3606763', 71 | 'version' => '1.2', 72 | ]); 73 | $_POST = array( 74 | "JSONData" =>"{\"Status\":\"FAILED\",\"Message\":\"\\u6388\\u6b0a\\u6210\\u529f\",\"Result\":\"{\\\"MerchantID\\\":\\\"MS3606763\\\",\\\"Amt\\\":1200,\\\"TradeNo\\\":\\\"17032212162728251\\\",\\\"MerchantOrderNo\\\":\\\"170322VT0034651\\\",\\\"RespondType\\\":\\\"JSON\\\",\\\"CheckCode\\\":\\\"B79A8F7171CDA95468FF8B091458124E55CA687242BD2848511052F40394256A\\\",\\\"IP\\\":\\\"1.34.194.146\\\",\\\"EscrowBank\\\":\\\"KGI\\\",\\\"PaymentType\\\":\\\"CREDIT\\\",\\\"RespondCode\\\":\\\"00\\\",\\\"Auth\\\":\\\"930637\\\",\\\"Card6No\\\":\\\"400022\\\",\\\"Card4No\\\":\\\"1111\\\",\\\"Exp\\\":\\\"2203\\\",\\\"TokenUseStatus\\\":\\\"0\\\",\\\"InstFirst\\\":1200,\\\"InstEach\\\":0,\\\"Inst\\\":0,\\\"ECI\\\":\\\"\\\",\\\"PayTime\\\":\\\"2017-03-22 12:16:27\\\"}\"}" 75 | ); 76 | 77 | $result = $gwr->processOrder(); 78 | 79 | $this->assertEquals(false, $result); 80 | 81 | } 82 | 83 | public function testProcessOrderPOST() 84 | { 85 | $gwr = new SpGatewayPaymentResponse([ 86 | 'hashKey' => 'fyjEf9sLkim7RdDvGeZZfVcLef5jDyWT', 87 | 'hashIV' => '6fxmp07KjuRaHvFo', 88 | 'merchantId' => 'MS3606763', 89 | 'version' => '1.2', 90 | ]); 91 | $_POST = array( 92 | 'Status' => 'SUCCESS', 93 | 'Message' => '授權成功', 94 | 'MerchantID' => 'MS3606763', 95 | 'Amt' => '1200', 96 | 'TradeNo' => '17032311330952317', 97 | 'MerchantOrderNo' => '170323VT0034715', 98 | 'RespondType' => 'String', 99 | 'CheckCode' => '4B3DDA5FE88966928FEB903D6037B06A1A929087046E5E8D7A8CB2778A30D67C', 100 | 'IP' => '111.71.96.26', 101 | 'EscrowBank' => 'KGI', 102 | 'PaymentType' => 'CREDIT', 103 | 'RespondCode' => '00', 104 | 'Auth' => '930637', 105 | 'Card6No' => '400022', 106 | 'Card4No' => '1111', 107 | 'Exp' => '2204', 108 | 'TokenUseStatus' => '0', 109 | 'InstFirst' => '1200', 110 | 'InstEach' => '0', 111 | 'Inst' => '0', 112 | 'ECI' => '', 113 | 'PayTime' => '2017-03-23 11:33:09', 114 | ); 115 | 116 | $result = $gwr->processOrder('POST'); 117 | 118 | $this->assertEquals(true, $result['matched']); 119 | 120 | } 121 | 122 | public function testProcessOrderWrongPOST() 123 | { 124 | $gwr = new SpGatewayPaymentResponse([ 125 | 'hashKey' => 'fyjEf9sLkim7RdDvGeZZfVcLef5jDyWT', 126 | 'hashIV' => '6fxmp07KjuRaHvFo', 127 | 'merchantId' => 'MS3606763', 128 | 'version' => '1.2', 129 | ]); 130 | 131 | $_POST = array( 132 | 'Status' => 'FAILED', 133 | ); 134 | 135 | $result = $gwr->processOrder('POST'); 136 | 137 | $this->assertEquals(false, $result); 138 | 139 | $_POST = []; 140 | 141 | $result = $gwr->processOrder('POST'); 142 | 143 | $this->assertEquals(false, $result); 144 | 145 | unset($_POST); 146 | 147 | $result = $gwr->processOrder('POST'); 148 | 149 | $this->assertEquals(false, $result); 150 | 151 | } 152 | 153 | } 154 | -------------------------------------------------------------------------------- /tests/TaiwanPaymentGateway/TaiwanPaymentGatewayTest.php: -------------------------------------------------------------------------------- 1 | gw = TaiwanPaymentGateway::create('SpGateway', [ 20 | 'hashKey' => 'c7fe1bfba42369ec1add502c9917e14d', 21 | 'hashIV' => '245a49c8fb5151f0', 22 | 'merchantId' => 'MS1234567', 23 | 'version' => '1.2', 24 | 'actionUrl' => 'https://ccore.spgateway.com/MPG/mpg_gateway', 25 | 'returnUrl' => 'https://localhost/payment/confirm', 26 | 'notifyUrl' => 'https://localhost/payment/notify', 27 | 'clientBackUrl' => 'https://localhost/payment/return', 28 | 'paymentInfoUrl'=> 'https://localhost/payment/information', 29 | ]); 30 | 31 | $this->assertEquals('VoiceTube\TaiwanPaymentGateway\SpGatewayPaymentGateway', get_class($this->gw)); 32 | } 33 | 34 | public function testFactoryWrongProvider() 35 | { 36 | try { 37 | $provider = 'SpGatewa'; 38 | 39 | $this->gw = TaiwanPaymentGateway::create($provider, [ 40 | 'hashKey' => 'c7fe1bfba42369ec1add502c9917e14d', 41 | 'hashIV' => '245a49c8fb5151f0', 42 | 'merchantId' => 'MS1234567', 43 | 'version' => '1.2', 44 | 'actionUrl' => 'https://ccore.spgateway.com/MPG/mpg_gateway', 45 | 'returnUrl' => 'https://localhost/payment/confirm', 46 | 'notifyUrl' => 'https://localhost/payment/notify', 47 | 'clientBackUrl' => 'https://localhost/payment/return', 48 | 'paymentInfoUrl'=> 'https://localhost/payment/information', 49 | ]); 50 | } catch (\RuntimeException $e) { 51 | $this->assertEquals("Class '\\VoiceTube\\TaiwanPaymentGateway\\{$provider}PaymentGateway' not found", $e->getMessage()); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/TaiwanPaymentGateway/TaiwanPaymentResponseTest.php: -------------------------------------------------------------------------------- 1 | gwr = TaiwanPaymentResponse::create('SpGateway', [ 20 | 'hashKey' => 'c7fe1bfba42369ec1add502c9917e14d', 21 | 'hashIV' => '245a49c8fb5151f0', 22 | 'merchantId' => 'MS1234567', 23 | ]); 24 | 25 | $this->assertEquals('VoiceTube\TaiwanPaymentGateway\SpGatewayPaymentResponse', get_class($this->gwr)); 26 | } 27 | 28 | public function testFactoryWrongProvider() 29 | { 30 | try { 31 | $provider = 'SpGatewa'; 32 | 33 | $this->gw = TaiwanPaymentResponse::create($provider, [ 34 | 'hashKey' => 'c7fe1bfba42369ec1add502c9917e14d', 35 | 'hashIV' => '245a49c8fb5151f0', 36 | 'merchantId' => 'MS1234567', 37 | ]); 38 | } catch (\RuntimeException $e) { 39 | $this->assertEquals("Class '\\VoiceTube\\TaiwanPaymentGateway\\{$provider}PaymentResponse' not found", $e->getMessage()); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | add('TaiwanPaymentGateway', __DIR__); 9 | --------------------------------------------------------------------------------