├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── composer.json ├── makedoc.sh ├── phpunit.xml.dist ├── runtests.sh ├── src ├── Message │ ├── AuthorizeRequest.php │ ├── CaptureRequest.php │ ├── CreateCardRequest.php │ ├── FetchTransactionRequest.php │ ├── InquiryRequest.php │ ├── PurchaseRequest.php │ ├── RefundRequest.php │ ├── Response.php │ └── VoidRequest.php └── ProGateway.php └── tests ├── Message ├── AuthorizeRequestTest.php ├── CaptureRequestTest.php └── ResponseTest.php ├── Mock ├── CreateCardSuccess.txt ├── PurchaseDecline.txt ├── PurchaseFailure.txt └── PurchaseSuccess.txt └── ProGatewayTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | composer.lock 3 | composer.phar 4 | phpunit.xml 5 | .directory 6 | .idea/ 7 | dirlist.app 8 | dirlist.vendor 9 | dirlist.cache 10 | /documents/ 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.6 5 | - 7.0 6 | - 7.1 7 | - 7.2 8 | 9 | before_script: 10 | - composer install -n --dev --prefer-source 11 | 12 | script: vendor/bin/phpcs --standard=PSR2 src && vendor/bin/phpunit --coverage-text 13 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | * Fork the project. 4 | * Make your feature addition or bug fix. 5 | * Add tests for it. This is important so I don't break it in a future version unintentionally. 6 | * Commit just the modifications, do not mess with the composer.json or CHANGELOG.md files. 7 | * Ensure your code is nicely formatted in the [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) 8 | style and that all tests pass. 9 | * Send the pull request. 10 | * Check that the Travis CI build passed. If not, rinse and repeat. 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2013 Adrian Macneil 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Omnipay: Payflow 2 | 3 | **Payflow driver for the Omnipay PHP payment processing library** 4 | 5 | [![Build Status](https://travis-ci.org/thephpleague/omnipay-payflow.png?branch=master)](https://travis-ci.org/thephpleague/omnipay-payflow) 6 | [![Latest Stable Version](https://poser.pugx.org/omnipay/payflow/version.png)](https://packagist.org/packages/omnipay/payflow) 7 | [![Total Downloads](https://poser.pugx.org/omnipay/payflow/d/total.png)](https://packagist.org/packages/omnipay/payflow) 8 | 9 | [Omnipay](https://github.com/thephpleague/omnipay) is a framework agnostic, multi-gateway payment 10 | processing library for PHP 5.3+. This package implements [Payflow](https://developer.paypal.com/docs/classic/products/payflow-gateway/) support for Omnipay. 11 | 12 | This package is tested and works with PHP 7 and 7.1. 13 | 14 | ## Installation 15 | 16 | Omnipay is installed via [Composer](http://getcomposer.org/). To install, simply add it 17 | to your `composer.json` file: 18 | 19 | ```json 20 | { 21 | "require": { 22 | "omnipay/payflow": "~2.0" 23 | } 24 | } 25 | ``` 26 | 27 | And run composer to update your dependencies: 28 | 29 | $ curl -s http://getcomposer.org/installer | php 30 | $ php composer.phar update 31 | 32 | ## Basic Usage 33 | 34 | The following gateways are provided by this package: 35 | 36 | * [Payflow_Pro](https://developer.paypal.com/docs/classic/products/payflow-gateway/) 37 | 38 | For general usage instructions, please see the main [Omnipay](https://github.com/thephpleague/omnipay) 39 | repository. 40 | 41 | ## Support 42 | 43 | If you are having general issues with Omnipay, we suggest posting on 44 | [Stack Overflow](http://stackoverflow.com/). Be sure to add the 45 | [omnipay tag](http://stackoverflow.com/questions/tagged/omnipay) so it can be easily found. 46 | 47 | If you want to keep up to date with release anouncements, discuss ideas for the project, 48 | or ask more detailed questions, there is also a [mailing list](https://groups.google.com/forum/#!forum/omnipay) which 49 | you can subscribe to. 50 | 51 | If you believe you have found a bug, please report it using the [GitHub issue tracker](https://github.com/thephpleague/omnipay-payflow/issues), 52 | or better yet, fork the library and submit a pull request. 53 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "omnipay/payflow", 3 | "type": "library", 4 | "description": "Payflow driver for the Omnipay payment processing library", 5 | "keywords": [ 6 | "gateway", 7 | "merchant", 8 | "omnipay", 9 | "pay", 10 | "payflow", 11 | "payment" 12 | ], 13 | "homepage": "https://github.com/thephpleague/omnipay-payflow", 14 | "license": "MIT", 15 | "authors": [ 16 | { 17 | "name": "Adrian Macneil", 18 | "email": "adrian@adrianmacneil.com" 19 | }, 20 | { 21 | "name": "Omnipay Contributors", 22 | "homepage": "https://github.com/thephpleague/omnipay-payflow/contributors" 23 | } 24 | ], 25 | "autoload": { 26 | "psr-4": { "Omnipay\\Payflow\\" : "src/" } 27 | }, 28 | "require": { 29 | "league/omnipay": "^3.0", 30 | "squizlabs/php_codesniffer": "^3" 31 | }, 32 | "require-dev": { 33 | "omnipay/tests": "^3.0" 34 | }, 35 | "extra": { 36 | "branch-alias": { 37 | "dev-master": "2.0.x-dev" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /makedoc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Smart little documentation generator. 5 | # GPL/LGPL 6 | # (c) Del 2015 http://www.babel.com.au/ 7 | # 8 | 9 | APPNAME='Omnipay Payflow Gateway Documentation' 10 | CMDFILE=apigen.cmd.$$ 11 | DESTDIR=./documents 12 | SRCDIRS="src" 13 | VENDORDIRS="vendor/guzzle vendor/omnipay" 14 | 15 | # 16 | # Ensure that dependencies are installed (including codeception and phpunit) 17 | # 18 | if [ -f composer.lock ]; then 19 | /usr/local/bin/composer install 20 | else 21 | /usr/local/bin/composer update 22 | fi 23 | 24 | # 25 | # Find apigen, either in the path or as a local phar file 26 | # 27 | if [ -f apigen.phar ]; then 28 | APIGEN="php apigen.phar" 29 | 30 | else 31 | APIGEN=`which apigen` 32 | if [ ! -f "$APIGEN" ]; then 33 | 34 | # Search for phpdoc if apigen is not found. 35 | if [ -f phpDocumentor.phar ]; then 36 | PHPDOC="php phpDocumentor.phar" 37 | 38 | else 39 | PHPDOC=`which phpdoc` 40 | if [ ! -f "$PHPDOC" ]; then 41 | echo "Neither apigen nor phpdoc is installed in the path or locally, please install one of them" 42 | echo "see http://www.apigen.org/ or http://www.phpdoc.org/" 43 | exit 1 44 | fi 45 | fi 46 | fi 47 | fi 48 | 49 | # 50 | # As of version 4 of apigen need to use the generate subcommand 51 | # 52 | if [ ! -z "$APIGEN" ]; then 53 | APIGEN="$APIGEN generate" 54 | fi 55 | 56 | # 57 | # Without any arguments this builds the entire system documentation, 58 | # making the cache file first if required. 59 | # 60 | if [ -z "$1" ]; then 61 | # 62 | # Check to see that the cache has been made. 63 | # 64 | if [ ! -f dirlist.cache ]; then 65 | echo "Making dirlist.cache file" 66 | $0 makecache 67 | fi 68 | 69 | # 70 | # Build the apigen/phpdoc command in a file. 71 | # 72 | if [ ! -z "$APIGEN" ]; then 73 | echo "$APIGEN --php --tree --title '$APPNAME API Documentation' --destination $DESTDIR/main \\" > $CMDFILE 74 | cat dirlist.cache | while read dir; do 75 | echo "--source $dir \\" >> $CMDFILE 76 | done 77 | echo "" >> $CMDFILE 78 | 79 | elif [ ! -z "$PHPDOC" ]; then 80 | echo "$PHPDOC --sourcecode --title '$APPNAME API Documentation' --target $DESTDIR/main --directory \\" > $CMDFILE 81 | cat dirlist.cache | while read dir; do 82 | echo "${dir},\\" >> $CMDFILE 83 | done 84 | echo "" >> $CMDFILE 85 | 86 | else 87 | "Neither apigen nor phpdoc are found, how did I get here?" 88 | exit 1 89 | fi 90 | 91 | # 92 | # Run the apigen command 93 | # 94 | rm -rf $DESTDIR/main 95 | mkdir -p $DESTDIR/main 96 | . ./$CMDFILE 97 | 98 | /bin/rm -f ./$CMDFILE 99 | 100 | # 101 | # The "makecache" argument causes the script to just make the cache file 102 | # 103 | elif [ "$1" = "makecache" ]; then 104 | echo "Find application source directories" 105 | find $SRCDIRS -name \*.php -print | \ 106 | ( 107 | while read file; do 108 | grep -q 'class' $file && dirname $file 109 | done 110 | ) | sort -u | \ 111 | grep -v -E 'config|docs|migrations|test|Test|views|web' > dirlist.app 112 | 113 | echo "Find vendor source directories" 114 | find $VENDORDIRS -name \*.php -print | \ 115 | ( 116 | while read file; do 117 | grep -q 'class' $file && dirname $file 118 | done 119 | ) | sort -u | \ 120 | grep -v -E 'config|docs|migrations|test|Test|views|codesniffer|phpmd|pdepend|php-parser|codeception|phpunit' > dirlist.vendor 121 | 122 | # 123 | # Filter out any directories for which apigen fails 124 | # 125 | echo "Filter source directories" 126 | mkdir -p $DESTDIR/tmp 127 | cat dirlist.app dirlist.vendor | while read dir; do 128 | if [ ! -z "$APIGEN" ]; then 129 | $APIGEN --quiet --title "Test please ignore" \ 130 | --source $dir \ 131 | --destination $DESTDIR/tmp && ( 132 | echo "Including $dir" 133 | echo $dir >> dirlist.cache 134 | ) || ( 135 | echo "Excluding $dir" 136 | ) 137 | 138 | elif [ ! -z "$PHPDOC" ]; then 139 | $PHPDOC --quiet --title "Test please ignore" \ 140 | --directory $dir \ 141 | --target $DESTDIR/tmp && ( 142 | echo "Including $dir" 143 | echo $dir >> dirlist.cache 144 | ) || ( 145 | echo "Excluding $dir" 146 | ) 147 | 148 | fi 149 | done 150 | echo "Documentation cache dirlist.cache built OK" 151 | 152 | # 153 | # Clean up 154 | # 155 | /bin/rm -rf $DESTDIR/tmp 156 | 157 | fi 158 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests/ 15 | 16 | 17 | 18 | 19 | ./src 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /runtests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Command line runner for unit tests for composer projects 5 | # (c) Del 2015 http://www.babel.com.au/ 6 | # No Rights Reserved 7 | # 8 | 9 | # 10 | # Clean up after any previous test runs 11 | # 12 | mkdir -p documents 13 | rm -rf documents/coverage-html-new 14 | rm -f documents/coverage.xml 15 | 16 | # 17 | # Run phpunit 18 | # 19 | vendor/bin/phpunit --coverage-html documents/coverage-html-new --coverage-clover documents/coverage.xml 20 | 21 | if [ -d documents/coverage-html-new ]; then 22 | rm -rf documents/coverage-html 23 | mv documents/coverage-html-new documents/coverage-html 24 | fi 25 | 26 | -------------------------------------------------------------------------------- /src/Message/AuthorizeRequest.php: -------------------------------------------------------------------------------- 1 | 13 | * // Create a gateway for the Payflow pro Gateway 14 | * // (routes to GatewayFactory::create) 15 | * $gateway = Omnipay::create('Payflow_Pro'); 16 | * 17 | * // Initialise the gateway 18 | * $gateway->initialize(array( 19 | * 'username' => $myusername, 20 | * 'password' => $mypassword, 21 | * 'vendor' => $mymerchantid, 22 | * 'partner' => $PayPalPartner, 23 | * 'testMode' => true, // Or false for live transactions. 24 | * )); 25 | * 26 | * // Create a credit card object 27 | * // This card can be used for testing. 28 | * $card = new CreditCard(array( 29 | * 'firstName' => 'Example', 30 | * 'lastName' => 'Customer', 31 | * 'number' => '4111111111111111', 32 | * 'expiryMonth' => '01', 33 | * 'expiryYear' => '2020', 34 | * 'cvv' => '123', 35 | * )); 36 | * 37 | * // Do an authorize transaction on the gateway 38 | * $transaction = $gateway->authorize(array( 39 | * 'amount' => '10.00', 40 | * 'currency' => 'AUD', 41 | * 'card' => $card, 42 | * )); 43 | * $response = $transaction->send(); 44 | * if ($response->isSuccessful()) { 45 | * echo "Authorize transaction was successful!\n"; 46 | * $sale_id = $response->getTransactionReference(); 47 | * echo "Transaction reference = " . $sale_id . "\n"; 48 | * } 49 | * 50 | */ 51 | class AuthorizeRequest extends AbstractRequest 52 | { 53 | protected $liveEndpoint = 'https://payflowpro.paypal.com'; 54 | protected $testEndpoint = 'https://pilot-payflowpro.paypal.com'; 55 | protected $action = 'A'; 56 | 57 | /** 58 | * Get the username. 59 | * 60 | * This is the ID that you specified when you got the Payflow account. 61 | * 62 | * @return string 63 | */ 64 | public function getUsername() 65 | { 66 | return $this->getParameter('username'); 67 | } 68 | 69 | /** 70 | * Set the username. 71 | * 72 | * This is the ID that you specified when you got the Payflow account. 73 | * 74 | * @param string $value 75 | * @return AuthorizeRequest provides a fluent interface. 76 | */ 77 | public function setUsername($value) 78 | { 79 | return $this->setParameter('username', $value); 80 | } 81 | 82 | /** 83 | * Get the password. 84 | * 85 | * This is the password that you specified when you got the Payflow account. 86 | * 87 | * @return string 88 | */ 89 | public function getPassword() 90 | { 91 | return $this->getParameter('password'); 92 | } 93 | 94 | /** 95 | * Set the password. 96 | * 97 | * This is the password that you specified when you got the Payflow account. 98 | * 99 | * @param string $value 100 | * @return AuthorizeRequest provides a fluent interface. 101 | */ 102 | public function setPassword($value) 103 | { 104 | return $this->setParameter('password', $value); 105 | } 106 | 107 | /** 108 | * Get the vendor. 109 | * 110 | * The ID that you specified when you got the Payflow account, the same as the username unless you 111 | * have created additional users on the account. That is, the merchant login ID for the account. 112 | * 113 | * @return string 114 | */ 115 | public function getVendor() 116 | { 117 | return $this->getParameter('vendor'); 118 | } 119 | 120 | /** 121 | * Set the vendor. 122 | * 123 | * The ID that you specified when you got the Payflow account, the same as the username unless you 124 | * have created additional users on the account. That is, the merchant login ID for the account. 125 | * 126 | * @param string $value 127 | * @return AuthorizeRequest provides a fluent interface. 128 | */ 129 | public function setVendor($value) 130 | { 131 | return $this->setParameter('vendor', $value); 132 | } 133 | 134 | /** 135 | * Get the partner. 136 | * 137 | * The Payflow partner. This may be PayPal, or if an account was provided by an authorized PayPal 138 | * reseller, who registered a Payflow user, then the ID provided by the reseller is used. 139 | * 140 | * @return string 141 | */ 142 | public function getPartner() 143 | { 144 | return $this->getParameter('partner'); 145 | } 146 | 147 | /** 148 | * Set the partner. 149 | * 150 | * The Payflow partner. This may be PayPal, or if an account was provided by an authorized PayPal 151 | * reseller, who registered a Payflow user, then the ID provided by the reseller is used. 152 | * 153 | * @param string $value 154 | * @return AuthorizeRequest provides a fluent interface. 155 | */ 156 | public function setPartner($value) 157 | { 158 | return $this->setParameter('partner', $value); 159 | } 160 | 161 | public function getComment1() 162 | { 163 | return $this->getDescription(); 164 | } 165 | 166 | public function setComment1($value) 167 | { 168 | return $this->setDescription($value); 169 | } 170 | 171 | public function getComment2() 172 | { 173 | return $this->getParameter('comment2'); 174 | } 175 | 176 | public function setComment2($value) 177 | { 178 | return $this->setParameter('comment2', $value); 179 | } 180 | 181 | public function getOrderId() 182 | { 183 | return $this->getParameter('orderid'); 184 | } 185 | 186 | public function setOrderId($value) 187 | { 188 | return $this->setParameter('orderid', $value); 189 | } 190 | 191 | public function setPoNum($value) 192 | { 193 | return $this->setParameter('ponum', $value); 194 | } 195 | 196 | public function getPoNum() 197 | { 198 | return $this->getParameter('ponum'); 199 | } 200 | 201 | /** 202 | * @deprecated 203 | */ 204 | public function getOrigid() 205 | { 206 | return $this->getParameter('origid'); 207 | } 208 | 209 | /** 210 | * @deprecated 211 | */ 212 | public function setOrigid($value) 213 | { 214 | return $this->setParameter('origid', $value); 215 | } 216 | 217 | protected function getBaseData() 218 | { 219 | $data = array(); 220 | $data['TRXTYPE'] = $this->action; 221 | $data['USER'] = $this->getUsername(); 222 | $data['PWD'] = $this->getPassword(); 223 | $data['VENDOR'] = $this->getVendor(); 224 | $data['PARTNER'] = $this->getPartner(); 225 | if ($this->getDescription()) { 226 | $data['COMMENT1'] = $this->getDescription(); 227 | } 228 | if ($this->getComment2()) { 229 | $data['COMMENT2'] = $this->getComment2(); 230 | } 231 | 232 | return $data; 233 | } 234 | 235 | public function getData() 236 | { 237 | $this->validate('amount'); 238 | $data = $this->getBaseData(); 239 | 240 | if ($this->getCardReference()) { 241 | $data['ORIGID'] = $this->getCardReference(); 242 | if ($this->getCard()) { 243 | $data['CVV2'] = $this->getCard()->getCvv(); 244 | } 245 | } else { 246 | $this->validate('card'); 247 | $this->getCard()->validate(); 248 | 249 | $data['ACCT'] = $this->getCard()->getNumber(); 250 | $data['EXPDATE'] = $this->getCard()->getExpiryDate('my'); 251 | $data['CVV2'] = $this->getCard()->getCvv(); 252 | $data['BILLTOFIRSTNAME'] = $this->getCard()->getFirstName(); 253 | $data['BILLTOLASTNAME'] = $this->getCard()->getLastName(); 254 | $data['BILLTOSTREET'] = $this->getCard()->getAddress1(); 255 | $data['BILLTOCITY'] = $this->getCard()->getCity(); 256 | $data['BILLTOSTATE'] = $this->getCard()->getState(); 257 | $data['BILLTOZIP'] = $this->getCard()->getPostcode(); 258 | $data['BILLTOCOUNTRY'] = $this->getCard()->getCountry(); 259 | } 260 | 261 | $data['TENDER'] = 'C'; 262 | $data['AMT'] = $this->getAmount(); 263 | $data['CURRENCY'] = $this->getCurrency(); 264 | $data['ORDERID'] = $this->getOrderId(); 265 | $data['PONUM'] = $this->getPoNum(); 266 | 267 | if ($this->getCard()) { 268 | $data['BILLTOEMAIL'] = $this->getCard()->getEmail(); 269 | $data['BILLTOPHONENUM'] = $this->getCard()->getBillingPhone(); 270 | } 271 | 272 | $items = $this->getItems(); 273 | if (!empty($items)) { 274 | foreach ($items as $key => $item) { 275 | $data['L_NAME' . $key] = $item->getName(); 276 | $data['L_QTY' . $key] = $item->getQuantity(); 277 | } 278 | } 279 | 280 | return $data; 281 | } 282 | 283 | public function sendData($data) 284 | { 285 | $httpResponse = $this->httpClient->request( 286 | 'POST', 287 | $this->getEndpoint(), 288 | [], 289 | $this->encodeData($data) 290 | ); 291 | 292 | return $this->response = new Response($this, $httpResponse->getBody()->getContents()); 293 | } 294 | 295 | /** 296 | * Encode absurd name value pair format 297 | */ 298 | public function encodeData(array $data) 299 | { 300 | $output = array(); 301 | foreach ($data as $key => $value) { 302 | $output[] = $key.'['.strlen($value).']='.$value; 303 | } 304 | 305 | return implode('&', $output); 306 | } 307 | 308 | protected function getEndpoint() 309 | { 310 | return $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint; 311 | } 312 | } 313 | -------------------------------------------------------------------------------- /src/Message/CaptureRequest.php: -------------------------------------------------------------------------------- 1 | 11 | * // Create a gateway for the Payflow pro Gateway 12 | * // (routes to GatewayFactory::create) 13 | * $gateway = Omnipay::create('Payflow_Pro'); 14 | * 15 | * // Initialise the gateway 16 | * $gateway->initialize(array( 17 | * 'username' => $myusername, 18 | * 'password' => $mypassword, 19 | * 'vendor' => $mymerchantid, 20 | * 'partner' => $PayPalPartner, 21 | * 'testMode' => true, // Or false for live transactions. 22 | * )); 23 | * 24 | * // Create a credit card object 25 | * // This card can be used for testing. 26 | * $card = new CreditCard(array( 27 | * 'firstName' => 'Example', 28 | * 'lastName' => 'Customer', 29 | * 'number' => '4111111111111111', 30 | * 'expiryMonth' => '01', 31 | * 'expiryYear' => '2020', 32 | * 'cvv' => '123', 33 | * )); 34 | * 35 | * // Do an authorize transaction on the gateway 36 | * $transaction = $gateway->authorize(array( 37 | * 'amount' => '10.00', 38 | * 'currency' => 'AUD', 39 | * 'card' => $card, 40 | * )); 41 | * $response = $transaction->send(); 42 | * if ($response->isSuccessful()) { 43 | * echo "Authorize transaction was successful!\n"; 44 | * $sale_id = $response->getTransactionReference(); 45 | * echo "Transaction reference = " . $sale_id . "\n"; 46 | * } 47 | * 48 | * // Capture the authorization 49 | * $transaction = $gateway->capture(array( 50 | * 'amount' => '10.00', 51 | * 'transactionReference' => $sale_id, 52 | * )); 53 | * $response = $transaction->send(); 54 | * if ($response->isSuccessful()) { 55 | * echo "Capture transaction was successful!\n"; 56 | * $sale_id = $response->getTransactionReference(); 57 | * echo "Transaction reference = " . $sale_id . "\n"; 58 | * } 59 | * 60 | */ 61 | class CaptureRequest extends AuthorizeRequest 62 | { 63 | protected $action = 'D'; 64 | 65 | public function getData() 66 | { 67 | $this->validate('transactionReference', 'amount'); 68 | 69 | $data = $this->getBaseData(); 70 | $data['AMT'] = $this->getAmount(); 71 | $data['ORIGID'] = $this->getTransactionReference(); 72 | 73 | return $data; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Message/CreateCardRequest.php: -------------------------------------------------------------------------------- 1 | 11 | * // Create a gateway for the Payflow pro Gateway 12 | * // (routes to GatewayFactory::create) 13 | * $gateway = Omnipay::create('Payflow_Pro'); 14 | * 15 | * // Initialise the gateway 16 | * $gateway->initialize(array( 17 | * 'username' => $myusername, 18 | * 'password' => $mypassword, 19 | * 'vendor' => $mymerchantid, 20 | * 'partner' => $PayPalPartner, 21 | * 'testMode' => true, // Or false for live transactions. 22 | * )); 23 | * 24 | * // Create a credit card object 25 | * // This card can be used for testing. 26 | * $card = new CreditCard(array( 27 | * 'firstName' => 'Example', 28 | * 'lastName' => 'Customer', 29 | * 'number' => '4111111111111111', 30 | * 'expiryMonth' => '01', 31 | * 'expiryYear' => '2020', 32 | * 'cvv' => '123', 33 | * )); 34 | * 35 | * // Do a create card transaction on the gateway 36 | * $transaction = $gateway->createCard(array( 37 | * 'card' => $card, 38 | * )); 39 | * $response = $transaction->send(); 40 | * if ($response->isSuccessful()) { 41 | * echo "Create Card transaction was successful!\n"; 42 | * $card_id = $response->getCardReference(); 43 | * echo "Card reference = " . $card_id . "\n"; 44 | * } 45 | * 46 | */ 47 | class CreateCardRequest extends AuthorizeRequest 48 | { 49 | protected $action = 'L'; 50 | 51 | public function getData() 52 | { 53 | 54 | $this->getCard()->validate(); 55 | $data = $this->getBaseData(); 56 | 57 | $data['TENDER'] = 'C'; 58 | 59 | $data['ACCT'] = $this->getCard()->getNumber(); 60 | $data['EXPDATE'] = $this->getCard()->getExpiryDate('my'); 61 | $data['CVV2'] = $this->getCard()->getCvv(); 62 | $data['BILLTOFIRSTNAME'] = $this->getCard()->getFirstName(); 63 | $data['BILLTOLASTNAME'] = $this->getCard()->getLastName(); 64 | $data['BILLTOSTREET'] = $this->getCard()->getAddress1(); 65 | $data['BILLTOCITY'] = $this->getCard()->getCity(); 66 | $data['BILLTOSTATE'] = $this->getCard()->getState(); 67 | $data['BILLTOZIP'] = $this->getCard()->getPostcode(); 68 | $data['BILLTOCOUNTRY'] = $this->getCard()->getCountry(); 69 | 70 | return $data; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Message/FetchTransactionRequest.php: -------------------------------------------------------------------------------- 1 | 11 | * // Create a gateway for the Payflow pro Gateway 12 | * // (routes to GatewayFactory::create) 13 | * $gateway = Omnipay::create('Payflow_Pro'); 14 | * 15 | * // Initialise the gateway 16 | * $gateway->initialize(array( 17 | * 'username' => $myusername, 18 | * 'password' => $mypassword, 19 | * 'vendor' => $mymerchantid, 20 | * 'partner' => $PayPalPartner, 21 | * 'testMode' => true, // Or false for live transactions. 22 | * )); 23 | * 24 | * // Create a credit card object 25 | * // This card can be used for testing. 26 | * $card = new CreditCard(array( 27 | * 'firstName' => 'Example', 28 | * 'lastName' => 'Customer', 29 | * 'number' => '4111111111111111', 30 | * 'expiryMonth' => '01', 31 | * 'expiryYear' => '2020', 32 | * 'cvv' => '123', 33 | * )); 34 | * 35 | * // Do a purchase transaction on the gateway 36 | * $transaction = $gateway->purchase(array( 37 | * 'amount' => '10.00', 38 | * 'currency' => 'AUD', 39 | * 'card' => $card, 40 | * )); 41 | * $response = $transaction->send(); 42 | * if ($response->isSuccessful()) { 43 | * echo "Purchase transaction was successful!\n"; 44 | * $sale_id = $response->getTransactionReference(); 45 | * echo "Transaction reference = " . $sale_id . "\n"; 46 | * } 47 | * 48 | * // Fetch the purchase 49 | * $transaction = $gateway->fetchTransaction(array( 50 | * 'transactionReference' => $sale_id, 51 | * )); 52 | * $response = $transaction->send(); 53 | * if ($response->isSuccessful()) { 54 | * echo "Fetch transaction was successful!\n"; 55 | * $data = $response->getData(); 56 | * echo "Transaction Data =\n" . print_r($data, true) . "\n"; 57 | * } 58 | * 59 | */ 60 | class FetchTransactionRequest extends AuthorizeRequest 61 | { 62 | protected $action = 'I'; 63 | 64 | public function getData() 65 | { 66 | $data = $this->getBaseData(); 67 | 68 | $data['TENDER'] = 'C'; 69 | $data['VERBOSITY'] = 'HIGH'; 70 | $data['ORIGID'] = $this->getTransactionReference(); 71 | 72 | return $data; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Message/InquiryRequest.php: -------------------------------------------------------------------------------- 1 | getBaseData(); 17 | 18 | $data['TENDER'] = 'C'; 19 | $data['VERBOSITY'] = 'HIGH'; 20 | $data['ORIGID'] = $this->getOrigid(); 21 | 22 | return $data; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Message/PurchaseRequest.php: -------------------------------------------------------------------------------- 1 | 11 | * // Create a gateway for the Payflow pro Gateway 12 | * // (routes to GatewayFactory::create) 13 | * $gateway = Omnipay::create('Payflow_Pro'); 14 | * 15 | * // Initialise the gateway 16 | * $gateway->initialize(array( 17 | * 'username' => $myusername, 18 | * 'password' => $mypassword, 19 | * 'vendor' => $mymerchantid, 20 | * 'partner' => $PayPalPartner, 21 | * 'testMode' => true, // Or false for live transactions. 22 | * )); 23 | * 24 | * // Next, there are two ways to conduct a sale with Payflow: 25 | * // 1. a reference sale in which an authorization transaction reference is passed 26 | * // 2. a sale in which card data is directly passed 27 | * // 28 | * // #1 should be used any time multiple charges must be committed against an authorization 29 | * // either because parts of an order shipped at different times or because authorization is 30 | * // being used to "tokenize" a card and store it on the gateway (a Paypal prescribed process). 31 | * // Capture can only be called once against an authorization but sale does not have this limitation. 32 | * 33 | * // @see developer.paypal.com/docs/classic/payflow/integration-guide/#submitting-reference-transactions---tokenization 34 | * 35 | * // 1. Reference (tokenized card) Sale example: 36 | * // $reference_id can be the transaction reference from a previous authorization, credit, capture, sale, voice auth, 37 | * // or void. 38 | * $transaction = $gateway->purchase(array( 39 | * 'amount' => '10.00', 40 | * 'cardReference' => $reference_id, 41 | * )); 42 | * 43 | * // 2. Sale (with card data) example: 44 | * // Create a credit card object 45 | * // This card can be used for testing. 46 | * $card = new CreditCard(array( 47 | * 'firstName' => 'Example', 48 | * 'lastName' => 'Customer', 49 | * 'number' => '4111111111111111', 50 | * 'expiryMonth' => '01', 51 | * 'expiryYear' => '2020', 52 | * 'cvv' => '123', 53 | * )); 54 | * 55 | * // Do a purchase transaction on the gateway 56 | * $transaction = $gateway->purchase(array( 57 | * 'amount' => '10.00', 58 | * 'currency' => 'AUD', 59 | * 'card' => $card, 60 | * )); 61 | * $response = $transaction->send(); 62 | * if ($response->isSuccessful()) { 63 | * echo "Purchase transaction was successful!\n"; 64 | * $sale_id = $response->getTransactionReference(); 65 | * echo "Transaction reference = " . $sale_id . "\n"; 66 | * } 67 | * 68 | */ 69 | class PurchaseRequest extends AuthorizeRequest 70 | { 71 | protected $action = 'S'; 72 | } 73 | -------------------------------------------------------------------------------- /src/Message/RefundRequest.php: -------------------------------------------------------------------------------- 1 | 11 | * // Create a gateway for the Payflow pro Gateway 12 | * // (routes to GatewayFactory::create) 13 | * $gateway = Omnipay::create('Payflow_Pro'); 14 | * 15 | * // Initialise the gateway 16 | * $gateway->initialize(array( 17 | * 'username' => $myusername, 18 | * 'password' => $mypassword, 19 | * 'vendor' => $mymerchantid, 20 | * 'partner' => $PayPalPartner, 21 | * 'testMode' => true, // Or false for live transactions. 22 | * )); 23 | * 24 | * // Create a credit card object 25 | * // This card can be used for testing. 26 | * $card = new CreditCard(array( 27 | * 'firstName' => 'Example', 28 | * 'lastName' => 'Customer', 29 | * 'number' => '4111111111111111', 30 | * 'expiryMonth' => '01', 31 | * 'expiryYear' => '2020', 32 | * 'cvv' => '123', 33 | * )); 34 | * 35 | * // Do a purchase transaction on the gateway 36 | * $transaction = $gateway->purchase(array( 37 | * 'amount' => '10.00', 38 | * 'currency' => 'AUD', 39 | * 'card' => $card, 40 | * )); 41 | * $response = $transaction->send(); 42 | * if ($response->isSuccessful()) { 43 | * echo "Purchase transaction was successful!\n"; 44 | * $sale_id = $response->getTransactionReference(); 45 | * echo "Transaction reference = " . $sale_id . "\n"; 46 | * } 47 | * 48 | * // Refund the purchase 49 | * $transaction = $gateway->refund(array( 50 | * 'amount' => '10.00', 51 | * 'transactionReference' => $sale_id, 52 | * )); 53 | * $response = $transaction->send(); 54 | * if ($response->isSuccessful()) { 55 | * echo "Refund transaction was successful!\n"; 56 | * $refund_id = $response->getTransactionReference(); 57 | * echo "Refund reference = " . $refund_id . "\n"; 58 | * } 59 | * 60 | */ 61 | class RefundRequest extends CaptureRequest 62 | { 63 | protected $action = 'C'; 64 | } 65 | -------------------------------------------------------------------------------- /src/Message/Response.php: -------------------------------------------------------------------------------- 1 | request = $request; 17 | 18 | if (empty($data)) { 19 | throw new InvalidResponseException; 20 | } 21 | 22 | $this->data = $this->decodeData($data); 23 | } 24 | 25 | /** 26 | * Decode absurd name value pair format 27 | */ 28 | public function decodeData($data) 29 | { 30 | $output = array(); 31 | while (strlen($data) > 0) { 32 | preg_match('/(\w+)(\[(\d+)\])?=/', $data, $matches); 33 | $key = $matches[1]; 34 | $data = substr($data, strlen($matches[0])); 35 | 36 | if (isset($matches[3])) { 37 | $value = substr($data, 0, $matches[3]); 38 | } else { 39 | $next = strpos($data, '&'); 40 | $value = $next === false ? $data : substr($data, 0, $next); 41 | } 42 | 43 | $data = substr($data, strlen($value) + 1); 44 | $output[$key] = $value; 45 | } 46 | 47 | return $output; 48 | } 49 | 50 | public function isSuccessful() 51 | { 52 | return isset($this->data['RESULT']) && '0' === $this->data['RESULT']; 53 | } 54 | 55 | public function getTransactionReference() 56 | { 57 | return isset($this->data['PNREF']) ? $this->data['PNREF'] : null; 58 | } 59 | 60 | public function getMessage() 61 | { 62 | return isset($this->data['RESPMSG']) ? $this->data['RESPMSG'] : null; 63 | } 64 | 65 | public function getCardReference() 66 | { 67 | return $this->request instanceof AuthorizeRequest || $this->request instanceof CreateCardRequest 68 | ? $this->getTransactionReference() 69 | : null; 70 | } 71 | 72 | public function getCode() 73 | { 74 | return isset($this->data['RESULT']) ? (int) $this->data['RESULT'] : null; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Message/VoidRequest.php: -------------------------------------------------------------------------------- 1 | 11 | * // Create a gateway for the Payflow pro Gateway 12 | * // (routes to GatewayFactory::create) 13 | * $gateway = Omnipay::create('Payflow_Pro'); 14 | * 15 | * // Initialise the gateway 16 | * $gateway->initialize(array( 17 | * 'username' => $myusername, 18 | * 'password' => $mypassword, 19 | * 'vendor' => $mymerchantid, 20 | * 'partner' => $PayPalPartner, 21 | * 'testMode' => true, // Or false for live transactions. 22 | * )); 23 | * 24 | * // Create a credit card object 25 | * // This card can be used for testing. 26 | * $card = new CreditCard(array( 27 | * 'firstName' => 'Example', 28 | * 'lastName' => 'Customer', 29 | * 'number' => '4111111111111111', 30 | * 'expiryMonth' => '01', 31 | * 'expiryYear' => '2020', 32 | * 'cvv' => '123', 33 | * )); 34 | * 35 | * // Do a purchase transaction on the gateway 36 | * $transaction = $gateway->purchase(array( 37 | * 'amount' => '10.00', 38 | * 'currency' => 'AUD', 39 | * 'card' => $card, 40 | * )); 41 | * $response = $transaction->send(); 42 | * if ($response->isSuccessful()) { 43 | * echo "Purchase transaction was successful!\n"; 44 | * $sale_id = $response->getTransactionReference(); 45 | * echo "Transaction reference = " . $sale_id . "\n"; 46 | * } 47 | * 48 | * // Void the purchase 49 | * $transaction = $gateway->void(array( 50 | * 'transactionReference' => $sale_id, 51 | * )); 52 | * $response = $transaction->send(); 53 | * if ($response->isSuccessful()) { 54 | * echo "Void transaction was successful!\n"; 55 | * } 56 | * 57 | */ 58 | class VoidRequest extends AuthorizeRequest 59 | { 60 | protected $action = 'V'; 61 | 62 | /** 63 | * Void prevents transactions from being settled. 64 | * 65 | * @return array ... the data Payflow needs to void a transaction 66 | * @throws \Omnipay\Common\Exception\InvalidRequestException 67 | */ 68 | public function getData() 69 | { 70 | $this->validate('transactionReference'); 71 | 72 | $data = $this->getBaseData(); 73 | $data['ORIGID'] = $this->getTransactionReference(); 74 | 75 | return $data; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/ProGateway.php: -------------------------------------------------------------------------------- 1 | 54 | * // Create a gateway for the Payflow pro Gateway 55 | * // (routes to GatewayFactory::create) 56 | * $gateway = Omnipay::create('Payflow_Pro'); 57 | * 58 | * // Initialise the gateway 59 | * $gateway->initialize(array( 60 | * 'username' => $myusername, 61 | * 'password' => $mypassword, 62 | * 'vendor' => $mymerchantid, 63 | * 'partner' => $PayPalPartner, 64 | * 'testMode' => true, // Or false for live transactions. 65 | * )); 66 | * 67 | * // Create a credit card object 68 | * // This card can be used for testing. 69 | * $card = new CreditCard(array( 70 | * 'firstName' => 'Example', 71 | * 'lastName' => 'Customer', 72 | * 'number' => '4111111111111111', 73 | * 'expiryMonth' => '01', 74 | * 'expiryYear' => '2020', 75 | * 'cvv' => '123', 76 | * )); 77 | * 78 | * // Do a purchase transaction on the gateway 79 | * $transaction = $gateway->purchase(array( 80 | * 'amount' => '10.00', 81 | * 'currency' => 'AUD', 82 | * 'card' => $card, 83 | * )); 84 | * $response = $transaction->send(); 85 | * if ($response->isSuccessful()) { 86 | * echo "Purchase transaction was successful!\n"; 87 | * $sale_id = $response->getTransactionReference(); 88 | * echo "Transaction reference = " . $sale_id . "\n"; 89 | * } 90 | * 91 | * 92 | * @link https://developer.paypal.com/docs/classic/products/payflow-gateway/ 93 | */ 94 | class ProGateway extends AbstractGateway 95 | { 96 | public function getName() 97 | { 98 | return 'Payflow'; 99 | } 100 | 101 | public function getDefaultParameters() 102 | { 103 | return array( 104 | 'username' => '', 105 | 'password' => '', 106 | 'vendor' => '', 107 | 'partner' => '', 108 | 'testMode' => false, 109 | ); 110 | } 111 | 112 | /** 113 | * Get the username. 114 | * 115 | * This is the ID that you specified when you got the Payflow account. 116 | * 117 | * @return string 118 | */ 119 | public function getUsername() 120 | { 121 | return $this->getParameter('username'); 122 | } 123 | 124 | /** 125 | * Set the username. 126 | * 127 | * This is the ID that you specified when you got the Payflow account. 128 | * 129 | * @param string $value 130 | * @return ProGateway provides a fluent interface. 131 | */ 132 | public function setUsername($value) 133 | { 134 | return $this->setParameter('username', $value); 135 | } 136 | 137 | /** 138 | * Get the password. 139 | * 140 | * This is the password that you specified when you got the Payflow account. 141 | * 142 | * @return string 143 | */ 144 | public function getPassword() 145 | { 146 | return $this->getParameter('password'); 147 | } 148 | 149 | /** 150 | * Set the password. 151 | * 152 | * This is the password that you specified when you got the Payflow account. 153 | * 154 | * @param string $value 155 | * @return ProGateway provides a fluent interface. 156 | */ 157 | public function setPassword($value) 158 | { 159 | return $this->setParameter('password', $value); 160 | } 161 | 162 | /** 163 | * Get the vendor. 164 | * 165 | * The ID that you specified when you got the Payflow account, the same as the username unless you 166 | * have created additional users on the account. That is, the merchant login ID for the account. 167 | * 168 | * @return string 169 | */ 170 | public function getVendor() 171 | { 172 | return $this->getParameter('vendor'); 173 | } 174 | 175 | /** 176 | * Set the vendor. 177 | * 178 | * The ID that you specified when you got the Payflow account, the same as the username unless you 179 | * have created additional users on the account. That is, the merchant login ID for the account. 180 | * 181 | * @param string $value 182 | * @return ProGateway provides a fluent interface. 183 | */ 184 | public function setVendor($value) 185 | { 186 | return $this->setParameter('vendor', $value); 187 | } 188 | 189 | /** 190 | * Get the partner. 191 | * 192 | * The Payflow partner. This may be PayPal, or if an account was provided by an authorized PayPal 193 | * reseller, who registered a Payflow user, then the ID provided by the reseller is used. 194 | * 195 | * @return string 196 | */ 197 | public function getPartner() 198 | { 199 | return $this->getParameter('partner'); 200 | } 201 | 202 | /** 203 | * Set the partner. 204 | * 205 | * The Payflow partner. This may be PayPal, or if an account was provided by an authorized PayPal 206 | * reseller, who registered a Payflow user, then the ID provided by the reseller is used. 207 | * 208 | * @param string $value 209 | * @return ProGateway provides a fluent interface. 210 | */ 211 | public function setPartner($value) 212 | { 213 | return $this->setParameter('partner', $value); 214 | } 215 | 216 | /** 217 | * Create an authorize request. 218 | * 219 | * @param array $parameters 220 | * @return \Omnipay\Payflow\Message\AuthorizeRequest 221 | */ 222 | public function authorize(array $parameters = array()) 223 | { 224 | return $this->createRequest('\Omnipay\Payflow\Message\AuthorizeRequest', $parameters); 225 | } 226 | 227 | /** 228 | * Create a capture request. 229 | * 230 | * @param array $parameters 231 | * @return \Omnipay\Payflow\Message\CaptureRequest 232 | */ 233 | public function capture(array $parameters = array()) 234 | { 235 | return $this->createRequest('\Omnipay\Payflow\Message\CaptureRequest', $parameters); 236 | } 237 | 238 | /** 239 | * Create a purchase request. 240 | * 241 | * @param array $parameters 242 | * @return \Omnipay\Payflow\Message\PurchaseRequest 243 | */ 244 | public function purchase(array $parameters = array()) 245 | { 246 | return $this->createRequest('\Omnipay\Payflow\Message\PurchaseRequest', $parameters); 247 | } 248 | 249 | /** 250 | * Create a refund request. 251 | * 252 | * @param array $parameters 253 | * @return \Omnipay\Payflow\Message\RefundRequest 254 | */ 255 | public function refund(array $parameters = array()) 256 | { 257 | return $this->createRequest('\Omnipay\Payflow\Message\RefundRequest', $parameters); 258 | } 259 | 260 | /** 261 | * Create a void request. 262 | * 263 | * @param array $parameters 264 | * @return \Omnipay\Payflow\Message\VoidRequest 265 | */ 266 | public function void(array $parameters = array()) 267 | { 268 | return $this->createRequest('\Omnipay\Payflow\Message\VoidRequest', $parameters); 269 | } 270 | 271 | /** 272 | * Create a create card request. 273 | * 274 | * @param array $parameters 275 | * @return \Omnipay\Payflow\Message\CreateCardRequest 276 | */ 277 | public function createCard(array $parameters = array()) 278 | { 279 | return $this->createRequest('\Omnipay\Payflow\Message\CreateCardRequest', $parameters); 280 | } 281 | 282 | /** 283 | * Create an inquiry request. 284 | * 285 | * @deprecated use fetchTransaction instead 286 | */ 287 | public function inquiry(array $parameters = array()) 288 | { 289 | return $this->createRequest('\Omnipay\Payflow\Message\InquiryRequest', $parameters); 290 | } 291 | 292 | /** 293 | * Create a fetch transaction request. 294 | * 295 | * @param array $parameters 296 | * @return \Omnipay\Payflow\Message\FetchTransactionRequest 297 | */ 298 | public function fetchTransaction(array $parameters = array()) 299 | { 300 | return $this->createRequest('\Omnipay\Payflow\Message\FetchTransactionRequest', $parameters); 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /tests/Message/AuthorizeRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new AuthorizeRequest($this->getHttpClient(), $this->getHttpRequest()); 12 | $this->request->initialize( 13 | array( 14 | 'amount' => '12.00', 15 | 'card' => $this->getValidCard(), 16 | ) 17 | ); 18 | } 19 | 20 | public function testComment1() 21 | { 22 | // comment1 is alias for description 23 | $this->assertSame($this->request, $this->request->setComment1('foo')); 24 | $this->assertSame('foo', $this->request->getComment1()); 25 | $this->assertSame('foo', $this->request->getDescription()); 26 | } 27 | 28 | public function testComment2() 29 | { 30 | $this->assertSame($this->request, $this->request->setComment2('bar')); 31 | $this->assertSame('bar', $this->request->getComment2()); 32 | } 33 | 34 | public function testPoNum() 35 | { 36 | $this->assertSame($this->request, $this->request->setPoNum('abcdefghijklmnopqrstuvwxy')); 37 | $this->assertSame('abcdefghijklmnopqrstuvwxy', $this->request->getPoNum()); 38 | } 39 | 40 | public function testGetData() 41 | { 42 | $card = $this->getValidCard(); 43 | $this->request->initialize( 44 | array( 45 | 'amount' => '12.00', 46 | 'description' => 'things', 47 | 'comment2' => 'more things', 48 | 'card' => $card, 49 | 'orderid' => '123', 50 | 'ponum' => 'abcdefghijklmnopqrstuvwxy', 51 | ) 52 | ); 53 | 54 | $data = $this->request->getData(); 55 | 56 | $this->assertSame('C', $data['TENDER']); 57 | $this->assertSame('12.00', $data['AMT']); 58 | $this->assertSame('things', $data['COMMENT1']); 59 | $this->assertSame('more things', $data['COMMENT2']); 60 | $this->assertSame('123', $data['ORDERID']); 61 | $this->assertSame('abcdefghijklmnopqrstuvwxy', $data['PONUM']); 62 | } 63 | 64 | public function testEncodeData() 65 | { 66 | $data = array( 67 | 'foo' => 'bar', 68 | 'key' => 'value &= reference', 69 | ); 70 | 71 | $expected = 'foo[3]=bar&key[18]=value &= reference'; 72 | $this->assertSame($expected, $this->request->encodeData($data)); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /tests/Message/CaptureRequestTest.php: -------------------------------------------------------------------------------- 1 | request = new CaptureRequest($this->getHttpClient(), $this->getHttpRequest()); 10 | $this->request->initialize( 11 | array( 12 | 'amount' => '10.00', 13 | 'transactionReference' => 'ABC123', 14 | ) 15 | ); 16 | } 17 | 18 | public function testComment1() 19 | { 20 | // comment1 is alias for description 21 | $this->assertSame($this->request, $this->request->setComment1('foo')); 22 | $this->assertSame('foo', $this->request->getComment1()); 23 | $this->assertSame('foo', $this->request->getDescription()); 24 | } 25 | 26 | public function testComment2() 27 | { 28 | $this->assertSame($this->request, $this->request->setComment2('bar')); 29 | $this->assertSame('bar', $this->request->getComment2()); 30 | } 31 | 32 | public function testGetData() 33 | { 34 | $this->request->initialize( 35 | array( 36 | 'amount' => '12.00', 37 | 'description' => 'things', 38 | 'comment2' => 'more things', 39 | 'transactionReference' => 'ABC123', 40 | ) 41 | ); 42 | 43 | $data = $this->request->getData(); 44 | 45 | $this->assertSame('D', $data['TRXTYPE']); 46 | $this->assertSame('12.00', $data['AMT']); 47 | $this->assertSame('ABC123', $data['ORIGID']); 48 | $this->assertSame('things', $data['COMMENT1']); 49 | $this->assertSame('more things', $data['COMMENT2']); 50 | } 51 | 52 | public function testDoesntSendEmptyComments() 53 | { 54 | $this->request->initialize( 55 | array( 56 | 'amount' => '12.00', 57 | 'transactionReference' => 'ABC123', 58 | ) 59 | ); 60 | 61 | $data = $this->request->getData(); 62 | $this->assertArrayNotHasKey('COMMENT1', $data); 63 | $this->assertArrayNotHasKey('COMMENT2', $data); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/Message/ResponseTest.php: -------------------------------------------------------------------------------- 1 | getMockRequest(), ''); 16 | } 17 | 18 | public function testDecodeData() 19 | { 20 | $response = new Response($this->getMockRequest(), 'x=y'); 21 | $data = 'BILLTOFIRSTNAME=Adrian&BILLTOLASTNAME[6]=&= Foo&TEST=Hi'; 22 | 23 | $expected = array( 24 | 'BILLTOFIRSTNAME' => 'Adrian', 25 | 'BILLTOLASTNAME' => '&= Foo', 26 | 'TEST' => 'Hi', 27 | ); 28 | 29 | $this->assertSame($expected, $response->decodeData($data)); 30 | } 31 | 32 | public function testDecodeDataSimple() 33 | { 34 | $response = new Response($this->getMockRequest(), 'x=y'); 35 | $data = 'foo=bar'; 36 | $expected = array('foo' => 'bar'); 37 | $this->assertSame($expected, $response->decodeData($data)); 38 | } 39 | 40 | public function testDecodeDataEmpty() 41 | { 42 | $response = new Response($this->getMockRequest(), 'x=y'); 43 | $data = ''; 44 | $expected = array(); 45 | $this->assertSame($expected, $response->decodeData($data)); 46 | } 47 | 48 | public function testPurchaseSuccess() 49 | { 50 | $httpResponse = $this->getMockHttpResponse('PurchaseSuccess.txt'); 51 | $response = new Response($this->getMockRequest(), $httpResponse->getBody()); 52 | 53 | $this->assertTrue($response->isSuccessful()); 54 | $this->assertFalse($response->isRedirect()); 55 | $this->assertEquals('A10A6AE7042E', $response->getTransactionReference()); 56 | $this->assertEquals('Approved', $response->getMessage()); 57 | $this->assertEquals(0, $response->getCode()); 58 | } 59 | 60 | public function testPurchaseFailure() 61 | { 62 | $httpResponse = $this->getMockHttpResponse('PurchaseFailure.txt'); 63 | $response = new Response($this->getMockRequest(), $httpResponse->getBody()); 64 | 65 | $this->assertFalse($response->isSuccessful()); 66 | $this->assertFalse($response->isRedirect()); 67 | $this->assertNull($response->getTransactionReference()); 68 | $this->assertSame('User authentication failed', $response->getMessage()); 69 | $this->assertEquals(1, $response->getCode()); 70 | } 71 | 72 | public function testPurchaseDecline() 73 | { 74 | $httpResponse = $this->getMockHttpResponse('PurchaseDecline.txt'); 75 | $response = new Response($this->getMockRequest(), $httpResponse->getBody()); 76 | 77 | $this->assertFalse($response->isSuccessful()); 78 | $this->assertFalse($response->isRedirect()); 79 | $this->assertEquals('A10AA63244D1', $response->getTransactionReference()); 80 | $this->assertEquals('Declined', $response->getMessage()); 81 | $this->assertEquals(12, $response->getCode()); 82 | } 83 | 84 | public function testCreateCard() 85 | { 86 | $httpResponse = $this->getMockHttpResponse('CreateCardSuccess.txt'); 87 | 88 | /* @var \Omnipay\Payflow\Message\CreateCardRequest $request */ 89 | $request = m::mock('\Omnipay\Payflow\Message\CreateCardRequest'); 90 | 91 | $response = new Response($request, $httpResponse->getBody()); 92 | 93 | $this->assertTrue($response->isSuccessful()); 94 | $this->assertFalse($response->isRedirect()); 95 | $this->assertEquals('A10AA633AB30', $response->getCardReference()); 96 | $this->assertEquals('Approved', $response->getMessage()); 97 | $this->assertEquals(0, $response->getCode()); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /tests/Mock/CreateCardSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Connection: close 3 | Server: VPS-3.033.00 4 | Date: Tue, 17 Aug 2017 02:34:58 GMT 5 | Content-type: text/namevalue 6 | Content-length: 44 7 | 8 | RESULT=0&PNREF=A10AA633AB30&RESPMSG=Approved -------------------------------------------------------------------------------- /tests/Mock/PurchaseDecline.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Connection: close 3 | Server: VPS-3.033.00 4 | Date: Sat, 23 Feb 2013 05:17:32 GMT 5 | Content-type: text/namevalue 6 | Content-length: 45 7 | 8 | RESULT=12&PNREF=A10AA63244D1&RESPMSG=Declined -------------------------------------------------------------------------------- /tests/Mock/PurchaseFailure.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Connection: close 3 | Server: VPS-3.033.00 4 | Date: Sat, 23 Feb 2013 05:17:32 GMT 5 | Content-type: text/namevalue 6 | Content-length: 43 7 | 8 | RESULT=1&RESPMSG=User authentication failed -------------------------------------------------------------------------------- /tests/Mock/PurchaseSuccess.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Connection: close 3 | Server: VPS-3.033.00 4 | Date: Tue, 11 Feb 2014 02:34:58 GMT 5 | Content-type: text/namevalue 6 | Content-length: 269 7 | 8 | RESULT=0&PNREF=A10A6AE7042E&RESPMSG=Approved&AUTHCODE=331PNI&AVSADDR=X&AVSZIP=X&CVV2MATCH=Y&HOSTCODE=A&PROCAVS=U&PROCCVV2=M&VISACARDLEVEL=12&TRANSTIME=2014-02-10 18:34:58&BILLTOFIRSTNAME=Adrian&BILLTOLASTNAME[5]=& Foo&AMT=362.45&ACCT=1111&EXPDATE=0316&CARDTYPE=0&IAVS=X 9 | -------------------------------------------------------------------------------- /tests/ProGatewayTest.php: -------------------------------------------------------------------------------- 1 | gateway = new ProGateway($this->getHttpClient(), $this->getHttpRequest()); 15 | 16 | $this->options = array( 17 | 'amount' => '10.00', 18 | 'card' => new CreditCard(array( 19 | 'firstName' => 'Example', 20 | 'lastName' => 'User', 21 | 'number' => '4111111111111111', 22 | 'expiryMonth' => '12', 23 | 'expiryYear' => '2020', 24 | 'cvv' => '123', 25 | )), 26 | ); 27 | } 28 | 29 | public function testAuthorizeSuccess() 30 | { 31 | $this->setMockHttpResponse('PurchaseSuccess.txt'); 32 | 33 | $response = $this->gateway->authorize($this->options)->send(); 34 | 35 | $this->assertTrue($response->isSuccessful()); 36 | $this->assertEquals('A10A6AE7042E', $response->getTransactionReference()); 37 | } 38 | 39 | public function testAuthorizeError() 40 | { 41 | $this->setMockHttpResponse('PurchaseFailure.txt'); 42 | 43 | $response = $this->gateway->authorize($this->options)->send(); 44 | 45 | $this->assertFalse($response->isSuccessful()); 46 | $this->assertSame('User authentication failed', $response->getMessage()); 47 | } 48 | 49 | public function testCapture() 50 | { 51 | $options = array( 52 | 'amount' => '10.00', 53 | 'transactionReference' => 'abc123', 54 | ); 55 | 56 | $this->setMockHttpResponse('PurchaseSuccess.txt'); 57 | 58 | $response = $this->gateway->capture($options)->send(); 59 | 60 | $this->assertTrue($response->isSuccessful()); 61 | $this->assertEquals('A10A6AE7042E', $response->getTransactionReference()); 62 | } 63 | 64 | public function testPurchaseSuccess() 65 | { 66 | $this->setMockHttpResponse('PurchaseSuccess.txt'); 67 | 68 | $response = $this->gateway->purchase($this->options)->send(); 69 | 70 | $this->assertTrue($response->isSuccessful()); 71 | $this->assertEquals('A10A6AE7042E', $response->getTransactionReference()); 72 | } 73 | 74 | public function testReferencePurchaseSuccess() 75 | { 76 | $options = array( 77 | 'amount' => '10.00', 78 | 'cardReference' => 'abc123', 79 | ); 80 | 81 | $this->setMockHttpResponse('PurchaseSuccess.txt'); 82 | 83 | $response = $this->gateway->purchase($options)->send(); 84 | 85 | $this->assertTrue($response->isSuccessful()); 86 | $this->assertEquals('A10A6AE7042E', $response->getTransactionReference()); 87 | } 88 | 89 | public function testReferencePurchaseWithCvvSuccess() 90 | { 91 | $options = array( 92 | 'amount' => '10.00', 93 | 'cardReference' => 'abc123', 94 | 'card' => new CreditCard(array( 95 | 'cvv' => '123', 96 | )), 97 | ); 98 | 99 | $this->setMockHttpResponse('PurchaseSuccess.txt'); 100 | 101 | $request = $this->gateway->purchase($options); 102 | $response = $request->send(); 103 | 104 | $this->assertArrayHasKey('CVV2', $request->getData()); 105 | $this->assertTrue($response->isSuccessful()); 106 | $this->assertEquals('A10A6AE7042E', $response->getTransactionReference()); 107 | } 108 | 109 | public function testPurchaseError() 110 | { 111 | $this->setMockHttpResponse('PurchaseFailure.txt'); 112 | 113 | $response = $this->gateway->purchase($this->options)->send(); 114 | 115 | $this->assertFalse($response->isSuccessful()); 116 | $this->assertSame('User authentication failed', $response->getMessage()); 117 | } 118 | 119 | public function testRefund() 120 | { 121 | $options = array( 122 | 'amount' => '10.00', 123 | 'transactionReference' => 'abc123', 124 | ); 125 | 126 | $this->setMockHttpResponse('PurchaseSuccess.txt'); 127 | 128 | $response = $this->gateway->refund($options)->send(); 129 | 130 | $this->assertTrue($response->isSuccessful()); 131 | $this->assertEquals('A10A6AE7042E', $response->getTransactionReference()); 132 | } 133 | 134 | public function testVoid() 135 | { 136 | $options = array( 137 | 'transactionReference' => 'abc123', 138 | ); 139 | 140 | $this->setMockHttpResponse('PurchaseSuccess.txt'); 141 | 142 | $response = $this->gateway->void($options)->send(); 143 | 144 | $this->assertTrue($response->isSuccessful()); 145 | $this->assertEquals('A10A6AE7042E', $response->getTransactionReference()); 146 | } 147 | } 148 | --------------------------------------------------------------------------------