diff --git a/README.md b/README.md index e9882d3..d27b49a 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,8 @@ And run composer to update your dependencies: The following gateways are provided by this package: -* MultiSafepay +* MultiSafepay_Rest +* MultiSafepay_Xml (Deprecated) For general usage instructions, please see the main [Omnipay](https://github.com/thephpleague/omnipay) repository. diff --git a/src/Gateway.php b/src/Gateway.php index 8ef958b..75373a3 100644 --- a/src/Gateway.php +++ b/src/Gateway.php @@ -1,157 +1,19 @@ - '', - 'locale' => 'en', - 'testMode' => false, - ); - } - - /** - * Get the locale. - * - * Optional ISO 639-1 language code which is used to specify a - * a language used to display gateway information and other - * messages in the responses. - * - * The default language is English. - * - * @return string - */ - public function getLocale() - { - return $this->getParameter('locale'); - } - - /** - * Set the locale. - * - * Optional ISO 639-1 language code which is used to specify a - * a language used to display gateway information and other - * messages in the responses. - * - * The default language is English. - * - * @param $value - * @return \Omnipay\Common\Message\AbstractRequest - */ - public function setLocale($value) - { - return $this->setParameter('locale', $value); - } - - /** - * Get the gateway API Key - * - * Authentication is by means of a single secret API key set as - * the apiKey parameter when creating the gateway object. - * - * @return string - */ - public function getApiKey() - { - return $this->getParameter('apiKey'); - } - - /** - * Set the gateway API Key - * - * Authentication is by means of a single secret API key set as - * the apiKey parameter when creating the gateway object. - * - * @param string $value - * @return Gateway provides a fluent interface. - */ - public function setApiKey($value) - { - return $this->setParameter('apiKey', $value); - } - - /** - * Retrieve payment methods active on the given MultiSafepay - * account. - * - * @param array $parameters - * - * @return \Omnipay\MultiSafepay\Message\FetchPaymentMethodsRequest - */ - public function fetchPaymentMethods(array $parameters = array()) - { - return $this->createRequest('Omnipay\MultiSafepay\Message\FetchPaymentMethodsRequest', $parameters); - } - - /** - * Retrieve issuers for gateway. - * - * @param array $parameters - * - * @return \Omnipay\MultiSafepay\Message\FetchIssuersRequest - */ - public function fetchIssuers(array $parameters = array()) - { - return $this->createRequest('Omnipay\MultiSafepay\Message\FetchIssuersRequest', $parameters); - } - - /** - * Retrieve transaction by the given identifier. - * - * @param array $parameters - * @return \Omnipay\Common\Message\AbstractRequest - */ - public function fetchTransaction(array $parameters = array()) - { - return $this->createRequest('Omnipay\MultiSafepay\Message\FetchTransactionRequest', $parameters); - } - - /** - * Create a refund. - * - * @param array $parameters - * @return \Omnipay\Common\Message\AbstractRequest - */ - public function refund(array $parameters = array()) - { - return $this->createRequest('Omnipay\MultiSafepay\Message\RefundRequest', $parameters); - } - - /** - * @param array $parameters - * - * @return \Omnipay\MultiSafepay\Message\PurchaseRequest - */ - public function purchase(array $parameters = array()) - { - return $this->createRequest('Omnipay\MultiSafepay\Message\PurchaseRequest', $parameters); - } - /** - * @param array $parameters - * - * @return \Omnipay\MultiSafepay\Message\CompletePurchaseRequest - */ - public function completePurchase(array $parameters = array()) - { - return $this->createRequest('Omnipay\MultiSafepay\Message\CompletePurchaseRequest', $parameters); - } } diff --git a/src/Message/AbstractRequest.php b/src/Message/AbstractRequest.php index 30ca42a..bc12a6f 100644 --- a/src/Message/AbstractRequest.php +++ b/src/Message/AbstractRequest.php @@ -1,9 +1,29 @@ -getParameter('locale'); + return $this->getParameter('accountId'); } /** - * Set the locale. - * - * Optional ISO 639-1 language code which is used to specify a - * a language used to display gateway information and other - * messages in the responses. - * - * The default language is English. + * Set the account identifier. * * @param $value - * @return \Omnipay\Common\Message\AbstractRequest + * @return BaseAbstractRequest */ - public function setLocale($value) + public function setAccountId($value) { - return $this->setParameter('locale', $value); + return $this->setParameter('accountId', $value); } /** - * Get the gateway API Key + * Get the site identifier. * - * Authentication is by means of a single secret API key set as - * the apiKey parameter when creating the gateway object. + * @return mixed + */ + public function getSiteId() + { + return $this->getParameter('siteId'); + } + + /** + * Set the site identifier. * - * @return string + * @param $value + * @return BaseAbstractRequest */ - public function getApiKey() + public function setSiteId($value) { - return $this->getParameter('apiKey'); + return $this->setParameter('siteId', $value); } /** - * Set the gateway API Key + * Get the site code. * - * Authentication is by means of a single secret API key set as - * the apiKey parameter when creating the gateway object. + * @return mixed + */ + public function getSiteCode() + { + return $this->getParameter('siteCode'); + } + + /** + * Set the site code. * * @param $value - * @return \Omnipay\Common\Message\AbstractRequest + * @return BaseAbstractRequest */ - public function setApiKey($value) + public function setSiteCode($value) { - return $this->setParameter('apiKey', $value); + return $this->setParameter('siteCode', $value); } /** - * Get endpoint. + * Get the API endpoint. * * @return string */ @@ -97,48 +120,14 @@ public function getEndpoint() } /** - * {@inheritdoc} - */ - public function getData() - { - $this->validate('apiKey'); - } - - /** - * @param $method - * @param $endpoint - * @param null $query - * @param null $data - * @return \Guzzle\Http\Message\Response + * Get headers. + * + * @return array */ - protected function sendRequest($method, $endpoint, $query = null, $data = null) + protected function getHeaders() { - $this->httpClient->getEventDispatcher()->addListener('request.error', function (Event $event) { - /** - * @var \Guzzle\Http\Message\Response $response - */ - $response = $event['response']; - if ($response->isError()) { - $event->stopPropagation(); - } - }); - - $httpRequest = $this->httpClient->createRequest( - $method, - $this->getEndpoint() . $endpoint, - array( - 'api_key' => $this->getApiKey(), - ), - $data + return array( + 'User-Agent' => $this->userAgent, ); - - // Add query parameters - if (is_array($query) && ! empty($query)) { - foreach ($query as $itemKey => $itemValue) { - $httpRequest->getQuery()->add($itemKey, $itemValue); - } - } - - return $httpRequest->send(); } } diff --git a/src/Message/AbstractResponse.php b/src/Message/AbstractResponse.php index 62412ae..bcbfc6a 100644 --- a/src/Message/AbstractResponse.php +++ b/src/Message/AbstractResponse.php @@ -1,66 +1,41 @@ -data['success'])) { - return false; - } +namespace Omnipay\MultiSafepay\Message; - return $this->data['success']; - } +use Omnipay\Common\Message\AbstractResponse as BaseAbstractResponse; +/** + * MultiSafepay Abstract XML Api Response. + * + * @deprecated This API is deprecated and will be removed in + * an upcoming version of this package. Please switch to the Rest API. + */ +abstract class AbstractResponse extends BaseAbstractResponse +{ /** - * Response Message - * - * @return null|string A response message from the payment gateway + * {@inheritdoc} */ public function getMessage() { - if (!$this->isSuccessful() && isset($this->data['error_info'])) { - return $this->data['error_info']; + if (isset($this->data->error)) { + return (string) $this->data->error->description; } - } - /** - * Response code - * - * @return null|string A response code from the payment gateway - */ - public function getCode() - { - if (! $this->isSuccessful() && isset($this->data['error_code'])) { - return $this->data['error_code']; - } + return null; } /** - * Gateway Reference - * - * @return null|string A reference provided by the gateway to represent this transaction + * {@inheritdoc} */ - public function getTransactionReference() + public function getCode() { - if (isset($this->data['data']['transaction_id'])) { - return $this->data['data']['transaction_id']; + if (isset($this->data->error)) { + return (string) $this->data->error->code; } - } - /** - * Get the transaction ID as generated by the merchant website. - * - * @return string - */ - public function getTransactionId() - { - if (isset($this->data['data']['order_id'])) { - return $this->data['data']['order_id']; - } + return null; } } diff --git a/src/Message/CompletePurchaseRequest.php b/src/Message/CompletePurchaseRequest.php index c3953a5..ed35964 100644 --- a/src/Message/CompletePurchaseRequest.php +++ b/src/Message/CompletePurchaseRequest.php @@ -1,6 +1,19 @@ -validate('transactionId'); - $transactionId = $this->getTransactionId(); + $data = new SimpleXMLElement(''); + $data->addAttribute('ua', $this->userAgent); + + $merchant = $data->addChild('merchant'); + $merchant->addChild('account', $this->getAccountId()); + $merchant->addChild('site_id', $this->getSiteId()); + $merchant->addChild('site_secure_code', $this->getSiteCode()); - return compact('transactionId'); + $transaction = $data->addChild('transaction'); + $transaction->addChild('id', $this->getTransactionId()); + + return $data; } /** @@ -19,14 +41,15 @@ public function getData() */ public function sendData($data) { - $httpResponse = $this->sendRequest( - 'get', - '/orders/' . $data['transactionId'] - ); + $httpResponse = $this->httpClient->post( + $this->getEndpoint(), + $this->getHeaders(), + $data->asXML() + )->send(); $this->response = new CompletePurchaseResponse( $this, - $httpResponse->json() + $httpResponse->xml() ); return $this->response; diff --git a/src/Message/CompletePurchaseResponse.php b/src/Message/CompletePurchaseResponse.php index b7c0f62..daf23e1 100644 --- a/src/Message/CompletePurchaseResponse.php +++ b/src/Message/CompletePurchaseResponse.php @@ -1,12 +1,106 @@ -getPaymentStatus() == 'completed'; + return $this->getPaymentStatus() === 'completed'; + } + + /** + * {@inheritdoc} + */ + public function getTransactionReference() + { + if (isset($this->data->transaction->id)) { + return (string) $this->data->transaction->id; + } + } + + /** + * Is the payment created, but uncompleted? + * + * @return boolean + */ + public function isInitialized() + { + return $this->getPaymentStatus() === 'initialized'; + } + + /** + * Is the payment created, but not yet exempted (credit cards)? + * + * @return boolean + */ + public function isUncleared() + { + return $this->getPaymentStatus() === 'uncleared'; + + } + + /** + * Is the payment canceled? + * + * @return boolean + */ + public function isCanceled() + { + return $this->getPaymentStatus() === 'canceled'; + } + + /** + * Is the payment rejected? + * + * @return boolean + */ + public function isRejected() + { + return $this->getPaymentStatus() === 'declined'; + } + + /** + * Is the payment refunded? + * + * @return boolean + */ + public function isRefunded() + { + return $this->getPaymentStatus() === 'refunded'; + } + + /** + * Is the payment expired? + * + * @return boolean + */ + public function isExpired() + { + return $this->getPaymentStatus() === 'expired'; + } + + /** + * Get raw payment status. + * + * @return null|string + */ + public function getPaymentStatus() + { + if (isset($this->data->ewallet->status)) { + return (string)$this->data->ewallet->status; + } } } diff --git a/src/Message/FetchIssuersRequest.php b/src/Message/FetchIssuersRequest.php index 62f3987..fd920c5 100644 --- a/src/Message/FetchIssuersRequest.php +++ b/src/Message/FetchIssuersRequest.php @@ -1,5 +1,18 @@ -'); + $data->addAttribute('ua', $this->userAgent); - $this->validate('paymentMethod'); + $merchant = $data->addChild('merchant'); + $merchant->addChild('account', $this->getAccountId()); + $merchant->addChild('site_id', $this->getSiteId()); + $merchant->addChild('site_secure_code', $this->getSiteCode()); - $paymentMethod = $this->getPaymentMethod(); - - return compact('paymentMethod'); + return $data; } /** @@ -21,14 +36,15 @@ public function getData() */ public function sendData($data) { - $httpResponse = $this->sendRequest( - 'GET', - '/issuers/' . $data['paymentMethod'] - ); + $httpResponse = $this->httpClient->post( + $this->getEndpoint(), + $this->getHeaders(), + $data->asXML() + )->send(); $this->response = new FetchIssuersResponse( $this, - $httpResponse->json() + $httpResponse->xml() ); return $this->response; diff --git a/src/Message/FetchIssuersResponse.php b/src/Message/FetchIssuersResponse.php index 1264249..6298b41 100644 --- a/src/Message/FetchIssuersResponse.php +++ b/src/Message/FetchIssuersResponse.php @@ -1,26 +1,39 @@ -data->issuers); + } + /** * Return available issuers as an associative array. * - * @return \Omnipay\Common\Issuer[] + * @return array */ public function getIssuers() { - $issuers = array(); + $result = array(); - foreach ($this->data['data'] as $issuer) { - $issuers[] = new Issuer( - $issuer['code'], - $issuer['description'] - ); + foreach ($this->data->issuers->issuer as $issuer) { + $result[(string) $issuer->code] = (string) $issuer->description; } - return $issuers; + return $result; } } diff --git a/src/Message/FetchPaymentMethodsRequest.php b/src/Message/FetchPaymentMethodsRequest.php index b3e546d..f21868a 100644 --- a/src/Message/FetchPaymentMethodsRequest.php +++ b/src/Message/FetchPaymentMethodsRequest.php @@ -1,9 +1,23 @@ -'); + $data->addAttribute('ua', $this->userAgent); - $data = array( - 'amount' => $this->getAmountInteger(), - 'country' => $this->getCountry(), - 'currency' => $this->getCurrency(), - ); + $merchant = $data->addChild('merchant'); + $merchant->addChild('account', $this->getAccountId()); + $merchant->addChild('site_id', $this->getSiteId()); + $merchant->addChild('site_secure_code', $this->getSiteCode()); + + $customer = $data->addChild('customer'); + $customer->addChild('country', $this->getCountry()); - return array_filter($data); + return $data; } /** @@ -40,11 +59,15 @@ public function getData() */ public function sendData($data) { - $httpResponse = $this->sendRequest('GET', '/gateways', $data); + $httpResponse = $this->httpClient->post( + $this->getEndpoint(), + $this->getHeaders(), + $data->asXML() + )->send(); $this->response = new FetchPaymentMethodsResponse( $this, - $httpResponse->json() + $httpResponse->xml() ); return $this->response; diff --git a/src/Message/FetchPaymentMethodsResponse.php b/src/Message/FetchPaymentMethodsResponse.php index 0f54110..503404a 100644 --- a/src/Message/FetchPaymentMethodsResponse.php +++ b/src/Message/FetchPaymentMethodsResponse.php @@ -1,28 +1,39 @@ -data->gateways); + } + + /** + * Return available payment methods as an associative array. * - * @return \Omnipay\Common\PaymentMethod[] + * @return array */ public function getPaymentMethods() { - $paymentMethods = array(); + $result = array(); - foreach ($this->data['data'] as $method) { - $paymentMethods[] = new PaymentMethod( - $method['id'], - $method['description'] - ); + foreach ($this->data->gateways->gateway as $gateway) { + $result[(string) $gateway->id] = (string) $gateway->description; } - return $paymentMethods; + return $result; } } diff --git a/src/Message/FetchTransactionRequest.php b/src/Message/FetchTransactionRequest.php deleted file mode 100644 index 144a730..0000000 --- a/src/Message/FetchTransactionRequest.php +++ /dev/null @@ -1,36 +0,0 @@ -validate('transactionId'); - - $transactionId = $this->getTransactionId(); - - return compact('transactionId'); - } - - /** - * {@inheritDoc} - */ - public function sendData($data) - { - $httpResponse = $this->sendRequest( - 'get', - '/orders/' . $data['transactionId'] - ); - - $this->response = new FetchTransactionResponse( - $this, - $httpResponse->json() - ); - - return $this->response; - } -} diff --git a/src/Message/PurchaseRequest.php b/src/Message/PurchaseRequest.php index b3a9aa1..7a31d6b 100644 --- a/src/Message/PurchaseRequest.php +++ b/src/Message/PurchaseRequest.php @@ -1,70 +1,45 @@ getParameter('type'); - } - - /** - * Set payment type. - * - * Specifies the payment flow for the checkout process. - * Possible values are 'redirect', 'direct' - * - * @param $value - * @return \Omnipay\Common\Message\AbstractRequest - */ - public function setType($value) - { - return $this->setParameter('type', $value); - } - - /** - * Get recurring Payment Id - * - * A previously stored identifier referring to a - * payment method to be charged again. - * - * @return int|null + * @return mixed */ - public function getRecurringId() + public function getLanguage() { - return $this->getParameter('recurring_id'); + return $this->getParameter('language'); } /** - * Set recurring Payment Id - * - * A previously stored identifier referring to a - * payment method to be charged again. + * Set the language. * * @param $value * @return \Omnipay\Common\Message\AbstractRequest */ - public function setRecurringId($value) + public function setLanguage($value) { - return $this->setParameter('recurring_id', $value); + return $this->setParameter('language', $value); } /** * Get the gateway. * - * The unique gateway id to immediately direct the customer to the payment method. - * You retrieve these gateways using a gateway request. - * * @return mixed */ public function getGateway() @@ -75,9 +50,6 @@ public function getGateway() /** * Set the gateway. * - * The unique gateway id to immediately direct the customer to the payment method. - * You retrieve these gateways using a gateway request. - * * @param $value * @return \Omnipay\Common\Message\AbstractRequest */ @@ -87,375 +59,232 @@ public function setGateway($value) } /** - * Get value of var1. - * - * A free variable for custom data to be stored and persisted. - * - * @return string|null - */ - public function getVar1() - { - return $this->getParameter('var1'); - } - - /** - * Set var1. - * - * A free optional variable for custom data to be stored and persisted. + * Get Issuer. * - * @param $value - * @return \Omnipay\Common\Message\AbstractRequest - */ - public function setVar1($value) - { - return $this->setParameter('var1', $value); - } - - /** - * Get var2. - * - * A free variable for custom data to be stored and persisted. - * - * @return string|null - */ - public function getVar2() - { - return $this->getParameter('var2'); - } - - /** - * Set var2. - * - * A free variable for custom data to be stored and persisted. - * - * @param $value - * @return \Omnipay\Common\Message\AbstractRequest - */ - public function setVar2($value) - { - return $this->setParameter('var2', $value); - } - - /** - * Get var3. - * - * A free variable for custom data to be stored and persisted. - * - * @return string|null + * @return mixed */ - public function getVar3() + public function getIssuer() { - return $this->getParameter('var3'); + return $this->getParameter('issuer'); } /** - * Set var3. + * Set issuer. * - * A free variable for custom data to be stored and persisted. - * - * @param $value + * @param string $value * @return \Omnipay\Common\Message\AbstractRequest */ - public function setVar3($value) + public function setIssuer($value) { - return $this->setParameter('var3', $value); + return $this->setParameter('issuer', $value); } /** - * Get manual. + * Get the Google analytics code. * - * If true this forces a credit card transaction to require manual - * acceptance regardless of the outcome from fraud checks. - * It is possible that a high risk transaction is still declined. - * - * @return boolean|null + * @return mixed */ - public function getManual() + public function getGoogleAnalyticsCode() { - return $this->getParameter('manual'); + return $this->getParameter('googleAnalyticsCode'); } /** - * Set manual. - * - * If true this forces a credit card transaction to require manual - * acceptance regardless of the outcome from fraud checks. - * It is possible that a high risk transaction is still declined. + * Set the Google analytics code. * * @param $value * @return \Omnipay\Common\Message\AbstractRequest */ - public function setManual($value) + public function setGoogleAnalyticsCode($value) { - return $this->setParameter('manual', $value); + return $this->setParameter('googleAnalyticsCode', $value); } /** - * Get days active. + * Get the value of "extradata1" * - * The number of days the payment link will be active for. - * When not specified the default will be 30 days. - * - * @return int|null + * @return mixed */ - public function getDaysActive() + public function getExtraData1() { - return $this->getParameter('days_active'); + return $this->getParameter('extraData1'); } /** - * Set days active. - * - * The number of days the payment link will be active for. - * When not specified the default will be 30 days. + * Set the value of "extradata1" * * @param $value * @return \Omnipay\Common\Message\AbstractRequest */ - public function setDaysActive($value) + public function setExtraData1($value) { - return $this->setParameter('days_active', $value); + return $this->setParameter('extraData1', $value); } /** - * Get close window. - * - * Set to true if you will display the MultiSafepay payment - * page in a new window and want it to close automatically - * after the payment process has been completed. + * Get the value of "extradata2" * - * @return boolean|null + * @return mixed */ - public function getCloseWindow() + public function getExtraData2() { - return $this->getParameter('close_window'); + return $this->getParameter('extraData2'); } /** - * Set close window. - * - * Set to true if you will display the MultiSafepay payment - * page in a new window and want it to close automatically - * after the payment process has been completed. + * Set the value of "extraData2 * * @param $value * @return \Omnipay\Common\Message\AbstractRequest */ - public function setCloseWindow($value) + public function setExtraData2($value) { - return $this->setParameter('close_window', $value); + return $this->setParameter('extraData2', $value); } /** - * Send mail. + * Get the value of "extraData3" * - * True if you will send your own bank transfer payment instructions to - * consumers and do not want MultiSafepay to do this. - * - * @return boolean + * @return mixed */ - public function getSendMail() + public function getExtraData3() { - return $this->getParameter('disable_send_mail'); + return $this->getParameter('extraData3'); } /** - * Send mail. - * - * True if you will send your own bank transfer payment instructions to - * consumers and do not want MultiSafepay to do this. + * Set the value of "extraData3" * * @param $value * @return \Omnipay\Common\Message\AbstractRequest */ - public function setSendMail($value) + public function setExtraData3($value) { - return $this->setParameter('disable_send_mail', $value); + return $this->setParameter('extraData3', $value); } /** - * Google analytics code. - * - * Your Google Analytics Site Id. - * This will be injected into the payment pages - * so you can trigger custom events and track payment metrics. + * Get the items. * - * @return string|null + * @return mixed */ - public function getGoogleAnalyticsCode() + public function getItems() { - return $this->getParameter('google_analytics'); + return $this->getParameter('items'); } /** - * Google analytics code. + * Set the items. * - * Your Google Analytics Site Id. - * This will be injected into the payment pages - * so you can trigger custom events and track payment metrics. - * - * @param $value + * @param array|\Omnipay\Common\ItemBag $value * @return \Omnipay\Common\Message\AbstractRequest */ - public function setGoogleAnalyticsCode($value) + public function setItems($value) { - return $this->setParameter('google_analytics', $value); + return $this->setParameter('items', $value); } /** - * Get the payment options. - * - * @return array + * {@inheritdoc} */ - protected function getPaymentData() + public function getData() { - $data = array( - 'cancel_url' => $this->getCancelUrl(), - 'close_window' => $this->getCloseWindow(), - 'notify_url' => $this->getNotifyUrl(), - 'return_url' => $this->getReturnUrl(), - ); + $this->validate('transactionId', 'amount', 'currency', 'description', 'clientIp', 'card'); - return array_filter($data); - } + if ('IDEAL' === $this->getGateway() && $this->getIssuer()) { + $data = new SimpleXMLElement(''); + } else { + $data = new SimpleXMLElement(''); + } - /** - * Customer information. - * - * This function returns all the provided - * client related parameters. - * - * @return array - */ - public function getCustomerData() - { - $data = array( - 'disable_send_mail' => $this->getSendMail(), - 'locale' => $this->getLocale(), - ); + $data->addAttribute('ua', $this->userAgent); + + $merchant = $data->addChild('merchant'); + $merchant->addChild('account', $this->getAccountId()); + $merchant->addChild('site_id', $this->getSiteId()); + $merchant->addChild('site_secure_code', $this->getSiteCode()); + $merchant->addChild('notification_url', htmlspecialchars($this->getNotifyUrl())); + $merchant->addChild('cancel_url', htmlspecialchars($this->getCancelUrl())); + $merchant->addChild('redirect_url', htmlspecialchars($this->getReturnUrl())); + + /** @var CreditCard $card */ + $card = $this->getCard(); + $customer = $data->addChild('customer'); + $customer->addChild('ipaddress', $this->getClientIp()); + $customer->addChild('locale', $this->getLanguage()); + $customer->addChild('email', $card->getEmail()); + $customer->addChild('firstname', $card->getFirstName()); + $customer->addChild('lastname', $card->getLastName()); + $customer->addChild('address1', $card->getAddress1()); + $customer->addChild('address2', $card->getAddress2()); + $customer->addChild('zipcode', $card->getPostcode()); + $customer->addChild('city', $card->getCity()); + $customer->addChild('country', $card->getCountry()); + $customer->addChild('phone', $card->getPhone()); + + $data->addChild('google_analytics', $this->getGoogleAnalyticsCode()); + + $transaction = $data->addChild('transaction'); + $transaction->addChild('id', $this->getTransactionId()); + $transaction->addChild('currency', $this->getCurrency()); + $transaction->addChild('amount', $this->getAmountInteger()); + $transaction->addChild('description', $this->getDescription()); + $transaction->addChild('var1', $this->getExtraData1()); + $transaction->addChild('var2', $this->getExtraData2()); + $transaction->addChild('var3', $this->getExtraData3()); + $transaction->addChild('gateway', $this->getGateway()); + + if ($items = $this->getItems()) { + $itemsHtml = '
    '; + foreach ($items as $item) { + $itemsHtml .= "
  • {$item['quantity']} x {$item['name']}
  • "; + } + $itemsHtml .= '
'; + $transaction->addChild('items', htmlspecialchars($itemsHtml)); + } - if (is_null($this->getCard())) { - return array_filter($data); + if ('IDEAL' === $this->getGateway() && $this->getIssuer()) { + $gatewayInfo = $data->addChild('gatewayinfo'); + $gatewayInfo->addChild('issuerid', $this->getIssuer()); } - $cardData = array( - 'address_1' => $this->getCard()->getAddress1(), - 'address_2' => $this->getCard()->getAddress2(), - 'city' => $this->getCard()->getCity(), - 'country' => $this->getCard()->getCountry(), - 'email' => $this->getCard()->getEmail(), - 'first_name' => $this->getCard()->getFirstName(), - 'house_number' => $this->getCard()->getNumber(), - 'last_name' => $this->getCard()->getLastName(), - 'phone' => $this->getCard()->getPhone(), - 'state' => $this->getCard()->getState(), - 'zip_code' => $this->getCard()->getPostcode(), - ); + $data->addChild('signature', $this->generateSignature()); - return array_filter( - array_merge($data, $cardData) - ); + return $data; } /** - * Get gateway data. - * - * @return array + * {@inheritdoc} */ - protected function getGatewayData() - { - $data = array( - 'issuer_id' => $this->getIssuer(), - ); - - return array_filter($data); - } - - /** - * Get the raw data array for this message. The format of this varies from gateway to - * gateway, but will usually be either an associative array, or a SimpleXMLElement. - * - * @return mixed - */ - public function getData() + public function sendData($data) { - parent::getData(); - - $this->validate( - 'amount', - 'currency', - 'description', - 'transactionId', - 'type' - ); - - // Direct order. - if ($this->getType() === 'direct') { - $this->validate('gateway'); - } + $httpResponse = $this->httpClient->post( + $this->getEndpoint(), + $this->getHeaders(), + $data->asXML() + )->send(); - // When the gateway is set to IDEAL, - // the issuer parameter is required. - if ( - $this->getType() == 'direct' && - $this->getGateway() == 'IDEAL' - ) { - $this->validate('issuer'); - } - - $data = array( - 'amount' => $this->getAmountInteger(), - 'currency' => $this->getCurrency(), - 'days_active' => $this->getDaysActive(), - 'description' => $this->getDescription(), - 'gateway' => $this->getGateway(), - 'google_analytics' => $this->getGoogleAnalyticsCode(), - 'items' => $this->getItems(), - 'manual' => $this->getManual(), - 'order_id' => $this->getTransactionId(), - 'recurring_id' => $this->getRecurringId(), - 'type' => $this->getType(), - 'var1' => $this->getVar1(), - 'var2' => $this->getVar2(), - 'var3' => $this->getVar3(), + $this->response = new PurchaseResponse( + $this, + $httpResponse->xml() ); - $paymentData = $this->getPaymentData(); - - if (! empty($paymentData)) { - $data['payment_options'] = $paymentData; - } - - $customerData = $this->getCustomerData(); - - if (! empty($customerData)) { - $data['customer'] = $customerData; - } - - $gatewayData = $this->getGatewayData(); - - if (! empty($gatewayData)) { - $data['gateway_info'] = $gatewayData; - } - - return array_filter($data); + return $this->response; } /** - * Send the request with specified data + * Generate signature. * - * @param mixed $data The data to send - * @return ResponseInterface + * @return string */ - public function sendData($data) + protected function generateSignature() { - $httpResponse = $this->sendRequest('POST', '/orders', null, $data); - - $this->response = new PurchaseResponse( - $this, - $httpResponse->json() + return md5( + $this->getAmountInteger(). + $this->getCurrency(). + $this->getAccountId(). + $this->getSiteId(). + $this->getTransactionId() ); - - return $this->response; } } diff --git a/src/Message/PurchaseResponse.php b/src/Message/PurchaseResponse.php index 144aa6a..97ab453 100644 --- a/src/Message/PurchaseResponse.php +++ b/src/Message/PurchaseResponse.php @@ -1,15 +1,50 @@ -data->transaction->id)) { + return (string)$this->data->transaction->id; + } + } + + /** + * {@inheritdoc} + */ + public function isSuccessful() + { + return false; + } + /** * {@inheritdoc} */ public function isRedirect() { - return isset($this->data['data']['payment_url']); + if (isset($this->data->transaction->payment_url) || + isset($this->data->gatewayinfo->redirecturl) + ) { + return true; + } + + return false; } /** @@ -17,11 +52,15 @@ public function isRedirect() */ public function getRedirectUrl() { - if (! $this->isRedirect()) { - return null; + if (isset($this->data->gatewayinfo->redirecturl)) { + return (string)$this->data->gatewayinfo->redirecturl; + } + + if (isset($this->data->transaction->payment_url)) { + return (string) $this->data->transaction->payment_url; } - return $this->data['data']['payment_url']; + return null; } /** diff --git a/src/Message/RefundRequest.php b/src/Message/RefundRequest.php deleted file mode 100644 index 2c02ab5..0000000 --- a/src/Message/RefundRequest.php +++ /dev/null @@ -1,40 +0,0 @@ -validate('amount', 'currency', 'description', 'transactionId'); - - return array( - 'amount' => $this->getAmountInteger(), - 'currency' => $this->getCurrency(), - 'description' => $this->getDescription(), - 'id' => $this->getTransactionId(), - 'type' => 'refund', - ); - } - - /** - * Send the request with specified data - * - * @param mixed $data The data to send - * @return ResponseInterface - */ - public function sendData($data) - { - $httpResponse = $this->sendRequest( - 'POST', - '/orders/' . $data['id'] . '/refunds', - $data - ); - - $this->response = new RefundResponse($this, $httpResponse); - - return $this->response; - } -} diff --git a/src/Message/RefundResponse.php b/src/Message/RefundResponse.php deleted file mode 100644 index a4dad8c..0000000 --- a/src/Message/RefundResponse.php +++ /dev/null @@ -1,6 +0,0 @@ -getParameter('locale'); + } + + /** + * Set the locale. + * + * Optional ISO 639-1 language code which is used to specify a + * a language used to display gateway information and other + * messages in the responses. + * + * The default language is English. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setLocale($value) + { + return $this->setParameter('locale', $value); + } + + /** + * Get the gateway API Key + * + * Authentication is by means of a single secret API key set as + * the apiKey parameter when creating the gateway object. + * + * @return string + */ + public function getApiKey() + { + return $this->getParameter('apiKey'); + } + + /** + * Set the gateway API Key + * + * Authentication is by means of a single secret API key set as + * the apiKey parameter when creating the gateway object. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setApiKey($value) + { + return $this->setParameter('apiKey', $value); + } + + /** + * Get endpoint + * + * @return string + */ + public function getEndpoint() + { + if ($this->getTestMode()) { + return $this->testEndpoint; + } + + return $this->liveEndpoint; + } + + /** + * Get the raw data array for this message. The format of this varies from gateway to + * gateway, but will usually be either an associative array, or a SimpleXMLElement. + * + * @return mixed + * @throws \Omnipay\Common\Exception\InvalidRequestException + */ + public function getData() + { + $this->validate('apiKey'); + } + + /** + * Get headers. + * + * @return array + */ + protected function getHeaders() + { + return array( + 'api_key' => $this->getApiKey(), + 'User-Agent' => $this->userAgent, + ); + } + + /** + * Execute the Guzzle request. + * + * @param $method + * @param $endpoint + * @param null $query + * @param null $data + * @return \Guzzle\Http\Message\Response + */ + protected function sendRequest($method, $endpoint, $query = null, $data = null) + { + $this->httpClient->getEventDispatcher()->addListener('request.error', function (Event $event) { + $response = $event['response']; + if ($response->isError()) { + $event->stopPropagation(); + } + }); + + $httpRequest = $this->httpClient->createRequest( + $method, + $this->getEndpoint() . $endpoint, + $this->getHeaders(), + $data + ); + + // Add query parameters + if (is_array($query) && ! empty($query)) { + foreach ($query as $itemKey => $itemValue) { + $httpRequest->getQuery()->add($itemKey, $itemValue); + } + } + + return $httpRequest->send(); + } +} diff --git a/src/Message/RestAbstractResponse.php b/src/Message/RestAbstractResponse.php new file mode 100644 index 0000000..56ccbb0 --- /dev/null +++ b/src/Message/RestAbstractResponse.php @@ -0,0 +1,79 @@ +data['success'])) { + return false; + } + + return $this->data['success']; + } + + /** + * Response Message. + * + * @return null|string A response message from the payment gateway + */ + public function getMessage() + { + if (!$this->isSuccessful() && isset($this->data['error_info'])) { + return $this->data['error_info']; + } + } + + /** + * Response code. + * + * @return null|string A response code from the payment gateway + */ + public function getCode() + { + if (! $this->isSuccessful() && isset($this->data['error_code'])) { + return $this->data['error_code']; + } + } + + /** + * Gateway Reference. + * + * @return null|string A reference provided by the gateway to represent this transaction + */ + public function getTransactionReference() + { + if (isset($this->data['data']['transaction_id'])) { + return $this->data['data']['transaction_id']; + } + } + + /** + * Get the transaction ID as generated by the merchant website. + * + * @return string + */ + public function getTransactionId() + { + if (isset($this->data['data']['order_id'])) { + return $this->data['data']['order_id']; + } + } +} diff --git a/src/Message/RestCompletePurchaseRequest.php b/src/Message/RestCompletePurchaseRequest.php new file mode 100644 index 0000000..c7d5735 --- /dev/null +++ b/src/Message/RestCompletePurchaseRequest.php @@ -0,0 +1,58 @@ + + * $transaction = $gateway->completePurchase(); + * $transaction->setTransactionId($transactionId); + * $response = $transaction->send(); + * print_r($response->getData()); + * + * + */ +class RestCompletePurchaseRequest extends RestFetchTransactionRequest +{ + /** + * Get the required data from the API request. + * + * @return array + * @throws \Omnipay\Common\Exception\InvalidRequestException + */ + public function getData() + { + $this->validate('transactionId'); + + $transactionId = $this->getTransactionId(); + + return compact('transactionId'); + } + + /** + * Send the API request. + * + * @param mixed $data + * @return RestCompletePurchaseResponse + */ + public function sendData($data) + { + $httpResponse = $this->sendRequest( + 'get', + '/orders/' . $data['transactionId'] + ); + + $this->response = new RestCompletePurchaseResponse( + $this, + $httpResponse->json() + ); + + return $this->response; + } +} diff --git a/src/Message/RestCompletePurchaseResponse.php b/src/Message/RestCompletePurchaseResponse.php new file mode 100644 index 0000000..4123aa7 --- /dev/null +++ b/src/Message/RestCompletePurchaseResponse.php @@ -0,0 +1,30 @@ + + * $transaction = $gateway->completePurchase(); + * $transaction->setTransactionId($transactionId); + * $response = $transaction->send(); + * print_r($response->getData()); + * + * + */ +class RestCompletePurchaseResponse extends RestFetchTransactionResponse +{ + /** + * {@inheritdoc} + */ + public function isSuccessful() + { + return $this->getPaymentStatus() == 'completed'; + } +} diff --git a/src/Message/RestFetchIssuersRequest.php b/src/Message/RestFetchIssuersRequest.php new file mode 100644 index 0000000..f3e7399 --- /dev/null +++ b/src/Message/RestFetchIssuersRequest.php @@ -0,0 +1,66 @@ + + * $request = $gateway->fetchIssuers(); + * $request->setPaymentMethod('IDEAL'); + * $response = $request->send(); + * $issuers = $response->getIssuers(); + * print_r($issuers); + * + * + * @link https://www.multisafepay.com/documentation/doc/API-Reference + */ +class RestFetchIssuersRequest extends RestAbstractRequest +{ + /** + * Get the required data for the API request. + * + * @return array + * @throws \Omnipay\Common\Exception\InvalidRequestException + */ + public function getData() + { + parent::getData(); + + $this->validate('paymentMethod'); + + $paymentMethod = $this->getPaymentMethod(); + + return compact('paymentMethod'); + } + + /** + * Execute the API request. + * + * @param mixed $data + * @return FetchIssuersResponse + */ + public function sendData($data) + { + $httpResponse = $this->sendRequest( + 'GET', + '/issuers/' . $data['paymentMethod'] + ); + + $this->response = new RestFetchIssuersResponse( + $this, + $httpResponse->json() + ); + + return $this->response; + } +} diff --git a/src/Message/RestFetchIssuersResponse.php b/src/Message/RestFetchIssuersResponse.php new file mode 100644 index 0000000..f11ceb9 --- /dev/null +++ b/src/Message/RestFetchIssuersResponse.php @@ -0,0 +1,48 @@ + + * $request = $gateway->fetchIssuers(); + * $request->setPaymentMethod('IDEAL'); + * $response = $request->send(); + * $issuers = $response->getIssuers(); + * print_r($issuers); + * + */ +class RestFetchIssuersResponse extends RestAbstractResponse implements FetchIssuersResponseInterface +{ + /** + * Return available issuers as an associative array. + * + * @return \Omnipay\Common\Issuer[] + */ + public function getIssuers() + { + $issuers = array(); + + foreach ($this->data['data'] as $issuer) { + $issuers[] = new Issuer( + $issuer['code'], + $issuer['description'] + ); + } + + return $issuers; + } +} diff --git a/src/Message/RestFetchPaymentMethodsRequest.php b/src/Message/RestFetchPaymentMethodsRequest.php new file mode 100644 index 0000000..5178b25 --- /dev/null +++ b/src/Message/RestFetchPaymentMethodsRequest.php @@ -0,0 +1,84 @@ + + * $request = $gateway->fetchPaymentMethods(); + * $response = $request->send(); + * $paymentMethods = $response->getPaymentMethods(); + * print_r($paymentMethods); + * + * + * @link https://www.multisafepay.com/documentation/doc/API-Reference + */ +class RestFetchPaymentMethodsRequest extends RestAbstractRequest +{ + /** + * Get the country. + * + * @return string|null + */ + public function getCountry() + { + return $this->getParameter('country'); + } + + /** + * Set the country. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setCountry($value) + { + return $this->setParameter('country', $value); + } + + /** + * Get the required data for the API request. + * + * @return array + */ + public function getData() + { + parent::getData(); + + $data = array( + 'amount' => $this->getAmountInteger(), + 'country' => $this->getCountry(), + 'currency' => $this->getCurrency(), + ); + + return array_filter($data); + } + + /** + * Execute the API request. + * + * @param mixed $data + * @return RestFetchPaymentMethodsResponse + */ + public function sendData($data) + { + $httpResponse = $this->sendRequest('GET', '/gateways', $data); + + $this->response = new RestFetchPaymentMethodsResponse( + $this, + $httpResponse->json() + ); + + return $this->response; + } +} diff --git a/src/Message/RestFetchPaymentMethodsResponse.php b/src/Message/RestFetchPaymentMethodsResponse.php new file mode 100644 index 0000000..c0488e7 --- /dev/null +++ b/src/Message/RestFetchPaymentMethodsResponse.php @@ -0,0 +1,52 @@ + + * $request = $gateway->fetchPaymentMethods(); + * $response = $request->send(); + * $paymentMethods = $response->getPaymentMethods(); + * print_r($paymentMethods); + * + */ +class RestFetchPaymentMethodsResponse extends RestAbstractResponse implements FetchPaymentMethodsResponseInterface +{ + /** + * Get the returned list of payment methods. + * + * These represent separate payment methods which the user must choose between. + * + * @return \Omnipay\Common\PaymentMethod[] + */ + public function getPaymentMethods() + { + $paymentMethods = array(); + + foreach ($this->data['data'] as $method) { + $paymentMethods[] = new PaymentMethod( + $method['id'], + $method['description'] + ); + } + + return $paymentMethods; + } +} diff --git a/src/Message/RestFetchTransactionRequest.php b/src/Message/RestFetchTransactionRequest.php new file mode 100644 index 0000000..6875735 --- /dev/null +++ b/src/Message/RestFetchTransactionRequest.php @@ -0,0 +1,65 @@ + + * // Fetch the transaction. + * $transaction = $gateway->fetchTransaction(); + * $transaction->setTransactionId($transactionId); + * $response = $transaction->send(); + * print_r($response->getData()); + * + * + * @link https://www.multisafepay.com/documentation/doc/API-Reference + */ +class RestFetchTransactionRequest extends RestAbstractRequest +{ + /** + * Get the required data which is needed + * to execute the API request. + * + * @return array + * @throws \Omnipay\Common\Exception\InvalidRequestException + */ + public function getData() + { + parent::getData(); + + $this->validate('transactionId'); + + $transactionId = $this->getTransactionId(); + + return compact('transactionId'); + } + + /** + * Execute the API request. + * + * @param mixed $data + * @return RestFetchTransactionResponse + */ + public function sendData($data) + { + $httpResponse = $this->sendRequest( + 'get', + '/orders/' . $data['transactionId'] + ); + + $this->response = new RestFetchTransactionResponse( + $this, + $httpResponse->json() + ); + + return $this->response; + } +} diff --git a/src/Message/FetchTransactionResponse.php b/src/Message/RestFetchTransactionResponse.php similarity index 67% rename from src/Message/FetchTransactionResponse.php rename to src/Message/RestFetchTransactionResponse.php index c25a296..9a075d6 100644 --- a/src/Message/FetchTransactionResponse.php +++ b/src/Message/RestFetchTransactionResponse.php @@ -1,6 +1,27 @@ - + * // Fetch the transaction. + * $transaction = $gateway->fetchTransaction(); + * $transaction->setTransactionId($transactionId); + * $response = $transaction->send(); + * print_r($response->getData()); + * + * + * @link https://www.multisafepay.com/documentation/doc/API-Reference + */ +class RestFetchTransactionResponse extends RestAbstractResponse { /** * Is the payment created, but uncompleted? diff --git a/src/Message/RestPurchaseRequest.php b/src/Message/RestPurchaseRequest.php new file mode 100644 index 0000000..13068c3 --- /dev/null +++ b/src/Message/RestPurchaseRequest.php @@ -0,0 +1,543 @@ + + * // Create a credit card object + * $card = new CreditCard(array( + * 'firstName' => 'Example', + * 'lastName' => 'Customer', + * 'number' => '4222222222222222', + * 'expiryMonth' => '01', + * 'expiryYear' => '2020', + * 'cvv' => '123', + * 'email' => 'customer@example.com', + * 'address1' => '1 Scrubby Creek Road', + * 'country' => 'AU', + * 'city' => 'Scrubby Creek', + * 'postalcode' => '4999', + * 'state' => 'QLD', + * )); + * + * + * ### Initialize a "redirect" payment. + * + * The customer will be redirected to the MultiSafepay website + * where they need to enter their payment details. + * + * + * $request = $gateway->purchase(); + * + * $request->setAmount('20.00'); + * $request->setTransactionId('TEST-TRANSACTION'); + * $request->setDescription('Test transaction'); + * + * $request->setCurrency('EUR'); + * $request->setType('redirect'); + * + * $response = $request->send(); + * var_dump($response->getData()); + * + * + * ### Initialize a "direct" payment. + * + * The merchant website need to collect the payment details, so + * the user can stay at the merchant website. + * + * + * $request = $gateway->purchase(); + * + * $request->setAmount('20.00'); + * $request->setTransactionId('TEST-TRANSACTION'); + * $request->setDescription('Test transaction'); + * + * $request->setCurrency('EUR'); + * $request->setType('direct'); + * $request->setCard($card); + * + * $request->setGateway('IDEAL'); + * $request->setIssuer('ISSUER-ID'); // This ID can be found, with the RestFetchIssuersRequest. + * + * $response = $request->send(); + * var_dump($response->getData()); + * + */ +class RestPurchaseRequest extends RestAbstractRequest +{ + /** + * Get payment type. + * + * Specifies the payment flow for the checkout process. + * + * @return string + */ + public function getType() + { + return $this->getParameter('type'); + } + + /** + * Set payment type. + * + * Specifies the payment flow for the checkout process. + * Possible values are 'redirect', 'direct' + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setType($value) + { + return $this->setParameter('type', $value); + } + + /** + * Get recurring Payment Id + * + * A previously stored identifier referring to a + * payment method to be charged again. + * + * @return int|null + */ + public function getRecurringId() + { + return $this->getParameter('recurring_id'); + } + + /** + * Set recurring Payment Id + * + * A previously stored identifier referring to a + * payment method to be charged again. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setRecurringId($value) + { + return $this->setParameter('recurring_id', $value); + } + + /** + * Get the gateway. + * + * The unique gateway id to immediately direct the customer to the payment method. + * You retrieve these gateways using a gateway request. + * + * @return mixed + */ + public function getGateway() + { + return $this->getParameter('gateway'); + } + + /** + * Set the gateway. + * + * The unique gateway id to immediately direct the customer to the payment method. + * You retrieve these gateways using a gateway request. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setGateway($value) + { + return $this->setParameter('gateway', $value); + } + + /** + * Get value of var1. + * + * A free variable for custom data to be stored and persisted. + * + * @return string|null + */ + public function getVar1() + { + return $this->getParameter('var1'); + } + + /** + * Set var1. + * + * A free optional variable for custom data to be stored and persisted. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setVar1($value) + { + return $this->setParameter('var1', $value); + } + + /** + * Get var2. + * + * A free variable for custom data to be stored and persisted. + * + * @return string|null + */ + public function getVar2() + { + return $this->getParameter('var2'); + } + + /** + * Set var2. + * + * A free variable for custom data to be stored and persisted. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setVar2($value) + { + return $this->setParameter('var2', $value); + } + + /** + * Get var3. + * + * A free variable for custom data to be stored and persisted. + * + * @return string|null + */ + public function getVar3() + { + return $this->getParameter('var3'); + } + + /** + * Set var3. + * + * A free variable for custom data to be stored and persisted. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setVar3($value) + { + return $this->setParameter('var3', $value); + } + + /** + * Get manual. + * + * If true this forces a credit card transaction to require manual + * acceptance regardless of the outcome from fraud checks. + * It is possible that a high risk transaction is still declined. + * + * @return boolean|null + */ + public function getManual() + { + return $this->getParameter('manual'); + } + + /** + * Set manual. + * + * If true this forces a credit card transaction to require manual + * acceptance regardless of the outcome from fraud checks. + * It is possible that a high risk transaction is still declined. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setManual($value) + { + return $this->setParameter('manual', $value); + } + + /** + * Get days active. + * + * The number of days the payment link will be active for. + * When not specified the default will be 30 days. + * + * @return int|null + */ + public function getDaysActive() + { + return $this->getParameter('days_active'); + } + + /** + * Set days active. + * + * The number of days the payment link will be active for. + * When not specified the default will be 30 days. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setDaysActive($value) + { + return $this->setParameter('days_active', $value); + } + + /** + * Get close window. + * + * Set to true if you will display the MultiSafepay payment + * page in a new window and want it to close automatically + * after the payment process has been completed. + * + * @return boolean|null + */ + public function getCloseWindow() + { + return $this->getParameter('close_window'); + } + + /** + * Set close window. + * + * Set to true if you will display the MultiSafepay payment + * page in a new window and want it to close automatically + * after the payment process has been completed. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setCloseWindow($value) + { + return $this->setParameter('close_window', $value); + } + + /** + * Send mail. + * + * True if you will send your own bank transfer payment instructions to + * consumers and do not want MultiSafepay to do this. + * + * @return boolean + */ + public function getSendMail() + { + return $this->getParameter('disable_send_mail'); + } + + /** + * Send mail. + * + * True if you will send your own bank transfer payment instructions to + * consumers and do not want MultiSafepay to do this. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setSendMail($value) + { + return $this->setParameter('disable_send_mail', $value); + } + + /** + * Google analytics code. + * + * Your Google Analytics Site Id. + * This will be injected into the payment pages + * so you can trigger custom events and track payment metrics. + * + * @return string|null + */ + public function getGoogleAnalyticsCode() + { + return $this->getParameter('google_analytics'); + } + + /** + * Google analytics code. + * + * Your Google Analytics Site Id. + * This will be injected into the payment pages + * so you can trigger custom events and track payment metrics. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setGoogleAnalyticsCode($value) + { + return $this->setParameter('google_analytics', $value); + } + + /** + * Get the payment options. + * + * @return array + */ + protected function getPaymentData() + { + $data = array( + 'cancel_url' => $this->getCancelUrl(), + 'close_window' => $this->getCloseWindow(), + 'notify_url' => $this->getNotifyUrl(), + 'return_url' => $this->getReturnUrl(), + ); + + return array_filter($data); + } + + /** + * Customer information. + * + * This function returns all the provided + * client related parameters. + * + * @return array + */ + public function getCustomerData() + { + $data = array( + 'disable_send_mail' => $this->getSendMail(), + 'locale' => $this->getLocale(), + ); + + if (is_null($this->getCard())) { + return array_filter($data); + } + + $cardData = array( + 'address_1' => $this->getCard()->getAddress1(), + 'address_2' => $this->getCard()->getAddress2(), + 'city' => $this->getCard()->getCity(), + 'country' => $this->getCard()->getCountry(), + 'email' => $this->getCard()->getEmail(), + 'first_name' => $this->getCard()->getFirstName(), + 'house_number' => $this->getCard()->getNumber(), + 'last_name' => $this->getCard()->getLastName(), + 'phone' => $this->getCard()->getPhone(), + 'state' => $this->getCard()->getState(), + 'zip_code' => $this->getCard()->getPostcode(), + ); + + return array_filter( + array_merge($data, $cardData) + ); + } + + /** + * Get gateway data. + * + * @return array + */ + protected function getGatewayData() + { + $data = array( + 'issuer_id' => $this->getIssuer(), + ); + + return array_filter($data); + } + + /** + * Get the raw data array for this message. The format of this varies from gateway to + * gateway, but will usually be either an associative array, or a SimpleXMLElement. + * + * @return array + * @throws \Omnipay\Common\Exception\InvalidRequestException + */ + public function getData() + { + parent::getData(); + + $this->validate( + 'amount', + 'currency', + 'description', + 'transactionId', + 'type' + ); + + // Direct order. + if ($this->getType() === 'direct') { + $this->validate('gateway'); + } + + // When the gateway is set to IDEAL, + // the issuer parameter is required. + if ( + $this->getType() == 'direct' && + $this->getGateway() == 'IDEAL' + ) { + $this->validate('issuer'); + } + + $data = array( + 'amount' => $this->getAmountInteger(), + 'currency' => $this->getCurrency(), + 'days_active' => $this->getDaysActive(), + 'description' => $this->getDescription(), + 'gateway' => $this->getGateway(), + 'google_analytics' => $this->getGoogleAnalyticsCode(), + 'items' => $this->getItems(), + 'manual' => $this->getManual(), + 'order_id' => $this->getTransactionId(), + 'recurring_id' => $this->getRecurringId(), + 'type' => $this->getType(), + 'var1' => $this->getVar1(), + 'var2' => $this->getVar2(), + 'var3' => $this->getVar3(), + ); + + $paymentData = $this->getPaymentData(); + + if (! empty($paymentData)) { + $data['payment_options'] = $paymentData; + } + + $customerData = $this->getCustomerData(); + + if (! empty($customerData)) { + $data['customer'] = $customerData; + } + + $gatewayData = $this->getGatewayData(); + + if (! empty($gatewayData)) { + $data['gateway_info'] = $gatewayData; + } + + return array_filter($data); + } + + /** + * Send the request with specified data + * + * @param mixed $data + * @return RestPurchaseResponse + */ + public function sendData($data) + { + $httpResponse = $this->sendRequest('POST', '/orders', null, $data); + + $this->response = new RestPurchaseResponse( + $this, + $httpResponse->json() + ); + + return $this->response; + } +} diff --git a/src/Message/RestPurchaseResponse.php b/src/Message/RestPurchaseResponse.php new file mode 100644 index 0000000..ed5ec6b --- /dev/null +++ b/src/Message/RestPurchaseResponse.php @@ -0,0 +1,126 @@ + + * // Create a credit card object + * $card = new CreditCard(array( + * 'firstName' => 'Example', + * 'lastName' => 'Customer', + * 'number' => '4222222222222222', + * 'expiryMonth' => '01', + * 'expiryYear' => '2020', + * 'cvv' => '123', + * 'email' => 'customer@example.com', + * 'address1' => '1 Scrubby Creek Road', + * 'country' => 'AU', + * 'city' => 'Scrubby Creek', + * 'postalcode' => '4999', + * 'state' => 'QLD', + * )); + * + * + * ### Initialize a "redirect" payment. + * + * The customer will be redirected to the MultiSafepay website + * where they need to enter their payment details. + * + * + * $request = $gateway->purchase(); + * + * $request->setAmount('20.00'); + * $request->setTransactionId('TEST-TRANSACTION'); + * $request->setDescription('Test transaction'); + * + * $request->setCurrency('EUR'); + * $request->setType('redirect'); + * + * $response = $request->send(); + * var_dump($response->getData()); + * + * + * ### Initialize a "direct" payment. + * + * The merchant website need to collect the payment details, so + * the user can stay at the merchant website. + * + * + * $request = $gateway->purchase(); + * + * $request->setAmount('20.00'); + * $request->setTransactionId('TEST-TRANSACTION'); + * $request->setDescription('Test transaction'); + * + * $request->setCurrency('EUR'); + * $request->setType('direct'); + * $request->setCard($card); + * + * $request->setGateway('IDEAL'); + * $request->setIssuer('ISSUER-ID'); // This ID can be found, with the RestFetchIssuersRequest. + * + * $response = $request->send(); + * var_dump($response->getData()); + * + */ +class RestPurchaseResponse extends RestAbstractResponse implements RedirectResponseInterface +{ + /** + * {@inheritdoc} + */ + public function isRedirect() + { + return isset($this->data['data']['payment_url']); + } + + /** + * {@inheritdoc} + */ + public function getRedirectUrl() + { + if (! $this->isRedirect()) { + return null; + } + + return $this->data['data']['payment_url']; + } + + /** + * {@inheritdoc} + */ + public function getRedirectMethod() + { + return 'GET'; + } + + /** + * {@inheritdoc} + */ + public function getRedirectData() + { + return null; + } +} diff --git a/src/Message/RestRefundRequest.php b/src/Message/RestRefundRequest.php new file mode 100644 index 0000000..947980a --- /dev/null +++ b/src/Message/RestRefundRequest.php @@ -0,0 +1,80 @@ + + * $request = $this->gateway->refund(); + * + * $request->setTransactionId('test-transaction'); + * $request->setAmount('10.00'); + * $request->setCurrency('eur'); + * $request->setDescription('Test Refund'); + * + * $response = $request->send(); + * var_dump($response->isSuccessful()); + * + */ +class RestRefundRequest extends RestAbstractRequest +{ + /** + * Get the required data for the API request. + * + * @return array + * @throws \Omnipay\Common\Exception\InvalidRequestException + */ + public function getData() + { + parent::getData(); + + $this->validate('amount', 'currency', 'description', 'transactionId'); + + return array( + 'amount' => $this->getAmountInteger(), + 'currency' => $this->getCurrency(), + 'description' => $this->getDescription(), + 'id' => $this->getTransactionId(), + 'type' => 'refund', + ); + } + + /** + * Send the request with specified data + * + * @param mixed $data + * @return RestRefundResponse + */ + public function sendData($data) + { + $httpResponse = $this->sendRequest( + 'POST', + '/orders/' . $data['id'] . '/refunds', + $data + ); + + $this->response = new RestRefundResponse( + $this, + $httpResponse + ); + + return $this->response; + } +} diff --git a/src/Message/RestRefundResponse.php b/src/Message/RestRefundResponse.php new file mode 100644 index 0000000..c499e67 --- /dev/null +++ b/src/Message/RestRefundResponse.php @@ -0,0 +1,38 @@ + + * $request = $this->gateway->refund(); + * + * $request->setTransactionId('test-transaction'); + * $request->setAmount('10.00'); + * $request->setCurrency('eur'); + * $request->setDescription('Test Refund'); + * + * $response = $request->send(); + * var_dump($response->isSuccessful()); + * + */ +class RestRefundResponse extends RestAbstractResponse +{ + +} diff --git a/src/RestGateway.php b/src/RestGateway.php new file mode 100644 index 0000000..3adc211 --- /dev/null +++ b/src/RestGateway.php @@ -0,0 +1,258 @@ + + * // Create the gateway + * $gateway = Omnipay::create('MultiSafepay_Rest'); + * + * // Initialise the gateway + * $gateway->initialize(array( + * 'apiKey' => 'API-KEY', + * 'locale' => 'en', + * 'testMode' => true, // Or false, when you want to use the production environment + * )); + * + * + * ### Retrieve Payment Methods + * + * + * $request = $gateway->fetchPaymentMethods(); + * $response = $request->send(); + * $paymentMethods = $response->getPaymentMethods(); + * + * + * @link https://github.com/MultiSafepay/PHP + * @link https://www.multisafepay.com/docs/getting-started/ + * @link https://www.multisafepay.com/documentation/doc/API-Reference/ + * @link https://www.multisafepay.com/documentation/doc/Step-by-Step/ + * @link https://www.multisafepay.com/signup/ + */ +class RestGateway extends AbstractGateway +{ + /** + * @{inheritdoc} + */ + public function getName() + { + return 'MultiSafepay REST'; + } + + /** + * Get the gateway parameters + * + * @return array + */ + public function getDefaultParameters() + { + return array( + 'apiKey' => '', + 'locale' => 'en', + 'testMode' => false, + ); + } + + /** + * Get the locale. + * + * Optional ISO 639-1 language code which is used to specify a + * a language used to display gateway information and other + * messages in the responses. + * + * The default language is English. + * + * @return string + */ + public function getLocale() + { + return $this->getParameter('locale'); + } + + /** + * Set the locale. + * + * Optional ISO 639-1 language code which is used to specify a + * a language used to display gateway information and other + * messages in the responses. + * + * The default language is English. + * + * @param $value + * @return \Omnipay\Common\Message\AbstractRequest + */ + public function setLocale($value) + { + return $this->setParameter('locale', $value); + } + + /** + * Get the gateway API Key + * + * Authentication is by means of a single secret API key set as + * the apiKey parameter when creating the gateway object. + * + * @return string + */ + public function getApiKey() + { + return $this->getParameter('apiKey'); + } + + /** + * Set the gateway API Key + * + * Authentication is by means of a single secret API key set as + * the apiKey parameter when creating the gateway object. + * + * @param string $value + * @return RestGateway provides a fluent interface. + */ + public function setApiKey($value) + { + return $this->setParameter('apiKey', $value); + } + + /** + * Retrieve payment methods active on the given MultiSafepay + * account. + * + * @param array $parameters + * + * @return \Omnipay\MultiSafepay\Message\RestFetchPaymentMethodsRequest + */ + public function fetchPaymentMethods(array $parameters = array()) + { + return $this->createRequest( + 'Omnipay\MultiSafepay\Message\RestFetchPaymentMethodsRequest', + $parameters + ); + } + + /** + * Retrieve issuers for gateway. + * + * @param array $parameters + * + * @return \Omnipay\MultiSafepay\Message\RestFetchIssuersRequest + */ + public function fetchIssuers(array $parameters = array()) + { + return $this->createRequest( + 'Omnipay\MultiSafepay\Message\RestFetchIssuersRequest', + $parameters + ); + } + + /** + * Retrieve transaction by the given identifier. + * + * @param array $parameters + * @return \Omnipay\MultiSafepay\Message\RestFetchTransactionRequest + */ + public function fetchTransaction(array $parameters = array()) + { + return $this->createRequest( + 'Omnipay\MultiSafepay\Message\RestFetchTransactionRequest', + $parameters + ); + } + + /** + * Create a refund. + * + * @param array $parameters + * @return \Omnipay\MultiSafepay\Message\RestRefundRequest + */ + public function refund(array $parameters = array()) + { + return $this->createRequest( + 'Omnipay\MultiSafepay\Message\RestRefundRequest', + $parameters + ); + } + + /** + * Create a purchase request. + * + * MultisafePay support different types of transactions, + * such as iDEAL, Paypal and CreditCard payments. + * + * @param array $parameters + * + * @return \Omnipay\MultiSafepay\Message\RestPurchaseRequest + */ + public function purchase(array $parameters = array()) + { + return $this->createRequest( + 'Omnipay\MultiSafepay\Message\RestPurchaseRequest', + $parameters + ); + } + + /** + * Complete a payment request. + * + * @param array $parameters + * + * @return \Omnipay\MultiSafepay\Message\RestCompletePurchaseRequest + */ + public function completePurchase(array $parameters = array()) + { + return $this->createRequest( + 'Omnipay\MultiSafepay\Message\RestCompletePurchaseRequest', + $parameters + ); + } +} diff --git a/src/XmlGateway.php b/src/XmlGateway.php new file mode 100644 index 0000000..ef2020d --- /dev/null +++ b/src/XmlGateway.php @@ -0,0 +1,178 @@ + + * // Create the gateway + * $gateway = Omnipay::create('MultiSafepay_Xml'); + * + * // Initialise the gateway + * $gateway->initialize(array( + * 'apiKey' => 'API-KEY', + * 'locale' => 'en', + * 'testMode' => true, // Or false, when you want to use the production environment + * )); + * + * + * @link https://www.multisafepay.com/downloads/handleidingen/Handleiding_connect(ENG).pdf + */ +class XmlGateway extends AbstractGateway +{ + /** + * {@inheritdoc} + */ + public function getName() + { + return 'MultiSafepay XML'; + } + + /** + * {@inheritdoc} + */ + public function getDefaultParameters() + { + return array( + 'accountId' => '', + 'siteId' => '', + 'siteCode' => '', + 'testMode' => false, + ); + } + + /** + * Get the account identifier. + * + * @return mixed + */ + public function getAccountId() + { + return $this->getParameter('accountId'); + } + + /** + * Set the account identifier. + * + * @param $value + * @return $this + */ + public function setAccountId($value) + { + return $this->setParameter('accountId', $value); + } + + /** + * Get the site identifier. + * + * @return mixed + */ + public function getSiteId() + { + return $this->getParameter('siteId'); + } + + /** + * Set the site identifier. + * + * @param $value + * @return $this + */ + public function setSiteId($value) + { + return $this->setParameter('siteId', $value); + } + + /** + * Get the site code. + * + * @return mixed + */ + public function getSiteCode() + { + return $this->getParameter('siteCode'); + } + + /** + * Set the site code. + * + * @param $value + * @return $this + */ + public function setSiteCode($value) + { + return $this->setParameter('siteCode', $value); + } + + /** + * Retrieve payment methods active on the given MultiSafepay + * account. + * + * @param array $parameters + * + * @return \Omnipay\MultiSafepay\Message\FetchPaymentMethodsRequest + */ + public function fetchPaymentMethods(array $parameters = array()) + { + return $this->createRequest( + '\Omnipay\MultiSafepay\Message\FetchPaymentMethodsRequest', + $parameters + ); + } + + /** + * Retrieve iDEAL issuers. + * + * @param array $parameters + * + * @return \Omnipay\MultiSafepay\Message\FetchIssuersRequest + */ + public function fetchIssuers(array $parameters = array()) + { + return $this->createRequest( + '\Omnipay\MultiSafepay\Message\FetchIssuersRequest', + $parameters + ); + } + + /** + * Create Purchase request. + * + * @param array $parameters + * + * @return \Omnipay\MultiSafepay\Message\PurchaseRequest + */ + public function purchase(array $parameters = array()) + { + return $this->createRequest( + '\Omnipay\MultiSafepay\Message\PurchaseRequest', + $parameters + ); + } + + /** + * Complete purchase request. + * + * @param array $parameters + * + * @return \Omnipay\MultiSafepay\Message\CompletePurchaseRequest + */ + public function completePurchase(array $parameters = array()) + { + return $this->createRequest( + '\Omnipay\MultiSafepay\Message\CompletePurchaseRequest', + $parameters + ); + } +} diff --git a/tests/Message/FetchIssuersRequestTest.php b/tests/Message/RestFetchIssuersRequestTest.php similarity index 73% rename from tests/Message/FetchIssuersRequestTest.php rename to tests/Message/RestFetchIssuersRequestTest.php index 73d2bc2..da80874 100644 --- a/tests/Message/FetchIssuersRequestTest.php +++ b/tests/Message/RestFetchIssuersRequestTest.php @@ -2,7 +2,7 @@ use Omnipay\Tests\TestCase; -class FetchIssuersRequestTest extends TestCase +class RestFetchIssuersRequestTest extends TestCase { /** * @var FetchIssuersRequest @@ -11,7 +11,7 @@ class FetchIssuersRequestTest extends TestCase protected function setUp() { - $this->request = new FetchIssuersRequest( + $this->request = new RestFetchIssuersRequest( $this->getHttpClient(), $this->getHttpRequest() ); @@ -26,7 +26,7 @@ protected function setUp() public function testSendSuccess() { - $this->setMockHttpResponse('FetchIssuersSuccess.txt'); + $this->setMockHttpResponse('RestFetchIssuersSuccess.txt'); $response = $this->request->send(); @@ -34,7 +34,7 @@ public function testSendSuccess() $this->assertContainsOnlyInstancesOf('Omnipay\Common\Issuer', $issuers); $this->assertFalse($response->isRedirect()); - $this->assertInstanceOf('Omnipay\MultiSafepay\Message\FetchIssuersResponse', $response); + $this->assertInstanceOf('Omnipay\MultiSafepay\Message\RestFetchIssuersResponse', $response); $this->assertInternalType('array', $issuers); $this->assertNull($response->getTransactionReference()); @@ -43,7 +43,7 @@ public function testSendSuccess() public function testIssuerNotFound() { - $this->setMockHttpResponse('FetchIssuersFailure.txt'); + $this->setMockHttpResponse('RestFetchIssuersFailure.txt'); $response = $this->request->send(); @@ -52,6 +52,6 @@ public function testIssuerNotFound() $this->assertFalse($response->isRedirect()); $this->assertFalse($response->isSuccessful()); - $this->assertInstanceOf('Omnipay\MultiSafepay\Message\FetchIssuersResponse', $response); + $this->assertInstanceOf('Omnipay\MultiSafepay\Message\RestFetchIssuersResponse', $response); } } diff --git a/tests/Message/FetchPaymentMethodsRequestTest.php b/tests/Message/RestFetchPaymentMethodsRequestTest.php similarity index 82% rename from tests/Message/FetchPaymentMethodsRequestTest.php rename to tests/Message/RestFetchPaymentMethodsRequestTest.php index 658d7c1..b1ac864 100644 --- a/tests/Message/FetchPaymentMethodsRequestTest.php +++ b/tests/Message/RestFetchPaymentMethodsRequestTest.php @@ -2,7 +2,7 @@ use Omnipay\Tests\TestCase; -class FetchPaymentMethodsRequestTest extends TestCase +class RestFetchPaymentMethodsRequestTest extends TestCase { /** * @var FetchPaymentMethodsRequest @@ -11,7 +11,7 @@ class FetchPaymentMethodsRequestTest extends TestCase protected function setUp() { - $this->request = new FetchPaymentMethodsRequest( + $this->request = new RestFetchPaymentMethodsRequest( $this->getHttpClient(), $this->getHttpRequest() ); @@ -26,7 +26,7 @@ protected function setUp() public function testSendSuccess() { - $this->setMockHttpResponse('FetchPaymentMethodsSuccess.txt'); + $this->setMockHttpResponse('RestFetchPaymentMethodsSuccess.txt'); $response = $this->request->send(); diff --git a/tests/Message/PurchaseRequestTest.php b/tests/Message/RestPurchaseRequestTest.php similarity index 93% rename from tests/Message/PurchaseRequestTest.php rename to tests/Message/RestPurchaseRequestTest.php index f8fdafd..3b80c17 100644 --- a/tests/Message/PurchaseRequestTest.php +++ b/tests/Message/RestPurchaseRequestTest.php @@ -2,7 +2,7 @@ use Omnipay\Tests\TestCase; -class PurchaseRequestTest extends TestCase +class RestPurchaseRequestTest extends TestCase { /** * @var PurchaseRequest @@ -11,7 +11,7 @@ class PurchaseRequestTest extends TestCase protected function setUp() { - $this->request = new PurchaseRequest( + $this->request = new RestPurchaseRequest( $this->getHttpClient(), $this->getHttpRequest() ); @@ -42,7 +42,7 @@ protected function setUp() public function testSendSuccess() { - $this->setMockHttpResponse('PurchaseSuccess.txt'); + $this->setMockHttpResponse('RestPurchaseSuccess.txt'); $response = $this->request->send(); @@ -59,7 +59,7 @@ public function testSendSuccess() public function testInvalidAmount() { - $this->setMockHttpResponse('PurchaseInvalidAmount.txt'); + $this->setMockHttpResponse('RestPurchaseInvalidAmount.txt'); $response = $this->request->send(); diff --git a/tests/Message/XmlAbstractRequestTest.php b/tests/Message/XmlAbstractRequestTest.php new file mode 100644 index 0000000..9c284be --- /dev/null +++ b/tests/Message/XmlAbstractRequestTest.php @@ -0,0 +1,37 @@ +request = m::mock('\Omnipay\MultiSafepay\Message\AbstractRequest')->makePartial(); + } + + /** + * @covers \Omnipay\MultiSafepay\Message\AbstractRequest::getHeaders() + */ + public function testUserAgentHeaderMustNotBeSet() + { + $method = new ReflectionMethod('\Omnipay\MultiSafepay\Message\AbstractRequest', 'getHeaders'); + $method->setAccessible(true); + + $headers = $method->invoke($this->request); + $this->assertArrayHasKey( + 'User-Agent', + $headers, + 'Omitting User-Agent header not allowed because then Guzzle will set it and cause 403 Forbidden on the gateway' + ); + $this->assertEquals('Omnipay', $headers['User-Agent'], 'User-Agent header set'); + } +} diff --git a/tests/Message/XmlCompletePurchaseRequestTest.php b/tests/Message/XmlCompletePurchaseRequestTest.php new file mode 100644 index 0000000..65e81ce --- /dev/null +++ b/tests/Message/XmlCompletePurchaseRequestTest.php @@ -0,0 +1,110 @@ +request = new CompletePurchaseRequest( + $this->getHttpClient(), + $this->getHttpRequest() + ); + + $this->request->initialize(array( + 'accountId' => '111111', + 'siteId' => '222222', + 'siteCode' => '333333', + 'notifyUrl' => 'http://localhost/notify', + 'cancelUrl' => 'http://localhost/cancel', + 'returnUrl' => 'http://localhost/return', + 'gateway' => 'IDEAL', + 'issuer' => 'issuer', + 'transactionId' => '123456', + 'currency' => 'EUR', + 'amount' => '100.00', + 'description' => 'desc', + 'extraData1' => 'extra 1', + 'extraData2' => 'extra 2', + 'extraData3' => 'extra 3', + 'language' => 'a language', + 'clientIp' => '127.0.0.1', + 'googleAnalyticsCode' => 'analytics code', + 'card' => array( + 'email' => 'something@example.com', + 'firstName' => 'first name', + 'lastName' => 'last name', + 'address1' => 'address 1', + 'address2' => 'address 2', + 'postcode' => '1000', + 'city' => 'a city', + 'country' => 'a country', + 'phone' => 'phone number', + ) + )); + } + + public function testSendSuccess() + { + $this->setMockHttpResponse('XmlCompletePurchaseSuccess.txt'); + + $response = $this->request->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertEquals('123456', $response->getTransactionReference()); + } + + public function testSendFailure() + { + $this->setMockHttpResponse('XmlCompletePurchaseFailure.txt'); + + $response = $this->request->send(); + + $this->assertFalse($response->isSuccessful()); + $this->assertEquals('Back-end: missing data', $response->getMessage()); + $this->assertEquals(1016, $response->getCode()); + } + + /** + * @dataProvider dataProvider + */ + public function testGetData($xml) + { + $data = $this->request->getData(); + $this->assertInstanceOf('SimpleXMLElement', $data); + + // Just so the provider remains readable... + $dom = dom_import_simplexml($data)->ownerDocument; + $dom->formatOutput = true; + $this->assertEquals($xml, $dom->saveXML()); + } + + public function dataProvider() + { + $xml = << + + + 111111 + 222222 + 333333 + + + 123456 + + + +EOF; + + return array( + array($xml), + ); + } +} diff --git a/tests/Message/XmlFetchIssuersRequestTest.php b/tests/Message/XmlFetchIssuersRequestTest.php new file mode 100644 index 0000000..d7c24c4 --- /dev/null +++ b/tests/Message/XmlFetchIssuersRequestTest.php @@ -0,0 +1,104 @@ +request = new FetchIssuersRequest( + $this->getHttpClient(), + $this->getHttpRequest() + ); + + $this->request->initialize(array( + 'accountId' => '111111', + 'siteId' => '222222', + 'siteCode' => '333333', + )); + } + + /** + * @dataProvider issuersProvider + */ + public function testSendSuccess($expected) + { + $this->setMockHttpResponse('XmlFetchIssuersSuccess.txt'); + + $response = $this->request->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertEquals($expected, $response->getIssuers()); + } + + public function testSendFailure() + { + $this->setMockHttpResponse('XmlFetchIssuersFailure.txt'); + + $response = $this->request->send(); + + $this->assertFalse($response->isSuccessful()); + $this->assertEquals('Invalid merchant security code', $response->getMessage()); + $this->assertEquals(1005, $response->getCode()); + } + + /** + * @dataProvider dataProvider + */ + public function testGetData($xml) + { + $data = $this->request->getData(); + $this->assertInstanceOf('SimpleXMLElement', $data); + + // Just so the provider remains readable... + $dom = dom_import_simplexml($data)->ownerDocument; + $dom->formatOutput = true; + $this->assertEquals($xml, $dom->saveXML()); + } + + public function issuersProvider() + { + return array( + array( + array( + '0031' => 'ABN AMRO', + '0751' => 'SNS Bank', + '0721' => 'ING', + '0021' => 'Rabobank', + '0091' => 'Friesland Bank', + '0761' => 'ASN Bank', + '0771' => 'SNS Regio Bank', + '0511' => 'Triodos Bank', + '0161' => 'Van Lanschot Bankiers', + '0801' => 'Knab', + ), + ), + ); + } + + public function dataProvider() + { + $xml = << + + + 111111 + 222222 + 333333 + + + +EOF; + + return array( + array($xml), + ); + } +} diff --git a/tests/Message/XmlFetchPaymentMethodsRequestTest.php b/tests/Message/XmlFetchPaymentMethodsRequestTest.php new file mode 100644 index 0000000..e16dea0 --- /dev/null +++ b/tests/Message/XmlFetchPaymentMethodsRequestTest.php @@ -0,0 +1,103 @@ +request = new FetchPaymentMethodsRequest( + $this->getHttpClient(), + $this->getHttpRequest() + ); + + $this->request->initialize(array( + 'accountId' => '111111', + 'siteId' => '222222', + 'siteCode' => '333333', + 'country' => 'NL', + )); + } + + /** + * @dataProvider paymentMethodsProvider + */ + public function testSendSuccess($expected) + { + $this->setMockHttpResponse('XmlFetchPaymentMethodsSuccess.txt'); + + $response = $this->request->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertEquals($expected, $response->getPaymentMethods()); + } + + public function testSendFailure() + { + $this->setMockHttpResponse('XmlFetchPaymentMethodsFailure.txt'); + + $response = $this->request->send(); + + $this->assertFalse($response->isSuccessful()); + $this->assertEquals('Invalid merchant security code', $response->getMessage()); + $this->assertEquals(1005, $response->getCode()); + } + + /** + * @dataProvider dataProvider + */ + public function testGetData($xml) + { + $data = $this->request->getData(); + $this->assertInstanceOf('SimpleXMLElement', $data); + + // Just so the provider remains readable... + $dom = dom_import_simplexml($data)->ownerDocument; + $dom->formatOutput = true; + $this->assertEquals($xml, $dom->saveXML()); + } + + public function paymentMethodsProvider() + { + return array( + array( + array( + 'VISA' => 'Visa CreditCards', + 'WALLET' => 'MultiSafepay', + 'IDEAL' => 'iDEAL', + 'BANKTRANS' => 'Bank Transfer', + 'MASTERCARD' => 'MasterCard', + ), + ), + ); + } + + public function dataProvider() + { + $xml = << + + + 111111 + 222222 + 333333 + + + NL + + + +EOF; + + return array( + array($xml), + ); + } +} diff --git a/tests/Message/XmlPurchaseRequestTest.php b/tests/Message/XmlPurchaseRequestTest.php new file mode 100644 index 0000000..ffd9e7f --- /dev/null +++ b/tests/Message/XmlPurchaseRequestTest.php @@ -0,0 +1,293 @@ +request = new PurchaseRequest( + $this->getHttpClient(), + $this->getHttpRequest() + ); + + $this->request->initialize(array( + 'accountId' => '111111', + 'siteId' => '222222', + 'siteCode' => '333333', + 'notifyUrl' => 'http://localhost/notify', + 'cancelUrl' => 'http://localhost/cancel', + 'returnUrl' => 'http://localhost/return', + 'gateway' => 'IDEAL', + 'issuer' => 'issuer', + 'transactionId' => '123456', + 'currency' => 'EUR', + 'amount' => '100.00', + 'description' => 'desc', + 'extraData1' => 'extra 1', + 'extraData2' => 'extra 2', + 'extraData3' => 'extra 3', + 'language' => 'a language', + 'items' => array( + array('name' => 'item 1', 'quantity' => 1), + array('name' => 'item 2', 'quantity' => 2) + ), + 'clientIp' => '127.0.0.1', + 'googleAnalyticsCode' => 'analytics code', + 'card' => array( + 'email' => 'something@example.com', + 'firstName' => 'first name', + 'lastName' => 'last name', + 'address1' => 'address 1', + 'address2' => 'address 2', + 'postcode' => '1000', + 'city' => 'a city', + 'country' => 'a country', + 'phone' => 'phone number', + ) + )); + } + + public function testSendSuccess() + { + $this->setMockHttpResponse('XmlPurchaseSuccess.txt'); + + $response = $this->request->send(); + + $this->assertFalse($response->isSuccessful()); + $this->assertTrue($response->isRedirect()); + $this->assertEquals( + 'https://testpay.multisafepay.com/pay/?transaction=1373536347Hz4sFtg7WgMulO5q123456&lang=', + $response->getRedirectUrl() + ); + + $this->assertEquals('123456', $response->getTransactionReference()); + } + + public function testSendFailure() + { + $this->setMockHttpResponse('XmlPurchaseFailure.txt'); + + $response = $this->request->send(); + + $this->assertFalse($response->isSuccessful()); + $this->assertEquals('Invalid amount', $response->getMessage()); + $this->assertEquals(1001, $response->getCode()); + } + + /** + * @dataProvider allDataProvider + */ + public function testGetData($xml) + { + $data = $this->request->getData(); + $this->assertInstanceOf('SimpleXMLElement', $data); + + // Just so the provider remains readable... + $dom = dom_import_simplexml($data)->ownerDocument; + $dom->formatOutput = true; + $this->assertEquals($xml, $dom->saveXML()); + } + + /** + * @dataProvider noIssuerDataProvider + */ + public function testGetDataWithNonIDEALGatewayDoesNotSetIssuer($xml) + { + $this->request->setGateway('another'); + $data = $this->request->getData(); + $this->assertInstanceOf('SimpleXMLElement', $data); + + // Just so the provider remains readable... + $dom = dom_import_simplexml($data)->ownerDocument; + $dom->formatOutput = true; + $this->assertEquals($xml, $dom->saveXML()); + } + + /** + * @dataProvider specialCharsDataProvider + */ + public function testGetDataWithUrlsWithSpecialChars($xml) + { + $this->request->setReturnUrl('http://localhost/?one=1&two=2'); + $this->request->setCancelUrl('http://localhost/?one=1&two=2'); + $this->request->setNotifyUrl('http://localhost/?one=1&two=2'); + $data = $this->request->getData(); + $this->assertInstanceOf('SimpleXMLElement', $data); + + // Just so the provider remains readable... + $dom = dom_import_simplexml($data)->ownerDocument; + $dom->formatOutput = true; + $this->assertEquals($xml, $dom->saveXML()); + } + + /** + * @covers \Omnipay\MultiSafepay\Message\PurchaseRequest::generateSignature() + */ + public function testGenerateSignature() + { + $method = new ReflectionMethod('\Omnipay\MultiSafepay\Message\PurchaseRequest', 'generateSignature'); + $method->setAccessible(true); + + $signature = $method->invoke($this->request); + $this->assertEquals('ad447bab87b8597853432c891e341db1', $signature); + } + + public function allDataProvider() + { + $xml = << + + + 111111 + 222222 + 333333 + http://localhost/notify + http://localhost/cancel + http://localhost/return + + + 127.0.0.1 + a language + something@example.com + first name + last name + address 1 + address 2 + 1000 + a city + a country + phone number + + analytics code + + 123456 + EUR + 10000 + desc + extra 1 + extra 2 + extra 3 + IDEAL + <ul><li>1 x item 1</li><li>2 x item 2</li></ul> + + + issuer + + ad447bab87b8597853432c891e341db1 + + +EOF; + + return array( + array($xml), + ); + } + + public function noIssuerDataProvider() + { + $xml = << + + + 111111 + 222222 + 333333 + http://localhost/notify + http://localhost/cancel + http://localhost/return + + + 127.0.0.1 + a language + something@example.com + first name + last name + address 1 + address 2 + 1000 + a city + a country + phone number + + analytics code + + 123456 + EUR + 10000 + desc + extra 1 + extra 2 + extra 3 + another + <ul><li>1 x item 1</li><li>2 x item 2</li></ul> + + ad447bab87b8597853432c891e341db1 + + +EOF; + + return array( + array($xml), + ); + } + + public function specialCharsDataProvider() + { + $xml = << + + + 111111 + 222222 + 333333 + http://localhost/?one=1&two=2 + http://localhost/?one=1&two=2 + http://localhost/?one=1&two=2 + + + 127.0.0.1 + a language + something@example.com + first name + last name + address 1 + address 2 + 1000 + a city + a country + phone number + + analytics code + + 123456 + EUR + 10000 + desc + extra 1 + extra 2 + extra 3 + IDEAL + <ul><li>1 x item 1</li><li>2 x item 2</li></ul> + + + issuer + + ad447bab87b8597853432c891e341db1 + + +EOF; + + return array( + array($xml), + ); + } +} diff --git a/tests/Mock/FetchIssuersFailure.txt b/tests/Mock/RestFetchIssuersFailure.txt similarity index 100% rename from tests/Mock/FetchIssuersFailure.txt rename to tests/Mock/RestFetchIssuersFailure.txt diff --git a/tests/Mock/FetchIssuersSuccess.txt b/tests/Mock/RestFetchIssuersSuccess.txt similarity index 100% rename from tests/Mock/FetchIssuersSuccess.txt rename to tests/Mock/RestFetchIssuersSuccess.txt diff --git a/tests/Mock/FetchPaymentMethodsSuccess.txt b/tests/Mock/RestFetchPaymentMethodsSuccess.txt similarity index 100% rename from tests/Mock/FetchPaymentMethodsSuccess.txt rename to tests/Mock/RestFetchPaymentMethodsSuccess.txt diff --git a/tests/Mock/InvalidApiKeyFailure.txt b/tests/Mock/RestInvalidApiKeyFailure.txt similarity index 100% rename from tests/Mock/InvalidApiKeyFailure.txt rename to tests/Mock/RestInvalidApiKeyFailure.txt diff --git a/tests/Mock/PurchaseInvalidAmount.txt b/tests/Mock/RestPurchaseInvalidAmount.txt similarity index 100% rename from tests/Mock/PurchaseInvalidAmount.txt rename to tests/Mock/RestPurchaseInvalidAmount.txt diff --git a/tests/Mock/PurchaseSuccess.txt b/tests/Mock/RestPurchaseSuccess.txt similarity index 100% rename from tests/Mock/PurchaseSuccess.txt rename to tests/Mock/RestPurchaseSuccess.txt diff --git a/tests/Mock/XmlCompletePurchaseFailure.txt b/tests/Mock/XmlCompletePurchaseFailure.txt new file mode 100644 index 0000000..3d4544b --- /dev/null +++ b/tests/Mock/XmlCompletePurchaseFailure.txt @@ -0,0 +1,8 @@ +HTTP/1.1 200 OK +Date: Thu, 11 Jul 2013 10:36:27 GMT +Server: Apache/2.2.22 (FreeBSD) mod_ssl/2.2.22 OpenSSL/0.9.8q DAV/2 +Content-Length: 153 +Content-Type: text/xml + + +1016Back-end: missing data diff --git a/tests/Mock/XmlCompletePurchaseSuccess.txt b/tests/Mock/XmlCompletePurchaseSuccess.txt new file mode 100644 index 0000000..e7cc843 --- /dev/null +++ b/tests/Mock/XmlCompletePurchaseSuccess.txt @@ -0,0 +1,8 @@ +HTTP/1.1 200 OK +Date: Thu, 11 Jul 2013 10:34:48 GMT +Server: Apache/2.2.22 (FreeBSD) mod_ssl/2.2.22 OpenSSL/0.9.8q DAV/2 +Content-Length: 931 +Content-Type: text/xml + + +2087325completedNO201307111233082013071112331710000EURen_UStester@example.com123456EUR10000descIDEAL213698412Hr E G H Küppers en/of Mw M J Küppers an nog een lange consumername0050000075107095 diff --git a/tests/Mock/XmlFetchIssuersFailure.txt b/tests/Mock/XmlFetchIssuersFailure.txt new file mode 100644 index 0000000..7507ec6 --- /dev/null +++ b/tests/Mock/XmlFetchIssuersFailure.txt @@ -0,0 +1,10 @@ +HTTP/1.1 200 OK +Date: Thu, 11 Jul 2013 13:22:17 GMT +Server: Apache/2.2.16 (Debian) +X-Powered-By: PHP/5.3.3-7+squeeze14 +Vary: Accept-Encoding +Content-Length: 173 +Content-Type: text/xml + + +1005Invalid merchant security code diff --git a/tests/Mock/XmlFetchIssuersSuccess.txt b/tests/Mock/XmlFetchIssuersSuccess.txt new file mode 100644 index 0000000..2633e28 --- /dev/null +++ b/tests/Mock/XmlFetchIssuersSuccess.txt @@ -0,0 +1,10 @@ +HTTP/1.1 200 OK +Date: Thu, 11 Jul 2013 13:21:39 GMT +Server: Apache/2.2.16 (Debian) +X-Powered-By: PHP/5.3.3-7+squeeze14 +Vary: Accept-Encoding +Content-Length: 810 +Content-Type: text/xml + + +0031ABN AMRO0751SNS Bank0721ING0021Rabobank0091Friesland Bank0761ASN Bank0771SNS Regio Bank0511Triodos Bank0161Van Lanschot Bankiers0801Knab diff --git a/tests/Mock/XmlFetchPaymentMethodsFailure.txt b/tests/Mock/XmlFetchPaymentMethodsFailure.txt new file mode 100644 index 0000000..f43de62 --- /dev/null +++ b/tests/Mock/XmlFetchPaymentMethodsFailure.txt @@ -0,0 +1,10 @@ +HTTP/1.1 200 OK +Date: Thu, 11 Jul 2013 12:32:27 GMT +Server: Apache/2.2.16 (Debian) +X-Powered-By: PHP/5.3.3-7+squeeze14 +Vary: Accept-Encoding +Content-Length: 165 +Content-Type: text/xml + + +1005Invalid merchant security code diff --git a/tests/Mock/XmlFetchPaymentMethodsSuccess.txt b/tests/Mock/XmlFetchPaymentMethodsSuccess.txt new file mode 100644 index 0000000..0761273 --- /dev/null +++ b/tests/Mock/XmlFetchPaymentMethodsSuccess.txt @@ -0,0 +1,10 @@ +HTTP/1.1 200 OK +Date: Thu, 11 Jul 2013 12:31:26 GMT +Server: Apache/2.2.16 (Debian) +X-Powered-By: PHP/5.3.3-7+squeeze14 +Vary: Accept-Encoding +Content-Length: 459 +Content-Type: text/xml + + +VISAVisa CreditCardsWALLETMultiSafepayIDEALiDEALBANKTRANSBank TransferMASTERCARDMasterCard diff --git a/tests/Mock/XmlPurchaseFailure.txt b/tests/Mock/XmlPurchaseFailure.txt new file mode 100644 index 0000000..b7900c9 --- /dev/null +++ b/tests/Mock/XmlPurchaseFailure.txt @@ -0,0 +1,8 @@ +HTTP/1.1 200 OK +Date: Thu, 11 Jul 2013 10:06:38 GMT +Server: Apache/2.2.22 (FreeBSD) mod_ssl/2.2.22 OpenSSL/0.9.8q DAV/2 +Content-Length: 213 +Content-Type: text/xml + + +1001Invalid amount123456 diff --git a/tests/Mock/XmlPurchaseSuccess.txt b/tests/Mock/XmlPurchaseSuccess.txt new file mode 100644 index 0000000..1abdd95 --- /dev/null +++ b/tests/Mock/XmlPurchaseSuccess.txt @@ -0,0 +1,8 @@ +HTTP/1.1 200 OK +Date: Thu, 11 Jul 2013 09:52:27 GMT +Server: Apache/2.2.22 (FreeBSD) mod_ssl/2.2.22 OpenSSL/0.9.8q DAV/2 +Content-Length: 256 +Content-Type: text/xml + + +123456https://testpay.multisafepay.com/pay/?transaction=1373536347Hz4sFtg7WgMulO5q123456&lang= diff --git a/tests/GatewayTest.php b/tests/RestGatewayTest.php similarity index 66% rename from tests/GatewayTest.php rename to tests/RestGatewayTest.php index 5fcb9ed..cbbc762 100644 --- a/tests/GatewayTest.php +++ b/tests/RestGatewayTest.php @@ -2,18 +2,21 @@ use Omnipay\Tests\GatewayTestCase; -class GatewayTest extends GatewayTestCase +class RestGatewayTest extends GatewayTestCase { /** * @var Gateway */ protected $gateway; + /** + * @{inheritdoc} + */ protected function setUp() { parent::setUp(); - $this->gateway = new Gateway( + $this->gateway = new RestGateway( $this->getHttpClient(), $this->getHttpRequest() ); @@ -27,7 +30,7 @@ public function testFetchPaymentMethodsRequest() array('country' => 'NL') ); - $this->assertInstanceOf('Omnipay\MultiSafepay\Message\FetchPaymentMethodsRequest', $request); + $this->assertInstanceOf('Omnipay\MultiSafepay\Message\RestFetchPaymentMethodsRequest', $request); $this->assertEquals('NL', $request->getCountry()); } @@ -35,14 +38,14 @@ public function testFetchIssuersRequest() { $request = $this->gateway->fetchIssuers(); - $this->assertInstanceOf('Omnipay\MultiSafepay\Message\FetchIssuersRequest', $request); + $this->assertInstanceOf('Omnipay\MultiSafepay\Message\RestFetchIssuersRequest', $request); } public function testPurchaseRequest() { $request = $this->gateway->purchase(array('amount' => 10.00)); - $this->assertInstanceOf('Omnipay\MultiSafepay\Message\PurchaseRequest', $request); + $this->assertInstanceOf('Omnipay\MultiSafepay\Message\RestPurchaseRequest', $request); $this->assertEquals($request->getAmount(), 10.00); } @@ -50,7 +53,7 @@ public function testCompletePurchaseRequest() { $request = $this->gateway->completePurchase(array('amount' => 10.00)); - $this->assertInstanceOf('Omnipay\MultiSafepay\Message\CompletePurchaseRequest', $request); + $this->assertInstanceOf('Omnipay\MultiSafepay\Message\RestCompletePurchaseRequest', $request); $this->assertEquals($request->getAmount(), 10.00); } } diff --git a/tests/XmlGatewayTest.php b/tests/XmlGatewayTest.php new file mode 100644 index 0000000..7151c4b --- /dev/null +++ b/tests/XmlGatewayTest.php @@ -0,0 +1,154 @@ +gateway = new Gateway($this->getHttpClient(), $this->getHttpRequest()); + $this->gateway->setAccountId('111111'); + $this->gateway->setSiteId('222222'); + $this->gateway->setSiteCode('333333'); + + $this->options = array( + 'notifyUrl' => 'http://localhost/notify', + 'cancelUrl' => 'http://localhost/cancel', + 'returnUrl' => 'http://localhost/return', + 'gateway' => 'IDEAL', + 'issuer' => 'issuer', + 'transactionId' => '123456', + 'currency' => 'EUR', + 'amount' => '100.00', + 'description' => 'desc', + 'extraData1' => 'extra 1', + 'extraData2' => 'extra 2', + 'extraData3' => 'extra 3', + 'language' => 'a language', + 'clientIp' => '127.0.0.1', + 'googleAnalyticsCode' => 'analytics code', + 'card' => array( + 'email' => 'something@example.com', + 'firstName' => 'first name', + 'lastName' => 'last name', + 'address1' => 'address 1', + 'address2' => 'address 2', + 'postcode' => '1000', + 'city' => 'a city', + 'country' => 'a country', + 'phone' => 'phone number', + ) + ); + } + + public function testFetchPaymentMethods() + { + /** @var \Omnipay\MultiSafepay\Message\FetchPaymentMethodsRequest $request */ + $request = $this->gateway->fetchPaymentMethods(array('country' => 'NL')); + + $this->assertInstanceOf('Omnipay\MultiSafepay\Message\FetchPaymentMethodsRequest', $request); + $this->assertEquals('NL', $request->getCountry()); + } + + public function testFetchIssuers() + { + /** @var \Omnipay\MultiSafepay\Message\FetchIssuersRequest $request */ + $request = $this->gateway->fetchIssuers(); + + $this->assertInstanceOf('Omnipay\MultiSafepay\Message\FetchIssuersRequest', $request); + } + + public function testPurchase() + { + /** @var \Omnipay\MultiSafepay\Message\PurchaseRequest $request */ + $request = $this->gateway->purchase($this->options); + + /** @var CreditCard $card */ + $card = $request->getCard(); + + $this->assertInstanceOf('Omnipay\MultiSafepay\Message\PurchaseRequest', $request); + $this->assertSame('http://localhost/notify', $request->getNotifyUrl()); + $this->assertSame('http://localhost/cancel', $request->getCancelUrl()); + $this->assertSame('http://localhost/return', $request->getReturnUrl()); + $this->assertSame('IDEAL', $request->getGateway()); + $this->assertSame('issuer', $request->getIssuer()); + $this->assertSame('123456', $request->getTransactionId()); + $this->assertSame('EUR', $request->getCurrency()); + $this->assertSame('100.00', $request->getAmount()); + $this->assertSame('desc', $request->getDescription()); + $this->assertSame('extra 1', $request->getExtraData1()); + $this->assertSame('extra 2', $request->getExtraData2()); + $this->assertSame('extra 3', $request->getExtraData3()); + $this->assertSame('a language', $request->getLanguage()); + $this->assertSame('analytics code', $request->getGoogleAnalyticsCode()); + $this->assertSame('127.0.0.1', $request->getClientIp()); + $this->assertSame('something@example.com', $card->getEmail()); + $this->assertSame('first name', $card->getFirstName()); + $this->assertSame('last name', $card->getLastName()); + $this->assertSame('address 1', $card->getAddress1()); + $this->assertSame('address 2', $card->getAddress2()); + $this->assertSame('1000', $card->getPostcode()); + $this->assertSame('a city', $card->getCity()); + $this->assertSame('a country', $card->getCountry()); + $this->assertSame('phone number', $card->getPhone()); + } + + public function testCompletePurchase() + { + /** @var \Omnipay\MultiSafepay\Message\CompletePurchaseRequest $request */ + $request = $this->gateway->completePurchase($this->options); + + /** @var CreditCard $card */ + $card = $request->getCard(); + + $this->assertInstanceOf('Omnipay\MultiSafepay\Message\CompletePurchaseRequest', $request); + $this->assertSame('http://localhost/notify', $request->getNotifyUrl()); + $this->assertSame('http://localhost/cancel', $request->getCancelUrl()); + $this->assertSame('http://localhost/return', $request->getReturnUrl()); + $this->assertSame('IDEAL', $request->getGateway()); + $this->assertSame('issuer', $request->getIssuer()); + $this->assertSame('123456', $request->getTransactionId()); + $this->assertSame('EUR', $request->getCurrency()); + $this->assertSame('100.00', $request->getAmount()); + $this->assertSame('desc', $request->getDescription()); + $this->assertSame('extra 1', $request->getExtraData1()); + $this->assertSame('extra 2', $request->getExtraData2()); + $this->assertSame('extra 3', $request->getExtraData3()); + $this->assertSame('a language', $request->getLanguage()); + $this->assertSame('analytics code', $request->getGoogleAnalyticsCode()); + $this->assertSame('127.0.0.1', $request->getClientIp()); + $this->assertSame('something@example.com', $card->getEmail()); + $this->assertSame('first name', $card->getFirstName()); + $this->assertSame('last name', $card->getLastName()); + $this->assertSame('address 1', $card->getAddress1()); + $this->assertSame('address 2', $card->getAddress2()); + $this->assertSame('1000', $card->getPostcode()); + $this->assertSame('a city', $card->getCity()); + $this->assertSame('a country', $card->getCountry()); + $this->assertSame('phone number', $card->getPhone()); + } +}