From 3e936b464c4079e73ef8be947053ffcb378e24ff Mon Sep 17 00:00:00 2001 From: securesubmit-buildmaster Date: Tue, 16 Nov 2021 10:51:00 -0500 Subject: [PATCH] OctopusDeploy release: 2.4.2 --- CHANGELOG.md | 7 ++ metadata.xml | 2 +- src/Entities/HostedPaymentData.php | 20 ++++ src/Entities/Transaction.php | 5 +- src/Gateways/RealexConnector.php | 99 ++++++++++++++++++- .../RealexConnector/Hpp/RealexHppClient.php | 75 ++++++++++---- .../Gateways/RealexConnector/HppTest.php | 60 ++++++++++- .../RealexConnector/RealexApmTest.php | 47 ++++++++- 8 files changed, 284 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 279df3f8..743bd027 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ ## Latest version +#### Enhancements: +- Add LPMs HPP on GP-ECOM +- Add PAYPAL on GP-ECOM + +## v2.4.1 (11/12/2021) + +#### Enhancements: - Add reporting service to get transaction by id on GP-ECOM - Add HPP_POST_DIMENSIONS and HPP_POST_RESPONSE to serialize on GP-ECOM diff --git a/metadata.xml b/metadata.xml index 3892d528..e23fb165 100644 --- a/metadata.xml +++ b/metadata.xml @@ -1,3 +1,3 @@ - 2.4.1 + 2.4.2 \ No newline at end of file diff --git a/src/Entities/HostedPaymentData.php b/src/Entities/HostedPaymentData.php index 5a1a1045..97ef9808 100644 --- a/src/Entities/HostedPaymentData.php +++ b/src/Entities/HostedPaymentData.php @@ -2,6 +2,8 @@ namespace GlobalPayments\Api\Entities; +use GlobalPayments\Api\Entities\Enums\AlternativePaymentType; + /** * Data collection to supplement a hosted payment page. */ @@ -87,6 +89,24 @@ class HostedPaymentData */ public $supplementaryData; + /** @var string */ + public $customerCountry; + + /** @var string */ + public $customerFirstName; + + /** @var string */ + public $customerLastName; + + /** @var string */ + public $merchantResponseUrl; + + /** @var string */ + public $transactionStatusUrl; + + /** @var array */ + public $presetPaymentMethods = []; + /** * Instantiates a new `HostedPaymentData` object. * diff --git a/src/Entities/Transaction.php b/src/Entities/Transaction.php index df3572db..c2ad9445 100644 --- a/src/Entities/Transaction.php +++ b/src/Entities/Transaction.php @@ -477,10 +477,11 @@ public function void($amount = null) * * @return ManagementBuilder */ - public function confirm() + public function confirm($amount = null) { return (new ManagementBuilder(TransactionType::CONFIRM)) - ->withPaymentMethod($this->transactionReference); + ->withPaymentMethod($this->transactionReference) + ->withAmount($amount); } public function __get($name) diff --git a/src/Gateways/RealexConnector.php b/src/Gateways/RealexConnector.php index 79b70e74..15588a08 100644 --- a/src/Gateways/RealexConnector.php +++ b/src/Gateways/RealexConnector.php @@ -8,6 +8,7 @@ use GlobalPayments\Api\Builders\RecurringBuilder; use GlobalPayments\Api\Builders\ReportBuilder; use GlobalPayments\Api\Entities\Address; +use GlobalPayments\Api\Entities\Enums\AlternativePaymentType; use GlobalPayments\Api\Entities\Enums\CvnPresenceIndicator; use GlobalPayments\Api\Entities\Enums\PaymentMethodType; use GlobalPayments\Api\Entities\Enums\ReportType; @@ -562,6 +563,7 @@ public function serializeRequest(AuthorizationBuilder $builder) $this->hostedPaymentConfig->directCurrencyConversionEnabled ? "1" : "0"; } if (!empty($builder->hostedPaymentData)) { + $hostedPaymentData = $builder->hostedPaymentData; $this->setSerializeData('CUST_NUM', $builder->hostedPaymentData->customerNumber); if (!empty($this->hostedPaymentConfig->displaySavedCards) && @@ -590,6 +592,26 @@ public function serializeRequest(AuthorizationBuilder $builder) if (isset($builder->hostedPaymentData->productId)) { $this->setSerializeData('PROD_ID', $builder->hostedPaymentData->productId); } + // APMs Fields + if (!empty($hostedPaymentData->customerCountry)) { + $this->setSerializeData('HPP_CUSTOMER_COUNTRY', $hostedPaymentData->customerCountry); + } + if (!empty($hostedPaymentData->customerFirstName)) { + $this->setSerializeData('HPP_CUSTOMER_FIRSTNAME', $hostedPaymentData->customerFirstName); + } + if (!empty($hostedPaymentData->customerLastName)) { + $this->setSerializeData('HPP_CUSTOMER_LASTNAME', $hostedPaymentData->customerLastName); + } + if (!empty($hostedPaymentData->merchantResponseUrl)) { + $this->setSerializeData('MERCHANT_RESPONSE_URL', $hostedPaymentData->merchantResponseUrl); + } + if (!empty($hostedPaymentData->transactionStatusUrl)) { + $this->setSerializeData('HPP_TX_STATUS_URL', $hostedPaymentData->transactionStatusUrl); + } + if (!empty($hostedPaymentData->presetPaymentMethods)) { + $this->setSerializeData('PM_METHODS', implode( '|', $hostedPaymentData->presetPaymentMethods)); + } + // end APMs Fields } elseif (isset($builder->customerId)) { $this->setSerializeData('CUST_NUM', $builder->customerId); } @@ -705,9 +727,13 @@ public function serializeRequest(AuthorizationBuilder $builder) null; } - if (!empty($this->hostedPaymentConfig->fraudFilterMode) && $this->hostedPaymentConfig->fraudFilterMode !== FraudFilterMode::NONE) { + if ( + !empty($this->hostedPaymentConfig->fraudFilterMode) && + $this->hostedPaymentConfig->fraudFilterMode !== FraudFilterMode::NONE + ) { $toHash[] = $this->hostedPaymentConfig->fraudFilterMode; } + if (!empty($builder->dynamicDescriptor)) { $this->serializeData["CHARGE_DESCRIPTION"] = $builder->dynamicDescriptor; } @@ -768,6 +794,17 @@ public function manageTransaction(ManagementBuilder $builder) if ($builder->alternativePaymentType !== null) { $request->appendChild($xml->createElement("paymentmethod", $builder->alternativePaymentType)); + if ($builder->transactionType == TransactionType::CONFIRM) { + $paymentMethodDetails = $xml->createElement("paymentmethoddetails"); + $apmResponse = $builder->paymentMethod->alternativePaymentResponse; + if ($builder->alternativePaymentType == AlternativePaymentType::PAYPAL) { + $paymentMethodDetails->appendChild($xml->createElement('Token', $apmResponse->sessionToken)); + $paymentMethodDetails->appendChild( + $xml->createElement('PayerID', $apmResponse->providerReference) + ); + } + $request->appendChild($paymentMethodDetails); + } } if ($builder->transactionType === TransactionType::VERIFY_SIGNATURE) { @@ -1123,6 +1160,39 @@ protected function mapResponse($rawResponse, array $acceptedCodes = null) $root->paymentmethoddetails->redirecturl; $result->alternativePaymentResponse->paymentPurpose = (string) $root->paymentmethoddetails->paymentpurpose; + $result->alternativePaymentResponse->providerName = (string) $root->paymentmethod; + if (!empty($root->paymentmethoddetails->SetExpressCheckoutResponse)) { + $apmResponseDetails = $root->paymentmethoddetails->SetExpressCheckoutResponse; + } elseif (!empty($root->paymentmethoddetails->DoExpressCheckoutPaymentResponse)) { + $apmResponseDetails = $root->paymentmethoddetails->DoExpressCheckoutPaymentResponse; + } + if (!empty($apmResponseDetails)) { + $result->alternativePaymentResponse->sessionToken = !empty($apmResponseDetails->Token) ? + (string) $apmResponseDetails->Token : null; + $result->alternativePaymentResponse->ack = !empty($apmResponseDetails->Ack) ? + (string) $apmResponseDetails->Ack : null; + $result->alternativePaymentResponse->timeCreatedReference = !empty($apmResponseDetails->Timestamp) ? + (string) $apmResponseDetails->Timestamp : null; + $result->alternativePaymentResponse->correlationReference = !empty($apmResponseDetails->CorrelationID) ? + (string) $apmResponseDetails->CorrelationID : null; + $result->alternativePaymentResponse->versionReference = !empty($apmResponseDetails->Version) ? + (string) $apmResponseDetails->Version : null; + $result->alternativePaymentResponse->buildReference = !empty($apmResponseDetails->Build) ? + (string) $apmResponseDetails->Build : null; + if (!empty($apmResponseDetails->PaymentInfo)) { + $paymentInfo = $apmResponseDetails->PaymentInfo; + $result->alternativePaymentResponse->transactionReference = (string) $paymentInfo->TransactionID; + $result->alternativePaymentResponse->paymentType = (string) $paymentInfo->PaymentType; + $result->alternativePaymentResponse->paymentTimeReference = (string) $paymentInfo->PaymentDate; + $result->alternativePaymentResponse->grossAmount = (string) $paymentInfo->GrossAmount; + $result->alternativePaymentResponse->feeAmount = (string) $paymentInfo->TaxAmount; + $result->alternativePaymentResponse->paymentStatus = (string) $paymentInfo->PaymentStatus; + $result->alternativePaymentResponse->pendingReason = (string) $paymentInfo->PendingReason; + $result->alternativePaymentResponse->reasonCode = (string) $paymentInfo->ReasonCode; + $result->alternativePaymentResponse->authProtectionEligibilty = (string) $paymentInfo->ProtectionEligibility; + $result->alternativePaymentResponse->authProtectionEligibiltyType = (string) $paymentInfo->ProtectionEligibilityType; + } + } } return $result; @@ -1275,6 +1345,8 @@ protected function mapManageRequestType(ManagementBuilder $builder) return 'void'; case TransactionType::VERIFY_SIGNATURE: return '3ds-verifysig'; + case TransactionType::CONFIRM: + return 'payment-do'; default: return 'unknown'; } @@ -1460,13 +1532,20 @@ public function buildAlternativePaymentMethod($builder, $request, $xml) )); $paymentMethodDetails = $xml->createElement("paymentmethoddetails"); + list($returnUrl, $statusUpdateUrl, $cancelUrl) = + $this->mapAPMUrls($builder->paymentMethod->alternativePaymentMethodType); $paymentMethodDetails->appendChild( - $xml->createElement("returnurl", $builder->paymentMethod->returnUrl) + $xml->createElement($returnUrl, $builder->paymentMethod->returnUrl) ); $paymentMethodDetails->appendChild( - $xml->createElement("statusupdateurl", $builder->paymentMethod->statusUpdateUrl) + $xml->createElement($statusUpdateUrl, $builder->paymentMethod->statusUpdateUrl) ); - + if (!empty($builder->paymentMethod->cancelUrl)) { + $paymentMethodDetails->appendChild( + $xml->createElement($cancelUrl, $builder->paymentMethod->cancelUrl) + ); + } + if (!empty($builder->paymentMethod->descriptor)) { $paymentMethodDetails->appendChild( $xml->createElement("descriptor", $builder->paymentMethod->descriptor) @@ -1491,11 +1570,21 @@ private function mapAcceptedCodes($paymentMethodType) case "3ds-verifyenrolled": return ["00", "110"]; case "payment-set": - return ["01"]; + return ["01", "00"]; default: return ["00"]; } } + + private function mapAPMUrls($paymentMethodType) + { + switch ($paymentMethodType) { + case AlternativePaymentType::PAYPAL: + return ['ReturnURL', 'StatusUpdateURL', 'CancelURL']; + default: + return ['returnurl', 'statusupdateurl', 'cancelurl']; + } + } private function setSerializeData($key, $value = null) { diff --git a/test/Integration/Gateways/RealexConnector/Hpp/RealexHppClient.php b/test/Integration/Gateways/RealexConnector/Hpp/RealexHppClient.php index ddb6136f..f1cb0492 100644 --- a/test/Integration/Gateways/RealexConnector/Hpp/RealexHppClient.php +++ b/test/Integration/Gateways/RealexConnector/Hpp/RealexHppClient.php @@ -1,20 +1,22 @@ accountId = $account; $config->sharedSecret = $this->sharedSecret; $config->serviceUrl = 'https://api.sandbox.realexpayments.com/epage-remote.cgi'; + //to be uncomment in case you need to log the raw request/response +// $config->requestLogger = new SampleRequestLogger(new Logger("logs")); $config->hostedPaymentConfig = new HostedPaymentConfig(); $config->hostedPaymentConfig->language = "GB"; $config->hostedPaymentConfig->responseUrl = "http://requestb.in/10q2bjb1"; $config->hostedPaymentConfig->version = $hppVersion; ServicesContainer::configureService($config); - - // create the card object - $card = new CreditCardData(); - $card->number = '4006097467207025'; - $card->expMonth = 12; - $card->expYear = TestCards::validCardExpYear(); - $card->cvn = '131'; - $card->cardHolderName = 'James Mason'; - // // check hash $hashParam = [ $timestamp, @@ -72,6 +67,29 @@ public function sendRequest($jsonData, $hppVersion = '') $currency ]; + // create the card/APM/LPM object + if (!empty($this->getValue('PM_METHODS'))) { + $apmTypes = explode("|", $this->getValue('PM_METHODS')); + $apmType = reset($apmTypes); + $card = new AlternativePaymentMethod($apmType); + $card->returnUrl = $this->getValue('MERCHANT_RESPONSE_URL'); + $card->statusUpdateUrl = $this->getValue('HPP_TX_STATUS_URL'); + if ($apmType == AlternativePaymentType::PAYPAL) { + //cancelUrl for Paypal example + $card->cancelUrl = 'https://www.example.com/failure/cancelURL'; + } + $card->country = $this->getValue('HPP_CUSTOMER_COUNTRY'); + $card->accountHolderName = + $this->getValue('HPP_CUSTOMER_FIRSTNAME') . ' '. $this->getValue('HPP_CUSTOMER_LASTNAME') ; + } else { + $card = new CreditCardData(); + $card->number = '4006097467207025'; + $card->expMonth = 12; + $card->expYear = TestCards::validCardExpYear(); + $card->cvn = '131'; + $card->cardHolderName = 'James Mason'; + } + //for stored card if (!empty($this->paymentData['OFFER_SAVE_CARD'])) { $hashParam[] = (!empty($this->paymentData['PAYER_REF'])) ? @@ -83,11 +101,11 @@ public function sendRequest($jsonData, $hppVersion = '') if (!empty($this->paymentData['HPP_FRAUDFILTER_MODE'])) { $hashParam[] = $this->paymentData['HPP_FRAUDFILTER_MODE']; } - $newHash = GenerationUtils::generateHash( $this->sharedSecret, implode('.', $hashParam) ); + if ($newHash != $requestHash) { throw new ApiException("Incorrect hash. Please check your code and the Developers Documentation."); } @@ -125,13 +143,14 @@ public function sendRequest($jsonData, $hppVersion = '') $this->addFraudManagementInfo($gatewayRequest, $orderId); $gatewayResponse = $gatewayRequest->execute(); - - if ($gatewayResponse->responseCode === '00') { + + if (in_array($gatewayResponse->responseCode, ['00', '01'])) { return $this->convertResponse($gatewayResponse); } } catch (ApiException $exc) { throw $exc; } + return null; } @@ -266,13 +285,29 @@ public function convertResponse($gatewayResponse) 'DCC_INFO_REQUST' => $this->getValue('DCC_INFO'), 'DCC_INFO_RESPONSE' => $gatewayResponse->dccResponseResult, 'HPP_FRAUDFILTER_MODE' => $this->getValue('HPP_FRAUDFILTER_MODE'), - 'HPP_FRAUDFILTER_RESULT' => $gatewayResponse->fraudFilterResponse->fraudResponseResult + 'HPP_FRAUDFILTER_RESULT' => !empty($gatewayResponse->fraudFilterResponse) ? + $gatewayResponse->fraudFilterResponse->fraudResponseResult : null ]; - $hppFraudRules = []; - foreach ($gatewayResponse->fraudFilterResponse->fraudResponseRules as $fraudResponseRule) { - $hppFraudRules['HPP_FRAUDFILTER_RULE_' .$fraudResponseRule['id']] = $fraudResponseRule['action']; + if (!empty($gatewayResponse->transactionReference->alternativePaymentResponse)) { + /** @var AlternativePaymentResponse $alternativePaymentResponse */ + $alternativePaymentResponse = $gatewayResponse->transactionReference->alternativePaymentResponse; + $apmResponse = [ + 'HPP_CUSTOMER_FIRSTNAME' => $this->getValue('HPP_CUSTOMER_FIRSTNAME'), + 'HPP_CUSTOMER_LASTNAME' => $this->getValue('HPP_CUSTOMER_LASTNAME'), + 'HPP_CUSTOMER_COUNTRY' => $this->getValue('HPP_CUSTOMER_COUNTRY'), + 'PAYMENTMETHOD' => $alternativePaymentResponse->providerName, + 'PAYMENTPURPOSE' => $alternativePaymentResponse->paymentPurpose, + 'HPP_CUSTOMER_BANK_ACCOUNT' => $alternativePaymentResponse->bankAccount + ]; + $response = array_merge($response, $apmResponse); + } + if (!empty($gatewayResponse->fraudFilterResponse)) { + $hppFraudRules = []; + foreach ($gatewayResponse->fraudFilterResponse->fraudResponseRules as $fraudResponseRule) { + $hppFraudRules['HPP_FRAUDFILTER_RULE_' .$fraudResponseRule['id']] = $fraudResponseRule['action']; + } + $response = array_merge($response, $hppFraudRules); } - $response = array_merge($response, $hppFraudRules); $response['TSS_INFO'] = $this->getValue('TSS_INFO'); return json_encode($response); diff --git a/test/Integration/Gateways/RealexConnector/HppTest.php b/test/Integration/Gateways/RealexConnector/HppTest.php index b861dd37..5fb8f423 100644 --- a/test/Integration/Gateways/RealexConnector/HppTest.php +++ b/test/Integration/Gateways/RealexConnector/HppTest.php @@ -3,6 +3,8 @@ namespace GlobalPayments\Api\Test\Integration\Gateways\RealexConnector; use GlobalPayments\Api\Entities\Address; +use GlobalPayments\Api\Entities\Enums\AlternativePaymentType; +use GlobalPayments\Api\Entities\Enums\TransactionStatus; use GlobalPayments\Api\Entities\FraudRuleCollection; use GlobalPayments\Api\Services\HostedService; use GlobalPayments\Api\HostedPaymentConfig; @@ -53,7 +55,7 @@ public function basicSetup() $config->merchantId = "heartlandgpsandbox"; $config->accountId = "hpp"; $config->sharedSecret = "secret"; - $config->serviceUrl = "https://api.sandbox.realexpayments.com/epage-remote.cgi"; + $config->serviceUrl = "https://pay.sandbox.realexpayments.com/pay"; $config->hostedPaymentConfig = new HostedPaymentConfig(); $config->hostedPaymentConfig->language = "GB"; $config->hostedPaymentConfig->responseUrl = "http://requestb.in/10q2bjb1"; @@ -851,4 +853,60 @@ public function testNetherlandsAntillesCountry() $this->assertEquals('AN', $response['BILLING_CO']); $this->assertEquals('530', $response['HPP_BILLING_COUNTRY']); } + + /** + * We can set multiple APMs/LPMs on $presetPaymentMethods, but our HppClient for testing will treat only the first + * entry from the list as an example for our unit test, in this case will be "sofort" + */ + public function testBasicChargeAlternativePayment() + { + $config = new GpEcomConfig(); + $config->merchantId = "heartlandgpsandbox"; + $config->accountId = "hpp"; + $config->sharedSecret = "secret"; + $config->serviceUrl = "https://pay.sandbox.realexpayments.com/pay"; + + $config->hostedPaymentConfig = new HostedPaymentConfig(); + $config->hostedPaymentConfig->version = HppVersion::VERSION_2; + + $service = new HostedService($config); + + $hostedPaymentData = new HostedPaymentData(); + $hostedPaymentData->customerCountry = 'DE'; + $hostedPaymentData->customerFirstName = 'James'; + $hostedPaymentData->customerLastName = 'Mason'; + $hostedPaymentData->merchantResponseUrl = 'https://www.example.com/returnUrl'; + $hostedPaymentData->transactionStatusUrl = 'https://www.example.com/statusUrl'; + + $apmTypes = [ + AlternativePaymentType::SOFORTUBERWEISUNG, + AlternativePaymentType::TEST_PAY, + AlternativePaymentType::PAYPAL, + AlternativePaymentType::SEPA_DIRECTDEBIT_PPPRO_MANDATE_MODEL_A + ]; + $hostedPaymentData->presetPaymentMethods = $apmTypes; + + $json = $service->charge(10.01) + ->withCurrency("EUR") + ->withHostedPaymentData($hostedPaymentData) + ->serialize(); + + $response = json_decode($json, true); + $this->assertEquals(implode('|', $apmTypes), $response['PM_METHODS']); + $this->assertEquals($hostedPaymentData->customerFirstName, $response['HPP_CUSTOMER_FIRSTNAME']); + $this->assertEquals($hostedPaymentData->customerLastName, $response['HPP_CUSTOMER_LASTNAME']); + $this->assertEquals($hostedPaymentData->merchantResponseUrl, $response['MERCHANT_RESPONSE_URL']); + $this->assertEquals($hostedPaymentData->transactionStatusUrl, $response['HPP_TX_STATUS_URL']); + $this->assertEquals($hostedPaymentData->customerCountry, $response['HPP_CUSTOMER_COUNTRY']); + + $client = new RealexHppClient("secret"); + $response = $client->sendRequest($json, $config->hostedPaymentConfig->version); + $parsedResponse = $service->parseResponse($response); + + $this->assertNotNull($parsedResponse); + $this->assertEquals("01", $parsedResponse->responseCode); + $this->assertEquals(TransactionStatus::PENDING, $parsedResponse->responseMessage); + $this->assertEquals(AlternativePaymentType::SOFORTUBERWEISUNG, $parsedResponse->responseValues['PAYMENTMETHOD']); + $this->assertEquals($hostedPaymentData->merchantResponseUrl, $parsedResponse->responseValues['MERCHANT_RESPONSE_URL']); + } } diff --git a/test/Integration/Gateways/RealexConnector/RealexApmTest.php b/test/Integration/Gateways/RealexConnector/RealexApmTest.php index fccdb5ee..06bcfe5b 100644 --- a/test/Integration/Gateways/RealexConnector/RealexApmTest.php +++ b/test/Integration/Gateways/RealexConnector/RealexApmTest.php @@ -8,6 +8,9 @@ use GlobalPayments\Api\Entities\Transaction; use GlobalPayments\Api\ServiceConfigs\Gateways\GpEcomConfig; use PHPUnit\Framework\TestCase; +use GlobalPayments\Api\Utils\Logging\Logger; +use GlobalPayments\Api\Utils\Logging\SampleRequestLogger; +use GlobalPayments\Api\Entities\Exceptions\GatewayException; class RealexApmTest extends TestCase { @@ -16,11 +19,13 @@ protected function config() { $config = new GpEcomConfig(); $config->merchantId = "heartlandgpsandbox"; - $config->accountId = "hpp"; + $config->accountId = "api"; $config->rebatePassword = 'refund'; $config->refundPassword = 'refund'; $config->sharedSecret = "secret"; $config->serviceUrl = "https://api.sandbox.realexpayments.com/epage-remote.cgi"; +// $config->requestLogger = new SampleRequestLogger(new Logger("logs")); + return $config; } @@ -174,7 +179,7 @@ public function testAPMPayByBankApp() $paymentMethod->accountHolderName = 'James Mason'; $response = $paymentMethod->charge(10) - ->withCurrency("EUR") + ->withCurrency("GBP") ->withDescription('New APM') ->execute(); @@ -182,6 +187,44 @@ public function testAPMPayByBankApp() $this->assertEquals("01", $response->responseCode); } + public function testAPMPaypal() + { + $paymentMethod = new AlternativePaymentMethod(AlternativePaymentType::PAYPAL); + $paymentMethod->returnUrl = 'https://7b8e82a17ac00346e91e984f42a2a5fb.m.pipedream.net'; + $paymentMethod->statusUpdateUrl = 'https://7b8e82a17ac00346e91e984f42a2a5fb.m.pipedream.net'; + $paymentMethod->cancelUrl = 'https://7b8e82a17ac00346e91e984f42a2a5fb.m.pipedream.net'; + $paymentMethod->descriptor = 'Test Transaction'; + $paymentMethod->country = 'US'; + $paymentMethod->accountHolderName = 'James Mason'; + $amount = 10; $currency = 'USD'; + $transaction = $paymentMethod->charge($amount) + ->withCurrency($currency) + ->withDescription('New APM') + ->execute(); + + $this->assertNotEquals(null, $transaction); + $this->assertEquals("00", $transaction->responseCode); + $this->assertNotNull($transaction->alternativePaymentResponse->sessionToken); + + $redirectUrl = "Open link in browser and confirm PAYPAL payment: https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token={$transaction->alternativePaymentResponse->sessionToken}"; + fwrite(STDERR, print_r($redirectUrl, TRUE)); + sleep(30); + + $transaction->alternativePaymentResponse->providerReference = 'SMKGK7K2BLEUA'; + $exceptionCaught = false; + try { + $response = $transaction->confirm($amount) + ->withCurrency($currency) + ->withAlternativePaymentType(AlternativePaymentType::PAYPAL) + ->execute(); + $this->assertNotNull($response); + $this->assertEquals("00", $transaction->responseCode); + } catch (GatewayException $e) { + $exceptionCaught = true; + $this->assertEquals('Unexpected Gateway Response: 101 - Payment has not been authorized by the user.', $e->getMessage()); + } + } + public function testApmForRefund() { // a settle request requires the original order id