├── .gitignore ├── src ├── Exceptions │ └── TradeException.php ├── Providers │ └── Pay2GoServiceProvider.php ├── Services │ └── Pay2GoService.php ├── Validation │ └── OrderValidatesRequests.php ├── Traits │ └── EncryptTrait.php ├── RequestCreditPay.php ├── Period.php ├── SpGateway.php └── Pay2Go.php ├── composer.json ├── LICENSE ├── config └── pay2go.php ├── README.md └── composer.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | vendor/ -------------------------------------------------------------------------------- /src/Exceptions/TradeException.php: -------------------------------------------------------------------------------- 1 | message = $exception_messages; 19 | } 20 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "maras0830/laravel5-pay2go", 3 | "description": "Laravel5 pay2go.", 4 | "type": "library", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Maras Chen", 9 | "email": "j999444@gmail.com" 10 | } 11 | ], 12 | "require": { 13 | "php": ">=5.4.0", 14 | "illuminate/support": "^5.1.0" 15 | }, 16 | "prefer-stable": true, 17 | "autoload": { 18 | "psr-4": { 19 | "Maras0830\\Pay2Go\\": "src" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Providers/Pay2GoServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->singleton(Pay2Go::class, function($app) { 15 | $config = $app['config']['pay2go']; 16 | 17 | return new Pay2Go($config['MerchantID'], $config['HashKey'], $config['HashIV']); 18 | }); 19 | 20 | $this->app->alias(Pay2Go::class, 'pay2go'); 21 | } 22 | 23 | /** 24 | * Boot 25 | */ 26 | public function boot() 27 | { 28 | $this->addConfig(); 29 | } 30 | 31 | /** 32 | * Config publishing 33 | */ 34 | private function addConfig() 35 | { 36 | $this->publishes([ 37 | __DIR__.'/../../config/pay2go.php' => config_path('pay2go.php') 38 | ]); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Maras Chen 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 | -------------------------------------------------------------------------------- /src/Services/Pay2GoService.php: -------------------------------------------------------------------------------- 1 | pay2go = new Pay2Go(Config::get('pay2go.MerchantID'), Config::get('pay2go.HashKey'), Config::get('pay2go.HashIV')); 26 | } 27 | 28 | /** 29 | * 設置訂單 30 | * 31 | * @param $order_id 32 | * @param $price 33 | * @param $descriptions 34 | * @param $email 35 | * @return Pay2Go 36 | */ 37 | public function setOrder($order_id, $price, $descriptions, $email) 38 | { 39 | return $this->pay2go->setOrder($order_id, $price, $descriptions, $email); 40 | } 41 | 42 | /** 43 | * 送出訂單 44 | * 45 | * @return string 46 | */ 47 | public function submitOrder() 48 | { 49 | return $this->pay2go->submitOrder(); 50 | } 51 | 52 | /** 53 | * 信用卡請款 54 | * 55 | * @param $order_unique_id 56 | * @param $amt 57 | * @return string 58 | */ 59 | public function requestPaymentPay($order_unique_id, $amt) 60 | { 61 | return $this->pay2go->requestPaymentPay($order_unique_id, $amt); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/Validation/OrderValidatesRequests.php: -------------------------------------------------------------------------------- 1 | isValidOnNull($required); 26 | 27 | $this->isValidOnInstFlag(); 28 | 29 | $this->isValidOnPort($valid_url_port); 30 | } 31 | 32 | /** 33 | * 檢查必填欄位是否有空值 34 | * 35 | * @param $required 36 | * @throws TradeException 37 | */ 38 | private function isValidOnNull($required) 39 | { 40 | foreach ($required as $field) 41 | if ($this->{$field} === null) 42 | throw new TradeException($field . ' is null.'); 43 | } 44 | 45 | /** 46 | * 檢查信用卡分期數是否正確 47 | * 48 | * @throws TradeException 49 | */ 50 | private function isValidOnInstFlag() 51 | { 52 | if (isset($this->InstFlag) and $this->InstFlag != null) 53 | if (!in_array($this->InstFlag, [1, 3, 6, 12, 18, 24])) 54 | throw new TradeException('InstFlag must be [1, 3, 6, 12, 18, 24].'); 55 | } 56 | 57 | /** 58 | * 檢查 Port 是否正確設置 59 | * 60 | * @param $valid_url_port 61 | * @throws TradeException 62 | */ 63 | private function isValidOnPort($valid_url_port) 64 | { 65 | foreach ($valid_url_port as $field) 66 | if ($this->{$field} != null) 67 | if (!(strpos($this->{$field}, "http://") !== false or strpos($this->{$field}, "https://") !== false)) 68 | throw new TradeException($field . ' must contain http or https port.'); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Traits/EncryptTrait.php: -------------------------------------------------------------------------------- 1 | PostData_ = $this->create_mpg_aes_encrypt($parameter); 9 | $this->TradeInfo = $this->create_mpg_aes_encrypt($parameter); 10 | } 11 | 12 | function create_mpg_aes_encrypt($parameter = "") 13 | { 14 | $return_str = ''; 15 | 16 | if (!empty($parameter)) { 17 | //將參數經過 URL ENCODED QUERY STRING 18 | $return_str = http_build_query($parameter); 19 | } 20 | 21 | return trim(bin2hex(openssl_encrypt($this->addpadding($return_str), 'aes-256-cbc', $this->HashKey, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $this->HashIV))); 22 | } 23 | 24 | public function create_aes_decrypt($encrypt_string = "") 25 | { 26 | 27 | return $this->stripPadding(openssl_decrypt(hex2bin($encrypt_string),'AES-256-CBC', $this->HashKey, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $this->HashIV)); 28 | } 29 | 30 | public function encryptDataBySHA256() 31 | { 32 | $this->TradeSha = strtoupper(hash("sha256", 'HashKey='.$this->HashKey . '&' . $this->TradeInfo . '&HashIV=' . $this->HashIV)); 33 | } 34 | 35 | public function stripPadding($string) 36 | { 37 | $slast = ord(substr($string, -1)); 38 | 39 | $slastc = chr($slast); 40 | 41 | if (preg_match("/$slastc{" . $slast . "}/", $string)) { 42 | $string = substr($string, 0, strlen($string) - $slast); 43 | 44 | return $string; 45 | } 46 | 47 | return false; 48 | } 49 | 50 | public function addPadding($string, $blocksize = 32) 51 | { 52 | $len = strlen($string); 53 | 54 | $pad = $blocksize - ($len % $blocksize); 55 | 56 | $string .= str_repeat(chr($pad), $pad); 57 | 58 | return $string; 59 | } 60 | 61 | /** 62 | * @param $encrypt_period_string 63 | * @return mixed 64 | */ 65 | public function decodeCallback($encrypt_period_string) : array 66 | { 67 | $decrypt_content = $this->create_aes_decrypt($encrypt_period_string); 68 | 69 | return json_decode($decrypt_content, true); 70 | } 71 | } -------------------------------------------------------------------------------- /src/RequestCreditPay.php: -------------------------------------------------------------------------------- 1 | pay2Go = $pay2Go; 29 | 30 | } 31 | 32 | /** 33 | * @return $this 34 | */ 35 | public function setRequestPayData() 36 | { 37 | $this->MerchantID_ = $this->pay2Go->getMerchantID(); 38 | $this->PostData_['RespondType'] = $this->pay2Go->getResponseType(); 39 | $this->PostData_['Version'] = $this->pay2Go->getVersion(); 40 | 41 | return $this; 42 | } 43 | 44 | /** 45 | * @param int|string $CloseType 46 | * @return $this 47 | */ 48 | public function setCreditRequestPayOrCloseByMerchantOrderNo($CloseType = 'Close') 49 | { 50 | $this->PostData_['Amt'] = $this->pay2Go->getAmt(); 51 | $this->PostData_['MerchantOrderNo'] = $this->pay2Go->getMerchantOrderNo(); 52 | $this->PostData_['TimeStamp'] = time(); 53 | $this->PostData_['IndexType'] = 1; 54 | $this->PostData_['TradeNo'] = ''; 55 | $this->PostData_['CloseType'] = $CloseType == 'Pay' ? 1 : 2; 56 | 57 | $post_data_str = http_build_query($this->PostData_); 58 | $this->PostData_ = openssl_encrypt($this->addPadding($post_data_str), 'AES-256-CBC', $this->pay2Go->getHashKey(), OPENSSL_RAW_DATA, $this->pay2Go->getHashIV()); 59 | // $this->PostData_ = trim(bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->pay2Go->getHashKey(), 60 | // $this->addPadding($post_data_str), MCRYPT_MODE_CBC, $this->pay2Go->getHashIV()))); 61 | 62 | return $this; 63 | } 64 | 65 | /** 66 | * @param bool $debug_mode 67 | * @return string 68 | */ 69 | public function getRequestCreditPayUrl($debug_mode = true) 70 | { 71 | return $debug_mode ? 'https://cweb.pay2go.com/API/CreditCard/Close' : 'https://web.pay2go.com/API/CreditCard/Close'; 72 | } 73 | 74 | /** 75 | * @return array 76 | */ 77 | public function getProperties() 78 | { 79 | return get_object_vars($this); 80 | } 81 | 82 | /** 83 | * @param $string 84 | * @param int $blocksize 85 | * @return string 86 | */ 87 | public function addPadding($string, $blocksize = 32) { 88 | $len = strlen($string); 89 | $pad = $blocksize - ($len % $blocksize); 90 | $string .= str_repeat(chr($pad), $pad); 91 | return $string; 92 | } 93 | 94 | 95 | } -------------------------------------------------------------------------------- /config/pay2go.php: -------------------------------------------------------------------------------- 1 | env('CASH_STORE_DEBUG_MODE'), 6 | 7 | /* 8 | * 智付寶商店代號 9 | */ 10 | 'MerchantID' => env('CASH_STORE_ID'), 11 | 12 | /* 13 | * 智付寶商店代號 14 | */ 15 | 'HashKey' => env('CASH_STORE_HashKey'), 16 | 17 | /* 18 | * 智付寶商店代號 19 | */ 20 | 'HashIV' => env('CASH_STORE_HashIV'), 21 | 22 | /* 23 | * 回傳格式 24 | * 25 | * json | html 26 | */ 27 | 'RespondType' => 'JSON', 28 | 29 | /* 30 | * 串接版本 31 | */ 32 | 'Version' => '1.2', 33 | 34 | /* 35 | * 語系 36 | * 37 | * zh-tw | en 38 | */ 39 | 'LangType' => 'zh-tw', 40 | 41 | /* 42 | * 是否需要登入智付寶會員 43 | */ 44 | 'LoginType' => false, 45 | 46 | /* 47 | * 交易秒數限制 48 | * 49 | * default: null 50 | * null: 不限制 51 | * 秒數下限為 60 秒,當秒數介於 1~59 秒時,會以 60 秒計算 52 | */ 53 | 'TradeLimit' => null, 54 | 55 | /* 56 | * 繳費-有效天數 57 | * 58 | * default: 7 59 | * maxValue: 180 60 | */ 61 | 'ExpireDays' => 7, 62 | 63 | /* 64 | * 繳費-有效時間(僅適用超商代碼交易) 65 | * 66 | * default: 235959 67 | * 格式為 date('His') ,例:235959 68 | */ 69 | 'ExpireTime' => '235959', 70 | 71 | /* 72 | * 付款完成-後導向頁面 73 | * 74 | * 僅接受 port 80 or 443 75 | */ 76 | 'ReturnURL' => env('CASH_ReturnUrl') != null ? env('APP_URL') . env('CASH_ReturnUrl') : null, 77 | 78 | /* 79 | * 付款完成-後的通知連結 80 | * 81 | * 以幕後方式回傳給商店相關支付結果資料 82 | * 僅接受 port 80 or 443 83 | */ 84 | 'NotifyURL' => env('CASH_NotifyURL') != null ? env('APP_URL') . env('CASH_NotifyURL') : null, 85 | 86 | /* 87 | * 商店取號網址 88 | * 89 | * 此參數若為空值,則會顯示取號結果在智付寶頁面。 90 | * default: null 91 | */ 92 | 'CustomerURL' => null, 93 | 94 | /* 95 | * 付款取消-返回商店網址 96 | * 97 | * default: null 98 | */ 99 | 'ClientBackURL' => env('CASH_Client_BackUrl') != null ? env('APP_URL') . env('CASH_Client_BackUrl') : null, 100 | 101 | /* 102 | * 付款人電子信箱是否開放修改 103 | * 104 | * default: false 105 | */ 106 | 'EmailModify' => false, 107 | 108 | /* 109 | * 商店備註 110 | * 111 | * 1.限制長度為 300 字。 112 | * 2.若有提供此參數,將會於 MPG 頁面呈現商店備註內容。 113 | * default: null 114 | */ 115 | 'OrderComment' => '商店備註', 116 | 117 | /* 118 | * 支付方式 119 | * 120 | * CREDIT: 信用卡支付 (default: false) 121 | * UNIONPAY: 銀聯卡支付 (default: false) 122 | * WEBATM: WEBATM支付 (default: true) 123 | * VACC: ATM支付 (default: true) 124 | * CVS: 超商代碼繳費支付 (default: true) 125 | * BARCODE: 條碼繳費支付 (default: true) 126 | * 127 | */ 128 | 'paymentMethod' => [ 129 | 130 | /* 131 | * 信用卡支付 132 | * enable: 是否啟用信用卡支付 133 | * CreditRed: 是否啟用紅利 134 | * InstFlag: 是否啟用分期 135 | * 136 | * 0: 不啟用 137 | * 1: 啟用全部分期 138 | * 3: 分 3 期 139 | * 6: 分 6 期功能 140 | * 12: 分 12 期功能 141 | * 18: 分 18 期功能 142 | * 24: 分 24 期功能 143 | * 以逗號方式開啟多種分期 144 | */ 145 | 'CREDIT' => [ 146 | 'enable' => false, 147 | 'CreditRed' => false, 148 | 'InstFlag' => 0, 149 | ], 150 | 'UNIONPAY' => false, 151 | 'WEBATM' => true, 152 | 'VACC' => true, 153 | 'CVS' => true, 154 | 'BARCODE' => true, 155 | 156 | 157 | 'PERIODIC' => false, 158 | ], 159 | 160 | /* 161 | * 是否啟用自定義支付 162 | * 163 | * 1. 自訂支付是提供商店可新增自訂的支付方式選項於智付寶付款頁,讓付款人進行選擇。 164 | * 2. 新增自訂支付欄位需於智付寶平台/商店設定中進行設定,最多可啟用 5 個新增自訂支付欄位。 165 | * 3. 當此參數為 1 時,則表示啟用所有於平台設定為啟用的自訂支付。 166 | * 167 | * default: false 168 | */ 169 | 'CUSTOM' => false, 170 | 171 | 'Period' => [ 172 | 'Version' => '1.0', 173 | 174 | // 1.於付款人填寫此委託單時,是否需顯示付款人資訊填寫欄位。 175 | // 2.若未提供此參數,則預設為是。 176 | // 3.付款人資訊填寫欄位包含付款人姓名、付款人電話、付款人手機。 177 | 'PaymentInfo' => false, 178 | 179 | // 1.於付款人填寫此委託單時,是否需顯示收件人資訊填寫欄位。 180 | // 2.若未提供此參數,則預設為是。 181 | // 3.收件人資訊填寫欄位包含收件人姓名、收件人電話、收件人手機、收件人地址。 182 | 'OrderInfo' => false, 183 | 184 | // 此委託單成立後,是否立即進行信用卡授權交易,作為檢查信用卡卡號之有效性。 185 | // 1=立即執行十元授權(因部分發卡銀行會阻擋一元交易,因此調整為十元) 186 | // 2=立即執行委託金額授權 187 | // 3=不檢查信用卡資訊,不授權 188 | 'first_authorization_type' => 1, 189 | ] 190 | ]; 191 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel5-Pay2Go-spgateway 2 | 3 | Cash trading with Pay2Go-Spagateway Package on Laravel 5.* 4 | 5 | ## EXAMPLE 6 | [laravel5-Pay2Go-spgateway-example](https://github.com/Maras0830/laravel5-Pay2Go-spgateway-example) 7 | 8 | ## FEATURE 9 | 1. Support add order. 10 | 2. Support credit payment pay or close. 11 | 12 | ## Official Documentation 13 | 14 | Official Documentation for the Payment can be found on the [Spgateway_gateway MPGapi_V1_0_3](https://www.spgateway.com/dw_files/info_api/spgateway_gateway_MPGapi_V1_0_3.pdf). 15 | 16 | ## Version 17 | 18 | Version | spgateway(智付通版本) | Period 定期定額 19 | ------- | ------------------- | -------------- 20 | 1.0.* | 1.2 | 21 | 2.0.* | 1.4 | Support(v) 22 | 23 | ## Installation 24 | 25 | ```bash 26 | "maras0830/laravel5-pay2go": "^1.0" 27 | ``` 28 | 29 | or 30 | 31 | ```bash 32 | "composer require maras0830/laravel5-pay2go" 33 | ``` 34 | 35 | In ```config/app.php``` add ```providers``` 36 | ```php 37 | Maras0830\Pay2Go\Providers\Pay2GoServiceProvider::class 38 | ``` 39 | In ```config/app.php``` add ```aliases``` 40 | ```php 41 | 'Pay2Go' => Maras0830\Pay2Go\Pay2Go::class 42 | ``` 43 | 44 | In ```.env``` add, you can register on 45 | 46 | [Pay2Go](https://www.spgateway.com/) or 47 | [Pay2Go Test](https://cwww.spgateway.com/) 48 | 49 | 50 | ```bash 51 | CASH_STORE_DEBUG_MODE=false 52 | CASH_STORE_ID=xxxxxxxx 53 | CASH_STORE_HashKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 54 | CASH_STORE_HashIV=xxxxxxxxxxxxxxxx 55 | ``` 56 | 57 | #### Remember to change your APP_URL, spgateway deny localhost. 58 | 59 | default return url 60 | ```bash 61 | CASH_ReturnUrl=/order/completed 62 | CASH_NotifyURL=/order/notify 63 | CASH_Client_BackUrl=/order/cancel 64 | ``` 65 | 66 | Publish config. 67 | ```php 68 | php artisan vendor:publish 69 | ``` 70 | 71 | ## USAGE 72 | ### MPG(Multi Payment Gateway) 單一串接多種支付 ### 73 | routes.php 74 | ```php 75 | Route::get('cash', 'CashController@index'); 76 | Route::post('cash/create', 'CashController@store'); 77 | ``` 78 | 79 | CashController.php 80 | ``` 81 | public function index() 82 | { 83 | return view('cash.index'); 84 | } 85 | ``` 86 | 87 | resources/views/cash/index.blade.php 88 | ```html 89 | 90 | 91 | Test Cash 92 | 93 | 94 |

智付寶 - 訂單測試

95 |
96 | {!! csrf_field() !!} 97 | 商店訂單編號:"/>
98 | 訂單金額:
99 | 商品資訊:
100 | Email:
101 | 102 | 103 |
104 | 105 | 106 | 107 | ```` 108 | 109 | CashController.php 110 | ```php 111 | public function store(Request $request) 112 | { 113 | $form = $request->except('_token'); 114 | 115 | // 建立商店 116 | $pay2go = new Pay2Go(env('CASH_STORE_ID'), env('CASH_STORE_HashKey'), env('CASH_STORE_HashIV')); 117 | 118 | // 商品資訊 119 | $order = $pay2go->setOrder($form['MerchantOrderNo'], $form['Amt'], $form['ItemDesc'], $form['Email'])->submitOrder(); 120 | 121 | 122 | // 將資訊回傳至自定義 view javascript auto submit 123 | return view('cash.submit')->with(compact('order')); 124 | } 125 | ``` 126 | 127 | resources/views/cash/submit.blade.php 128 | ```html 129 | 130 | 131 | redirect pay2go ... 132 | 133 | 134 | 135 | {!! $order !!} 136 | 137 | 138 | ``` 139 | ### Payment Pay or Close (信用卡請款或退款) ### 140 | 141 | routes.php 142 | ```php 143 | Route::get('admin/order', 'admin\OrderController@index'); 144 | Route::get('admin/order/requestPay/{order_id}', 'admin\OrderController@requestPay'); 145 | ``` 146 | 147 | Admin/OrderController.php 148 | ```php 149 | public function index() 150 | { 151 | $orders = $this->orderRepository->all()->get(); 152 | 153 | return view('admin.cash.index')->with(compact('orders')); 154 | } 155 | ``` 156 | 157 | ```php 158 | public function requestPay($order_id) 159 | { 160 | $order = $this->orderRepository->findBy('order_unique_id', $order_id); 161 | 162 | $pay2go = new Pay2Go(config('pay2go.MerchantID'), config('pay2go.HashKey'), config('pay2go.HashIV')); 163 | 164 | $result = $pay2go->requestPaymentPay($order->order_unique_id, $order->amt); 165 | 166 | return view('admin.cash.request_pay')->with(compact('result')); 167 | } 168 | ``` 169 | 170 | ## ChangeLog 171 | [2017.08.25] Add Debug Mode On .env. 172 | [2016.11.25] Change API URL to spgateway.com. 173 | [2016.09.06] Support credit payment pay or close. 174 | [2016.08.29] Only support add order, will add invoice feature and welcome developers join this project. 175 | ## 176 | -------------------------------------------------------------------------------- /src/Period.php: -------------------------------------------------------------------------------- 1 | setPay2GoPeriodUrl(Config::get('pay2go.Debug', true)); 56 | 57 | $this->MerchantID = ($MerchantID != null ? $MerchantID : Config::get('pay2go.MerchantID')); 58 | $this->HashKey = ($HashKey != null ? $HashKey : Config::get('pay2go.HashKey')); 59 | $this->HashIV = ($HashIV != null ? $HashIV : Config::get('pay2go.HashIV')); 60 | 61 | $this->setRespondType(Config::get('pay2go.RespondType', 'JSON')); 62 | $this->setTimeStamp(); 63 | $this->setVersion(Config::get('pay2go.Period.Version', '1.0')); 64 | 65 | $this->setEmailModify(Config::get('pay2go.EmailModify', false)); 66 | 67 | $this->setPaymentInfo(Config::get('pay2go.Period.PaymentInfo', false)); 68 | $this->setOrderInfo(Config::get('pay2go.Period.OrderInfo', true)); 69 | 70 | $this->setReturnURL(Config::get('pay2go.ReturnURL', null)); 71 | $this->setClientBackURL(Config::get('pay2go.ClientBackURL', null)); 72 | $this->setNotifyURL(Config::get('pay2go.NotifyURL', null)); 73 | // $this->setNotifyURL('https://requestbin.fullcontact.com/1klchpq1'); 74 | } 75 | 76 | /** 77 | * 定期定額扣款 78 | * 79 | * @param $email 80 | * @param $order_number 81 | * @param string $description 82 | * @param $per_price 83 | * @param string $type 84 | * @param string $check_point 85 | * @param int $period_times 86 | * @param int $first_authorization_type 87 | * @param string $memo 88 | * @return Period 89 | */ 90 | public function setPeriod($email, $order_number, $description, $per_price, $type = 'M', $check_point = '01', $period_times = 999, $first_authorization_type = 2, $memo = '') 91 | { 92 | $this->MerOrderNo = $order_number; 93 | $this->ProdDesc = $description; 94 | $this->PeriodAmt = $per_price; 95 | $this->PeriodType = $type; 96 | $this->PeriodPoint = $check_point; 97 | $this->PeriodStartType = $first_authorization_type; 98 | $this->PeriodTimes = $period_times; 99 | $this->PeriodMemo = $memo; 100 | 101 | $this->PayerEmail = $email; 102 | 103 | return $this; 104 | } 105 | 106 | /** 107 | * 是否開啟測試模式 108 | * 109 | * @param $debug_mode 110 | */ 111 | public function setPay2GoPeriodUrl($debug_mode) 112 | { 113 | if ($debug_mode) 114 | $this->Pay2GoUrl = 'https://ccore.spgateway.com/MPG/period'; 115 | else 116 | $this->Pay2GoUrl = 'https://core.spgateway.com/MPG/period'; 117 | } 118 | 119 | /** 120 | * 設定版本 (預設為 1.0) 121 | * 122 | * @param $version 123 | */ 124 | private function setVersion($version) 125 | { 126 | $this->Version = $version; 127 | } 128 | 129 | /** 130 | * 設定回傳型態 (預設為json) 131 | * 132 | * @param $response_type 133 | */ 134 | public function setRespondType($response_type = 'json') 135 | { 136 | $this->RespondType = $response_type; 137 | } 138 | 139 | 140 | /** 141 | * 設定交易完成後連結 142 | * 143 | * @param $return_url 144 | * @return $this 145 | */ 146 | public function setReturnURL($return_url) 147 | { 148 | $this->ReturnURL = $return_url; 149 | 150 | return $this; 151 | } 152 | 153 | /** 154 | * 設定交易通知連結 155 | * 156 | * @param $notify_url 157 | * @return $this 158 | */ 159 | public function setNotifyURL($notify_url) 160 | { 161 | if ($notify_url != null) 162 | $this->NotifyURL = $notify_url; 163 | 164 | return $this; 165 | } 166 | 167 | /** 168 | * 設定交易失敗連結 169 | * 170 | * @param $client_back_url 171 | * @return $this 172 | */ 173 | public function setClientBackURL($client_back_url) 174 | { 175 | if ($client_back_url != null) 176 | $this->BackURL = $client_back_url; 177 | 178 | return $this; 179 | } 180 | 181 | /** 182 | * 設定 email 是否可在交易時修改 183 | * 184 | * @param $email_modify 185 | */ 186 | public function setEmailModify($email_modify = false) 187 | { 188 | $this->EmailModify = $email_modify ? 1 : 0; 189 | } 190 | 191 | /** 192 | * 設定交易時間 193 | */ 194 | public function setTimeStamp() 195 | { 196 | $this->TimeStamp = time(); 197 | } 198 | 199 | /** 200 | * 取得 POST URL 201 | * 202 | * @return mixed 203 | */ 204 | public function getPay2GoUrl() 205 | { 206 | return $this->Pay2GoUrl; 207 | } 208 | 209 | /** 210 | * 送出 211 | * 212 | * @return string 213 | */ 214 | public function submit() 215 | { 216 | $parameter = [ 217 | 'RespondType' => $this->RespondType, 218 | 'TimeStamp' => $this->TimeStamp, 219 | 'Version' => '1.0', 220 | 'MerOrderNo' => $this->MerOrderNo, 221 | 'ProdDesc' => $this->ProdDesc, 222 | 'PeriodAmt' => $this->PeriodAmt, 223 | 'PeriodType' => $this->PeriodType, 224 | 'PeriodPoint' => $this->PeriodPoint, 225 | 'PeriodStartType' => $this->PeriodStartType, 226 | 'PeriodTimes' => $this->PeriodTimes, 227 | 'ReturnURL' => $this->ReturnURL, 228 | 'PeriodMemo' => $this->PeriodMemo, 229 | 'PayerEmail' => $this->PayerEmail, 230 | 'EmailModify' => $this->EmailModify, 231 | 'PaymentInfo' => $this->PaymentInfo, 232 | 'OrderInfo' => $this->OrderInfo, 233 | 'NotifyURL' => $this->NotifyURL, 234 | 'BackURL' => $this->BackURL, 235 | ]; 236 | 237 | $this->encryptDataByAES($parameter); 238 | 239 | // dd($this->PostData_); 240 | 241 | $result = $this->setOrderSubmitForm(); 242 | 243 | // $this->orderValidates(); 244 | 245 | return $result; 246 | } 247 | 248 | /** 249 | * 設置訂單新增的表單 250 | * 251 | * @return string 252 | */ 253 | private function setOrderSubmitForm() 254 | { 255 | $result = '
'; 256 | 257 | $result .= ''; 258 | $result .= ''; 259 | 260 | $result .= '
'; 261 | 262 | return $result; 263 | } 264 | 265 | /** 266 | * @param $enable_payment_info 267 | */ 268 | private function setPaymentInfo($enable_payment_info) 269 | { 270 | $this->PaymentInfo = $enable_payment_info ? 'Y' : 'N'; 271 | } 272 | 273 | /** 274 | * @param $enable_order_info 275 | */ 276 | private function setOrderInfo($enable_order_info) 277 | { 278 | $this->OrderInfo = $enable_order_info ? 'Y' : 'N'; 279 | } 280 | 281 | /** 282 | * @return mixed|null 283 | */ 284 | public function getMerchantID() 285 | { 286 | return $this->MerchantID; 287 | } 288 | 289 | /** 290 | * @return mixed 291 | */ 292 | public function getResponseType() 293 | { 294 | return $this->RespondType; 295 | } 296 | 297 | /** 298 | * @return mixed 299 | */ 300 | public function getVersion() 301 | { 302 | return $this->Version; 303 | } 304 | } 305 | -------------------------------------------------------------------------------- /src/SpGateway.php: -------------------------------------------------------------------------------- 1 | MerchantID = ($MerchantID != null ? $MerchantID : Config::get('pay2go.MerchantID')); 68 | $this->HashKey = ($HashKey != null ? $HashKey : Config::get('pay2go.HashKey')); 69 | $this->HashIV = ($HashIV != null ? $HashIV : Config::get('pay2go.HashIV')); 70 | 71 | $this->setPay2GoUrl(Config::get('pay2go.Debug', true)); 72 | $this->setRespondType(Config::get('pay2go.RespondType', 'JSON')); 73 | 74 | $this->setExpireDate(Config::get('pay2go.ExpireDays', 7)); 75 | $this->setLoginType(Config::get('pay2go.LoginType', false)); 76 | $this->setVersion(Config::get('pay2go.Version', '1.4')); 77 | $this->setLangType(Config::get('pay2go.LangType', 'zh-tw')); 78 | $this->setEmailModify(Config::get('pay2go.EmailModify', false)); 79 | $this->setPaymentMethod(Config::get('pay2go.paymentMethod', $this->getDefaultPaymentMethod())); 80 | $this->setTradeLimit(Config::get('pay2go.TradeLimit', null)); 81 | $this->setOrderComment(Config::get('pay2go.OrderComment', 'store comment')); 82 | $this->setClientBackURL(Config::get('pay2go.ClientBackURL', null)); 83 | $this->setCustomerURL(Config::get('pay2go.CustomerURL', null)); 84 | $this->setNotifyURL(Config::get('pay2go.NotifyURL', null)); 85 | $this->setReturnURL(Config::get('pay2go.ReturnURL', null)); 86 | 87 | $this->setTimeStamp(); 88 | } 89 | 90 | /** 91 | * 設置訂單 92 | * 93 | * @param $order_id 94 | * @param $price 95 | * @param $descriptions 96 | * @param $email 97 | * @return $this 98 | */ 99 | public function setOrder($order_id, $price, $descriptions, $email) 100 | { 101 | $this->MerchantOrderNo = $order_id; 102 | $this->Amt = $price; 103 | $this->ItemDesc = $descriptions; 104 | $this->Email = $email; 105 | 106 | return $this; 107 | } 108 | 109 | /** 110 | * 是否開啟測試模式 111 | * 112 | * @param $debug_mode 113 | */ 114 | public function setPay2GoUrl($debug_mode) 115 | { 116 | if ($debug_mode) 117 | $this->Pay2GoUrl = 'https://ccore.spgateway.com/MPG/mpg_gateway'; 118 | else 119 | $this->Pay2GoUrl = 'https://core.spgateway.com/MPG/mpg_gateway'; 120 | } 121 | 122 | /** 123 | * 設定金流方式 124 | * 125 | * @param $payments_config_array 126 | * @return $this 127 | */ 128 | public function setPaymentMethod($payments_config_array) 129 | { 130 | $this->CREDIT = $payments_config_array['CREDIT']['enable'] ? 1 : 0; 131 | $this->CreditRed = ($this->CREDIT and $payments_config_array['CREDIT']['CreditRed']) ? 1 : 0; 132 | $this->InstFlag = ($this->CREDIT and $payments_config_array['CREDIT']['InstFlag']) ? $payments_config_array['CREDIT']['InstFlag'] : 0; 133 | 134 | $this->UNIONPAY = $payments_config_array['UNIONPAY']? $payments_config_array['UNIONPAY'] : 0; 135 | $this->WEBATM = $payments_config_array['WEBATM'] ? 1 : 0; 136 | $this->VACC = $payments_config_array['VACC'] ? 1 : 0; 137 | $this->CVS = $payments_config_array['CVS'] ? 1 : 0; 138 | $this->BARCODE = $payments_config_array['BARCODE'] ? 1 : 0; 139 | 140 | return $this; 141 | } 142 | 143 | /** 144 | * 設定版本 (預設為 1.2) 145 | * 146 | * @param $version 147 | */ 148 | private function setVersion($version) 149 | { 150 | $this->Version = $version; 151 | } 152 | 153 | /** 154 | * 設定語言 (預設為 zh-tw) 155 | * 156 | * @param $lang 157 | */ 158 | public function setLangType($lang) 159 | { 160 | $this->LangType = $lang; 161 | } 162 | 163 | /** 164 | * 設定回傳型態 (預設為json) 165 | * 166 | * @param $response_type 167 | */ 168 | public function setRespondType($response_type = 'json') 169 | { 170 | $this->RespondType = $response_type; 171 | } 172 | 173 | /** 174 | * 設定交易限制秒數 175 | * 176 | * @param null $trade_limit 177 | */ 178 | public function setTradeLimit($trade_limit = null) 179 | { 180 | $this->TradeLimit = $trade_limit != null ? $trade_limit : 0; 181 | } 182 | 183 | /** 184 | * 設定過期日 185 | * 186 | * @param int $expireDays 187 | */ 188 | public function setExpireDate($expireDays = 7) 189 | { 190 | $this->ExpireDate = date('Ymd',strtotime(Carbon::today()->addDay($expireDays))); 191 | } 192 | 193 | /** 194 | * 設定交易完成後連結 195 | * 196 | * @param $return_url 197 | * @return $this 198 | */ 199 | public function setReturnURL($return_url) 200 | { 201 | $this->ReturnURL = $return_url; 202 | 203 | return $this; 204 | } 205 | 206 | /** 207 | * 設定交易通知連結 208 | * 209 | * @param $notify_url 210 | * @return $this 211 | */ 212 | public function setNotifyURL($notify_url) 213 | { 214 | if ($notify_url != null) 215 | $this->NotifyURL = $notify_url; 216 | 217 | return $this; 218 | } 219 | 220 | /** 221 | * 設定客製化連結 222 | * 223 | * @param $customer_url 224 | * @return $this 225 | */ 226 | public function setCustomerURL($customer_url) 227 | { 228 | if ($customer_url != null) 229 | $this->CustomerURL = $customer_url; 230 | 231 | return $this; 232 | } 233 | 234 | /** 235 | * 設定交易失敗連結 236 | * 237 | * @param $client_back_url 238 | * @return $this 239 | */ 240 | public function setClientBackURL($client_back_url) 241 | { 242 | if ($client_back_url != null) 243 | $this->ClientBackURL = $client_back_url; 244 | 245 | return $this; 246 | } 247 | 248 | /** 249 | * 設定 email 是否可在交易時修改 250 | * 251 | * @param $email_modify 252 | */ 253 | public function setEmailModify($email_modify = false) 254 | { 255 | $this->EmailModify = $email_modify ? 1 : 0; 256 | } 257 | 258 | /** 259 | * 設定是否要登入智付寶 260 | * 261 | * @param $login_type 262 | */ 263 | public function setLoginType($login_type = false) 264 | { 265 | $this->LoginType = $login_type ? 1 : 0; 266 | } 267 | 268 | /** 269 | * 設定商店備註 270 | * 271 | * @param $order_comment 272 | * @return $this 273 | */ 274 | public function setOrderComment($order_comment) 275 | { 276 | $this->OrderComment = $order_comment != null ? $order_comment : ''; 277 | 278 | return $this; 279 | } 280 | 281 | /** 282 | * 設定交易時間 283 | */ 284 | public function setTimeStamp() 285 | { 286 | $this->TimeStamp = time(); 287 | } 288 | 289 | /** 290 | * 商品敘述 291 | * 292 | * @return mixed 293 | */ 294 | public function getItemOrder() 295 | { 296 | return $this->ItemDesc; 297 | } 298 | 299 | /** 300 | * 取得 POST URL 301 | * 302 | * @return mixed 303 | */ 304 | public function getPay2GoUrl() 305 | { 306 | return $this->Pay2GoUrl; 307 | } 308 | 309 | public function getHashKey() 310 | { 311 | return $this->HashKey; 312 | } 313 | 314 | public function getHashIV() 315 | { 316 | return $this->HashIV; 317 | } 318 | 319 | public function getMerchantID() 320 | { 321 | return $this->MerchantID; 322 | } 323 | 324 | public function getMerchantOrderNo() 325 | { 326 | return $this->MerchantOrderNo; 327 | } 328 | 329 | public function getResponseType() 330 | { 331 | return $this->RespondType; 332 | } 333 | 334 | public function getVersion() 335 | { 336 | return $this->Version; 337 | } 338 | 339 | public function getAmt() 340 | { 341 | return $this->Amt; 342 | } 343 | 344 | /** 345 | * 送出訂單 346 | * 347 | * @return string 348 | * @throws Exceptions\TradeException 349 | */ 350 | public function submitOrder() 351 | { 352 | $parameter = [ 353 | 'MerchantID' => $this->MerchantID, 354 | 'RespondType' => $this->RespondType, 355 | 'TimeStamp' => $this->TimeStamp, 356 | 'Version' => $this->Version, 357 | 'MerchantOrderNo' => $this->MerchantOrderNo, 358 | 'Amt' => $this->Amt, 359 | 'ItemDesc' => $this->ItemDesc, 360 | 'NotifyURL' => $this->NotifyURL 361 | ]; 362 | 363 | $this->encryptDataByAES($parameter); 364 | 365 | $this->encryptDataBySHA256(); 366 | 367 | $result = $this->setOrderSubmitForm(); 368 | 369 | 370 | $this->orderValidates(); 371 | 372 | return $result; 373 | } 374 | 375 | /** 376 | * 信用卡請款 377 | * 378 | * @param $MerchantOrderNo 379 | * @param $amt 380 | * @return string 381 | */ 382 | public function requestPaymentPay($MerchantOrderNo, $amt) 383 | { 384 | $this->setOrder($MerchantOrderNo, $amt, null, null); 385 | 386 | $request_pay = new RequestCreditPay($this); 387 | 388 | $request_pay->setRequestPayData()->setCreditRequestPayOrCloseByMerchantOrderNo('Pay'); 389 | 390 | $result = $this->setRequestPaymentForm($request_pay); 391 | 392 | return $result; 393 | } 394 | 395 | /** 396 | * 信用卡退款 397 | * 398 | * @param $MerchantOrderNo 399 | * @param $amt 400 | * @return string 401 | */ 402 | public function requestPaymentClose($MerchantOrderNo, $amt) 403 | { 404 | $this->setOrder($MerchantOrderNo, $amt, null, null); 405 | 406 | $request_pay = new RequestCreditPay($this); 407 | 408 | $request_pay->setRequestPayData()->setCreditRequestPayOrCloseByMerchantOrderNo('Close'); 409 | 410 | $result = $this->setRequestPaymentForm($request_pay); 411 | 412 | return $result; 413 | } 414 | 415 | /** 416 | * 設置請款或退款的表單 417 | * 418 | * @param $request_pay 419 | * @return string 420 | */ 421 | private function setRequestPaymentForm($request_pay) 422 | { 423 | $result = '
'; 424 | 425 | foreach ($request_pay->getProperties() as $key => $value) { 426 | if ($key != "pay2Go") { 427 | if (is_array($value)) { 428 | foreach ($value as $sub_key => $sub_value) 429 | $result .= ''; 430 | } else { 431 | $result .= ''; 432 | } 433 | } 434 | } 435 | 436 | $result .= '
'; 437 | 438 | return $result; 439 | } 440 | 441 | /** 442 | * 設置訂單新增的表單 443 | * 444 | * @return string 445 | */ 446 | private function setOrderSubmitForm() 447 | { 448 | $result = '
'; 449 | 450 | $result .= ''; 451 | $result .= ''; 452 | $result .= ''; 453 | $result .= ''; 454 | 455 | $result .= '
'; 456 | 457 | return $result; 458 | } 459 | 460 | private function getDefaultPaymentMethod() 461 | { 462 | return [ 463 | 464 | /* 465 | * 信用卡支付 466 | * enable: 是否啟用信用卡支付 467 | * CreditRed: 是否啟用紅利 468 | * InstFlag: 是否啟用分期 469 | * 470 | * 0: 不啟用 471 | * 1: 啟用全部分期 472 | * 3: 分 3 期 473 | * 6: 分 6 期功能 474 | * 12: 分 12 期功能 475 | * 18: 分 18 期功能 476 | * 24: 分 24 期功能 477 | * 以逗號方式開啟多種分期 478 | */ 479 | 'CREDIT' => [ 480 | 'enable' => true, 481 | 'CreditRed' => false, 482 | 'InstFlag' => 0, 483 | ], 484 | 'ANDROIDPAY' => false, 485 | 'SAMSUNGPAY' => false, 486 | 'UNIONPAY' => false, 487 | 'WEBATM' => false, 488 | 'VACC' => false, 489 | 'CVS' => false, 490 | 'BARCODE' => false, 491 | 'P2G' => false, 492 | ]; 493 | } 494 | } 495 | -------------------------------------------------------------------------------- /src/Pay2Go.php: -------------------------------------------------------------------------------- 1 | MerchantID = ($MerchantID != null ? $MerchantID : Config::get('pay2go.MerchantID')); 59 | $this->HashKey = ($HashKey != null ? $HashKey : Config::get('pay2go.HashKey')); 60 | $this->HashIV = ($HashIV != null ? $HashIV : Config::get('pay2go.HashIV')); 61 | 62 | $this->setPay2GoUrl(Config::get('pay2go.Debug', true)); 63 | $this->setExpireDate(Config::get('pay2go.ExpireDays', 7)); 64 | $this->setExpireTime(Config::get('pay2go.ExpireTime', 235959)); 65 | $this->setLoginType(Config::get('pay2go.LoginType', false)); 66 | $this->setVersion(Config::get('pay2go.Version', '1.4')); 67 | $this->setLangType(Config::get('pay2go.LangType', 'zh-tw')); 68 | $this->setRespondType(Config::get('pay2go.RespondType', 'json')); 69 | $this->setEmailModify(Config::get('pay2go.EmailModify', false)); 70 | $this->setPaymentMethod(Config::get('pay2go.paymentMethod', $this->getDefaultPaymentMethod())); 71 | $this->setTradeLimit(Config::get('pay2go.TradeLimit', null)); 72 | $this->setOrderComment(Config::get('pay2go.OrderComment', 'store comment')); 73 | $this->setClientBackURL(Config::get('pay2go.ClientBackURL', null)); 74 | $this->setCustomerURL(Config::get('pay2go.CustomerURL', null)); 75 | $this->setNotifyURL(Config::get('pay2go.NotifyURL', null)); 76 | $this->setReturnURL(Config::get('pay2go.ReturnURL', null)); 77 | 78 | $this->setTimeStamp(); 79 | $this->MerchantID = $MerchantID; 80 | $this->HashKey = $HashKey; 81 | $this->HashIV = $HashIV; 82 | } 83 | 84 | /** 85 | * 設置訂單 86 | * 87 | * @param $order_id 88 | * @param $price 89 | * @param $descriptions 90 | * @param $email 91 | * @return $this 92 | */ 93 | public function setOrder($order_id, $price, $descriptions, $email) 94 | { 95 | $this->MerchantOrderNo = $order_id; 96 | $this->Amt = $price; 97 | $this->ItemDesc = $descriptions; 98 | $this->Email = $email; 99 | 100 | return $this; 101 | } 102 | 103 | /** 104 | * 定期定額扣款 105 | * 106 | * @param $per_price 107 | * @param string $type 108 | * @param int $check_point 109 | * @param int $period_times 110 | * @param int $first_authorization_type 111 | * @param string $memo 112 | */ 113 | public function setPeriod($per_price, $type = 'Month', $check_point = 1, $period_times = 999, $first_authorization_type = 2, $memo = '') 114 | { 115 | 116 | } 117 | 118 | /** 119 | * 是否開啟測試模式 120 | * 121 | * @param $debug_mode 122 | */ 123 | public function setPay2GoUrl($debug_mode) 124 | { 125 | if ($debug_mode) 126 | $this->Pay2GoUrl = 'https://ccore.spgateway.com/MPG/mpg_gateway'; 127 | else 128 | $this->Pay2GoUrl = 'https://core.spgateway.com/MPG/mpg_gateway'; 129 | } 130 | 131 | /** 132 | * 設定金流方式 133 | * 134 | * @param $payments_config_array 135 | * @return $this 136 | */ 137 | public function setPaymentMethod($payments_config_array) 138 | { 139 | $this->CREDIT = $payments_config_array['CREDIT']['enable'] ? 1 : 0; 140 | $this->CreditRed = ($this->CREDIT and $payments_config_array['CREDIT']['CreditRed']) ? 1 : 0; 141 | $this->InstFlag = ($this->CREDIT and $payments_config_array['CREDIT']['InstFlag']) ? $payments_config_array['CREDIT']['InstFlag'] : 0; 142 | 143 | $this->UNIONPAY = $payments_config_array['UNIONPAY']? $payments_config_array['UNIONPAY'] : 0; 144 | $this->WEBATM = $payments_config_array['WEBATM'] ? 1 : 0; 145 | $this->VACC = $payments_config_array['VACC'] ? 1 : 0; 146 | $this->CVS = $payments_config_array['CVS'] ? 1 : 0; 147 | $this->BARCODE = $payments_config_array['BARCODE'] ? 1 : 0; 148 | 149 | return $this; 150 | } 151 | 152 | /** 153 | * 設定版本 (預設為 1.2) 154 | * 155 | * @param $version 156 | */ 157 | private function setVersion($version) 158 | { 159 | $this->Version = $version; 160 | } 161 | 162 | /** 163 | * 設定語言 (預設為 zh-tw) 164 | * 165 | * @param $lang 166 | */ 167 | public function setLangType($lang) 168 | { 169 | $this->LangType = $lang; 170 | } 171 | 172 | /** 173 | * 設定回傳型態 (預設為json) 174 | * 175 | * @param $response_type 176 | */ 177 | public function setRespondType($response_type = 'json') 178 | { 179 | $this->RespondType = $response_type; 180 | } 181 | 182 | /** 183 | * 設定交易限制秒數 184 | * 185 | * @param null $trade_limit 186 | */ 187 | public function setTradeLimit($trade_limit = null) 188 | { 189 | $this->TradeLimit = $trade_limit != null ? $trade_limit : 0; 190 | } 191 | 192 | /** 193 | * 設定過期日 194 | * 195 | * @param int $expireDays 196 | */ 197 | public function setExpireDate($expireDays = 7) 198 | { 199 | $this->ExpireDate = date('Ymd',strtotime(Carbon::today()->addDay($expireDays))); 200 | } 201 | 202 | /** 203 | * 設定過期時間 204 | * 205 | * @param string $expireTime 206 | */ 207 | public function setExpireTime($expireTime = '235959') 208 | { 209 | $this->ExpireTime = $expireTime; 210 | } 211 | 212 | /** 213 | * 設定交易完成後連結 214 | * 215 | * @param $return_url 216 | * @return $this 217 | */ 218 | public function setReturnURL($return_url) 219 | { 220 | $this->ReturnURL = $return_url; 221 | 222 | return $this; 223 | } 224 | 225 | /** 226 | * 設定交易通知連結 227 | * 228 | * @param $notify_url 229 | * @return $this 230 | */ 231 | public function setNotifyURL($notify_url) 232 | { 233 | if ($notify_url != null) 234 | $this->NotifyURL = $notify_url; 235 | 236 | return $this; 237 | } 238 | 239 | /** 240 | * 設定客製化連結 241 | * 242 | * @param $customer_url 243 | * @return $this 244 | */ 245 | public function setCustomerURL($customer_url) 246 | { 247 | if ($customer_url != null) 248 | $this->CustomerURL = $customer_url; 249 | 250 | return $this; 251 | } 252 | 253 | /** 254 | * 設定交易失敗連結 255 | * 256 | * @param $client_back_url 257 | * @return $this 258 | */ 259 | public function setClientBackURL($client_back_url) 260 | { 261 | if ($client_back_url != null) 262 | $this->ClientBackURL = $client_back_url; 263 | 264 | return $this; 265 | } 266 | 267 | /** 268 | * 設定 email 是否可在交易時修改 269 | * 270 | * @param $email_modify 271 | */ 272 | public function setEmailModify($email_modify = false) 273 | { 274 | $this->EmailModify = $email_modify ? 1 : 0; 275 | } 276 | 277 | /** 278 | * 設定是否要登入智付寶 279 | * 280 | * @param $login_type 281 | */ 282 | public function setLoginType($login_type = false) 283 | { 284 | $this->LoginType = $login_type ? 1 : 0; 285 | } 286 | 287 | /** 288 | * 設定商店備註 289 | * 290 | * @param $order_comment 291 | * @return $this 292 | */ 293 | public function setOrderComment($order_comment) 294 | { 295 | $this->OrderComment = $order_comment != null ? $order_comment : ''; 296 | 297 | return $this; 298 | } 299 | 300 | /** 301 | * 設定交易時間 302 | */ 303 | public function setTimeStamp() 304 | { 305 | $this->TimeStamp = time(); 306 | } 307 | 308 | /** 309 | * 商品敘述 310 | * 311 | * @return mixed 312 | */ 313 | public function getItemOrder() 314 | { 315 | return $this->ItemDesc; 316 | } 317 | 318 | /** 319 | * 取得 POST URL 320 | * 321 | * @return mixed 322 | */ 323 | public function getPay2GoUrl() 324 | { 325 | return $this->Pay2GoUrl; 326 | } 327 | 328 | /** 329 | * 設置 檢核碼 330 | * 331 | * @return string 332 | */ 333 | public function setCheckValue() 334 | { 335 | $check_field = array( 336 | "Amt" => $this->Amt, 337 | "MerchantID" => $this->MerchantID, 338 | "MerchantOrderNo" => $this->MerchantOrderNo, 339 | "TimeStamp" => $this->TimeStamp, 340 | "Version" => $this->Version 341 | ); 342 | 343 | ksort($check_field); 344 | $check_field_str = http_build_query($check_field); 345 | $checkValue = 'HashKey='.$this->HashKey . '&' . $check_field_str . '&HashIV=' . $this->HashIV; 346 | 347 | $this->CheckValue = strtoupper(hash("sha256", $checkValue)); 348 | } 349 | 350 | public function getHashKey() 351 | { 352 | return $this->HashKey; 353 | } 354 | 355 | public function getHashIV() 356 | { 357 | return $this->HashIV; 358 | } 359 | 360 | public function getMerchantID() 361 | { 362 | return $this->MerchantID; 363 | } 364 | 365 | public function getMerchantOrderNo() 366 | { 367 | return $this->MerchantOrderNo; 368 | } 369 | 370 | public function getResponseType() 371 | { 372 | return $this->RespondType; 373 | } 374 | 375 | public function getVersion() 376 | { 377 | return $this->Version; 378 | } 379 | 380 | public function getAmt() 381 | { 382 | return $this->Amt; 383 | } 384 | 385 | /** 386 | * 送出訂單 387 | * 388 | * @return string 389 | * @throws Exceptions\TradeException 390 | */ 391 | public function submitOrder() 392 | { 393 | $this->setCheckValue(); 394 | 395 | $result = $this->setOrderSubmitForm(); 396 | 397 | // 驗證欄位是否正確設置 398 | $this->orderValidates(); 399 | 400 | return $result; 401 | } 402 | 403 | /** 404 | * 信用卡請款 405 | * 406 | * @param $MerchantOrderNo 407 | * @param $amt 408 | * @return string 409 | */ 410 | public function requestPaymentPay($MerchantOrderNo, $amt) 411 | { 412 | $this->setOrder($MerchantOrderNo, $amt, null, null); 413 | 414 | $request_pay = new RequestCreditPay($this); 415 | 416 | $request_pay->setRequestPayData()->setCreditRequestPayOrCloseByMerchantOrderNo('Pay'); 417 | 418 | $result = $this->setRequestPaymentForm($request_pay); 419 | 420 | return $result; 421 | } 422 | 423 | /** 424 | * 信用卡退款 425 | * 426 | * @param $MerchantOrderNo 427 | * @param $amt 428 | * @return string 429 | */ 430 | public function requestPaymentClose($MerchantOrderNo, $amt) 431 | { 432 | $this->setOrder($MerchantOrderNo, $amt, null, null); 433 | 434 | $request_pay = new RequestCreditPay($this); 435 | 436 | $request_pay->setRequestPayData()->setCreditRequestPayOrCloseByMerchantOrderNo('Close'); 437 | 438 | $result = $this->setRequestPaymentForm($request_pay); 439 | 440 | return $result; 441 | } 442 | 443 | /** 444 | * 設置請款或退款的表單 445 | * 446 | * @param $request_pay 447 | * @return string 448 | */ 449 | private function setRequestPaymentForm($request_pay) 450 | { 451 | $result = '
'; 452 | 453 | foreach ($request_pay->getProperties() as $key => $value) { 454 | if ($key != "pay2Go") { 455 | if (is_array($value)) { 456 | foreach ($value as $sub_key => $sub_value) 457 | $result .= ''; 458 | } else { 459 | $result .= ''; 460 | } 461 | } 462 | } 463 | 464 | $result .= '
'; 465 | 466 | return $result; 467 | } 468 | 469 | /** 470 | * 設置訂單新增的表單 471 | * 472 | * @return string 473 | */ 474 | private function setOrderSubmitForm() 475 | { 476 | $result = '
'; 477 | 478 | foreach($this as $key => $value) { 479 | $count = is_array($value) ? count($value) : 1; 480 | if ($key != 'Pay2GoUrl' and !is_null($value) and $count) 481 | $result .= ''; 482 | } 483 | 484 | $result .= '
'; 485 | 486 | return $result; 487 | } 488 | 489 | private function getDefaultPaymentMethod() 490 | { 491 | return [ 492 | 493 | /* 494 | * 信用卡支付 495 | * enable: 是否啟用信用卡支付 496 | * CreditRed: 是否啟用紅利 497 | * InstFlag: 是否啟用分期 498 | * 499 | * 0: 不啟用 500 | * 1: 啟用全部分期 501 | * 3: 分 3 期 502 | * 6: 分 6 期功能 503 | * 12: 分 12 期功能 504 | * 18: 分 18 期功能 505 | * 24: 分 24 期功能 506 | * 以逗號方式開啟多種分期 507 | */ 508 | 'CREDIT' => [ 509 | 'enable' => true, 510 | 'CreditRed' => false, 511 | 'InstFlag' => 0, 512 | ], 513 | 'UNIONPAY' => false, 514 | 'WEBATM' => false, 515 | 'VACC' => false, 516 | 'CVS' => false, 517 | 'BARCODE' => false, 518 | 519 | 520 | 'PERIODIC' => true, 521 | ]; 522 | } 523 | 524 | } 525 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "c79643a69ab6806b3a1faec2aa165604", 8 | "packages": [ 9 | { 10 | "name": "doctrine/inflector", 11 | "version": "v1.3.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/doctrine/inflector.git", 15 | "reference": "5527a48b7313d15261292c149e55e26eae771b0a" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/5527a48b7313d15261292c149e55e26eae771b0a", 20 | "reference": "5527a48b7313d15261292c149e55e26eae771b0a", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": "^7.1" 25 | }, 26 | "require-dev": { 27 | "phpunit/phpunit": "^6.2" 28 | }, 29 | "type": "library", 30 | "extra": { 31 | "branch-alias": { 32 | "dev-master": "1.3.x-dev" 33 | } 34 | }, 35 | "autoload": { 36 | "psr-4": { 37 | "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector" 38 | } 39 | }, 40 | "notification-url": "https://packagist.org/downloads/", 41 | "license": [ 42 | "MIT" 43 | ], 44 | "authors": [ 45 | { 46 | "name": "Roman Borschel", 47 | "email": "roman@code-factory.org" 48 | }, 49 | { 50 | "name": "Benjamin Eberlei", 51 | "email": "kontakt@beberlei.de" 52 | }, 53 | { 54 | "name": "Guilherme Blanco", 55 | "email": "guilhermeblanco@gmail.com" 56 | }, 57 | { 58 | "name": "Jonathan Wage", 59 | "email": "jonwage@gmail.com" 60 | }, 61 | { 62 | "name": "Johannes Schmitt", 63 | "email": "schmittjoh@gmail.com" 64 | } 65 | ], 66 | "description": "Common String Manipulations with regard to casing and singular/plural rules.", 67 | "homepage": "http://www.doctrine-project.org", 68 | "keywords": [ 69 | "inflection", 70 | "pluralize", 71 | "singularize", 72 | "string" 73 | ], 74 | "time": "2018-01-09T20:05:19+00:00" 75 | }, 76 | { 77 | "name": "illuminate/contracts", 78 | "version": "v5.6.34", 79 | "source": { 80 | "type": "git", 81 | "url": "https://github.com/illuminate/contracts.git", 82 | "reference": "2c029101285f6066f45e3ae5910b1b5f900fdcb4" 83 | }, 84 | "dist": { 85 | "type": "zip", 86 | "url": "https://api.github.com/repos/illuminate/contracts/zipball/2c029101285f6066f45e3ae5910b1b5f900fdcb4", 87 | "reference": "2c029101285f6066f45e3ae5910b1b5f900fdcb4", 88 | "shasum": "" 89 | }, 90 | "require": { 91 | "php": "^7.1.3", 92 | "psr/container": "~1.0", 93 | "psr/simple-cache": "~1.0" 94 | }, 95 | "type": "library", 96 | "extra": { 97 | "branch-alias": { 98 | "dev-master": "5.6-dev" 99 | } 100 | }, 101 | "autoload": { 102 | "psr-4": { 103 | "Illuminate\\Contracts\\": "" 104 | } 105 | }, 106 | "notification-url": "https://packagist.org/downloads/", 107 | "license": [ 108 | "MIT" 109 | ], 110 | "authors": [ 111 | { 112 | "name": "Taylor Otwell", 113 | "email": "taylor@laravel.com" 114 | } 115 | ], 116 | "description": "The Illuminate Contracts package.", 117 | "homepage": "https://laravel.com", 118 | "time": "2018-07-31T12:49:53+00:00" 119 | }, 120 | { 121 | "name": "illuminate/support", 122 | "version": "v5.6.34", 123 | "source": { 124 | "type": "git", 125 | "url": "https://github.com/illuminate/support.git", 126 | "reference": "4eb12aa00bbf2d5e73c355ad404a9d0679879094" 127 | }, 128 | "dist": { 129 | "type": "zip", 130 | "url": "https://api.github.com/repos/illuminate/support/zipball/4eb12aa00bbf2d5e73c355ad404a9d0679879094", 131 | "reference": "4eb12aa00bbf2d5e73c355ad404a9d0679879094", 132 | "shasum": "" 133 | }, 134 | "require": { 135 | "doctrine/inflector": "~1.1", 136 | "ext-mbstring": "*", 137 | "illuminate/contracts": "5.6.*", 138 | "nesbot/carbon": "^1.24.1", 139 | "php": "^7.1.3" 140 | }, 141 | "conflict": { 142 | "tightenco/collect": "<5.5.33" 143 | }, 144 | "suggest": { 145 | "illuminate/filesystem": "Required to use the composer class (5.6.*).", 146 | "ramsey/uuid": "Required to use Str::uuid() (^3.7).", 147 | "symfony/process": "Required to use the composer class (~4.0).", 148 | "symfony/var-dumper": "Required to use the dd function (~4.0)." 149 | }, 150 | "type": "library", 151 | "extra": { 152 | "branch-alias": { 153 | "dev-master": "5.6-dev" 154 | } 155 | }, 156 | "autoload": { 157 | "psr-4": { 158 | "Illuminate\\Support\\": "" 159 | }, 160 | "files": [ 161 | "helpers.php" 162 | ] 163 | }, 164 | "notification-url": "https://packagist.org/downloads/", 165 | "license": [ 166 | "MIT" 167 | ], 168 | "authors": [ 169 | { 170 | "name": "Taylor Otwell", 171 | "email": "taylor@laravel.com" 172 | } 173 | ], 174 | "description": "The Illuminate Support package.", 175 | "homepage": "https://laravel.com", 176 | "time": "2018-08-15T21:02:31+00:00" 177 | }, 178 | { 179 | "name": "nesbot/carbon", 180 | "version": "1.33.0", 181 | "source": { 182 | "type": "git", 183 | "url": "https://github.com/briannesbitt/Carbon.git", 184 | "reference": "55667c1007a99e82030874b1bb14d24d07108413" 185 | }, 186 | "dist": { 187 | "type": "zip", 188 | "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/55667c1007a99e82030874b1bb14d24d07108413", 189 | "reference": "55667c1007a99e82030874b1bb14d24d07108413", 190 | "shasum": "" 191 | }, 192 | "require": { 193 | "php": ">=5.3.9", 194 | "symfony/translation": "~2.6 || ~3.0 || ~4.0" 195 | }, 196 | "require-dev": { 197 | "friendsofphp/php-cs-fixer": "~2", 198 | "phpunit/phpunit": "^4.8.35 || ^5.7" 199 | }, 200 | "type": "library", 201 | "extra": { 202 | "laravel": { 203 | "providers": [ 204 | "Carbon\\Laravel\\ServiceProvider" 205 | ] 206 | } 207 | }, 208 | "autoload": { 209 | "psr-4": { 210 | "": "src/" 211 | } 212 | }, 213 | "notification-url": "https://packagist.org/downloads/", 214 | "license": [ 215 | "MIT" 216 | ], 217 | "authors": [ 218 | { 219 | "name": "Brian Nesbitt", 220 | "email": "brian@nesbot.com", 221 | "homepage": "http://nesbot.com" 222 | } 223 | ], 224 | "description": "A simple API extension for DateTime.", 225 | "homepage": "http://carbon.nesbot.com", 226 | "keywords": [ 227 | "date", 228 | "datetime", 229 | "time" 230 | ], 231 | "time": "2018-08-07T08:39:47+00:00" 232 | }, 233 | { 234 | "name": "psr/container", 235 | "version": "1.0.0", 236 | "source": { 237 | "type": "git", 238 | "url": "https://github.com/php-fig/container.git", 239 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" 240 | }, 241 | "dist": { 242 | "type": "zip", 243 | "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 244 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 245 | "shasum": "" 246 | }, 247 | "require": { 248 | "php": ">=5.3.0" 249 | }, 250 | "type": "library", 251 | "extra": { 252 | "branch-alias": { 253 | "dev-master": "1.0.x-dev" 254 | } 255 | }, 256 | "autoload": { 257 | "psr-4": { 258 | "Psr\\Container\\": "src/" 259 | } 260 | }, 261 | "notification-url": "https://packagist.org/downloads/", 262 | "license": [ 263 | "MIT" 264 | ], 265 | "authors": [ 266 | { 267 | "name": "PHP-FIG", 268 | "homepage": "http://www.php-fig.org/" 269 | } 270 | ], 271 | "description": "Common Container Interface (PHP FIG PSR-11)", 272 | "homepage": "https://github.com/php-fig/container", 273 | "keywords": [ 274 | "PSR-11", 275 | "container", 276 | "container-interface", 277 | "container-interop", 278 | "psr" 279 | ], 280 | "time": "2017-02-14T16:28:37+00:00" 281 | }, 282 | { 283 | "name": "psr/simple-cache", 284 | "version": "1.0.1", 285 | "source": { 286 | "type": "git", 287 | "url": "https://github.com/php-fig/simple-cache.git", 288 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" 289 | }, 290 | "dist": { 291 | "type": "zip", 292 | "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", 293 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", 294 | "shasum": "" 295 | }, 296 | "require": { 297 | "php": ">=5.3.0" 298 | }, 299 | "type": "library", 300 | "extra": { 301 | "branch-alias": { 302 | "dev-master": "1.0.x-dev" 303 | } 304 | }, 305 | "autoload": { 306 | "psr-4": { 307 | "Psr\\SimpleCache\\": "src/" 308 | } 309 | }, 310 | "notification-url": "https://packagist.org/downloads/", 311 | "license": [ 312 | "MIT" 313 | ], 314 | "authors": [ 315 | { 316 | "name": "PHP-FIG", 317 | "homepage": "http://www.php-fig.org/" 318 | } 319 | ], 320 | "description": "Common interfaces for simple caching", 321 | "keywords": [ 322 | "cache", 323 | "caching", 324 | "psr", 325 | "psr-16", 326 | "simple-cache" 327 | ], 328 | "time": "2017-10-23T01:57:42+00:00" 329 | }, 330 | { 331 | "name": "symfony/polyfill-mbstring", 332 | "version": "v1.9.0", 333 | "source": { 334 | "type": "git", 335 | "url": "https://github.com/symfony/polyfill-mbstring.git", 336 | "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" 337 | }, 338 | "dist": { 339 | "type": "zip", 340 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", 341 | "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", 342 | "shasum": "" 343 | }, 344 | "require": { 345 | "php": ">=5.3.3" 346 | }, 347 | "suggest": { 348 | "ext-mbstring": "For best performance" 349 | }, 350 | "type": "library", 351 | "extra": { 352 | "branch-alias": { 353 | "dev-master": "1.9-dev" 354 | } 355 | }, 356 | "autoload": { 357 | "psr-4": { 358 | "Symfony\\Polyfill\\Mbstring\\": "" 359 | }, 360 | "files": [ 361 | "bootstrap.php" 362 | ] 363 | }, 364 | "notification-url": "https://packagist.org/downloads/", 365 | "license": [ 366 | "MIT" 367 | ], 368 | "authors": [ 369 | { 370 | "name": "Nicolas Grekas", 371 | "email": "p@tchwork.com" 372 | }, 373 | { 374 | "name": "Symfony Community", 375 | "homepage": "https://symfony.com/contributors" 376 | } 377 | ], 378 | "description": "Symfony polyfill for the Mbstring extension", 379 | "homepage": "https://symfony.com", 380 | "keywords": [ 381 | "compatibility", 382 | "mbstring", 383 | "polyfill", 384 | "portable", 385 | "shim" 386 | ], 387 | "time": "2018-08-06T14:22:27+00:00" 388 | }, 389 | { 390 | "name": "symfony/translation", 391 | "version": "v4.1.3", 392 | "source": { 393 | "type": "git", 394 | "url": "https://github.com/symfony/translation.git", 395 | "reference": "6fcd1bd44fd6d7181e6ea57a6f4e08a09b29ef65" 396 | }, 397 | "dist": { 398 | "type": "zip", 399 | "url": "https://api.github.com/repos/symfony/translation/zipball/6fcd1bd44fd6d7181e6ea57a6f4e08a09b29ef65", 400 | "reference": "6fcd1bd44fd6d7181e6ea57a6f4e08a09b29ef65", 401 | "shasum": "" 402 | }, 403 | "require": { 404 | "php": "^7.1.3", 405 | "symfony/polyfill-mbstring": "~1.0" 406 | }, 407 | "conflict": { 408 | "symfony/config": "<3.4", 409 | "symfony/dependency-injection": "<3.4", 410 | "symfony/yaml": "<3.4" 411 | }, 412 | "require-dev": { 413 | "psr/log": "~1.0", 414 | "symfony/config": "~3.4|~4.0", 415 | "symfony/console": "~3.4|~4.0", 416 | "symfony/dependency-injection": "~3.4|~4.0", 417 | "symfony/finder": "~2.8|~3.0|~4.0", 418 | "symfony/intl": "~3.4|~4.0", 419 | "symfony/yaml": "~3.4|~4.0" 420 | }, 421 | "suggest": { 422 | "psr/log-implementation": "To use logging capability in translator", 423 | "symfony/config": "", 424 | "symfony/yaml": "" 425 | }, 426 | "type": "library", 427 | "extra": { 428 | "branch-alias": { 429 | "dev-master": "4.1-dev" 430 | } 431 | }, 432 | "autoload": { 433 | "psr-4": { 434 | "Symfony\\Component\\Translation\\": "" 435 | }, 436 | "exclude-from-classmap": [ 437 | "/Tests/" 438 | ] 439 | }, 440 | "notification-url": "https://packagist.org/downloads/", 441 | "license": [ 442 | "MIT" 443 | ], 444 | "authors": [ 445 | { 446 | "name": "Fabien Potencier", 447 | "email": "fabien@symfony.com" 448 | }, 449 | { 450 | "name": "Symfony Community", 451 | "homepage": "https://symfony.com/contributors" 452 | } 453 | ], 454 | "description": "Symfony Translation Component", 455 | "homepage": "https://symfony.com", 456 | "time": "2018-07-26T11:24:31+00:00" 457 | } 458 | ], 459 | "packages-dev": [], 460 | "aliases": [], 461 | "minimum-stability": "stable", 462 | "stability-flags": [], 463 | "prefer-stable": true, 464 | "prefer-lowest": false, 465 | "platform": { 466 | "php": ">=5.4.0" 467 | }, 468 | "platform-dev": [] 469 | } 470 | --------------------------------------------------------------------------------