diff --git a/composer.json b/composer.json index 0dd8b4c3..d10e9352 100644 --- a/composer.json +++ b/composer.json @@ -1,4 +1,4 @@ -{ + { "name": "omnipay/authorizenet", "type": "library", "description": "Authorize.Net gateway for the Omnipay payment processing library", diff --git a/src/AIMGateway.php b/src/AIMGateway.php index 52b2508c..82cbb344 100644 --- a/src/AIMGateway.php +++ b/src/AIMGateway.php @@ -5,6 +5,7 @@ use Omnipay\AuthorizeNet\Message\AIMAuthorizeRequest; use Omnipay\AuthorizeNet\Message\AIMCaptureRequest; use Omnipay\AuthorizeNet\Message\AIMPurchaseRequest; +use Omnipay\AuthorizeNet\Message\AIMRefundRequest; use Omnipay\AuthorizeNet\Message\AIMVoidRequest; use Omnipay\Common\AbstractGateway; @@ -102,5 +103,4 @@ public function refund(array $parameters = array()) { return $this->createRequest('\Omnipay\AuthorizeNet\Message\AIMRefundRequest', $parameters); } - } diff --git a/src/CIMGateway.php b/src/CIMGateway.php new file mode 100644 index 00000000..793210ca --- /dev/null +++ b/src/CIMGateway.php @@ -0,0 +1,46 @@ +createRequest('\Omnipay\AuthorizeNet\Message\CIMCreateCardRequest', $parameters); + } + + public function authorize(array $parameters = array()) + { + return $this->createRequest('\Omnipay\AuthorizeNet\Message\CIMAuthorizeRequest', $parameters); + } + + public function capture(array $parameters = array()) + { + return $this->createRequest('\Omnipay\AuthorizeNet\Message\CIMCaptureRequest', $parameters); + } + + public function purchase(array $parameters = array()) + { + return $this->createRequest('\Omnipay\AuthorizeNet\Message\CIMPurchaseRequest', $parameters); + } + + public function refund(array $parameters = array()) + { + return $this->createRequest('\Omnipay\AuthorizeNet\Message\CIMRefundRequest', $parameters); + } +} \ No newline at end of file diff --git a/src/Message/AIMRefundRequest.php b/src/Message/AIMRefundRequest.php index 8ab144b3..becdfd6e 100644 --- a/src/Message/AIMRefundRequest.php +++ b/src/Message/AIMRefundRequest.php @@ -27,4 +27,4 @@ public function getData() return $data; } -} \ No newline at end of file +} diff --git a/src/Message/CIMAbstractRequest.php b/src/Message/CIMAbstractRequest.php new file mode 100644 index 00000000..35fd328f --- /dev/null +++ b/src/Message/CIMAbstractRequest.php @@ -0,0 +1,87 @@ +setParameter('email', $value); + } + + public function getEmail() + { + return $this->getParameter('email'); + } + + public function setName($value) + { + return $this->setParameter('name', $value); + } + + public function getName() + { + return $this->getParameter('name'); + } + + public function setCustomerProfileId($value) + { + return $this->setParameter('customerProfileId', $value); + } + + public function getCustomerProfileId() + { + return $this->getParameter('customerProfileId'); + } + + public function setCustomerPaymentProfileId($value) + { + return $this->setParameter('customerPaymentProfileId', $value); + } + + public function getCustomerPaymentProfileId() + { + return $this->getParameter('customerPaymentProfileId'); + } + + /** + * Flag to force update consumer payment profile if duplicate is found + * + * @param $value + * + * @return $this + */ + public function setForceCardUpdate($value) + { + return $this->setParameter('forceCardUpdate', $value); + } + + public function getForceCardUpdate() + { + return $this->getParameter('forceCardUpdate'); + } + + /** + * @throws InvalidRequestException + * @return mixed|\SimpleXMLElement + */ + public function getBaseData() + { + $data = new \SimpleXMLElement("<" . $this->xmlRootElement . "/>"); + $data->addAttribute('xmlns', 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'); + + // Credentials + $data->merchantAuthentication->name = $this->getApiLoginId(); + $data->merchantAuthentication->transactionKey = $this->getTransactionKey(); + + return $data; + } +} diff --git a/src/Message/CIMAbstractResponse.php b/src/Message/CIMAbstractResponse.php new file mode 100644 index 00000000..7793841a --- /dev/null +++ b/src/Message/CIMAbstractResponse.php @@ -0,0 +1,169 @@ +request = $request; + + // Check if this is an error response + $isError = strpos((string)$data, 'xmlRootElement; + // Strip out the xmlns junk so that PHP can parse the XML + $xml = preg_replace('/<' . $xmlRootElement . '[^>]+>/', '<' . $xmlRootElement . '>', (string)$data); + + try { + $xml = simplexml_load_string($xml); + } catch(\Exception $e) { + throw new InvalidResponseException(); + } + + if (!$xml) { + throw new InvalidResponseException(); + } + + $this->data = $this->xml2array($xml); + } + + public function isSuccessful() + { + return 1 === $this->getResultCode(); + } + + /** + * Overall status of the transaction. This field is also known as "Response Code" in Authorize.NET terminology. + * + * @return int 1 = Approved, 2 = Declined, 3 = Error, 4 = Held for Review + */ + public function getResultCode() + { + $result = (string)$this->data['messages'][0]['resultCode'][0]; + switch ($result) { + case 'Ok': + return 1; + case 'Error': + return 3; + default: + return null; + + } + } + + /** + * A more detailed version of the Result/Response code. + * + * @return int|null + */ + public function getReasonCode() + { + $code = null; + + if (isset($this->data['messages'])) { + // In case of a successful transaction, a "messages" element is present + $code = (string)$this->data['messages'][0]['message'][0]['code'][0]; + + } + + return $code; + } + + /** + * Text description of the status. + * + * @return string|null + */ + public function getMessage() + { + $message = null; + + if (isset($this->data['messages'])) { + // In case of a successful transaction, a "messages" element is present + $message = (string)$this->data['messages'][0]['message'][0]['text'][0]; + + } + + return $message; + } + + public function getCardReference() + { + $cardRef = null; + if ($this->isSuccessful()) { + $data['customerProfileId'] = $this->getCustomerProfileId(); + $data['customerPaymentProfileId'] = $this->getCustomerPaymentProfileId(); + if (!empty($data['customerProfileId']) && !empty($data['customerPaymentProfileId'])) { + // For card reference both profileId and payment profileId should exist + $cardRef = json_encode($data); + } + } + return $cardRef; + } + + /** + * http://bookofzeus.com/articles/convert-simplexml-object-into-php-array/ + * + * Convert a simpleXMLElement in to an array + * + * @param \SimpleXMLElement $xml + * + * @return array + */ + public function xml2array(\SimpleXMLElement $xml) + { + $arr = array(); + foreach ($xml as $element) { + $tag = $element->getName(); + $e = get_object_vars($element); + if (!empty($e)) { + $arr[$tag][] = $element instanceof \SimpleXMLElement ? $this->xml2array($element) : $e; + } else { + $arr[$tag][] = trim($element); + } + } + + return $arr; + } + + public function getCustomerProfileId() + { + return null; + } + + public function getCustomerPaymentProfileId() + { + return null; + } + + /** + * Authorize net does not provide finger print and brand of the card hence we build the parameters from the + * requested card data + * + */ + public function augmentResponse() + { + if ($this->isSuccessful()) { + /** @var CreditCard $card */ + $card = $this->request->getCard(); + if ($card) { + $ccString = $card->getNumber() . $card->getExpiryMonth() . $card->getExpiryYear(); + $this->data['hash'] = md5($ccString); + $this->data['brand'] = $card->getBrand(); + $this->data['expiryYear'] = $card->getExpiryYear(); + $this->data['expiryMonth'] = $card->getExpiryMonth(); + } + } + } +} diff --git a/src/Message/CIMAuthorizeRequest.php b/src/Message/CIMAuthorizeRequest.php new file mode 100644 index 00000000..f5c2068e --- /dev/null +++ b/src/Message/CIMAuthorizeRequest.php @@ -0,0 +1,61 @@ +validate('cardReference', 'amount'); + + $data = $this->getBaseData(); + + $this->addTransactionData($data); + return $data; + } + + /** + * Adds transaction data + * + * @param \SimpleXMLElement $data + * + * @return \SimpleXMLElement + */ + protected function addTransactionData(\SimpleXMLElement $data) + { + $transaction = $data->addChild('transaction'); + $action = $transaction->addChild($this->action); + $action->amount = number_format($this->getAmount(), 2); + + $cardRef = json_decode($this->getCardReference(), true); + $action->customerProfileId = $cardRef['customerProfileId']; + $action->customerPaymentProfileId = $cardRef['customerPaymentProfileId']; + if (!empty($cardRef['customerShippingAddressId'])) { + $action->customerShippingAddressId = $cardRef['customerShippingAddressId']; + } + + $desc = $this->getDescription(); + if (!empty($desc)) { + $action->order->description = $desc; + } + + return $data; + } + + public function sendData($data) + { + $headers = array('Content-Type' => 'text/xml; charset=utf-8'); + $data = $data->saveXml(); + $httpResponse = $this->httpClient->post($this->getEndpoint(), $headers, $data)->send(); + + return $this->response = new CIMResponse($this, $httpResponse->getBody()); + } + +} diff --git a/src/Message/CIMCaptureRequest.php b/src/Message/CIMCaptureRequest.php new file mode 100644 index 00000000..e406abf8 --- /dev/null +++ b/src/Message/CIMCaptureRequest.php @@ -0,0 +1,44 @@ +validate('transactionReference', 'amount'); + + // Get the card reference from the transaction reference and set it into the request. Card reference is required + // to make all the transactions + $transRef = json_decode($this->getTransactionReference(), true); + $this->setCardReference($transRef['cardReference']); + + $data = $this->getBaseData(); + + $this->addTransactionData($data); + $this->addTransactionReferenceData($data); + return $data; + } + + /** + * Adds references for original transaction to a partially filled request data object. + * + * @param \SimpleXMLElement $data + * + * @return \SimpleXMLElement + */ + protected function addTransactionReferenceData(\SimpleXMLElement $data) + { + $action = $data->transaction->profileTransCaptureOnly; + + $transRef = json_decode($this->getTransactionReference(), true); + + $action->approvalCode = $transRef['approvalCode']; + return $data; + } +} diff --git a/src/Message/CIMCreateCardRequest.php b/src/Message/CIMCreateCardRequest.php new file mode 100644 index 00000000..31be07a4 --- /dev/null +++ b/src/Message/CIMCreateCardRequest.php @@ -0,0 +1,282 @@ +validate('card'); + + /** @var CreditCard $card */ + $card = $this->getCard(); + $card->validate(); + + $data = $this->getBaseData(); + $this->addProfileData($data); + $this->addTestModeSetting($data); + + return $data; + } + + /** + * Add customer profile data to the specified xml element + * + * @param \SimpleXMLElement $data + */ + protected function addProfileData(\SimpleXMLElement $data) + { + $req = $data->addChild('profile'); + // Merchant assigned customer ID + $customer = $this->getCustomerId(); + if (!empty($customer)) { + $req->merchantCustomerId = $customer; + } + + $description = $this->getDescription(); + if (!empty($description)) { + $req->description = $description; + } + + $email = $this->getEmail(); + if (!empty($email)) { + $req->email = $email; + } + + $this->addPaymentProfileData($req); + $this->addShippingData($req); + } + + /** + * Adds payment profile to the specified xml element + * + * @param \SimpleXMLElement $data + */ + protected function addPaymentProfileData(\SimpleXMLElement $data) + { + // This order is important. Payment profiles should come in this order only + $req = $data->addChild('paymentProfiles'); + $this->addBillingData($req); + } + + /** + * Adds billing/payment data to the specified xml element + * + * @param \SimpleXMLElement $data + * + * @return \SimpleXMLElement|void + */ + protected function addBillingData(\SimpleXMLElement $data) + { + /** @var CreditCard $card */ + if ($card = $this->getCard()) { + $req = $data->addChild('billTo'); + // A card is present, so include billing details + $req->firstName = $card->getBillingFirstName(); + $req->lastName = $card->getBillingLastName(); + $req->company = $card->getBillingCompany(); + $req->address = trim($card->getBillingAddress1() . " \n" . $card->getBillingAddress2()); + $req->city = $card->getBillingCity(); + $req->state = $card->getBillingState(); + $req->zip = $card->getBillingPostcode(); + $req->country = $card->getBillingCountry(); + + $req = $data->addChild('payment'); + $req->creditCard->cardNumber = $card->getNumber(); + $req->creditCard->expirationDate = $card->getExpiryDate('Y-m'); + $req->creditCard->cardCode = $card->getCvv(); + } + } + + /** + * Adds shipping data to the specified xml element + * + * @param \SimpleXMLElement $data + */ + protected function addShippingData(\SimpleXMLElement $data) + { + /** @var CreditCard $card */ + if ($card = $this->getCard()) { + if ($card->getShippingFirstName()) { + $data->shipToList->firstName = $card->getShippingFirstName(); + } + if ($card->getShippingLastName()) { + $data->shipToList->lastName = $card->getShippingLastName(); + } + if ($card->getShippingCompany()) { + $data->shipToList->company = $card->getShippingCompany(); + } + if ($card->getShippingAddress1() || $card->getShippingAddress2()) { + $data->shipToList->address = trim($card->getShippingAddress1() . " \n" . $card->getShippingAddress2()); + } + if ($card->getShippingCity()) { + $data->shipToList->city = $card->getShippingCity(); + } + if ($card->getShippingState()) { + $data->shipToList->state = $card->getShippingState(); + } + if ($card->getShippingPostcode()) { + $data->shipToList->zip = $card->getShippingPostcode(); + } + if ($card->getShippingCountry()) { + $data->shipToList->country = $card->getShippingCountry(); + } + } + } + + protected function addTestModeSetting(\SimpleXMLElement $data) + { + // Test mode setting + $data->validationMode = $this->getDeveloperMode() ? 'testMode' : 'liveMode'; + } + + public function sendData($data) + { + $headers = array('Content-Type' => 'text/xml; charset=utf-8'); + $data = $data->saveXml(); + $httpResponse = $this->httpClient->post($this->getEndpoint(), $headers, $data)->send(); + + $response = new CIMCreateCardResponse($this, $httpResponse->getBody()); + + if (!$response->isSuccessful() && $response->getReasonCode() == 'E00039') { + // Duplicate profile. Try adding a new payment profile for the same profile and get the response + $response = $this->createPaymentProfile($response); + } elseif ($response->isSuccessful()) { + $parameters = array( + 'customerProfileId' => $response->getCustomerProfileId(), + 'customerPaymentProfileId' => $response->getCustomerPaymentProfileId() + ); + // Get the payment profile for the specified card. + $response = $this->makeGetPaymentProfileRequest($parameters); + } + + $response->augmentResponse(); + return $this->response = $response; + } + + /** + * Attempts to add a payment profile to the existing customer profile and return the updated customer profile + * + * @param CIMCreateCardResponse $createCardResponse Duplicate customer profile response + * + * @return CIMCreateCardResponse + */ + public function createPaymentProfile(CIMCreateCardResponse $createCardResponse) + { + // Parse the customer profile Id from the message + $msg = $createCardResponse->getMessage(); + preg_match("/ID (.+) already/i", $msg, $matches); + if (empty($matches[1])) { + // Duplicate profile id not found. Return current response + return $createCardResponse; + } + + // Use the customerProfileId and create a payment profile for the customer + $parameters = array_replace($this->getParameters(), array('customerProfileId' => $matches[1])); + $createPaymentProfileResponse = $this->makeCreatePaymentProfileRequest($parameters); + if ($createPaymentProfileResponse->isSuccessful()) { + $parameters['customerPaymentProfileId'] = $createPaymentProfileResponse->getCustomerPaymentProfileId(); + } elseif ($this->getForceCardUpdate() !== true) { + // force card update flag turned off. No need to further process. + return $createCardResponse; + } + + $getProfileResponse = $this->makeGetProfileRequest($parameters); + + if (!$createPaymentProfileResponse->isSuccessful() && + $createPaymentProfileResponse->getReasonCode() == 'E00039' + ) { + // Found a duplicate payment profile existing for the same card data. Force update is turned on, + // So find matching payment profile id from the customer profile and update it. + $card = $this->getCard(); + $last4 = substr($card->getNumber(), -4); + + $customerPaymentProfileId = $getProfileResponse->getMatchingPaymentProfileId($last4); + + if (!$customerPaymentProfileId) { + // Failed. Matching customer payment profile id not found. Return the original response + return $createCardResponse; + } + + $parameters['customerPaymentProfileId'] = $customerPaymentProfileId; + $updatePaymentProfileResponse = $this->makeUpdatePaymentProfileRequest($parameters); + if (!$updatePaymentProfileResponse->isSuccessful()) { + // Could not update payment profile. Return the original response + return $createCardResponse; + } + } + + // return the updated customer profile + $getPaymentProfileResponse = $this->makeGetPaymentProfileRequest($parameters); + if (!$getPaymentProfileResponse->isSuccessful()) { + // Could not get the updated customer profile. Return the original response + return $createCardResponse; + } + + return $getPaymentProfileResponse; + } + + /** + * Make a request to add a payment profile to the current customer profile + * + * @param $parameters + * + * @return CIMCreatePaymentProfileResponse + */ + public function makeCreatePaymentProfileRequest($parameters) + { + $obj = new CIMCreatePaymentProfileRequest($this->httpClient, $this->httpRequest); + $obj->initialize($parameters); + return $obj->send(); + } + + /** + * Get the customer profile + * + * @param array $parameters + * + * @return CIMGetProfileResponse + */ + public function makeGetProfileRequest($parameters) + { + $obj = new CIMGetProfileRequest($this->httpClient, $this->httpRequest); + $obj->initialize(array_replace($this->getParameters(), $parameters)); + return $obj->send(); + } + + /** + * Get the customer payment profile + * + * @param array $parameters + * + * @return CIMGetPaymentProfileResponse + */ + public function makeGetPaymentProfileRequest($parameters) + { + $obj = new CIMGetPaymentProfileRequest($this->httpClient, $this->httpRequest); + $obj->initialize(array_replace($this->getParameters(), $parameters)); + return $obj->send(); + } + + /** + * Makes an update profile request + * + * @param $parameters + * + * @return CIMCreateCardResponse + */ + public function makeUpdatePaymentProfileRequest($parameters) + { + $obj = new CIMUpdatePaymentProfileRequest($this->httpClient, $this->httpRequest); + $obj->initialize(array_replace($this->getParameters(), $parameters)); + return $obj->send(); + } + +} diff --git a/src/Message/CIMCreateCardResponse.php b/src/Message/CIMCreateCardResponse.php new file mode 100644 index 00000000..d13dd0c4 --- /dev/null +++ b/src/Message/CIMCreateCardResponse.php @@ -0,0 +1,27 @@ +isSuccessful()) { + return $this->data['customerProfileId'][0]; + } + return null; + } + + public function getCustomerPaymentProfileId() + { + if ($this->isSuccessful()) { + return $this->data['customerPaymentProfileIdList'][0]['numericString'][0]; + } + return null; + } +} diff --git a/src/Message/CIMCreatePaymentProfileRequest.php b/src/Message/CIMCreatePaymentProfileRequest.php new file mode 100644 index 00000000..d7f3d556 --- /dev/null +++ b/src/Message/CIMCreatePaymentProfileRequest.php @@ -0,0 +1,50 @@ +validate('card', 'customerProfileId'); + + /** @var CreditCard $card */ + $card = $this->getCard(); + $card->validate(); + + $data = $this->getBaseData(); + $data->customerProfileId = $this->getCustomerProfileId(); + $this->addPaymentProfileData($data); + $this->addTestModeSetting($data); + + return $data; + } + + /** + * Adds payment profile to the specified xml element + * + * @param \SimpleXMLElement $data + */ + protected function addPaymentProfileData(\SimpleXMLElement $data) + { + // This order is important. Payment profiles should come in this order only + $req = $data->addChild('paymentProfile'); + $this->addBillingData($req); + } + + public function sendData($data) + { + $headers = array('Content-Type' => 'text/xml; charset=utf-8'); + $data = $data->saveXml(); + $httpResponse = $this->httpClient->post($this->getEndpoint(), $headers, $data)->send(); + + return $this->response = new CIMCreatePaymentProfileResponse($this, $httpResponse->getBody()); + } +} diff --git a/src/Message/CIMCreatePaymentProfileResponse.php b/src/Message/CIMCreatePaymentProfileResponse.php new file mode 100644 index 00000000..122c9dd0 --- /dev/null +++ b/src/Message/CIMCreatePaymentProfileResponse.php @@ -0,0 +1,27 @@ +isSuccessful()) { + return $this->request->getCustomerProfileId(); + } + return null; + } + + public function getCustomerPaymentProfileId() + { + if ($this->isSuccessful()) { + return $this->data['customerPaymentProfileId'][0]; + } + return null; + } +} diff --git a/src/Message/CIMGetPaymentProfileRequest.php b/src/Message/CIMGetPaymentProfileRequest.php new file mode 100644 index 00000000..bef74200 --- /dev/null +++ b/src/Message/CIMGetPaymentProfileRequest.php @@ -0,0 +1,35 @@ +validate('customerProfileId', 'customerPaymentProfileId'); + + $data = $this->getBaseData(); + + $data->customerProfileId = $this->getCustomerProfileId(); + $data->customerPaymentProfileId = $this->getCustomerPaymentProfileId(); + + return $data; + } + + public function sendData($data) + { + $headers = array('Content-Type' => 'text/xml; charset=utf-8'); + $data = $data->saveXml(); + $httpResponse = $this->httpClient->post($this->getEndpoint(), $headers, $data)->send(); + + return $this->response = new CIMGetPaymentProfileResponse($this, $httpResponse->getBody()); + } + +} diff --git a/src/Message/CIMGetPaymentProfileResponse.php b/src/Message/CIMGetPaymentProfileResponse.php new file mode 100644 index 00000000..b16bafa1 --- /dev/null +++ b/src/Message/CIMGetPaymentProfileResponse.php @@ -0,0 +1,19 @@ +isSuccessful()) { + return $this->data['paymentProfile'][0]['customerPaymentProfileId'][0]; + } + return null; + } +} diff --git a/src/Message/CIMGetProfileRequest.php b/src/Message/CIMGetProfileRequest.php new file mode 100644 index 00000000..c74a9e74 --- /dev/null +++ b/src/Message/CIMGetProfileRequest.php @@ -0,0 +1,34 @@ +validate('customerProfileId'); + + $data = $this->getBaseData(); + + $data->customerProfileId = $this->getCustomerProfileId(); + + return $data; + } + + public function sendData($data) + { + $headers = array('Content-Type' => 'text/xml; charset=utf-8'); + $data = $data->saveXml(); + $httpResponse = $this->httpClient->post($this->getEndpoint(), $headers, $data)->send(); + + return $this->response = new CIMGetProfileResponse($this, $httpResponse->getBody()); + } + +} diff --git a/src/Message/CIMGetProfileResponse.php b/src/Message/CIMGetProfileResponse.php new file mode 100644 index 00000000..f5a43237 --- /dev/null +++ b/src/Message/CIMGetProfileResponse.php @@ -0,0 +1,44 @@ +isSuccessful()) { + return null; + } + + foreach ($this->data['profile'][0]['paymentProfiles'] as $paymentProfile) { + // For every payment profile check if the last4 matches the last4 of the card in request. + $cardLast4 = substr($paymentProfile['payment'][0]['creditCard'][0]['cardNumber'][0], -4); + if ($last4 == $cardLast4) { + return (string)$paymentProfile['customerPaymentProfileId'][0]; + } + } + + return null; + } + + public function getCustomerPaymentProfileId() + { + if ($this->isSuccessful()) { + return $this->request->getCustomerPaymentProfileId(); + } + return null; + } +} diff --git a/src/Message/CIMPurchaseRequest.php b/src/Message/CIMPurchaseRequest.php new file mode 100644 index 00000000..b359e959 --- /dev/null +++ b/src/Message/CIMPurchaseRequest.php @@ -0,0 +1,11 @@ +transaction->profileTransRefund; + + $transRef = json_decode($this->getTransactionReference(), true); + + $action->transId = $transRef['transId']; + return $data; + } +} diff --git a/src/Message/CIMResponse.php b/src/Message/CIMResponse.php new file mode 100644 index 00000000..157ea1cd --- /dev/null +++ b/src/Message/CIMResponse.php @@ -0,0 +1,35 @@ +isSuccessful()) { + return null; + } + $transRef = null; + if (isset($this->data['directResponse'])) { + $transRef = array(); + // In case of a successful transaction, a "directResponse" element is present + $directResponse = explode(',', (string)$this->data['directResponse'][0]); + // Required for capturing an authorized transaction + $transRef['approvalCode'] = $directResponse[4]; + // Required for refund a transaction + $transRef['transId'] = $directResponse[6]; + + // Save the card reference also as it is needed for making further transactions. + // This card reference is got from the request. (transaction response does not have it) + $transRef['cardReference'] = $this->request->getCardReference(); + $transRef = json_encode($transRef); + } + + return $transRef; + } +} diff --git a/src/Message/CIMUpdatePaymentProfileRequest.php b/src/Message/CIMUpdatePaymentProfileRequest.php new file mode 100644 index 00000000..be273ce3 --- /dev/null +++ b/src/Message/CIMUpdatePaymentProfileRequest.php @@ -0,0 +1,51 @@ +validate('card', 'customerProfileId', 'customerPaymentProfileId'); + + /** @var CreditCard $card */ + $card = $this->getCard(); + $card->validate(); + + $data = $this->getBaseData(); + $data->customerProfileId = $this->getCustomerProfileId(); + $this->addPaymentProfileData($data); + $this->addTestModeSetting($data); + + return $data; + } + + /** + * Adds payment profile to the specified xml element + * + * @param \SimpleXMLElement $data + */ + protected function addPaymentProfileData(\SimpleXMLElement $data) + { + // This order is important. Payment profiles should come in this order only + $req = $data->addChild('paymentProfile'); + $this->addBillingData($req); + $req->customerPaymentProfileId = $this->getCustomerPaymentProfileId(); + } + + public function sendData($data) + { + $headers = array('Content-Type' => 'text/xml; charset=utf-8'); + $data = $data->saveXml(); + $httpResponse = $this->httpClient->post($this->getEndpoint(), $headers, $data)->send(); + + return $this->response = new CIMUpdatePaymentProfileResponse($this, $httpResponse->getBody()); + } +} diff --git a/src/Message/CIMUpdatePaymentProfileResponse.php b/src/Message/CIMUpdatePaymentProfileResponse.php new file mode 100644 index 00000000..8b069970 --- /dev/null +++ b/src/Message/CIMUpdatePaymentProfileResponse.php @@ -0,0 +1,16 @@ +request->getCustomerPaymentProfileId(); + } +} diff --git a/tests/CIMGatewayIntegrationTest.php b/tests/CIMGatewayIntegrationTest.php new file mode 100644 index 00000000..5475a1cb --- /dev/null +++ b/tests/CIMGatewayIntegrationTest.php @@ -0,0 +1,176 @@ +pushHandler(new \Monolog\Handler\StreamHandler('/var/log/php/debug.log', \Monolog\Logger::DEBUG)); + $logger->pushHandler(new \Monolog\Handler\FirePHPHandler()); + $adapter = new PsrLogAdapter($logger); + $logPlugin = new LogPlugin($adapter, MessageFormatter::DEBUG_FORMAT); + + $client = new Client(); + $client->addSubscriber($logPlugin); + + $this->gateway = new CIMGateway($client, $this->getHttpRequest()); + $this->gateway->setDeveloperMode(true); + $this->gateway->setApiLoginId($apiLoginId); + $this->gateway->setTransactionKey($transactionKey); + } else { + // No credentials were found, so skip this test + $this->markTestSkipped(); + } + } + + public function testIntegration() + { + // Create card + $rand = rand(100000, 999999); + $params = array( + 'card' => $this->getValidCard(), + 'name' => 'Kaywinnet Lee Frye', + 'email' => "kaylee$rand@serenity.com", + ); + $request = $this->gateway->createCard($params); + $request->setDeveloperMode(true); + + $response = $request->send(); + $this->assertTrue($response->isSuccessful(), 'Profile should get created'); + $this->assertNotNull($response->getCardReference(), 'Card reference should be returned'); + + $cardRef = $response->getCardReference(); + + // Try different creating card for same user + $params = array( + 'card' => $this->getValidCard(), + 'name' => 'Kaywinnet Lee Frye', + 'email' => "kaylee$rand@serenity.com", + ); + $params['card']['number'] = '4007000000027'; + $request = $this->gateway->createCard($params); + $request->setDeveloperMode(true); + + $response = $request->send(); + $this->assertTrue($response->isSuccessful(), 'Should be a success as we create a payment profile'); + $this->assertNotNull($response->getCardReference(), 'Card reference should be returned'); + + // Try creating same card for the same user without force card update flag. + $params = array( + 'card' => $this->getValidCard(), + 'name' => 'Kaywinnet Lee Frye', + 'email' => "kaylee$rand@serenity.com", + ); + $request = $this->gateway->createCard($params); + $request->setDeveloperMode(true); + + $response = $request->send(); + $this->assertFalse($response->isSuccessful(), 'Should not success as we tried creating duplicate profile'); + $this->assertNull($response->getCardReference(), 'Card reference should be returned'); + + // Try creating same card for the same user again with force card update flag. + $params = array( + 'card' => $this->getValidCard(), + 'name' => 'Kaywinnet Lee Frye', + 'email' => "kaylee$rand@serenity.com", + 'forceCardUpdate' => true + ); + $request = $this->gateway->createCard($params); + $request->setDeveloperMode(true); + + $response = $request->send(); + $this->assertTrue($response->isSuccessful(), 'Should succeed updating of the existing payment profile'); + $this->assertEquals( + $cardRef, + $response->getCardReference(), + 'Card reference should be same as with the one newly created' + ); + + // Create Authorize only transaction + $params = array( + 'cardReference' => $cardRef, + 'amount' => 100.00, + 'description' + ); + $request = $this->gateway->authorize($params); + $request->setDeveloperMode(true); + + $response = $request->send(); + $this->assertTrue($response->isSuccessful(), 'Authorize transaction should get created'); + $this->assertNotNull($response->getTransactionReference(), 'Transaction reference should exist'); + + $transRef = $response->getTransactionReference(); + + // Capture the authorised transaction + $params = array( + 'transactionReference' => $transRef, + 'amount' => 100.00, + ); + $request = $this->gateway->capture($params); + $request->setDeveloperMode(true); + + $response = $request->send(); + $this->assertTrue($response->isSuccessful(), 'Capture transaction should get created'); + $this->assertNotNull($response->getTransactionReference(), 'Transaction reference should exist'); + $captureTransRef = $response->getTransactionReference(); + + // Make a purchase using the saved card. i.e auth and capture + $params = array( + 'cardReference' => $cardRef, + 'amount' => 110.00, + ); + $request = $this->gateway->purchase($params); + $request->setDeveloperMode(true); + + $response = $request->send(); + $this->assertTrue($response->isSuccessful(), 'Purchase transaction should get created'); + $this->assertNotNull($response->getTransactionReference(), 'Transaction reference should exist'); + $purchaseTransRef = $response->getTransactionReference(); + + // Make a refund on the purchase transaction + $params = array( + 'transactionReference' => $purchaseTransRef, + 'amount' => 110.00, + ); + $request = $this->gateway->refund($params); + $request->setDeveloperMode(true); + + $response = $request->send(); + // todo: Fix refunds, and add unit tests using mocks +// $this->assertTrue($response->isSuccessful(), 'Refund transaction should get created'); +// $this->assertNotNull($response->getTransactionReference(), 'Transaction reference should exist'); + + } +} diff --git a/tests/CIMGatewayTest.php b/tests/CIMGatewayTest.php new file mode 100644 index 00000000..a52e21ef --- /dev/null +++ b/tests/CIMGatewayTest.php @@ -0,0 +1,189 @@ +gateway = new CIMGateway($this->getHttpClient(), $this->getHttpRequest()); + + $this->createCardOptions = array( + 'email' => "kaylee@serenity.com", + 'card' => $this->getValidCard(), + 'testMode' => true + ); + + $this->authorizeOptions = array( + 'cardReference' => '{"customerProfileId":"28972084","customerPaymentProfileId":"26317840","customerShippingAddressId":"27057149"}', + 'amount' => 10.00, + 'description' => 'authorize' + ); + + $this->captureOptions = array( + 'amount' => '10.00', + 'description' => 'capture', + 'transactionReference' => '{"approvalCode":"DMK100","transId":"2220001902","cardReference":"{\"customerProfileId\":\"28972084\",\"customerPaymentProfileId\":\"26317840\",\"customerShippingAddressId\":\"27057149\"}"}', + ); + + $this->authorizeOptions = array( + 'cardReference' => '{"customerProfileId":"28972084","customerPaymentProfileId":"26317840","customerShippingAddressId":"27057149"}', + 'amount' => 10.00, + 'description' => 'purchase' + ); + + $this->refundOptions = array( + 'amount' => '10.00', + 'transactionReference' => '{"approvalCode":"DMK100","transId":"2220001902","cardReference":"{\"customerProfileId\":\"28972084\",\"customerPaymentProfileId\":\"26317840\",\"customerShippingAddressId\":\"27057149\"}"}', + 'description' => 'refund' + ); + } + + public function testCreateCardSuccess() + { + $this->setMockHttpResponse(array('CIMCreateCardSuccess.txt','CIMGetPaymentProfileSuccess.txt')); + + $response = $this->gateway->createCard($this->createCardOptions)->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertSame( + '{"customerProfileId":"28972084","customerPaymentProfileId":"26485433"}', + $response->getCardReference() + ); + $this->assertSame('Successful.', $response->getMessage()); + } + + public function testCreateCardFailure() + { + $this->setMockHttpResponse('CIMCreateCardFailure.txt'); + + $response = $this->gateway->createCard($this->createCardOptions)->send(); + + $this->assertFalse($response->isSuccessful()); + $this->assertNull($response->getCardReference()); + $this->assertSame('One or more fields in the profile must contain a value.', $response->getMessage()); + } + + public function testAuthorizeSuccess() + { + $this->setMockHttpResponse('CIMAuthorizeSuccess.txt'); + + $response = $this->gateway->authorize($this->authorizeOptions)->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertSame( + '{"approvalCode":"DMK100","transId":"2220001902","cardReference":"{\"customerProfileId\":\"28972084\",\"customerPaymentProfileId\":\"26317840\",\"customerShippingAddressId\":\"27057149\"}"}', + $response->getTransactionReference() + ); + $this->assertSame('Successful.', $response->getMessage()); + } + + public function testAuthorizeFailure() + { + $this->setMockHttpResponse('CIMAuthorizeFailure.txt'); + + try { + $response = $this->gateway->authorize($this->authorizeOptions)->send(); + } catch(\Exception $e) { + + } + + $this->assertFalse($response->isSuccessful()); + $this->assertNull($response->getTransactionReference()); + $this->assertSame( + "The 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:amount' element is invalid - The value '-100.00' is invalid according to its datatype 'Decimal' - The MinInclusive constraint failed.", + $response->getMessage() + ); + } + + public function testCaptureSuccess() + { + $this->setMockHttpResponse('CIMCaptureSuccess.txt'); + + $response = $this->gateway->capture($this->captureOptions)->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertSame( + '{"approvalCode":"DMK100","transId":"2220001903","cardReference":"{\"customerProfileId\":\"28972084\",\"customerPaymentProfileId\":\"26317840\",\"customerShippingAddressId\":\"27057149\"}"}', + $response->getTransactionReference() + ); + $this->assertSame('Successful.', $response->getMessage()); + } + + public function testCaptureFailure() + { + $this->setMockHttpResponse('CIMCaptureFailure.txt'); + + $response = $this->gateway->capture($this->captureOptions)->send(); + + $this->assertFalse($response->isSuccessful()); + $this->assertNull($response->getTransactionReference()); + $this->assertSame('Approval Code is required.', $response->getMessage()); + } + + public function testPurchaseSuccess() + { + $this->setMockHttpResponse('CIMPurchaseSuccess.txt'); + + $response = $this->gateway->purchase($this->authorizeOptions)->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertSame( + '{"approvalCode":"MNLXJQ","transId":"2220001904","cardReference":"{\"customerProfileId\":\"28972084\",\"customerPaymentProfileId\":\"26317840\",\"customerShippingAddressId\":\"27057149\"}"}', + $response->getTransactionReference() + ); + $this->assertSame('Successful.', $response->getMessage()); + } + + public function testPurchaseFailure() + { + $this->setMockHttpResponse('CIMPurchaseFailure.txt'); + + $response = $this->gateway->purchase($this->authorizeOptions)->send(); + + $this->assertFalse($response->isSuccessful()); + $this->assertNull( + $response->getTransactionReference() + ); + $this->assertSame('This transaction has been declined.', $response->getMessage()); + } + + public function testRefundSuccess() + { +// $this->setMockHttpResponse('CIMRefundSuccess.txt'); +// +// $response = $this->gateway->refund($this->refundOptions)->send(); +// +// $this->assertTrue($response->isSuccessful()); +// $this->assertSame('', $response->getTransactionReference()); +// $this->assertSame('This transaction has been approved.', $response->getMessage()); + } + + public function testRefundFailure() + { + $this->setMockHttpResponse('CIMRefundFailure.txt'); + + $response = $this->gateway->refund($this->refundOptions)->send(); + + $this->assertFalse($response->isSuccessful()); + $this->assertNull( + $response->getTransactionReference() + ); + $this->assertSame( + 'The referenced transaction does not meet the criteria for issuing a credit.', + $response->getMessage() + ); + } +} diff --git a/tests/Message/AIMRefundRequestTest.php b/tests/Message/AIMRefundRequestTest.php index f000f2c2..1c90dcbb 100644 --- a/tests/Message/AIMRefundRequestTest.php +++ b/tests/Message/AIMRefundRequestTest.php @@ -15,7 +15,7 @@ public function setUp() $this->request = new AIMRefundRequest($this->getHttpClient(), $this->getHttpRequest()); } - public function testGetData_MissingCardInfo() + public function testGetDataMissingCardInfo() { $this->request->initialize( array( @@ -26,10 +26,12 @@ public function testGetData_MissingCardInfo() try { $this->request->getData(); - } catch(InvalidRequestException $irex) { - return $this->assertEquals($irex->getMessage(), "The card parameter is required"); - } catch(\Exception $e) { - return $this->fail("Invalid exception was thrown: " . $e->getMessage()); + } catch (InvalidRequestException $irex) { + $this->assertEquals($irex->getMessage(), "The card parameter is required"); + return; + } catch (\Exception $e) { + $this->fail("Invalid exception was thrown: " . $e->getMessage()); + return; } $this->fail("InvalidRequestException should get thrown because card is missing"); @@ -52,11 +54,11 @@ public function testGetData() $data = $this->request->getData(); $this->assertEquals('refundTransaction', $data->transactionRequest->transactionType); - $this->assertEquals('12.12', (string) $data->transactionRequest->amount[0]); + $this->assertEquals('12.12', (string)$data->transactionRequest->amount[0]); $this->assertEquals('authnet-transaction-reference', $data->transactionRequest->refTransId); $setting = $data->transactionRequest->transactionSettings->setting[0]; $this->assertEquals('testRequest', $setting->settingName); $this->assertEquals('false', $setting->settingValue); } -} \ No newline at end of file +} diff --git a/tests/Message/CIMAuthorizeRequestTest.php b/tests/Message/CIMAuthorizeRequestTest.php new file mode 100644 index 00000000..dcfd2e56 --- /dev/null +++ b/tests/Message/CIMAuthorizeRequestTest.php @@ -0,0 +1,34 @@ +request = new CIMAuthorizeRequest($this->getHttpClient(), $this->getHttpRequest()); + $this->request->initialize( + array( + 'cardReference' => '{"customerProfileId":"28972085","customerPaymentProfileId":"26317841","customerShippingAddressId":"27057151"}', + 'amount' => '12.00', + 'description' => 'Test authorize transaction' + ) + ); + } + + public function testGetData() + { + $data = $this->request->getData(); + + $this->assertEquals('12.00', $data->transaction->profileTransAuthOnly->amount); + $this->assertEquals('28972085', $data->transaction->profileTransAuthOnly->customerProfileId); + $this->assertEquals('26317841', $data->transaction->profileTransAuthOnly->customerPaymentProfileId); + $this->assertEquals('27057151', $data->transaction->profileTransAuthOnly->customerShippingAddressId); + $this->assertEquals('Test authorize transaction', $data->transaction->profileTransAuthOnly->order->description); + } +} diff --git a/tests/Message/CIMCaptureRequestTest.php b/tests/Message/CIMCaptureRequestTest.php new file mode 100644 index 00000000..3d34936b --- /dev/null +++ b/tests/Message/CIMCaptureRequestTest.php @@ -0,0 +1,38 @@ +request = new CIMCaptureRequest($this->getHttpClient(), $this->getHttpRequest()); + $this->request->initialize( + array( + 'transactionReference' => '{"approvalCode":"V7DO8Q","transId":"2220001612","cardReference":"{\"customerProfileId\":\"28972085\",\"customerPaymentProfileId\":\"26317841\",\"customerShippingAddressId\":\"27057151\"}"}', + 'amount' => 12.00, + 'description' => 'Test capture only transaction' + ) + ); + } + + public function testGetData() + { + $data = $this->request->getData(); + + $this->assertEquals('12.00', $data->transaction->profileTransCaptureOnly->amount); + $this->assertEquals('28972085', $data->transaction->profileTransCaptureOnly->customerProfileId); + $this->assertEquals('26317841', $data->transaction->profileTransCaptureOnly->customerPaymentProfileId); + $this->assertEquals('27057151', $data->transaction->profileTransCaptureOnly->customerShippingAddressId); + $this->assertEquals( + 'Test capture only transaction', + $data->transaction->profileTransCaptureOnly->order->description + ); + $this->assertEquals('V7DO8Q', $data->transaction->profileTransCaptureOnly->approvalCode); + } +} \ No newline at end of file diff --git a/tests/Message/CIMCreateCardRequestTest.php b/tests/Message/CIMCreateCardRequestTest.php new file mode 100644 index 00000000..e8042c39 --- /dev/null +++ b/tests/Message/CIMCreateCardRequestTest.php @@ -0,0 +1,32 @@ +request = new CIMCreateCardRequest($this->getHttpClient(), $this->getHttpRequest()); + $this->request->initialize( + array( + 'email' => "kaylee@serenity.com", + 'card' => $this->getValidCard(), + 'developerMode' => true + ) + ); + } + + public function testGetData() + { + $data = $this->request->getData(); + $card = $this->getValidCard(); + $this->assertEquals('12345', $data->profile->paymentProfiles->billTo->zip); + $this->assertEquals($card['number'], $data->profile->paymentProfiles->payment->creditCard->cardNumber); + $this->assertEquals('testMode', $data->validationMode); + } +} diff --git a/tests/Message/CIMCreateCardResponseTest.php b/tests/Message/CIMCreateCardResponseTest.php new file mode 100644 index 00000000..a68942cf --- /dev/null +++ b/tests/Message/CIMCreateCardResponseTest.php @@ -0,0 +1,46 @@ +getMockRequest(), ''); + } + + public function testCreateCardSuccess() + { + $httpResponse = $this->getMockHttpResponse('CIMCreateCardSuccess.txt'); + $response = new CIMCreateCardResponse($this->getMockRequest(), $httpResponse->getBody()); + + $this->assertTrue($response->isSuccessful()); + $this->assertEquals('I00001', $response->getReasonCode()); + $this->assertEquals("1", $response->getResultCode()); + $this->assertEquals("Successful.", $response->getMessage()); + + $this->assertEquals('28972084', $response->getCustomerProfileId()); + $this->assertEquals('26317840', $response->getCustomerPaymentProfileId()); + } + + public function testCreateCardFailure() + { + $httpResponse = $this->getMockHttpResponse('CIMCreateCardFailure.txt'); + $response = new CIMCreateCardResponse($this->getMockRequest(), $httpResponse->getBody()); + + $this->assertFalse($response->isSuccessful()); + $this->assertEquals('E00041', $response->getReasonCode()); + $this->assertEquals("3", $response->getResultCode()); + $this->assertEquals("One or more fields in the profile must contain a value.", $response->getMessage()); + + $this->assertNull($response->getCustomerProfileId()); + $this->assertNull($response->getCustomerPaymentProfileId()); + + $this->assertNull($response->getCardReference()); + } +} diff --git a/tests/Message/CIMCreatePaymentProfileRequestTest.php b/tests/Message/CIMCreatePaymentProfileRequestTest.php new file mode 100644 index 00000000..cf407618 --- /dev/null +++ b/tests/Message/CIMCreatePaymentProfileRequestTest.php @@ -0,0 +1,34 @@ +request = new CIMCreatePaymentProfileRequest($this->getHttpClient(), $this->getHttpRequest()); + $this->request->initialize( + array( + 'customerProfileId' => '28775801', + 'email' => "kaylee@serenity.com", + 'card' => $this->getValidCard(), + 'developerMode' => true + ) + ); + } + + public function testGetData() + { + $data = $this->request->getData(); + + $card = $this->getValidCard(); + $this->assertEquals('28775801', $data->customerProfileId); + $this->assertEquals($card['number'], $data->paymentProfile->payment->creditCard->cardNumber); + $this->assertEquals('testMode', $data->validationMode); + } +} diff --git a/tests/Message/CIMCreatePaymentProfileResponseTest.php b/tests/Message/CIMCreatePaymentProfileResponseTest.php new file mode 100644 index 00000000..70b33914 --- /dev/null +++ b/tests/Message/CIMCreatePaymentProfileResponseTest.php @@ -0,0 +1,43 @@ +getMockRequest(), ''); + } + + public function testCreateCardSuccess() + { + $httpResponse = $this->getMockHttpResponse('CIMCreatePaymentProfileSuccess.txt'); + $mockRequest = \Mockery::mock('\Omnipay\Common\Message\RequestInterface'); + $mockRequest->shouldReceive('getCustomerProfileId')->times(1)->andReturn('28775801'); + $response = new CIMCreatePaymentProfileResponse($mockRequest, $httpResponse->getBody()); + + $this->assertTrue($response->isSuccessful()); + $this->assertEquals('I00001', $response->getReasonCode()); + $this->assertEquals("1", $response->getResultCode()); + $this->assertEquals("Successful.", $response->getMessage()); + $this->assertEquals("26455709", $response->getCustomerPaymentProfileId()); + $this->assertEquals("28775801", $response->getCustomerProfileId()); + } + + public function testCreateCardFailure() + { + $httpResponse = $this->getMockHttpResponse('CIMCreatePaymentProfileFailure.txt'); + $response = new CIMCreatePaymentProfileResponse($this->getMockRequest(), $httpResponse->getBody()); + + $this->assertFalse($response->isSuccessful()); + $this->assertEquals('E00039', $response->getReasonCode()); + $this->assertEquals("3", $response->getResultCode()); + $this->assertEquals("A duplicate customer payment profile already exists.", $response->getMessage()); + $this->assertNull($response->getCardReference()); + } +} diff --git a/tests/Message/CIMGetPaymentProfileRequestTest.php b/tests/Message/CIMGetPaymentProfileRequestTest.php new file mode 100644 index 00000000..9c85e531 --- /dev/null +++ b/tests/Message/CIMGetPaymentProfileRequestTest.php @@ -0,0 +1,29 @@ +request = new CIMGetPaymentProfileRequest($this->getHttpClient(), $this->getHttpRequest()); + $this->request->initialize( + array( + 'customerProfileId' => '28775801', + 'customerPaymentProfileId' => '28775803', + ) + ); + } + + public function testGetData() + { + $data = $this->request->getData(); + $this->assertEquals('28775801', $data->customerProfileId); + $this->assertEquals('28775803', $data->customerPaymentProfileId); + } +} \ No newline at end of file diff --git a/tests/Message/CIMGetPaymentProfileResponseTest.php b/tests/Message/CIMGetPaymentProfileResponseTest.php new file mode 100644 index 00000000..76576c65 --- /dev/null +++ b/tests/Message/CIMGetPaymentProfileResponseTest.php @@ -0,0 +1,26 @@ +getMockRequest(), ''); + } + + public function testGetMatchingPaymentProfileId() + { + $httpResponse = $this->getMockHttpResponse('CIMGetPaymentProfileSuccess.txt'); + $mockRequest = \Mockery::mock('\Omnipay\Common\Message\RequestInterface'); + $mockRequest->shouldReceive('getCustomerProfileId')->andReturn('28972085'); + $response = new CIMGetPaymentProfileResponse($mockRequest, $httpResponse->getBody()); + + $this->assertEquals('{"customerProfileId":"28972085","customerPaymentProfileId":"26485433"}', $response->getCardReference()); + } +} diff --git a/tests/Message/CIMGetProfileRequestTest.php b/tests/Message/CIMGetProfileRequestTest.php new file mode 100644 index 00000000..f6669141 --- /dev/null +++ b/tests/Message/CIMGetProfileRequestTest.php @@ -0,0 +1,27 @@ +request = new CIMGetProfileRequest($this->getHttpClient(), $this->getHttpRequest()); + $this->request->initialize( + array( + 'customerProfileId' => '28775801', + ) + ); + } + + public function testGetData() + { + $data = $this->request->getData(); + $this->assertEquals('28775801', $data->customerProfileId); + } +} \ No newline at end of file diff --git a/tests/Message/CIMGetProfileResponseTest.php b/tests/Message/CIMGetProfileResponseTest.php new file mode 100644 index 00000000..c1abda05 --- /dev/null +++ b/tests/Message/CIMGetProfileResponseTest.php @@ -0,0 +1,26 @@ +getMockRequest(), ''); + } + + public function testGetMatchingPaymentProfileId() + { + $httpResponse = $this->getMockHttpResponse('CIMGetProfileSuccess.txt'); + $response = new CIMGetProfileResponse($this->getMockRequest(), $httpResponse->getBody()); + + $this->assertEquals('26455656', $response->getMatchingPaymentProfileId('1111')); + $this->assertEquals('26455709', $response->getMatchingPaymentProfileId('8888')); + $this->assertNull($response->getMatchingPaymentProfileId('8889')); + } +} diff --git a/tests/Message/CIMPurchaseRequestTest.php b/tests/Message/CIMPurchaseRequestTest.php new file mode 100644 index 00000000..4cf76acc --- /dev/null +++ b/tests/Message/CIMPurchaseRequestTest.php @@ -0,0 +1,30 @@ +request = new CIMPurchaseRequest($this->getHttpClient(), $this->getHttpRequest()); + $this->request->initialize( + array( + 'cardReference' => '{"customerProfileId":"28972085","customerPaymentProfileId":"26317841","customerShippingAddressId":"27057151"}', + 'amount' => '12.00', + 'description' => 'Test purchase transaction' + ) + ); + } + + public function testGetData() + { + $data = $this->request->getData(); + + $this->assertObjectHasAttribute('profileTransAuthCapture',$data->transaction); + } +} diff --git a/tests/Message/CIMRefundRequestTest.php b/tests/Message/CIMRefundRequestTest.php new file mode 100644 index 00000000..79c5cfe2 --- /dev/null +++ b/tests/Message/CIMRefundRequestTest.php @@ -0,0 +1,38 @@ +request = new CIMRefundRequest($this->getHttpClient(), $this->getHttpRequest()); + $this->request->initialize( + array( + 'transactionReference' => '{"approvalCode":"V7DO8Q","transId":"2220001612","cardReference":"{\"customerProfileId\":\"28972085\",\"customerPaymentProfileId\":\"26317841\",\"customerShippingAddressId\":\"27057151\"}"}', + 'amount' => 12.00, + 'description' => 'Test refund transaction' + ) + ); + } + + public function testGetData() + { + $data = $this->request->getData(); + + $this->assertEquals('12.00', $data->transaction->profileTransRefund->amount); + $this->assertEquals('28972085', $data->transaction->profileTransRefund->customerProfileId); + $this->assertEquals('26317841', $data->transaction->profileTransRefund->customerPaymentProfileId); + $this->assertEquals('27057151', $data->transaction->profileTransRefund->customerShippingAddressId); + $this->assertEquals( + 'Test refund transaction', + $data->transaction->profileTransRefund->order->description + ); + $this->assertEquals('2220001612', $data->transaction->profileTransRefund->transId); + } +} \ No newline at end of file diff --git a/tests/Message/CIMResponseTest.php b/tests/Message/CIMResponseTest.php new file mode 100644 index 00000000..bc587f95 --- /dev/null +++ b/tests/Message/CIMResponseTest.php @@ -0,0 +1,32 @@ +getMockRequest(), ''); + } + + public function testGetTransactionReference() + { + $httpResponse = $this->getMockHttpResponse('CIMAuthorizeSuccess.txt'); + $mockRequest = \Mockery::mock('\Omnipay\Common\Message\RequestInterface'); + $mockRequest->shouldReceive('getCardReference')->times(1)->andReturn( + '{"customerProfileId":"28972085","customerPaymentProfileId":"26317841","customerShippingAddressId":"27057151"}' + ); + $response = new CIMResponse($mockRequest, $httpResponse->getBody()); + + $this->assertEquals( + '{"approvalCode":"DMK100","transId":"2220001902","cardReference":"{\"customerProfileId\":\"28972085\",\"customerPaymentProfileId\":\"26317841\",\"customerShippingAddressId\":\"27057151\"}"}', + $response->getTransactionReference() + ); + } +} diff --git a/tests/Message/CIMUpdatePaymentProfileRequestTest.php b/tests/Message/CIMUpdatePaymentProfileRequestTest.php new file mode 100644 index 00000000..cff4d46c --- /dev/null +++ b/tests/Message/CIMUpdatePaymentProfileRequestTest.php @@ -0,0 +1,35 @@ +request = new CIMUpdatePaymentProfileRequest($this->getHttpClient(), $this->getHttpRequest()); + $this->request->initialize( + array( + 'customerProfileId' => '28775801', + 'customerPaymentProfileId' => '26455709', + 'email' => "kaylee@serenity.com", + 'card' => $this->getValidCard(), + 'developerMode' => true + ) + ); + } + + public function testGetData() + { + $data = $this->request->getData(); + + $card = $this->getValidCard(); + $this->assertEquals('28775801', $data->customerProfileId); + $this->assertEquals($card['number'], $data->paymentProfile->payment->creditCard->cardNumber); + $this->assertEquals('testMode', $data->validationMode); + } +} \ No newline at end of file diff --git a/tests/Message/CIMUpdatePaymentProfileResponseTest.php b/tests/Message/CIMUpdatePaymentProfileResponseTest.php new file mode 100644 index 00000000..0e08ddcf --- /dev/null +++ b/tests/Message/CIMUpdatePaymentProfileResponseTest.php @@ -0,0 +1,34 @@ +getMockRequest(), ''); + } + + public function testCreateCardSuccess() + { + $httpResponse = $this->getMockHttpResponse('CIMUpdatePaymentProfileSuccess.txt'); + $mockRequest = \Mockery::mock('\Omnipay\Common\Message\RequestInterface'); + $mockRequest->shouldReceive('getCustomerProfileId')->times(1)->andReturn('28775801'); + $mockRequest->shouldReceive('getCustomerPaymentProfileId')->times(1)->andReturn('26455709'); + $response = new CIMUpdatePaymentProfileResponse($mockRequest, $httpResponse->getBody()); + + $this->assertTrue($response->isSuccessful()); + $this->assertEquals('I00001', $response->getReasonCode()); + $this->assertEquals("1", $response->getResultCode()); + $this->assertEquals("Successful.", $response->getMessage()); + $this->assertEquals( + '{"customerProfileId":"28775801","customerPaymentProfileId":"26455709"}', + $response->getCardReference() + ); + } +} diff --git a/tests/Mock/CIMAuthorizeFailure.txt b/tests/Mock/CIMAuthorizeFailure.txt new file mode 100644 index 00000000..8ff4d2f0 --- /dev/null +++ b/tests/Mock/CIMAuthorizeFailure.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 832 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 04:15:22 GMT + +ErrorE00003The 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:amount' element is invalid - The value '-100.00' is invalid according to its datatype 'Decimal' - The MinInclusive constraint failed. diff --git a/tests/Mock/CIMAuthorizeSuccess.txt b/tests/Mock/CIMAuthorizeSuccess.txt new file mode 100644 index 00000000..5bd792a3 --- /dev/null +++ b/tests/Mock/CIMAuthorizeSuccess.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 832 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 04:15:22 GMT + +OkI00001Successful.1,1,1,This transaction has been approved.,DMK100,Y,2220001902,,,100.00,CC,auth_only,,Example,User,,123 Billing St Billsville,Billstown,CA,12345,US,,,kaylee346183@serenity.com,Example,User,,123 Shipping St Shipsville,Shipstown,NY,54321,US,,,,,,F667DD4AF086CA3C1588D77F088C2E1B,,2,,,,,,,,,,,XXXX1111,Visa,,,,,,,,,,,,,,,,,27057177 diff --git a/tests/Mock/CIMCaptureFailure.txt b/tests/Mock/CIMCaptureFailure.txt new file mode 100644 index 00000000..f15fbffe --- /dev/null +++ b/tests/Mock/CIMCaptureFailure.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 1027 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 04:15:23 GMT + +ErrorE00014Approval Code is required. diff --git a/tests/Mock/CIMCaptureSuccess.txt b/tests/Mock/CIMCaptureSuccess.txt new file mode 100644 index 00000000..713b7b81 --- /dev/null +++ b/tests/Mock/CIMCaptureSuccess.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 1027 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 04:15:23 GMT + +OkI00001Successful.1,1,1,This transaction has been approved.,DMK100,P,2220001903,,,100.00,CC,capture_only,,Example,User,,123 Billing St Billsville,Billstown,CA,12345,US,,,kaylee346183@serenity.com,Example,User,,123 Shipping St Shipsville,Shipstown,NY,54321,US,,,,,,28AF50C3CB7ED3D132E6BED4558CDE8F,,,,,,,,,,,,,XXXX1111,Visa,,,,,,,,,,,,,,,,,27057177 diff --git a/tests/Mock/CIMCreateCardFailure.txt b/tests/Mock/CIMCreateCardFailure.txt new file mode 100644 index 00000000..fe7bdc5a --- /dev/null +++ b/tests/Mock/CIMCreateCardFailure.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 746 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 03:59:27 GMT + +ErrorE00041One or more fields in the profile must contain a value. diff --git a/tests/Mock/CIMCreateCardFailureWithDuplicate.txt b/tests/Mock/CIMCreateCardFailureWithDuplicate.txt new file mode 100644 index 00000000..617eaaad --- /dev/null +++ b/tests/Mock/CIMCreateCardFailureWithDuplicate.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 746 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 03:59:27 GMT + +ErrorE00039A duplicate record with ID 28775801 already exists.1,1,1,(TESTMODE) This transaction has been approved.,000000,P,0,none,Test transaction for ValidateCustomerPaymentProfile.,1.00,CC,auth_only,,,,,,,,12345,,,,kaylee@serenity.com,,,,,,,,,0.00,0.00,0.00,FALSE,none,9ACE39F249AB996589D58E6FCCCFFFA3,,,,,,,,,,,,,XXXX8888,Visa,,,,,,,,,,,,,,,, diff --git a/tests/Mock/CIMCreateCardSuccess.txt b/tests/Mock/CIMCreateCardSuccess.txt new file mode 100644 index 00000000..97e06ed2 --- /dev/null +++ b/tests/Mock/CIMCreateCardSuccess.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 746 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 03:59:27 GMT + +OkI00001Successful.2897208426317840270571491,1,1,(TESTMODE) This transaction has been approved.,000000,P,0,none,Test transaction for ValidateCustomerPaymentProfile.,1.00,CC,auth_only,,Example,User,,123 Billing St Billsville,Billstown,CA,12345,US,,,kaylee427330@serenity.com,,,,,,,,,0.00,0.00,0.00,FALSE,none,9ACE39F249AB996589D58E6FCCCFFFA3,,,,,,,,,,,,,XXXX1111,Visa,,,,,,,,,,,,,,,, diff --git a/tests/Mock/CIMCreatePaymentProfileFailure.txt b/tests/Mock/CIMCreatePaymentProfileFailure.txt new file mode 100644 index 00000000..c7791c3c --- /dev/null +++ b/tests/Mock/CIMCreatePaymentProfileFailure.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 746 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 03:59:27 GMT + +ErrorE00039A duplicate customer payment profile already exists.1,1,1,(TESTMODE) This transaction has been approved.,000000,P,0,none,Test transaction for ValidateCustomerPaymentProfile.,1.00,CC,auth_only,none,,,,,,,12345,,,,email@example.com,,,,,,,,,0.00,0.00,0.00,FALSE,none,9ACE39F249AB996589D58E6FCCCFFFA3,,,,,,,,,,,,,XXXX8888,Visa,,,,,,,,,,,,,,,, diff --git a/tests/Mock/CIMCreatePaymentProfileSuccess.txt b/tests/Mock/CIMCreatePaymentProfileSuccess.txt new file mode 100644 index 00000000..40bdb247 --- /dev/null +++ b/tests/Mock/CIMCreatePaymentProfileSuccess.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 746 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 03:59:27 GMT + +OkI00001Successful.264557091,1,1,(TESTMODE) This transaction has been approved.,000000,P,0,none,Test transaction for ValidateCustomerPaymentProfile.,1.00,CC,auth_only,none,,,,,,,12345,,,,email@example.com,,,,,,,,,0.00,0.00,0.00,FALSE,none,9ACE39F249AB996589D58E6FCCCFFFA3,,,,,,,,,,,,,XXXX8888,Visa,,,,,,,,,,,,,,,, diff --git a/tests/Mock/CIMGetPaymentProfileSuccess.txt b/tests/Mock/CIMGetPaymentProfileSuccess.txt new file mode 100644 index 00000000..9c4c6782 --- /dev/null +++ b/tests/Mock/CIMGetPaymentProfileSuccess.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 746 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 03:59:27 GMT4 + +OkI00001Successful.
1234526485433XXXX8888XXXX diff --git a/tests/Mock/CIMGetProfileSuccess.txt b/tests/Mock/CIMGetProfileSuccess.txt new file mode 100644 index 00000000..0c7f5fbe --- /dev/null +++ b/tests/Mock/CIMGetProfileSuccess.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 746 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 03:59:27 GMT + +OkI00001Successful.kaylee@serenity.com28775801
1234526455656XXXX1111XXXX
1234526455709XXXX8888XXXX diff --git a/tests/Mock/CIMPurchaseFailure.txt b/tests/Mock/CIMPurchaseFailure.txt new file mode 100644 index 00000000..922df3b2 --- /dev/null +++ b/tests/Mock/CIMPurchaseFailure.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 746 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 04:15:24 GMT + +ErrorE00027This transaction has been declined.2,1,2,This transaction has been declined.,,Y,2220009663,,,110.00,CC,auth_capture,,Example,User,,123 Billing St Billsville,Billstown,CA,46282,US,,,kaylee729813@serenity.com,Example,User,,123 Shipping St Shipsville,Shipstown,NY,54321,US,,,,,,CE96C60797B394AF0BFFD6FEBEDE7C2A,,2,,,,,,,,,,,XXXX1111,Visa,,,,,,,,,,,,,,,,,27058978 diff --git a/tests/Mock/CIMPurchaseSuccess.txt b/tests/Mock/CIMPurchaseSuccess.txt new file mode 100644 index 00000000..61eb0ba3 --- /dev/null +++ b/tests/Mock/CIMPurchaseSuccess.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 746 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 04:15:24 GMT + +OkI00001Successful.1,1,1,This transaction has been approved.,MNLXJQ,Y,2220001904,,,110.00,CC,auth_capture,,Example,User,,123 Billing St Billsville,Billstown,CA,12345,US,,,kaylee346183@serenity.com,Example,User,,123 Shipping St Shipsville,Shipstown,NY,54321,US,,,,,,FE4AE98F3E5BD3AA01280DF8DC1EB640,,2,,,,,,,,,,,XXXX1111,Visa,,,,,,,,,,,,,,,,,27057177 diff --git a/tests/Mock/CIMRefundFailure.txt b/tests/Mock/CIMRefundFailure.txt new file mode 100644 index 00000000..b33fd61f --- /dev/null +++ b/tests/Mock/CIMRefundFailure.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 832 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 04:15:24 GMT + +ErrorE00027The referenced transaction does not meet the criteria for issuing a credit.3,2,54,The referenced transaction does not meet the criteria for issuing a credit.,,P,0,,,110.00,CC,credit,,Example,User,,123 Billing St Billsville,Billstown,CA,12345,US,,,kaylee346183@serenity.com,Example,User,,123 Shipping St Shipsville,Shipstown,NY,54321,US,,,,,,C42AF83A6FF4CF347A06BFF79715849D,,,,,,,,,,,,,XXXX1111,Visa,,,,,,,,,,,,,,,,,27057177 diff --git a/tests/Mock/CIMUpdatePaymentProfileSuccess.txt b/tests/Mock/CIMUpdatePaymentProfileSuccess.txt new file mode 100644 index 00000000..bb760503 --- /dev/null +++ b/tests/Mock/CIMUpdatePaymentProfileSuccess.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Cache-Control: private +Content-Length: 746 +Content-Type: text/xml; +charset=utf-8 +Server: Microsoft-IIS/7.5 +X-AspNet-Version: 2.0.50727 +X-Powered-By: ASP.NET +Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET,POST,OPTIONS +Date: Thu, 18 Sep 2014 03:59:27 GMT + +OkI00001Successful.1,1,1,(TESTMODE) This transaction has been approved.,000000,P,0,none,Test transaction for ValidateCustomerPaymentProfile.,1.00,CC,auth_only,,,,,,,,12345,,,,kaylee@serenity.com,,,,,,,,,0.00,0.00,0.00,FALSE,none,9ACE39F249AB996589D58E6FCCCFFFA3,,,,,,,,,,,,,XXXX8888,Visa,,,,,,,,,,,,,,,,