Skip to content

Commit

Permalink
Merge pull request #35 from rondogency/paypal-fix
Browse files Browse the repository at this point in the history
Fix PayPal email field from Vindicia response typo
  • Loading branch information
Ziyi Mu authored Jun 18, 2018
2 parents 72b1b50 + 8fd9e70 commit e651272
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 3 deletions.
16 changes: 13 additions & 3 deletions src/ObjectHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ public function buildTransaction(stdClass $object)
}
}

// Vindicia made a small typo in the response field of PayPal email used in PayPal checkout
// they return 'paypalEmail' instead of camel case 'payPalEmail' in fetch transaction response
// Also there is a discrepancy between Vindicia document and actual response regarding 'paypalEmail'field
// PayPal email field is documented under Payment Method object, but it's under Transaction Statuslog actually
// we should deal with "payPalEmail" and "paypalEmail" in case they fix the camel case typo on their side
$paypalEmail = null;
if (isset($object->statusLog[0]->payPalStatus->payPalEmail)) {
$paypalEmail = $object->statusLog[0]->payPalStatus->payPalEmail;
} elseif (isset($object->statusLog[0]->payPalStatus->paypalEmail)) {
$paypalEmail = $object->statusLog[0]->payPalStatus->paypalEmail;
}

return new Transaction(array(
'transactionId' => isset($object->merchantTransactionId) ? $object->merchantTransactionId : null,
'transactionReference' => isset($object->VID) ? $object->VID : null,
Expand All @@ -74,9 +86,7 @@ public function buildTransaction(stdClass $object)
: null,
'status' => isset($object->statusLog[0]->status) ? $object->statusLog[0]->status : null,
'statusLog' => $statusLog,
'payPalEmail' => isset($object->statusLog[0]->payPalStatus->payPalEmail)
? $object->statusLog[0]->payPalStatus->payPalEmail
: null,
'payPalEmail' => $paypalEmail,
'payPalRedirectUrl' => isset($object->statusLog[0]->payPalStatus->redirectUrl)
? $object->statusLog[0]->payPalStatus->redirectUrl
: null,
Expand Down
85 changes: 85 additions & 0 deletions tests/Message/FetchTransactionRequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public function setUp()
$this->authorizationCode = $this->faker->statusCode();
$this->cvvCode = $this->faker->statusCode();
$this->avsCode = $this->faker->statusCode();
$this->token = $this->faker->payPalToken();
$this->paypalEmail = $this->faker->email();
}

/**
Expand Down Expand Up @@ -253,4 +255,87 @@ public function testSendByReferenceFailure()

$this->assertNull($response->getTransaction());
}

/**
* @return void
*/
public function testSendPayPalSuccess()
{
$this->setMockSoapResponse('FetchPayPalTransactionSuccess.xml', array(
'TRANSACTION_ID' => $this->transactionId,
'TRANSACTION_REFERENCE' => $this->transactionReference,
'CURRENCY' => $this->currency,
'AMOUNT' => $this->amount,
'TAX_AMOUNT' => $this->tax_amount,
'CUSTOMER_ID' => $this->customerId,
'CUSTOMER_REFERENCE' => $this->customerReference,
'PAYMENT_METHOD_ID' => $this->paymentMethodId,
'PAYMENT_METHOD_REFERENCE' => $this->paymentMethodReference,
'IP_ADDRESS' => $this->ipAddress,
'TAX_CLASSIFICATION' => $this->taxClassification,
'SKU' => $this->sku,
'TOKEN' => $this->token,
'PAYPAL_EMAIL' => $this->paypalEmail
));

$response = $this->request->send();

$this->assertTrue($response->isSuccessful());
$this->assertFalse($response->isRedirect());
$this->assertFalse($response->isPending());
$this->assertSame('OK', $response->getMessage());

$transaction = $response->getTransaction();
$this->assertInstanceOf('\Omnipay\Vindicia\Transaction', $transaction);
$this->assertSame($this->transactionId, $response->getTransactionId());
$this->assertSame($this->transactionReference, $response->getTransactionReference());
$this->assertSame($this->transactionId, $transaction->getId());
$this->assertSame($this->transactionReference, $transaction->getReference());
$this->assertSame($this->currency, $transaction->getCurrency());
$this->assertSame($this->amount, $transaction->getAmount());
$customer = $transaction->getCustomer();
$this->assertSame($this->customerId, $transaction->getCustomerId());
$this->assertSame($this->customerId, $customer->getId());
$this->assertSame($this->customerReference, $transaction->getCustomerReference());
$this->assertSame($this->customerReference, $customer->getReference());
$paymentMethod = $transaction->getPaymentMethod();
$this->assertSame($this->paymentMethodId, $transaction->getPaymentMethodId());
$this->assertSame($this->paymentMethodId, $paymentMethod->getId());
$this->assertSame($this->paymentMethodReference, $transaction->getPaymentMethodReference());
$this->assertSame($this->paymentMethodReference, $paymentMethod->getReference());
$items = $transaction->getItems();
$this->assertSame(2, count($items));
foreach ($items as $i => $item) {
$this->assertInstanceOf('\Omnipay\Vindicia\VindiciaItem', $item);
$item->validate();
if ($i === 0) {
$this->assertSame($this->taxClassification, $item->getTaxClassification());
$this->assertSame($this->amount, $item->getPrice());
$this->assertSame($this->sku, $item->getSku());
} else if ($i === 1) {
$this->assertSame('Total Tax', $item->getSku());
$this->assertSame($this->tax_amount, $item->getPrice());
}
}
$this->assertSame($this->amount, $items[0]->getPrice());
$this->assertSame($this->ipAddress, $transaction->getIp());
$this->assertEquals($this->paypalEmail, $transaction->getPayPalEmail());
$this->assertSame('Authorized', $transaction->getStatus());
$statusLog = $transaction->getStatusLog();
$this->assertSame(2, count($statusLog));
foreach ($statusLog as $logEntry) {
$this->assertInstanceOf('\Omnipay\Vindicia\TransactionStatus', $logEntry);
}
$this->assertSame('Authorized', $statusLog[0]->getStatus());
$this->assertSame('New', $statusLog[1]->getStatus());
$attributes = $transaction->getAttributes();
$this->assertSame(2, count($attributes));
foreach ($attributes as $attribute) {
$this->assertInstanceOf('\Omnipay\Vindicia\Attribute', $attribute);
$this->assertTrue(is_string($attribute->getName()));
$this->assertTrue(is_string($attribute->getValue()));
}

$this->assertSame('https://soap.prodtest.sj.vindicia.com/18.0/Transaction.wsdl', $this->getLastEndpoint());
}
}
116 changes: 116 additions & 0 deletions tests/Mock/FetchPayPalTransactionSuccess.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:vin="http://soap.vindicia.com/v18_0/Vindicia"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<fetchByMerchantTransactionIdResponse xmlns="http://soap.vindicia.com/v18_0/Transaction">
<return xmlns="" xsi:type="vin:Return">
<returnCode xsi:type="vin:ReturnCode">200</returnCode>
<soapId xsi:type="xsd:string">1234567890abcdef1234567890abcdef</soapId>
<returnString xsi:type="xsd:string">OK</returnString>
</return>
<transaction xmlns="" xsi:type="vin:Transaction">
<VID xmlns="" xsi:type="xsd:string">[TRANSACTION_REFERENCE]</VID>
<amount xmlns="" xsi:type="xsd:decimal">[AMOUNT]</amount>
<currency xmlns="" xsi:type="xsd:string">[CURRENCY]</currency>
<divisionNumber xmlns="" xsi:type="xsd:string">12345</divisionNumber>
<merchantTransactionId xmlns="" xsi:type="xsd:string">[TRANSACTION_ID]</merchantTransactionId>
<timestamp xmlns="" xsi:type="xsd:dateTime">2016-10-04T08:06:04-07:00</timestamp>
<account xmlns="" xsi:type="vin:Account">
<VID xmlns="" xsi:type="xsd:string">[CUSTOMER_REFERENCE]</VID>
<merchantAccountId xmlns="" xsi:type="xsd:string">[CUSTOMER_ID]</merchantAccountId>
<emailAddress xmlns="" xsi:type="xsd:string">test@example.com</emailAddress>
<emailTypePreference xmlns="" xsi:type="vin:EmailPreference">html</emailTypePreference>
<name xmlns="" xsi:type="xsd:string">Test Customer</name>
</account>
<sourcePaymentMethod xmlns="" xsi:type="vin:PaymentMethod">
<VID xmlns="" xsi:type="xsd:string">[PAYMENT_METHOD_REFERENCE]</VID>
<type xmlns="" xsi:type="vin:PaymentMethodType">PayPal</type>
<payPal xmlns="" xsi:type="vin:PayPal">
<returnUrl xmlns="" xsi:type="xsd:string">https://vimeo.dev/haggle/pro/vindiciapaypalomnipay/finalize</returnUrl>
<cancelUrl xmlns="" xsi:type="xsd:string">https://vimeo.dev/haggle/pro/vindiciapaypalomnipay/finalize</cancelUrl>
<requestReferenceId xmlns="" xsi:type="xsd:int">1</requestReferenceId>
<referenceId xmlns="" xsi:type="xsd:string">B-27J89747YL063522A</referenceId>
</payPal>
<billingAddress xmlns="" xsi:type="vin:Address">
<VID xmlns="" xsi:type="xsd:string">99988877766655544433322211100000</VID>
<postalCode xmlns="" xsi:type="xsd:string">[POSTCODE]</postalCode>
<country xmlns="" xsi:type="xsd:string">[COUNTRY]</country>
</billingAddress>
<merchantPaymentMethodId xmlns="" xsi:type="xsd:string">[PAYMENT_METHOD_ID]</merchantPaymentMethodId>
<sortOrder xmlns="" xsi:type="xsd:int">1</sortOrder>
<active xmlns="" xsi:type="xsd:boolean">1</active>
</sourcePaymentMethod>
<statusLog xmlns="" xsi:type="vin:TransactionStatus">
<status xmlns="" xsi:type="vin:TransactionStatusType">Authorized</status>
<timestamp xmlns="" xsi:type="xsd:dateTime">2018-06-15T08:06:05-07:00</timestamp>
<paymentMethodType xmlns="" xsi:type="vin:PaymentMethodType">PayPal</paymentMethodType>
<payPalStatus xmlns="" xsi:type="vin:TransactionStatusPayPal">
<token xmlns="" xsi:type="xsd:string">[TOKEN]</token>
<paypalEmail xmlns="" xsi:type="xsd:string">[PAYPAL_EMAIL]</paypalEmail>
<payerId xmlns="" xsi:type="xsd:string">ABCDEFG123456</payerId>
<authCode xmlns="" xsi:type="xsd:string">000</authCode>
<redirectUrl xmlns="" xsi:type="xsd:string">https://www.sandbox.paypal.com</redirectUrl>
</payPalStatus>
</statusLog>
<statusLog xmlns="" xsi:type="vin:TransactionStatus">
<status xmlns="" xsi:type="vin:TransactionStatusType">New</status>
<timestamp xmlns="" xsi:type="xsd:dateTime">2018-06-15T08:06:04-07:00</timestamp>
<paymentMethodType xmlns="" xsi:type="vin:PaymentMethodType">PayPal</paymentMethodType>
<payPalStatus xmlns="" xsi:type="vin:TransactionStatusPayPal">
<token xmlns="" xsi:type="xsd:string">[TOKEN]</token>
<paypalEmail xmlns="" xsi:type="xsd:string">[PAYPAL_EMAIL]</paypalEmail>
<payerId xmlns="" xsi:type="xsd:string">ABCDEFG123456</payerId>
<authCode xmlns="" xsi:type="xsd:string">000</authCode>
<redirectUrl xmlns="" xsi:type="xsd:string">https://www.sandbox.paypal.com</redirectUrl>
</payPalStatus>
</statusLog>
<paymentProcessor xmlns="" xsi:type="xsd:string">ProcessorName</paymentProcessor>
<paymentProcessorTransactionId xmlns="" xsi:type="xsd:string">123XYZ</paymentProcessorTransactionId>
<transactionItems xmlns="" xsi:type="vin:TransactionItem">
<sku xmlns="" xsi:type="xsd:string">[SKU]</sku>
<indexNumber xmlns="" xsi:type="xsd:int">1</indexNumber>
<itemType xmlns="" xsi:type="vin:TransactionItemType">Purchase</itemType>
<name xmlns="" xsi:type="xsd:string">Generic item</name>
<price xmlns="" xsi:type="xsd:decimal">[AMOUNT]</price>
<quantity xmlns="" xsi:type="xsd:decimal">1</quantity>
<taxClassification xmlns="" xsi:type="xsd:string">[TAX_CLASSIFICATION]</taxClassification>
<taxType xmlns="" xsi:type="xsd:string">Exclusive Sales</taxType>
<subtotal xmlns="" xsi:type="xsd:decimal">[AMOUNT]</subtotal>
<total xmlns="" xsi:type="xsd:decimal">[AMOUNT]</total>
</transactionItems>
<transactionItems xmlns="" xsi:type="vin:TransactionItem">
<sku xmlns="" xsi:type="xsd:string">Total Tax</sku>
<indexNumber xmlns="" xsi:type="xsd:int">2</indexNumber>
<itemType xmlns="" xsi:type="vin:TransactionItemType">Purchase</itemType>
<name xmlns="" xsi:type="xsd:string">Total Tax</name>
<price xmlns="" xsi:type="xsd:decimal">0</price>
<quantity xmlns="" xsi:type="xsd:decimal">1</quantity>
<taxClassification xmlns="" xsi:type="xsd:string">TaxExempt</taxClassification>
<taxType xmlns="" xsi:type="xsd:string">Exclusive Sales</taxType>
<tax xmlns="" xsi:type="vin:TaxItem">
<jurisdiction xmlns="" xsi:type="xsd:string">COUNTRY</jurisdiction>
<name xmlns="" xsi:type="xsd:string">XY COUNTRY SALES TAX</name>
<amount xmlns="" xsi:type="xsd:decimal">[TAX_AMOUNT]</amount>
</tax>
<discount xmlns="" xsi:type="xsd:decimal">0</discount>
<subtotal xmlns="" xsi:type="xsd:decimal">0</subtotal>
<total xmlns="" xsi:type="xsd:decimal">[TAX_AMOUNT]</total>
</transactionItems>
<sourceIp xmlns="" xsi:type="xsd:string">[IP_ADDRESS]</sourceIp>
<nameValues xmlns="" xsi:type="vin:NameValuePair">
<name xmlns="" xsi:type="xsd:string">[ATTRIBUTE_1_NAME]</name>
<value xmlns="" xsi:type="xsd:string">[ATTRIBUTE_1_VALUE]</value>
</nameValues>
<nameValues xmlns="" xsi:type="vin:NameValuePair">
<name xmlns="" xsi:type="xsd:string">[ATTRIBUTE_2_NAME]</name>
<value xmlns="" xsi:type="xsd:string">[ATTRIBUTE_2_VALUE]</value>
</nameValues>
</transaction>
</fetchByMerchantTransactionIdResponse>
</soap:Body>
</soap:Envelope>

0 comments on commit e651272

Please sign in to comment.