From 7afec74738646753906534a908afc8e4f7a39596 Mon Sep 17 00:00:00 2001 From: Rob van Hoose Date: Fri, 13 Oct 2017 11:24:46 -0400 Subject: [PATCH] Implement reference purchases - This is a key feature of the payflow api, - Is required for tokenization and multi-part shipping - Is described in https://developer.paypal.com/docs/classic/payflow/integration-guide/#submitting-reference-transactions---tokenization --- src/Message/PurchaseRequest.php | 41 +++++++++++++++++++++++++++++++++ tests/ProGatewayTest.php | 15 ++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/Message/PurchaseRequest.php b/src/Message/PurchaseRequest.php index 8723bae..3283048 100644 --- a/src/Message/PurchaseRequest.php +++ b/src/Message/PurchaseRequest.php @@ -21,6 +21,26 @@ * 'testMode' => true, // Or false for live transactions. * )); * + * // Next, there are two ways to conduct a sale with Payflow: + * // 1. a reference sale in which an authorization transaction reference is passed + * // 2. a sale in which card data is directly passed + * // + * // #1 should be used any time multiple charges must be committed against an authorization + * // either because parts of an order shipped at different times or because authorization is + * // being used to "tokenize" a card and store it on the gateway (a Paypal prescribed process). + * // Capture can only be called once against an authorization but sale does not have this limitation. + * + * // @see developer.paypal.com/docs/classic/payflow/integration-guide/#submitting-reference-transactions---tokenization + * + * // 1. Reference (tokenized card) Sale example: + * // $reference_id can be the transaction reference from a previous authorization, credit, capture, sale, voice auth, + * // or void. + * $transaction = $gateway->purchase(array( + * 'amount' => '10.00', + * 'transactionReference' => $reference_id, + * )); + * + * // 2. Sale (with card data) example: * // Create a credit card object * // This card can be used for testing. * $card = new CreditCard(array( @@ -49,4 +69,25 @@ class PurchaseRequest extends AuthorizeRequest { protected $action = 'S'; + + public function getData() + { + if ($this->parameters->get('transactionReference')) { + return $this->getReferenceSaleData(); + } + + return parent::getData(); + } + + public function getReferenceSaleData() + { + $this->validate('transactionReference', 'amount'); + + $data = $this->getBaseData(); + $data['AMT'] = $this->getAmount(); + $data['ORIGID'] = $this->getTransactionReference(); + $data['TENDER'] = 'C'; + + return $data; + } } diff --git a/tests/ProGatewayTest.php b/tests/ProGatewayTest.php index 83ba547..06b43d6 100644 --- a/tests/ProGatewayTest.php +++ b/tests/ProGatewayTest.php @@ -71,6 +71,21 @@ public function testPurchaseSuccess() $this->assertEquals('A10A6AE7042E', $response->getTransactionReference()); } + public function testReferencePurchaseSuccess() + { + $options = array( + 'amount' => '10.00', + 'transactionReference' => 'abc123', + ); + + $this->setMockHttpResponse('PurchaseSuccess.txt'); + + $response = $this->gateway->purchase($options)->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertEquals('A10A6AE7042E', $response->getTransactionReference()); + } + public function testPurchaseError() { $this->setMockHttpResponse('PurchaseFailure.txt');