diff --git a/src/Message/AbstractRequest.php b/src/Message/AbstractRequest.php index e33c7c03..0b0e3038 100644 --- a/src/Message/AbstractRequest.php +++ b/src/Message/AbstractRequest.php @@ -357,17 +357,30 @@ protected function getCardData() $data = array(); $data['object'] = 'card'; + + // If track data is present, only return data relevant to a card present charge + $tracks = $card->getTracks(); + $cvv = $card->getCvv(); + $postcode = $card->getPostcode(); + if (!empty($postcode)) { + $data['address_zip'] = $postcode; + } + if (!empty($cvv)) { + $data['cvc'] = $cvv; + } + if (!empty($tracks)) { + $data['swipe_data'] = $tracks; + return $data; + } + + // If we got here, it's a card not present transaction, so include everything we have $data['number'] = $card->getNumber(); $data['exp_month'] = $card->getExpiryMonth(); $data['exp_year'] = $card->getExpiryYear(); - if ($card->getCvv()) { - $data['cvc'] = $card->getCvv(); - } $data['name'] = $card->getName(); $data['address_line1'] = $card->getAddress1(); $data['address_line2'] = $card->getAddress2(); $data['address_city'] = $card->getCity(); - $data['address_zip'] = $card->getPostcode(); $data['address_state'] = $card->getState(); $data['address_country'] = $card->getCountry(); $data['email'] = $card->getEmail(); diff --git a/tests/Message/AuthorizeRequestTest.php b/tests/Message/AuthorizeRequestTest.php index 9999d244..f1fdf639 100644 --- a/tests/Message/AuthorizeRequestTest.php +++ b/tests/Message/AuthorizeRequestTest.php @@ -2,6 +2,7 @@ namespace Omnipay\Stripe\Message; +use Omnipay\Common\CreditCard; use Omnipay\Common\ItemBag; use Omnipay\Tests\TestCase; @@ -107,6 +108,48 @@ public function testDataWithCard() $this->assertSame($card['number'], $data['source']['number']); } + public function testDataWithTracks() + { + $cardData = $this->getValidCard(); + $tracks = "%25B4242424242424242%5ETESTLAST%2FTESTFIRST%5E1505201425400714000000%3F"; + $cardData['tracks'] = $tracks; + unset($cardData['cvv']); + unset($cardData['billingPostcode']); + $this->request->setCard(new CreditCard($cardData)); + $data = $this->request->getData(); + + $this->assertSame($tracks, $data['source']['swipe_data']); + $this->assertCount(2, $data['source'], "Swipe data should be present. All other fields are not required"); + + // If there is any mismatch between the track data and the parsed data, Stripe rejects the transaction, so it's + // best to suppress fields that is already present in the track data. + $this->assertArrayNotHasKey('number', $data, 'Should not send card number for card present charge'); + $this->assertArrayNotHasKey('exp_month', $data, 'Should not send expiry month for card present charge'); + $this->assertArrayNotHasKey('exp_year', $data, 'Should not send expiry year for card present charge'); + $this->assertArrayNotHasKey('name', $data, 'Should not send name for card present charge'); + + // Billing address is not accepted for card present transactions. + $this->assertArrayNotHasKey('address_line1', $data, 'Should not send billing address for card present charge'); + $this->assertArrayNotHasKey('address_line2', $data, 'Should not send billing address for card present charge'); + $this->assertArrayNotHasKey('address_city', $data, 'Should not send billing address for card present charge'); + $this->assertArrayNotHasKey('address_state', $data, 'Should not send billing address for card present charge'); + + } + + public function testDataWithTracksAndZipCVVManuallyEntered() + { + $cardData = $this->getValidCard(); + $tracks = "%25B4242424242424242%5ETESTLAST%2FTESTFIRST%5E1505201425400714000000%3F"; + $cardData['tracks'] = $tracks; + $this->request->setCard(new CreditCard($cardData)); + $data = $this->request->getData(); + + $this->assertSame($tracks, $data['source']['swipe_data']); + $this->assertSame($cardData['cvv'], $data['source']['cvc']); + $this->assertSame($cardData['billingPostcode'], $data['source']['address_zip']); + $this->assertCount(4, $data['source'], "Swipe data, cvv and zip code should be present"); + } + public function testSendSuccess() { $this->setMockHttpResponse('PurchaseSuccess.txt');