├── .gitignore ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml ├── src ├── Exceptions │ └── IndipayParametersMissingException.php ├── Facades │ └── Indipay.php ├── Gateways │ ├── CCAvenueGateway.php │ ├── CitrusGateway.php │ ├── EBSGateway.php │ ├── InstaMojoGateway.php │ ├── MockerGateway.php │ ├── PayUMoneyGateway.php │ ├── PaymentGatewayInterface.php │ ├── PaytmGateway.php │ └── ZapakPayGateway.php ├── Indipay.php ├── IndipayServiceProvider.php ├── config │ └── config.php └── views │ ├── ccavenue.blade.php │ ├── citrus.blade.php │ ├── ebs.blade.php │ ├── instamojo.blade.php │ ├── middleware.blade.php │ ├── mocker.blade.php │ ├── paytm.blade.php │ ├── payumoney.blade.php │ └── zapakpay.blade.php └── tests └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | composer.phar 3 | composer.lock 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.4 5 | - 5.5 6 | - 5.6 7 | - hhvm 8 | 9 | before_script: 10 | - travis_retry composer self-update 11 | - travis_retry composer install --prefer-source --no-interaction --dev 12 | 13 | script: phpunit 14 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at admin@softon.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IndiPay 2 | The Laravel 5+ Package for Indian Payment Gateways. Currently supported gateway: CCAvenue, PayUMoney, EBS, CitrusPay ,ZapakPay (Mobikwik), Paytm, Mocker 3 | 4 | For Laravel 4.2 Package Click Here 5 | 6 |

Installation

7 | Step 1: Install package using composer 8 |

 9 |     composer require softon/indipay
10 | 
11 | 12 | Step 2: Add the service provider to the config/app.php file in Laravel (Optional for Laravel 5.5+) 13 |

14 |     Softon\Indipay\IndipayServiceProvider::class,
15 | 
16 | 17 | Step 3: Add an alias for the Facade to the config/app.php file in Laravel (Optional for Laravel 5.5+) 18 |

19 |     'Indipay' => Softon\Indipay\Facades\Indipay::class,
20 | 
21 | 22 | Step 4: Publish the config & Middleware by running in your terminal 23 |

24 |     php artisan vendor:publish --provider="Softon\Indipay\IndipayServiceProvider" 
25 | 
26 | 27 | Step 5: Modify the app\Http\Kernel.php to use the new Middleware. 28 | This is required so as to avoid CSRF verification on the Response Url from the payment gateways. 29 | You may adjust the routes in the config file config/indipay.php to disable CSRF on your gateways response routes. 30 | 31 | > NOTE: You may also use the new `VerifyCsrfToken` middleware and add the routes in the `$except` array. 32 | 33 |
App\Http\Middleware\VerifyCsrfToken::class,
34 | to 35 |
App\Http\Middleware\VerifyCsrfMiddleware::class,
36 | 37 |

Usage

38 | 39 | Edit the config/indipay.php. Set the appropriate Gateway parameters. Also set the default gateway to use by setting the `gateway` key in config file. Then in your code...
40 |
 use Softon\Indipay\Facades\Indipay;  
41 | Initiate Purchase Request and Redirect using the default gateway:- 42 | ```php 43 | /* All Required Parameters by your Gateway will differ from gateway to gateway refer the gate manual */ 44 | 45 | $parameters = [ 46 | 'transaction_no' => '1233221223322', 47 | 'amount' => '1200.00', 48 | 'name' => 'Jon Doe', 49 | 'email' => 'jon@doe.com' 50 | ]; 51 | 52 | $order = Indipay::prepare($parameters); 53 | return Indipay::process($order); 54 | ``` 55 | > Please check for the required parameters in your gateway manual. There is a basic validation in this package to check for it. 56 | 57 | You may also use multiple gateways:- 58 | ```php 59 | // gateway = CCAvenue / PayUMoney / EBS / Citrus / InstaMojo / ZapakPay / Paytm / Mocker 60 | 61 | $order = Indipay::gateway('Paytm')->prepare($parameters); 62 | return Indipay::process($order); 63 | ``` 64 | Get the Response from the Gateway (Add the Code to the Redirect Url Set in the config file. 65 | Also add the response route to the remove_csrf_check config item to remove CSRF check on these routes.):- 66 |
 
67 |     public function response(Request $request)
68 |     
69 |     {
70 |         // For default Gateway
71 |         $response = Indipay::response($request);
72 |         
73 |         // For Otherthan Default Gateway
74 |         $response = Indipay::gateway('NameOfGatewayUsedDuringRequest')->response($request);
75 | 
76 |         dd($response);
77 |     
78 |     }  
79 | 
80 | The `Indipay::response` will take care of checking the response for validity as most gateways will add a checksum to detect any tampering of data. 81 | 82 | Important point to note is to store the transaction info to a persistant database before proceding to the gateway so that the status can be verified later. 83 | 84 | ## Payment Verification 85 | 86 | From version v1.0.12 `Indipay` has started implementing verify method in some gateways so that the developer can verify the payment in case of pending payments etc. 87 | 88 | ```php 89 | $order = Indipay::verify([ 90 | 'transaction_no' => '3322344231223' 91 | ]); 92 | 93 | ``` 94 | The parameters to be passed, again depends on Gateway used. 95 | 96 | > **Verify Feature Currently Supported in** : Paytm, Mocker -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "softon/indipay", 3 | "description": "The Laravel 5+ Package for Indian Payment Gateways. Currently supported gateways: CCAvenue, PayUMoney, EBS, CitrusPay, InstaMojo, ZapakPay, Paytm, Mocker.", 4 | "license": "MIT", 5 | "keywords": [ 6 | "Laravel 5", 7 | "Indian Payment Gateways", 8 | "CCAvenue", 9 | "PayUMoney", 10 | "EBS", 11 | "CitrusPay", 12 | "InstaMojo", 13 | "Mobikwik / ZapakPay", 14 | "Paytm", 15 | "Mocker" 16 | ], 17 | "authors": [ 18 | { 19 | "name": "Shiburaj", 20 | "email": "powerupneo@gmail.com" 21 | } 22 | ], 23 | "require": { 24 | "php": ">=5.4.0", 25 | "illuminate/support": "~5.6.0|~5.7.0|~5.8.0|^6.0|^7.0|^8.0", 26 | "guzzlehttp/guzzle": "~5.0|~6.0|^7.0" 27 | }, 28 | "autoload": { 29 | "psr-4": { 30 | "Softon\\Indipay\\": "src/" 31 | } 32 | }, 33 | "extra": { 34 | "laravel": { 35 | "providers": [ 36 | "Softon\\Indipay\\IndipayServiceProvider" 37 | ], 38 | "aliases": { 39 | "Indipay": "Softon\\Indipay\\Facades\\Indipay" 40 | } 41 | } 42 | }, 43 | "minimum-stability": "dev" 44 | } 45 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Exceptions/IndipayParametersMissingException.php: -------------------------------------------------------------------------------- 1 | getMessage(); 20 | } 21 | } -------------------------------------------------------------------------------- /src/Facades/Indipay.php: -------------------------------------------------------------------------------- 1 | workingKey = Config::get('indipay.ccavenue.workingKey'); 24 | $this->accessCode = Config::get('indipay.ccavenue.accessCode'); 25 | $this->testMode = Config::get('indipay.testMode'); 26 | $this->parameters['merchant_id'] = Config::get('indipay.ccavenue.merchantId'); 27 | $this->parameters['currency'] = Config::get('indipay.ccavenue.currency'); 28 | $this->parameters['redirect_url'] = url(Config::get('indipay.ccavenue.redirectUrl')); 29 | $this->parameters['cancel_url'] = url(Config::get('indipay.ccavenue.cancelUrl')); 30 | $this->parameters['language'] = Config::get('indipay.ccavenue.language'); 31 | } 32 | 33 | public function getEndPoint() 34 | { 35 | return $this->testMode?$this->testEndPoint:$this->liveEndPoint; 36 | } 37 | 38 | public function request($parameters) 39 | { 40 | $this->parameters = array_merge($this->parameters,$parameters); 41 | 42 | $this->checkParameters($this->parameters); 43 | 44 | foreach($this->parameters as $key=>$value) { 45 | $this->merchantData .= $key.'='.$value.'&'; 46 | } 47 | 48 | $this->encRequest = $this->encrypt($this->merchantData,$this->workingKey); 49 | 50 | return $this; 51 | 52 | } 53 | 54 | /** 55 | * @return mixed 56 | */ 57 | public function send() 58 | { 59 | 60 | Log::info('Indipay Payment Request Initiated: '); 61 | return View::make('indipay::ccavenue')->with('encRequest',$this->encRequest) 62 | ->with('accessCode',$this->accessCode) 63 | ->with('endPoint',$this->getEndPoint()); 64 | 65 | } 66 | 67 | 68 | /** 69 | * Check Response 70 | * @param $request 71 | * @return array 72 | */ 73 | public function response($request) 74 | { 75 | $encResponse = $request->encResp; 76 | 77 | $rcvdString = $this->decrypt($encResponse,$this->workingKey); 78 | parse_str($rcvdString, $decResponse); 79 | 80 | return $decResponse; 81 | } 82 | 83 | 84 | /** 85 | * @param $parameters 86 | * @throws IndipayParametersMissingException 87 | */ 88 | public function checkParameters($parameters) 89 | { 90 | $validator = Validator::make($parameters, [ 91 | 'merchant_id' => 'required', 92 | 'currency' => 'required', 93 | 'redirect_url' => 'required|url', 94 | 'cancel_url' => 'required|url', 95 | 'language' => 'required', 96 | 'order_id' => 'required', 97 | 'amount' => 'required|numeric', 98 | ]); 99 | 100 | if ($validator->fails()) { 101 | throw new IndipayParametersMissingException($validator->errors()); 102 | } 103 | 104 | } 105 | 106 | /** 107 | * CCAvenue encryption 108 | * @param $plainText string 109 | * @param $key string 110 | * @return string 111 | */ 112 | public function encrypt($plainText, $key) 113 | { 114 | $key = $this->hextobin(md5($key)); 115 | $initVector = pack("C*", 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f); 116 | $openMode = openssl_encrypt($plainText, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $initVector); 117 | $encryptedText = bin2hex($openMode); 118 | return $encryptedText; 119 | } 120 | 121 | 122 | /** 123 | * CCAvenue decryption 124 | * @param $encryptedText string 125 | * @param $key 126 | * @return string 127 | */ 128 | public function decrypt($encryptedText, $key) 129 | { 130 | $key = $this->hextobin(md5($key)); 131 | $initVector = pack("C*", 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f); 132 | $encryptedText = $this->hextobin($encryptedText); 133 | $decryptedText = openssl_decrypt($encryptedText, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $initVector); 134 | return $decryptedText; 135 | } 136 | 137 | 138 | 139 | /** 140 | * @param $plainText 141 | * @param $blockSize 142 | * @return string 143 | */ 144 | protected function pkcs5_pad($plainText, $blockSize) 145 | { 146 | $pad = $blockSize - (strlen($plainText) % $blockSize); 147 | return $plainText . str_repeat(chr($pad), $pad); 148 | } 149 | 150 | 151 | /** 152 | * @param $hexString 153 | * @return string 154 | */ 155 | protected function hextobin($hexString) 156 | { 157 | $length = strlen($hexString); 158 | $binString=""; 159 | $count=0; 160 | while($count<$length) 161 | { 162 | $subString =substr($hexString,$count,2); 163 | $packedString = pack("H*",$subString); 164 | if ($count==0) 165 | { 166 | $binString=$packedString; 167 | } 168 | 169 | else 170 | { 171 | $binString.=$packedString; 172 | } 173 | 174 | $count+=2; 175 | } 176 | return $binString; 177 | } 178 | 179 | 180 | 181 | 182 | } 183 | -------------------------------------------------------------------------------- /src/Gateways/CitrusGateway.php: -------------------------------------------------------------------------------- 1 | vanityUrl = Config::get('indipay.citrus.vanityUrl'); 22 | $this->secretKey = Config::get('indipay.citrus.secretKey'); 23 | $this->testMode = Config::get('indipay.testMode'); 24 | 25 | $this->parameters['merchantTxnId'] = $this->generateTransactionID(); 26 | $this->parameters['currency'] = 'INR'; 27 | $this->parameters['returnUrl'] = url(Config::get('indipay.citrus.returnUrl')); 28 | $this->parameters['notifyUrl'] = url(Config::get('indipay.citrus.notifyUrl')); 29 | } 30 | 31 | public function getEndPoint() 32 | { 33 | return $this->testMode?$this->testEndPoint.$this->vanityUrl:$this->liveEndPoint.$this->vanityUrl; 34 | } 35 | 36 | public function request($parameters) 37 | { 38 | $this->parameters = array_merge($this->parameters,$parameters); 39 | 40 | $this->checkParameters($this->parameters); 41 | 42 | $this->encrypt(); 43 | 44 | return $this; 45 | 46 | } 47 | 48 | /** 49 | * @return mixed 50 | */ 51 | public function send() 52 | { 53 | Log::info('Indipay Payment Request Initiated: '); 54 | return View::make('indipay::citrus')->with('hash',$this->hash) 55 | ->with('parameters',$this->parameters) 56 | ->with('endPoint',$this->getEndPoint()); 57 | 58 | } 59 | 60 | 61 | /** 62 | * Check Response 63 | * @param $request 64 | * @return array 65 | */ 66 | public function response($request) 67 | { 68 | $response = $request->all(); 69 | 70 | $response_hash = $this->decrypt($response); 71 | 72 | if($response_hash!=$response['signature']){ 73 | return 'Hash Mismatch Error'; 74 | } 75 | 76 | return $response; 77 | } 78 | 79 | 80 | /** 81 | * @param $parameters 82 | * @throws IndipayParametersMissingException 83 | */ 84 | public function checkParameters($parameters) 85 | { 86 | $validator = Validator::make($parameters, [ 87 | 'merchantTxnId' => 'required', 88 | 'currency' => 'required', 89 | 'returnUrl' => 'required|url', 90 | 'orderAmount' => 'required|numeric', 91 | ]); 92 | 93 | if ($validator->fails()) { 94 | throw new IndipayParametersMissingException($validator->errors()); 95 | } 96 | 97 | } 98 | 99 | /** 100 | * Citrus Encrypt Function 101 | * 102 | */ 103 | protected function encrypt() 104 | { 105 | 106 | $hash_string = $this->vanityUrl.$this->parameters['orderAmount'].$this->parameters['merchantTxnId'].$this->parameters['currency']; 107 | 108 | $this->hash = hash_hmac('sha1', $hash_string, $this->secretKey); 109 | 110 | } 111 | 112 | /** 113 | * Citrus Decrypt Function 114 | * 115 | * @param $response 116 | * @return string 117 | */ 118 | protected function decrypt($response) 119 | { 120 | $hash_string = ''; 121 | $hash_string .= $response['TxId']; 122 | $hash_string .= $response['TxStatus']; 123 | $hash_string .= $response['amount']; 124 | $hash_string .= $response['pgTxnNo']; 125 | $hash_string .= $response['issuerRefNo']; 126 | $hash_string .= $response['authIdCode']; 127 | $hash_string .= $response['firstName']; 128 | $hash_string .= $response['lastName']; 129 | $hash_string .= $response['pgRespCode']; 130 | $hash_string .= $response['addressZip']; 131 | 132 | 133 | return hash_hmac('sha1', $hash_string, $this->secretKey); 134 | 135 | } 136 | 137 | 138 | 139 | public function generateTransactionID() 140 | { 141 | return substr(hash('sha256', mt_rand() . microtime()), 0, 20); 142 | } 143 | 144 | 145 | 146 | 147 | } -------------------------------------------------------------------------------- /src/Gateways/EBSGateway.php: -------------------------------------------------------------------------------- 1 | secretKey = Config::get('indipay.ebs.secretKey'); 22 | $this->testMode = Config::get('indipay.testMode'); 23 | 24 | $this->parameters['channel'] = 0; // Standard 25 | $this->parameters['account_id'] = Config::get('indipay.ebs.account_id'); 26 | $this->parameters['reference_no'] = $this->generateTransactionID(); 27 | $this->parameters['currency'] = 'INR'; 28 | $this->parameters['mode'] = 'LIVE'; 29 | if($this->testMode){ 30 | $this->parameters['mode'] = 'TEST'; 31 | } 32 | $this->parameters['return_url'] = url(Config::get('indipay.ebs.return_url')); 33 | 34 | 35 | } 36 | 37 | public function getEndPoint() 38 | { 39 | return $this->endPoint; 40 | } 41 | 42 | public function request($parameters) 43 | { 44 | $this->parameters = array_merge($this->parameters,$parameters); 45 | 46 | $this->checkParameters($this->parameters); 47 | 48 | $this->encrypt(); 49 | 50 | return $this; 51 | 52 | } 53 | 54 | /** 55 | * @return mixed 56 | */ 57 | public function send() 58 | { 59 | 60 | Log::info('Indipay Payment Request Initiated: '); 61 | return View::make('indipay::ebs')->with('hash',$this->hash) 62 | ->with('parameters',$this->parameters) 63 | ->with('endPoint',$this->getEndPoint()); 64 | 65 | } 66 | 67 | 68 | /** 69 | * Check Response 70 | * @param $request 71 | * @return array 72 | */ 73 | public function response($request) 74 | { 75 | $response = $request->all(); 76 | 77 | return $response; 78 | } 79 | 80 | 81 | /** 82 | * @param $parameters 83 | * @throws IndipayParametersMissingException 84 | */ 85 | public function checkParameters($parameters) 86 | { 87 | $validator = Validator::make($parameters, [ 88 | 'channel' => 'required', 89 | 'account_id' => 'required', 90 | 'reference_no' => 'required', 91 | 'mode' => 'required', 92 | 'currency' => 'required', 93 | 'description' => 'required', 94 | 'return_url' => 'required|url', 95 | 'name' => 'required', 96 | 'address' => 'required', 97 | 'city' => 'required', 98 | 'country' => 'required', 99 | 'postal_code' => 'required', 100 | 'phone' => 'required', 101 | 'email' => 'required|email', 102 | 'amount' => 'required|numeric', 103 | ]); 104 | 105 | if ($validator->fails()) { 106 | throw new IndipayParametersMissingException($validator->errors()); 107 | } 108 | 109 | } 110 | 111 | /** 112 | * EBS Encrypt Function 113 | * 114 | */ 115 | protected function encrypt() 116 | { 117 | $this->hash = ''; 118 | $hash_string = $this->secretKey."|".urlencode($this->parameters['account_id'])."|".urlencode($this->parameters['amount'])."|".urlencode($this->parameters['reference_no'])."|".$this->parameters['return_url']."|".urlencode($this->parameters['mode']); 119 | $this->hash = md5($hash_string); 120 | } 121 | 122 | /** 123 | * EBS Decrypt Function 124 | * 125 | * @param $plainText 126 | * @param $key 127 | * @return string 128 | */ 129 | protected function decrypt($response) 130 | { 131 | 132 | return $response; 133 | } 134 | 135 | 136 | 137 | public function generateTransactionID() 138 | { 139 | return substr(hash('sha256', mt_rand() . microtime()), 0, 20); 140 | } 141 | 142 | 143 | 144 | 145 | } -------------------------------------------------------------------------------- /src/Gateways/InstaMojoGateway.php: -------------------------------------------------------------------------------- 1 | testMode = Config::get('indipay.testMode'); 25 | $this->api_key = Config::get('indipay.instamojo.api_key'); 26 | $this->auth_token = Config::get('indipay.instamojo.auth_token'); 27 | 28 | $this->parameters['redirect_url'] = url(Config::get('indipay.instamojo.redirectUrl')); 29 | } 30 | 31 | public function getEndPoint($param='') 32 | { 33 | $endpoint = $this->testMode?$this->testEndPoint:$this->liveEndPoint; 34 | return $endpoint.$param; 35 | } 36 | 37 | public function request($parameters) 38 | { 39 | $this->parameters = array_merge($this->parameters,$parameters); 40 | 41 | $this->checkParameters($this->parameters); 42 | 43 | $client = new \GuzzleHttp\Client(); 44 | $response = $client->post($this->getEndPoint('payment-requests/'), 45 | [ 46 | 'headers'=> array( 47 | 'X-Api-Key' => $this->api_key, 48 | 'X-Auth-Token' => $this->auth_token, 49 | ), 50 | 'form_params' => $this->parameters, 51 | ])->getBody()->getContents(); 52 | $response = json_decode($response); 53 | 54 | if($response->success){ 55 | $this->response = $response; 56 | } 57 | 58 | return $this; 59 | 60 | } 61 | 62 | /** 63 | * @return mixed 64 | */ 65 | public function send() 66 | { 67 | 68 | Log::info('Indipay Payment Request Initiated: '); 69 | //dd($this->response->payment_request->longurl); 70 | return View::make('indipay::instamojo')->with('longurl',$this->response->payment_request->longurl); 71 | 72 | } 73 | 74 | 75 | /** 76 | * Check Response 77 | * @param $request 78 | * @return array 79 | */ 80 | public function response($request) 81 | { 82 | $payment_request_id = Request::input('payment_request_id'); 83 | $payment_id = Request::input('payment_id'); 84 | 85 | $client = new \GuzzleHttp\Client(); 86 | $response = $client->get($this->getEndPoint('payment-requests/'.$payment_request_id.'/'.$payment_id.'/'), 87 | [ 88 | 'headers'=> array( 89 | 'X-Api-Key' => $this->api_key, 90 | 'X-Auth-Token' => $this->auth_token, 91 | ), 92 | ])->getBody()->getContents(); 93 | $response = json_decode($response); 94 | 95 | if($response->success){ 96 | return $response; 97 | } 98 | 99 | return false; 100 | 101 | } 102 | 103 | 104 | /** 105 | * @param $parameters 106 | * @throws IndipayParametersMissingException 107 | */ 108 | public function checkParameters($parameters) 109 | { 110 | $validator = Validator::make($parameters, [ 111 | 'purpose' => 'required|max:30', 112 | 'amount' => 'required|numeric|between:9,200000', 113 | 'buyer_name' => 'max:100', 114 | 'email' => 'email|max:75', 115 | 'phone' => 'digits:10', 116 | ]); 117 | 118 | if ($validator->fails()) { 119 | throw new IndipayParametersMissingException($validator->errors()); 120 | } 121 | 122 | } 123 | 124 | 125 | 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/Gateways/MockerGateway.php: -------------------------------------------------------------------------------- 1 | service = Config::get('indipay.mocker.service'); 22 | $this->testMode = Config::get('indipay.testMode'); 23 | $this->parameters['redirect_url'] = url(Config::get('indipay.mocker.redirect_url')); 24 | } 25 | 26 | public function getEndPoint() 27 | { 28 | return $this->testMode?$this->testEndPoint.$this->service:$this->liveEndPoint.$this->service; 29 | } 30 | 31 | public function request($parameters) 32 | { 33 | $this->parameters = array_merge($this->parameters,$parameters); 34 | 35 | $this->checkParameters($this->parameters); 36 | 37 | return $this; 38 | 39 | } 40 | 41 | /** 42 | * @return mixed 43 | */ 44 | public function send() 45 | { 46 | 47 | Log::info('Indipay Payment Request Initiated: '); 48 | return View::make('indipay::mocker')->with('data',$this->parameters) 49 | ->with('end_point',$this->getEndPoint()); 50 | 51 | } 52 | 53 | 54 | /** 55 | * Check Response 56 | * @param $request 57 | * @return array 58 | */ 59 | public function response($request) 60 | { 61 | $params = $request->all(); 62 | if($params['transaction_status'] == 'success'){ 63 | $params['status'] = 'success'; 64 | return $params; 65 | } 66 | $params['status'] = 'failure'; 67 | return $params; 68 | } 69 | 70 | /** 71 | * Check Response 72 | * @param $request 73 | * @return array 74 | */ 75 | public function verify($parameters) 76 | { 77 | if(!isset($parameters['transaction_no']) || !isset($parameters['amount'])){ 78 | throw new IndipayParametersMissingException; 79 | } 80 | $client = new \GuzzleHttp\Client(); 81 | $res = $client->request('GET', $this->statusEndPoint, [ 82 | 'query' => [ 83 | 'transaction_no' => $parameters['transaction_no'], 84 | 'redirect_url' => $this->parameters['redirect_url'] 85 | ] 86 | ]); 87 | $mocker_data = json_decode($res->getBody()); 88 | if($mocker_data->amount == $parameters['amount']){ 89 | $mocker_data['status'] = 'success'; 90 | return $mocker_data; 91 | } 92 | $mocker_data['status'] = 'failure'; 93 | return $mocker_data; 94 | } 95 | 96 | 97 | /** 98 | * @param $parameters 99 | * @throws IndipayParametersMissingException 100 | */ 101 | public function checkParameters($parameters) 102 | { 103 | if($this->service == 'default') { 104 | $validator = Validator::make($parameters, [ 105 | 'transaction_no' => 'required', 106 | 'redirect_url' => 'required|url', 107 | 'amount' => 'required|numeric', 108 | ]); 109 | 110 | }elseif($this->service == 'instamojo'){ 111 | $validator = Validator::make($parameters, [ 112 | 'amount' => 'required|numeric|between:9,200000', 113 | 'redirect_url' => 'required|url', 114 | ]); 115 | }elseif($this->service == 'ccavenue'){ 116 | $validator = Validator::make($parameters, [ 117 | 'amount' => 'required|numeric|between:9,200000', 118 | 'redirect_url' => 'required|url', 119 | ]); 120 | } 121 | 122 | if ($validator->fails()) { 123 | throw new IndipayParametersMissingException($validator->errors()); 124 | } 125 | 126 | } 127 | 128 | 129 | 130 | } 131 | -------------------------------------------------------------------------------- /src/Gateways/PayUMoneyGateway.php: -------------------------------------------------------------------------------- 1 | merchantKey = Config::get('indipay.payumoney.merchantKey'); 23 | $this->salt = Config::get('indipay.payumoney.salt'); 24 | $this->testMode = Config::get('indipay.testMode'); 25 | 26 | $this->parameters['key'] = $this->merchantKey; 27 | $this->parameters['txnid'] = $this->generateTransactionID(); 28 | $this->parameters['surl'] = url(Config::get('indipay.payumoney.successUrl')); 29 | $this->parameters['furl'] = url(Config::get('indipay.payumoney.failureUrl')); 30 | } 31 | 32 | public function getEndPoint() 33 | { 34 | return $this->testMode?$this->testEndPoint:$this->liveEndPoint; 35 | } 36 | 37 | public function request($parameters) 38 | { 39 | $this->parameters = array_merge($this->parameters,$parameters); 40 | 41 | $this->checkParameters($this->parameters); 42 | 43 | $this->encrypt(); 44 | 45 | return $this; 46 | 47 | } 48 | 49 | /** 50 | * @return mixed 51 | */ 52 | public function send() 53 | { 54 | 55 | Log::info('Indipay Payment Request Initiated: '); 56 | return View::make('indipay::payumoney')->with('hash',$this->hash) 57 | ->with('parameters',$this->parameters) 58 | ->with('endPoint',$this->getEndPoint()); 59 | 60 | } 61 | 62 | 63 | /** 64 | * Check Response 65 | * @param $request 66 | * @return array 67 | */ 68 | public function response($request) 69 | { 70 | $response = $request->all(); 71 | 72 | $response_hash = $this->decrypt($response); 73 | 74 | if($response_hash!=$response['hash']){ 75 | return 'Hash Mismatch Error'; 76 | } 77 | 78 | return $response; 79 | } 80 | 81 | 82 | /** 83 | * @param $parameters 84 | * @throws IndipayParametersMissingException 85 | */ 86 | public function checkParameters($parameters) 87 | { 88 | $validator = Validator::make($parameters, [ 89 | 'key' => 'required', 90 | 'txnid' => 'required', 91 | 'surl' => 'required|url', 92 | 'furl' => 'required|url', 93 | 'firstname' => 'required', 94 | 'email' => 'required', 95 | 'phone' => 'required', 96 | 'productinfo' => 'required', 97 | 'amount' => 'required|numeric', 98 | ]); 99 | 100 | if ($validator->fails()) { 101 | throw new IndipayParametersMissingException($validator->errors()); 102 | } 103 | 104 | } 105 | 106 | /** 107 | * PayUMoney Encrypt Function 108 | * 109 | */ 110 | protected function encrypt() 111 | { 112 | $this->hash = ''; 113 | $hashSequence = "key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5|udf6|udf7|udf8|udf9|udf10"; 114 | $hashVarsSeq = explode('|', $hashSequence); 115 | $hash_string = ''; 116 | 117 | foreach($hashVarsSeq as $hash_var) { 118 | $hash_string .= isset($this->parameters[$hash_var]) ? $this->parameters[$hash_var] : ''; 119 | $hash_string .= '|'; 120 | } 121 | 122 | $hash_string .= $this->salt; 123 | $this->hash = strtolower(hash('sha512', $hash_string)); 124 | } 125 | 126 | /** 127 | * PayUMoney Decrypt Function 128 | * 129 | * @param $plainText 130 | * @param $key 131 | * @return string 132 | */ 133 | protected function decrypt($response) 134 | { 135 | 136 | $hashSequence = "status||||||udf5|udf4|udf3|udf2|udf1|email|firstname|productinfo|amount|txnid|key"; 137 | $hashVarsSeq = explode('|', $hashSequence); 138 | $hash_string = $this->salt."|"; 139 | 140 | foreach($hashVarsSeq as $hash_var) { 141 | $hash_string .= isset($response[$hash_var]) ? $response[$hash_var] : ''; 142 | $hash_string .= '|'; 143 | } 144 | 145 | $hash_string = trim($hash_string,'|'); 146 | 147 | return strtolower(hash('sha512', $hash_string)); 148 | } 149 | 150 | 151 | 152 | public function generateTransactionID() 153 | { 154 | return substr(hash('sha256', mt_rand() . microtime()), 0, 20); 155 | } 156 | 157 | 158 | 159 | 160 | } 161 | -------------------------------------------------------------------------------- /src/Gateways/PaymentGatewayInterface.php: -------------------------------------------------------------------------------- 1 | MERCHANT_KEY = Config::get('indipay.paytm.MERCHANT_KEY'); 25 | $this->testMode = Config::get('indipay.testMode'); 26 | $this->parameters['MID'] = Config::get('indipay.paytm.MID'); 27 | $this->parameters['CHANNEL_ID'] = Config::get('indipay.paytm.CHANNEL_ID'); 28 | $this->parameters['CALLBACK_URL'] = url(Config::get('indipay.paytm.REDIRECT_URL')); 29 | $this->parameters['WEBSITE'] = Config::get('indipay.paytm.WEBSITE'); 30 | $this->parameters['INDUSTRY_TYPE_ID'] = Config::get('indipay.paytm.INDUSTRY_TYPE_ID'); 31 | } 32 | 33 | public function getEndPoint() 34 | { 35 | return $this->testMode?$this->testEndPoint:$this->liveEndPoint; 36 | } 37 | 38 | public function getStatusEndPoint() 39 | { 40 | return $this->testMode?$this->statusTestEndPoint:$this->statusLiveEndPoint; 41 | } 42 | 43 | public function request($parameters) 44 | { 45 | $this->parameters = array_merge($this->parameters,$parameters); 46 | 47 | $this->checksum = $this->getChecksumFromArray($this->parameters,$this->MERCHANT_KEY); 48 | 49 | $this->parameters['CHECKSUMHASH'] = $this->checksum; 50 | 51 | $this->checkParameters($this->parameters); 52 | 53 | return $this; 54 | 55 | } 56 | 57 | /** 58 | * @return mixed 59 | */ 60 | public function send() 61 | { 62 | 63 | Log::info('Indipay Payment Request Initiated: '); 64 | return View::make('indipay::paytm')->with('params',$this->parameters) 65 | ->with('checksum',$this->checksum) 66 | ->with('endPoint',$this->getEndPoint()); 67 | 68 | } 69 | 70 | 71 | /** 72 | * Check Response 73 | * @param $request 74 | * @return array 75 | */ 76 | public function response($request) 77 | { 78 | $params = $request->all(); 79 | $checksum = isset($request->CHECKSUMHASH) ? $request->CHECKSUMHASH : ""; 80 | 81 | $isValidChecksum = $this->verifychecksum_e($params,$this->MERCHANT_KEY,$checksum); 82 | 83 | if($isValidChecksum == "TRUE" && $request->STATUS == "TXN_SUCCESS"){ 84 | $params['status'] = "success"; 85 | return $params; 86 | } 87 | $params['status'] = "failure"; 88 | return $params; 89 | } 90 | 91 | public function verify($parameters){ 92 | if(!isset($parameters['ORDERID'])){ 93 | return false; 94 | } 95 | $requestParamList = array("MID" => $this->parameters['MID'] , "ORDERID" => $parameters['ORDERID']); 96 | $requestParamList['CHECKSUMHASH'] = $this->getChecksumFromArray($requestParamList,$this->MERCHANT_KEY); 97 | $responseParamList = (array)$this->getTxnStatusNew($requestParamList); 98 | if($responseParamList['STATUS'] == "TXN_SUCCESS"){ 99 | $responseParamList['status'] = "success"; 100 | return $responseParamList; 101 | } 102 | $responseParamList['status'] = "failure"; 103 | return $responseParamList; 104 | } 105 | 106 | 107 | /** 108 | * @param $parameters 109 | * @throws IndipayParametersMissingException 110 | */ 111 | public function checkParameters($parameters) 112 | 113 | { 114 | $validator = Validator::make($parameters, [ 115 | 'MID' => 'required', 116 | 'ORDER_ID' => 'required', 117 | 'CUST_ID' => 'required', 118 | 'CHANNEL_ID' => 'required', 119 | 'WEBSITE' => 'required', 120 | 'INDUSTRY_TYPE_ID' => 'required', 121 | 'CALLBACK_URL' => 'required|url', 122 | 'TXN_AMOUNT' => 'required|numeric', 123 | 'CHECKSUMHASH' => 'required', 124 | ]); 125 | 126 | if ($validator->fails()) { 127 | throw new IndipayParametersMissingException($validator->errors()); 128 | } 129 | 130 | } 131 | 132 | 133 | 134 | /** 135 | * Paytm Gateway Functions 136 | */ 137 | 138 | 139 | function encrypt_e($input, $ky) { 140 | $key = html_entity_decode($ky); 141 | $iv = "@@@@&&&&####$$$$"; 142 | $data = openssl_encrypt ( $input , "AES-128-CBC" , $key, 0, $iv ); 143 | return $data; 144 | } 145 | 146 | function decrypt_e($crypt, $ky) { 147 | $key = html_entity_decode($ky); 148 | $iv = "@@@@&&&&####$$$$"; 149 | $data = openssl_decrypt ( $crypt , "AES-128-CBC" , $key, 0, $iv ); 150 | return $data; 151 | } 152 | 153 | function generateSalt_e($length) { 154 | $random = ""; 155 | srand((double) microtime() * 1000000); 156 | 157 | $data = "AbcDE123IJKLMN67QRSTUVWXYZ"; 158 | $data .= "aBCdefghijklmn123opq45rs67tuv89wxyz"; 159 | $data .= "0FGH45OP89"; 160 | 161 | for ($i = 0; $i < $length; $i++) { 162 | $random .= substr($data, (rand() % (strlen($data))), 1); 163 | } 164 | 165 | return $random; 166 | } 167 | 168 | function checkString_e($value) { 169 | if ($value == 'null') 170 | $value = ''; 171 | return $value; 172 | } 173 | 174 | function getChecksumFromArray($arrayList, $key, $sort=1) { 175 | if ($sort != 0) { 176 | ksort($arrayList); 177 | } 178 | $str = $this->getArray2Str($arrayList); 179 | $salt = $this->generateSalt_e(4); 180 | $finalString = $str . "|" . $salt; 181 | $hash = hash("sha256", $finalString); 182 | $hashString = $hash . $salt; 183 | $checksum = $this->encrypt_e($hashString, $key); 184 | return $checksum; 185 | } 186 | function getChecksumFromString($str, $key) { 187 | 188 | $salt = $this->generateSalt_e(4); 189 | $finalString = $str . "|" . $salt; 190 | $hash = hash("sha256", $finalString); 191 | $hashString = $hash . $salt; 192 | $checksum = $this->encrypt_e($hashString, $key); 193 | return $checksum; 194 | } 195 | 196 | function verifychecksum_e($arrayList, $key, $checksumvalue) { 197 | $arrayList = $this->removeCheckSumParam($arrayList); 198 | ksort($arrayList); 199 | $str = $this->getArray2StrForVerify($arrayList); 200 | $paytm_hash = $this->decrypt_e($checksumvalue, $key); 201 | $salt = substr($paytm_hash, -4); 202 | 203 | $finalString = $str . "|" . $salt; 204 | 205 | $website_hash = hash("sha256", $finalString); 206 | $website_hash .= $salt; 207 | 208 | $validFlag = "FALSE"; 209 | if ($website_hash == $paytm_hash) { 210 | $validFlag = "TRUE"; 211 | } else { 212 | $validFlag = "FALSE"; 213 | } 214 | return $validFlag; 215 | } 216 | 217 | function verifychecksum_eFromStr($str, $key, $checksumvalue) { 218 | $paytm_hash = $this->decrypt_e($checksumvalue, $key); 219 | $salt = substr($paytm_hash, -4); 220 | 221 | $finalString = $str . "|" . $salt; 222 | 223 | $website_hash = hash("sha256", $finalString); 224 | $website_hash .= $salt; 225 | 226 | $validFlag = "FALSE"; 227 | if ($website_hash == $paytm_hash) { 228 | $validFlag = "TRUE"; 229 | } else { 230 | $validFlag = "FALSE"; 231 | } 232 | return $validFlag; 233 | } 234 | 235 | function getArray2Str($arrayList) { 236 | $findme = 'REFUND'; 237 | $findmepipe = '|'; 238 | $paramStr = ""; 239 | $flag = 1; 240 | foreach ($arrayList as $key => $value) { 241 | $pos = strpos($value, $findme); 242 | $pospipe = strpos($value, $findmepipe); 243 | if ($pos !== false || $pospipe !== false) 244 | { 245 | continue; 246 | } 247 | 248 | if ($flag) { 249 | $paramStr .= $this->checkString_e($value); 250 | $flag = 0; 251 | } else { 252 | $paramStr .= "|" . $this->checkString_e($value); 253 | } 254 | } 255 | return $paramStr; 256 | } 257 | 258 | function getArray2StrForVerify($arrayList) { 259 | $paramStr = ""; 260 | $flag = 1; 261 | foreach ($arrayList as $key => $value) { 262 | if ($flag) { 263 | $paramStr .= $this->checkString_e($value); 264 | $flag = 0; 265 | } else { 266 | $paramStr .= "|" . $this->checkString_e($value); 267 | } 268 | } 269 | return $paramStr; 270 | } 271 | 272 | function redirect2PG($paramList, $key) { 273 | $hashString = $this->getchecksumFromArray($paramList, $key); 274 | $checksum = $this->encrypt_e($hashString, $key); 275 | } 276 | 277 | function removeCheckSumParam($arrayList) { 278 | if (isset($arrayList["CHECKSUMHASH"])) { 279 | unset($arrayList["CHECKSUMHASH"]); 280 | } 281 | return $arrayList; 282 | } 283 | 284 | function getTxnStatus($requestParamList) { 285 | return $this->callAPI($this->getStatusEndPoint(), $requestParamList); 286 | } 287 | 288 | function getTxnStatusNew($requestParamList) { 289 | return $this->callNewAPI($this->getStatusEndPoint(), $requestParamList); 290 | } 291 | 292 | function initiateTxnRefund($requestParamList) { 293 | //$CHECKSUM = $this->getRefundChecksumFromArray($requestParamList,PAYTM_MERCHANT_KEY,0); 294 | //$requestParamList["CHECKSUM"] = $CHECKSUM; 295 | //return $this->callAPI(PAYTM_REFUND_URL, $requestParamList); 296 | } 297 | 298 | function callAPI($apiURL, $requestParamList) { 299 | $jsonResponse = ""; 300 | $responseParamList = array(); 301 | $JsonData =json_encode($requestParamList); 302 | $postData = 'JsonData='.urlencode($JsonData); 303 | $ch = curl_init($apiURL); 304 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); 305 | curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); 306 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 307 | curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); 308 | curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); 309 | curl_setopt($ch, CURLOPT_HTTPHEADER, array( 310 | 'Content-Type: application/json', 311 | 'Content-Length: ' . strlen($postData)) 312 | ); 313 | $jsonResponse = curl_exec($ch); 314 | $responseParamList = json_decode($jsonResponse,true); 315 | return $responseParamList; 316 | } 317 | 318 | function callNewAPI($apiURL, $requestParamList) { 319 | $jsonResponse = ""; 320 | $responseParamList = array(); 321 | $JsonData =json_encode($requestParamList); 322 | $postData = 'JsonData='.urlencode($JsonData); 323 | $ch = curl_init($apiURL); 324 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); 325 | curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); 326 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 327 | curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); 328 | curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); 329 | curl_setopt($ch, CURLOPT_HTTPHEADER, array( 330 | 'Content-Type: application/json', 331 | 'Content-Length: ' . strlen($postData)) 332 | ); 333 | $jsonResponse = curl_exec($ch); 334 | $responseParamList = json_decode($jsonResponse,true); 335 | return $responseParamList; 336 | } 337 | function getRefundChecksumFromArray($arrayList, $key, $sort=1) { 338 | if ($sort != 0) { 339 | ksort($arrayList); 340 | } 341 | $str = $this->getRefundArray2Str($arrayList); 342 | $salt = $this->generateSalt_e(4); 343 | $finalString = $str . "|" . $salt; 344 | $hash = hash("sha256", $finalString); 345 | $hashString = $hash . $salt; 346 | $checksum = $this->encrypt_e($hashString, $key); 347 | return $checksum; 348 | } 349 | function getRefundArray2Str($arrayList) { 350 | $findmepipe = '|'; 351 | $paramStr = ""; 352 | $flag = 1; 353 | foreach ($arrayList as $key => $value) { 354 | $pospipe = strpos($value, $findmepipe); 355 | if ($pospipe !== false) 356 | { 357 | continue; 358 | } 359 | 360 | if ($flag) { 361 | $paramStr .= $this->checkString_e($value); 362 | $flag = 0; 363 | } else { 364 | $paramStr .= "|" . $this->checkString_e($value); 365 | } 366 | } 367 | return $paramStr; 368 | } 369 | function callRefundAPI($refundApiURL, $requestParamList) { 370 | $jsonResponse = ""; 371 | $responseParamList = array(); 372 | $JsonData =json_encode($requestParamList); 373 | $postData = 'JsonData='.urlencode($JsonData); 374 | $ch = curl_init($refundApiURL); 375 | curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); 376 | curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); 377 | curl_setopt($ch, CURLOPT_URL, $refundApiURL); 378 | curl_setopt($ch, CURLOPT_POST, true); 379 | curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); 380 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 381 | $headers = array(); 382 | $headers[] = 'Content-Type: application/json'; 383 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 384 | $jsonResponse = curl_exec($ch); 385 | $responseParamList = json_decode($jsonResponse,true); 386 | return $responseParamList; 387 | } 388 | 389 | 390 | 391 | 392 | } -------------------------------------------------------------------------------- /src/Gateways/ZapakPayGateway.php: -------------------------------------------------------------------------------- 1 | secret = Config::get('indipay.zapakpay.secret'); 23 | $this->merchantIdentifier = Config::get('indipay.zapakpay.merchantIdentifier'); 24 | $this->testMode = Config::get('indipay.testMode'); 25 | $this->parameters['merchantIdentifier'] = $this->merchantIdentifier; 26 | $this->parameters['returnUrl'] = url(Config::get('indipay.zapakpay.returnUrl')); 27 | 28 | } 29 | 30 | public function getEndPoint() 31 | { 32 | return $this->testMode?$this->testEndPoint:$this->liveEndPoint; 33 | } 34 | 35 | public function request($parameters) 36 | { 37 | $this->parameters = array_merge($this->parameters,$parameters); 38 | 39 | $this->checkParameters($this->parameters); 40 | 41 | $encodeString = $this->getAllParams($this->parameters); 42 | $this->checksum = $this->calculateChecksum($this->secret,$encodeString); 43 | 44 | return $this; 45 | 46 | } 47 | 48 | /** 49 | * @return mixed 50 | */ 51 | public function send() 52 | { 53 | 54 | Log::info('Indipay Payment Request Initiated: '); 55 | return View::make('indipay::zapakpay')->with('params',$this->parameters) 56 | ->with('checksum',$this->checksum) 57 | ->with('endPoint',$this->getEndPoint()); 58 | 59 | } 60 | 61 | 62 | /** 63 | * Check Response 64 | * @param $request 65 | * @return array 66 | */ 67 | public function response($request) 68 | { 69 | $response = $request->all(); 70 | $rcvd_checksum = $request->checksum; 71 | 72 | $rcvd_data = $this->getAllResponseParams($response); 73 | $checksum_check = $this->verifyChecksum($rcvd_checksum,$rcvd_data,$this->secret); 74 | 75 | if(!$checksum_check){ 76 | return "Recieved Checksum Mismatch."; 77 | } 78 | 79 | $this->response = $response; 80 | 81 | return $this->response; 82 | } 83 | 84 | 85 | /** 86 | * @param $parameters 87 | * @throws IndipayParametersMissingException 88 | */ 89 | public function checkParameters($parameters) 90 | { 91 | $validator = Validator::make($parameters, [ 92 | 'merchantIdentifier' => 'required', 93 | 'buyerEmail' => 'required|email', 94 | 'currency' => 'required', 95 | 'orderId' => 'required', 96 | 'amount' => 'required|numeric', 97 | ]); 98 | 99 | if ($validator->fails()) { 100 | throw new IndipayParametersMissingException($validator->errors()); 101 | } 102 | 103 | } 104 | 105 | 106 | public function calculateChecksum($secret_key, $all) 107 | { 108 | $hash = hash_hmac('sha256', $all , $secret_key); 109 | $checksum = $hash; 110 | return $checksum; 111 | } 112 | 113 | 114 | public function getAllParams($params) { 115 | //ksort($_POST); 116 | $all = ''; 117 | 118 | 119 | $checksumsequence= array("amount","bankid","buyerAddress", 120 | "buyerCity","buyerCountry","buyerEmail","buyerFirstName","buyerLastName","buyerPhoneNumber","buyerPincode", 121 | "buyerState","currency","debitorcredit","merchantIdentifier","merchantIpAddress","mode","orderId", 122 | "product1Description","product2Description","product3Description","product4Description", 123 | "productDescription","productInfo","purpose","returnUrl","shipToAddress","shipToCity","shipToCountry", 124 | "shipToFirstname","shipToLastname","shipToPhoneNumber","shipToPincode","shipToState","showMobile","txnDate", 125 | "txnType","zpPayOption"); 126 | 127 | 128 | foreach($checksumsequence as $seqvalue) { 129 | if(array_key_exists($seqvalue, $params)) { 130 | if(!$params[$seqvalue]=="") 131 | { 132 | if($seqvalue != 'checksum') 133 | { 134 | $all .= $seqvalue; 135 | $all .="="; 136 | if ($seqvalue == 'returnUrl') 137 | { 138 | $params[$seqvalue] = $this->sanitizedURL($params[$seqvalue]); 139 | $all .= $this->sanitizedURL($params[$seqvalue]); 140 | } 141 | else 142 | { 143 | $params[$seqvalue] = $this->sanitizedParam($params[$seqvalue]); 144 | $all .= $this->sanitizedParam($params[$seqvalue]); 145 | } 146 | $all .= "&"; 147 | } 148 | } 149 | 150 | } 151 | } 152 | 153 | 154 | 155 | return $all; 156 | } 157 | 158 | 159 | 160 | 161 | public function verifyChecksum($checksum, $all, $secret) { 162 | $cal_checksum = $this->calculateChecksum($secret, $all); 163 | $bool = 0; 164 | if($checksum == $cal_checksum) { 165 | $bool = 1; 166 | } 167 | 168 | return $bool; 169 | } 170 | 171 | public function sanitizedParam($param) { 172 | $pattern[0] = "%,%"; 173 | $pattern[1] = "%#%"; 174 | $pattern[2] = "%\(%"; 175 | $pattern[3] = "%\)%"; 176 | $pattern[4] = "%\{%"; 177 | $pattern[5] = "%\}%"; 178 | $pattern[6] = "%<%"; 179 | $pattern[7] = "%>%"; 180 | $pattern[8] = "%`%"; 181 | $pattern[9] = "%!%"; 182 | $pattern[10] = "%\\$%"; 183 | $pattern[11] = "%\%%"; 184 | $pattern[12] = "%\^%"; 185 | $pattern[13] = "%=%"; 186 | $pattern[14] = "%\+%"; 187 | $pattern[15] = "%\|%"; 188 | $pattern[16] = "%\\\%"; 189 | $pattern[17] = "%:%"; 190 | $pattern[18] = "%'%"; 191 | $pattern[19] = "%\"%"; 192 | $pattern[20] = "%;%"; 193 | $pattern[21] = "%~%"; 194 | $pattern[22] = "%\[%"; 195 | $pattern[23] = "%\]%"; 196 | $pattern[24] = "%\*%"; 197 | $pattern[25] = "%&%"; 198 | $sanitizedParam = preg_replace($pattern, "", $param); 199 | return $sanitizedParam; 200 | } 201 | 202 | public function sanitizedURL($param) { 203 | $pattern[0] = "%,%"; 204 | $pattern[1] = "%\(%"; 205 | $pattern[2] = "%\)%"; 206 | $pattern[3] = "%\{%"; 207 | $pattern[4] = "%\}%"; 208 | $pattern[5] = "%<%"; 209 | $pattern[6] = "%>%"; 210 | $pattern[7] = "%`%"; 211 | $pattern[8] = "%!%"; 212 | $pattern[9] = "%\\$%"; 213 | $pattern[10] = "%\%%"; 214 | $pattern[11] = "%\^%"; 215 | $pattern[12] = "%\+%"; 216 | $pattern[13] = "%\|%"; 217 | $pattern[14] = "%\\\%"; 218 | $pattern[15] = "%'%"; 219 | $pattern[16] = "%\"%"; 220 | $pattern[17] = "%;%"; 221 | $pattern[18] = "%~%"; 222 | $pattern[19] = "%\[%"; 223 | $pattern[20] = "%\]%"; 224 | $pattern[21] = "%\*%"; 225 | $sanitizedParam = preg_replace($pattern, "", $param); 226 | return $sanitizedParam; 227 | } 228 | 229 | 230 | public function getAllResponseParams($response) { 231 | 232 | $all = ''; 233 | $checksumsequence= array("amount","bank","bankid", 234 | "cardId","cardScheme","cardToken","cardhashid","doRedirect", 235 | "orderId","paymentMethod","paymentMode","responseCode", 236 | "responseDescription"); 237 | foreach($checksumsequence as $seqvalue) { 238 | if(array_key_exists($seqvalue, $response)) { 239 | 240 | $all .= $seqvalue; 241 | $all .="="; 242 | if ($seqvalue == 'returnUrl') { 243 | $all .= $response[$seqvalue]; 244 | } else { 245 | $all .= $response[$seqvalue]; 246 | } 247 | $all .= "&"; 248 | 249 | } 250 | } 251 | 252 | 253 | return $all; 254 | } 255 | 256 | 257 | 258 | 259 | 260 | 261 | } -------------------------------------------------------------------------------- /src/Indipay.php: -------------------------------------------------------------------------------- 1 | gateway = $gateway; 22 | } 23 | 24 | public function purchase($parameters = array()) 25 | { 26 | 27 | return $this->gateway->request($parameters)->send(); 28 | 29 | } 30 | 31 | public function response($request) 32 | { 33 | return $this->gateway->response($request); 34 | } 35 | 36 | public function prepare($parameters = array()) 37 | { 38 | return $this->gateway->request($parameters); 39 | } 40 | 41 | public function verify($parameters = array()) 42 | { 43 | return $this->gateway->verify($parameters); 44 | } 45 | 46 | public function process($order) 47 | { 48 | return $order->send(); 49 | } 50 | 51 | public function gateway($name) 52 | { 53 | $name = strtolower($name); 54 | switch($name) 55 | { 56 | case 'ccavenue': 57 | $this->gateway = new CCAvenueGateway(); 58 | break; 59 | 60 | case 'payumoney': 61 | $this->gateway = new PayUMoneyGateway(); 62 | break; 63 | 64 | case 'ebs': 65 | $this->gateway = new EBSGateway(); 66 | break; 67 | 68 | case 'citrus': 69 | $this->gateway = new CitrusGateway(); 70 | break; 71 | 72 | case 'instamojo': 73 | $this->gateway = new InstaMojoGateway(); 74 | break; 75 | 76 | case 'mocker': 77 | $this->gateway = new MockerGateway(); 78 | break; 79 | 80 | case 'zapakpay': 81 | $this->gateway = new ZapakPayGateway(); 82 | break; 83 | 84 | } 85 | 86 | return $this; 87 | } 88 | 89 | 90 | 91 | } -------------------------------------------------------------------------------- /src/IndipayServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->bind('indipay', 'Softon\Indipay\Indipay'); 24 | 25 | $this->app->bind('Softon\Indipay\Gateways\PaymentGatewayInterface','Softon\Indipay\Gateways\\'.$gateway.'Gateway'); 26 | } 27 | 28 | 29 | public function boot(){ 30 | $this->publishes([ 31 | __DIR__.'/config/config.php' => base_path('config/indipay.php'), 32 | __DIR__.'/views/middleware.blade.php' => base_path('app/Http/Middleware/VerifyCsrfMiddleware.php'), 33 | ]); 34 | 35 | $this->loadViewsFrom(__DIR__.'/views', 'indipay'); 36 | 37 | } 38 | 39 | /** 40 | * Get the services provided by the provider. 41 | * 42 | * @return array 43 | */ 44 | public function provides() 45 | { 46 | return [ 47 | 48 | ]; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/config/config.php: -------------------------------------------------------------------------------- 1 | 'Mocker', // Replace with the name of default gateway you want to use 13 | 14 | 'testMode' => true, // True for Testing the Gateway [For production false] 15 | 16 | 'ccavenue' => [ // CCAvenue Parameters 17 | 'merchantId' => env('INDIPAY_MERCHANT_ID', ''), 18 | 'accessCode' => env('INDIPAY_ACCESS_CODE', ''), 19 | 'workingKey' => env('INDIPAY_WORKING_KEY', ''), 20 | 21 | // Should be route address for url() function 22 | 'redirectUrl' => env('INDIPAY_REDIRECT_URL', 'indipay/response'), 23 | 'cancelUrl' => env('INDIPAY_CANCEL_URL', 'indipay/response'), 24 | 25 | 'currency' => env('INDIPAY_CURRENCY', 'INR'), 26 | 'language' => env('INDIPAY_LANGUAGE', 'EN'), 27 | ], 28 | 29 | 'payumoney' => [ // PayUMoney Parameters 30 | 'merchantKey' => env('INDIPAY_MERCHANT_KEY', ''), 31 | 'salt' => env('INDIPAY_SALT', ''), 32 | 'workingKey' => env('INDIPAY_WORKING_KEY', ''), 33 | 34 | // Should be route address for url() function 35 | 'successUrl' => env('INDIPAY_SUCCESS_URL', 'indipay/response'), 36 | 'failureUrl' => env('INDIPAY_FAILURE_URL', 'indipay/response'), 37 | ], 38 | 39 | 'ebs' => [ // EBS Parameters 40 | 'account_id' => env('INDIPAY_MERCHANT_ID', ''), 41 | 'secretKey' => env('INDIPAY_WORKING_KEY', ''), 42 | 43 | // Should be route address for url() function 44 | 'return_url' => env('INDIPAY_SUCCESS_URL', 'indipay/response'), 45 | ], 46 | 47 | 'citrus' => [ // Citrus Parameters 48 | 'vanityUrl' => env('INDIPAY_CITRUS_VANITY_URL', ''), 49 | 'secretKey' => env('INDIPAY_WORKING_KEY', ''), 50 | 51 | // Should be route address for url() function 52 | 'returnUrl' => env('INDIPAY_SUCCESS_URL', 'indipay/response'), 53 | 'notifyUrl' => env('INDIPAY_SUCCESS_URL', 'indipay/response'), 54 | ], 55 | 56 | 'instamojo' => [ 57 | 'api_key' => env('INSTAMOJO_API_KEY',''), 58 | 'auth_token' => env('INSTAMOJO_AUTH_TOKEN',''), 59 | 'redirectUrl' => env('INDIPAY_REDIRECT_URL', 'indipay/response'), 60 | ], 61 | 62 | 'mocker' => [ 63 | 'service' => env('MOCKER_SERVICE','default'), 64 | 'redirect_url' => env('MOCKER_REDIRECT_URL', 'indipay/response'), 65 | ], 66 | 67 | 'zapakpay' => [ 68 | 'merchantIdentifier' => env('ZAPAKPAY_MERCHANT_ID',''), 69 | 'secret' => env('ZAPAKPAY_SECRET', ''), 70 | 'returnUrl' => env('ZAPAKPAY_RETURN_URL', 'indipay/response'), 71 | ], 72 | 73 | 'paytm' => [ 74 | 'MERCHANT_KEY' => env('PAYTM_MERCHANT_KEY',''), 75 | 'MID' => env('PAYTM_MID', ''), 76 | 'CHANNEL_ID' => env('PAYTM_CHANNEL_ID', 'WEB'), 77 | 'WEBSITE' => env('PAYTM_WEBSITE', 'WEBSTAGING'), 78 | 'INDUSTRY_TYPE_ID' => env('PAYTM_INDUSTRY_TYPE_ID', 'Retail'), 79 | 'REDIRECT_URL' => env('PAYTM_REDIRECT_URL', 'indipay/response'), 80 | ], 81 | 82 | // Add your response link here. In Laravel 5.2+ you may use the VerifyCsrf Middleware. 83 | 'remove_csrf_check' => [ 84 | 'indipay/response' 85 | ], 86 | 87 | 88 | 89 | 90 | 91 | ]; 92 | -------------------------------------------------------------------------------- /src/views/ccavenue.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | IndiPay 4 | 5 | 6 |
7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/views/citrus.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | IndiPay 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/views/ebs.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | IndiPay 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/views/instamojo.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | IndiPay 4 | 5 | 6 |
7 | 8 |
9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/views/middleware.blade.php: -------------------------------------------------------------------------------- 1 | isReading($request) || $this->excludedRoutes($request) || $this->tokensMatch($request)) 12 | { 13 | return $this->addCookieToResponse($request, $next($request)); 14 | } 15 | 16 | throw new TokenMismatchException; 17 | } 18 | 19 | protected function excludedRoutes($request) 20 | { 21 | $routes = Config::get('indipay.remove_csrf_check'); 22 | 23 | foreach($routes as $route) 24 | if ($request->is($route)) 25 | return true; 26 | 27 | return false; 28 | } 29 | } -------------------------------------------------------------------------------- /src/views/mocker.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | IndiPay 4 | 5 | 6 |
7 | @foreach ($data as $param_key=>$param_name) 8 | 9 | @endforeach 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/views/paytm.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | IndiPay 4 | 5 | 6 |
7 | @foreach($params as $param_key=>$param_value) 8 | 9 | @endforeach 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/views/payumoney.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | IndiPay 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/views/zapakpay.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | IndiPay 4 | 5 | 6 |
7 | @foreach($params as $param_key=>$param_value) 8 | @if($param_key=='returnUrl') 9 | 10 | @else 11 | 12 | @endif 13 | 14 | @endforeach 15 | 16 |
17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softon/indipay/3aaa44c50d3fedbb10b5d8df66dc16313af5380c/tests/.gitkeep --------------------------------------------------------------------------------