From ff590969c7b5a3b87fcd1ec3ab343391204f3ce6 Mon Sep 17 00:00:00 2001 From: Friedemann Schmuhl Date: Fri, 2 Dec 2022 06:59:50 +0100 Subject: [PATCH] add 3DS v2.0 params with external authentication in FOP --- CHANGELOG.md | 1 + docs/samples/fop-createfop.rst | 62 +++++++++++ .../RequestOptions/Fop/CreditCardInfo.php | 5 + .../Fop/CreditCardSupplementaryData.php | 63 +++++++++++ .../Client/RequestOptions/Fop/MopInfo.php | 9 ++ .../RequestOptions/Fop/ThreeDSecureInfo.php | 103 ++++++++++++++++++ .../Client/Struct/Fop/AuthenticationData.php | 16 ++- .../Struct/Fop/AuthenticationDataDetails.php | 22 +++- .../Fop/CardSupplementaryCriteriaDetails.php | 52 +++++++++ .../Struct/Fop/CardSupplementaryData.php | 12 ++ .../Fop/CreateFormOfPayment/GroupUsage14.php | 6 +- .../Struct/Fop/CreditCardDetailedData.php | 14 ++- src/Amadeus/Client/Struct/Fop/GroupUsage.php | 6 +- .../Client/Struct/Fop/MopDescription.php | 14 ++- .../Client/Struct/Fop/PaymentModule.php | 8 +- .../Client/Struct/Fop/TdsInformation.php | 34 +++++- .../Client/Struct/Fop/TdsReferenceDetails.php | 2 + .../Struct/Fop/CreateFormOfPaymentTest.php | 69 +++++++++++- .../Client/Struct/Fop/MopDescriptionTest.php | 39 +++++++ .../Client/Struct/Fop/TdsInformationTest.php | 25 +++++ 20 files changed, 537 insertions(+), 25 deletions(-) create mode 100644 src/Amadeus/Client/RequestOptions/Fop/CreditCardSupplementaryData.php create mode 100644 src/Amadeus/Client/Struct/Fop/CardSupplementaryCriteriaDetails.php diff --git a/CHANGELOG.md b/CHANGELOG.md index c0f725b45..1d098705e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ## Unreleased +* Added Support for 3DS v2.0 with external Authentication in FOP_CreateFormOfPayment ## Release 1.13.0 (5 Apr 2021) * Add support for multiple pax types in Fare_MasterPricerTravelBoardSearch (https://github.com/amabnl/amadeus-ws-client/pull/432) - Artem Zakharchenko diff --git a/docs/samples/fop-createfop.rst b/docs/samples/fop-createfop.rst index 7d7dfd9dd..38f35665b 100644 --- a/docs/samples/fop-createfop.rst +++ b/docs/samples/fop-createfop.rst @@ -60,6 +60,68 @@ Query and response for handling 3DS data. $fopResponse = $client->fopCreateFormOfPayment($options); +3D-Secure payment version 2.x with external authentication +================= + +.. code-block:: php + + use Amadeus\Client\RequestOptions\Fop\CreditCardInfo; + use Amadeus\Client\RequestOptions\Fop\CreditCardSupplementaryData; + use Amadeus\Client\RequestOptions\Fop\Group; + use Amadeus\Client\RequestOptions\Fop\MopInfo; + use Amadeus\Client\RequestOptions\Fop\ThreeDSecureInfo; + use Amadeus\Client\RequestOptions\FopCreateFopOptions; + use Amadeus\Client\Struct\Fop\AttributeDetails; + + $options = new FopCreateFopOptions([ + 'transactionCode' => FopCreateFopOptions::TRANS_CREATE_FORM_OF_PAYMENT, + 'fopGroup' => [ + new Group([ + 'mopInfo' => [ + new MopInfo([ + 'fopType' => 'CC', + 'attributeType' => AttributeDetails::TYPE_FP_ELEMENT, + 'payMerchant' => 'EW', + 'mopPaymentType' => MopInfo::MOP_PAY_TYPE_CREDIT_CARD, + 'creditCardInfo' => new CreditCardInfo([ + 'name' => 'Name Surname', + 'cardNumber' => 'XXXXXXXXXXXX0003', + 'vendorCode' => 'VI', + 'expiryDate' => '1020', + 'securityId' => '999', + 'threeDSecure' => new ThreeDSecureInfo([ + 'transactionsStatus' => ThreeDSecureInfo::PARES_AUTHENTICATION_SUCCESSFUL, + 'tdsVersion' => '2.0.1', + 'creditCardCompany' => ThreeDSecureInfo::CC_COMP_VISA_DIRECTORY_SERVER, + 'authenticationIndicator' => '05', + 'tdsServerTransactionId' => 'U0RTRzNTRUczNEdTR1NFUldXRkNXRkRXRUZFRw==', + 'tdsServerTransactionIdLength' => 28, + 'directoryServerTransactionId' => 'Q2pENDJ0Tll0WlZ6VFcwSEVvdDVIRGt4TXpFPQ', + 'directoryServerTransactionIdLength' => 28, + 'tdsAuthenticationVerificationCode' => 'QUFBQkJYbGprUUFBQUFBRUFXT1JBQUFBQUFBPQ', + 'tdsAuthenticationVerificationCodeLength' => 28, + 'tdsAuthenticationVerificationCodeReference' => ThreeDSecureInfo::AUTHENTICATION_VERIFICATION_CODE_VISA + ]), + 'supplementaryData' => [ + new CreditCardSupplementaryData([ + 'setType' => CreditCardSupplementaryData::SET_TYPE_3DS, + 'attributeType' => CreditCardSupplementaryData::ATTRIBUTE_TYPE_EXTERNAL_AUTHENTICATION, + 'attributeDescription' => CreditCardSupplementaryData::ATTRIBUTE_DESCRIPTION_Y, + ]) + ] + ]), + 'sequenceNr' => 1, + 'fopCode' => CC, + 'fopStatus' => MopInfo::STATUS_NEW, + ]) + ] + ]) + ] + ]); + + $fopResponse = $client->fopCreateFormOfPayment($options); + + Best Effort =========== diff --git a/src/Amadeus/Client/RequestOptions/Fop/CreditCardInfo.php b/src/Amadeus/Client/RequestOptions/Fop/CreditCardInfo.php index 02c64adcf..fcba841b0 100644 --- a/src/Amadeus/Client/RequestOptions/Fop/CreditCardInfo.php +++ b/src/Amadeus/Client/RequestOptions/Fop/CreditCardInfo.php @@ -107,4 +107,9 @@ class CreditCardInfo extends LoadParamsFromArray * @var ThreeDSecureInfo */ public $threeDSecure; + + /** + * @var CreditCardSupplementaryData[] + */ + public $supplementaryData = []; } diff --git a/src/Amadeus/Client/RequestOptions/Fop/CreditCardSupplementaryData.php b/src/Amadeus/Client/RequestOptions/Fop/CreditCardSupplementaryData.php new file mode 100644 index 000000000..593fe6ec7 --- /dev/null +++ b/src/Amadeus/Client/RequestOptions/Fop/CreditCardSupplementaryData.php @@ -0,0 +1,63 @@ + + */ +class CreditCardSupplementaryData extends LoadParamsFromArray +{ + const SET_TYPE_AUTHENTICATION = 'ATN'; + const SET_TYPE_AUTHORIZATION = 'AUT'; + const SET_TYPE_3DS = '3DS'; + + const ATTRIBUTE_TYPE_EXTERNAL_AUTHENTICATION = 'EXTERNAL_AUTHENTICATION'; + + const ATTRIBUTE_DESCRIPTION_Y = 'Y'; + + /** + * Type of Data related to FOP account + * + * @var string + */ + public $setType; + + /** + * Used to add data related to FOP Account + * + * @var string + */ + public $attributeType; + + /** + * This is the data value. This may contain: - a potential attribute of the switch - the value of the structured data of the FOP + * + * @var string + */ + public $attributeDescription; +} diff --git a/src/Amadeus/Client/RequestOptions/Fop/MopInfo.php b/src/Amadeus/Client/RequestOptions/Fop/MopInfo.php index 164fc9d0e..6527453cd 100644 --- a/src/Amadeus/Client/RequestOptions/Fop/MopInfo.php +++ b/src/Amadeus/Client/RequestOptions/Fop/MopInfo.php @@ -121,6 +121,15 @@ class MopInfo extends LoadParamsFromArray */ public $fopType; + /** + * Describe one processing option at FOP level + * + * AttributeDetails::TYPE_* + * + * @var string + */ + public $attributeType; + /** * The Merchant company * diff --git a/src/Amadeus/Client/RequestOptions/Fop/ThreeDSecureInfo.php b/src/Amadeus/Client/RequestOptions/Fop/ThreeDSecureInfo.php index 20cdde5a9..741cccfad 100644 --- a/src/Amadeus/Client/RequestOptions/Fop/ThreeDSecureInfo.php +++ b/src/Amadeus/Client/RequestOptions/Fop/ThreeDSecureInfo.php @@ -42,12 +42,27 @@ class ThreeDSecureInfo extends LoadParamsFromArray const PARES_AUTHENTICATION_UNABLE = "U"; const PARES_AUTHENTICATION_SUCCESSFUL = "Y"; + const TRANSACTION_STATUS_ATTEMPTED_AUTHENTICATION = "A"; + const TRANSACTION_STATUS_AUTHENTICATION_FAILED = "N"; + const TRANSACTION_STATUS_AUTHENTICATION_UNABLE = "U"; + const TRANSACTION_STATUS_AUTHENTICATION_SUCCESSFUL = "Y"; + const CC_COMP_MASTERCARD_DIRECTORY_SERVER = "CADS"; const CC_COMP_VISA_DIRECTORY_SERVER = "VIDS"; const DATATYPE_BINARY = "B"; const DATATYPE_EDIFACT = "E"; + const CREDIT_CARD_COMPANY_VISA = 'VIDS'; + const CREDIT_CARD_COMPANY_MASTER_CARD = 'CADS'; + const CREDIT_CARD_COMPANY_AMERICAN_EXPRESS = 'AXDS'; + const CREDIT_CARD_COMPANY_DINERS = 'DCDS'; + const CREDIT_CARD_COMPANY_JCB = 'JCDS'; + + const AUTHENTICATION_VERIFICATION_CODE_VISA = 'CAVV'; + const AUTHENTICATION_VERIFICATION_CODE_AMERICAN_EXPRESS = 'AEVV'; + const AUTHENTICATION_VERIFICATION_CODE_MASTERCARD = 'AAV'; + /** * VERES status * @@ -66,6 +81,14 @@ class ThreeDSecureInfo extends LoadParamsFromArray */ public $paresStatus; + /** + * Transaction status + * + * self::TRANSACTION_STATUS_* + * + * @var string + */ + public $transactionsStatus; /** * self::CC_COMP_* * @@ -73,6 +96,13 @@ class ThreeDSecureInfo extends LoadParamsFromArray */ public $creditCardCompany; + /** + * Indicates the status of the enrolment and authentication phases + * + * @var string + */ + public $authenticationIndicator; + /** * Access Control Server URL * @@ -101,6 +131,79 @@ class ThreeDSecureInfo extends LoadParamsFromArray */ public $transactionIdentifierLength; + /** + * 3DS protocol version + * + * @var string + */ + public $tdsVersion; + + /** + * 3DS 2.0 partner transaction identifier + * + * @var string + */ + public $tdsServerTransactionId; + + /** + * @var string + */ + public $tdsServerTransactionIdDataType = self::DATATYPE_BINARY; + + /** + * Length of 3DS 2.0 partner transaction identifier + * + * @var string + */ + public $tdsServerTransactionIdLength; + + /** + * 3DS authentication verification code + * + * @var string + */ + public $tdsAuthenticationVerificationCode; + + /** + * 3DS authentication verification code reference (CAVV : Visa, Diners, JCB AEVV : American Express AAV : Mastercard) + * + * @var string + */ + public $tdsAuthenticationVerificationCodeReference; + + /** + * @var string + */ + public $tdsAuthenticationVerificationCodeDataType = self::DATATYPE_BINARY; + + /** + * 3DS authentication verification code + * + * @var int + */ + public $tdsAuthenticationVerificationCodeLength; + + /** + * Transaction identifier related to the Directory Server + * + * @package Amadeus\Client\RequestOptions\Fop + * + * @var string + */ + public $directoryServerTransactionId; + + /** + * @var string + */ + public $directoryServerTransactionIdDataType = self::DATATYPE_BINARY; + + /** + * Length of Directory Server Transaction Identifier string + * + * @var int + */ + public $directoryServerTransactionIdLength; + /** * PARES Authentication response * diff --git a/src/Amadeus/Client/Struct/Fop/AuthenticationData.php b/src/Amadeus/Client/Struct/Fop/AuthenticationData.php index 083376c79..a5930df7d 100644 --- a/src/Amadeus/Client/Struct/Fop/AuthenticationData.php +++ b/src/Amadeus/Client/Struct/Fop/AuthenticationData.php @@ -35,6 +35,12 @@ class AuthenticationData */ public $authenticationDataDetails; + /** + * Version of the 3DS protocol + * @var string + */ + public $tdsVersion; + /** * AuthenticationData constructor. * @@ -42,12 +48,18 @@ class AuthenticationData * @param string|null $paresStatus * @param string|null $company */ - public function __construct($veresStatus, $paresStatus, $company) + public function __construct($veresStatus, $paresStatus, $company, $transactionsStatus, $authenticationIndicator, $tdsVersion) { + if (false === empty($tdsVersion)) { + $this->tdsVersion = $tdsVersion; + } + $this->authenticationDataDetails = new AuthenticationDataDetails( $veresStatus, $paresStatus, - $company + $company, + $transactionsStatus, + $authenticationIndicator ); } } diff --git a/src/Amadeus/Client/Struct/Fop/AuthenticationDataDetails.php b/src/Amadeus/Client/Struct/Fop/AuthenticationDataDetails.php index 9c8dec5b9..9d6191c34 100644 --- a/src/Amadeus/Client/Struct/Fop/AuthenticationDataDetails.php +++ b/src/Amadeus/Client/Struct/Fop/AuthenticationDataDetails.php @@ -26,7 +26,7 @@ * AuthenticationDataDetails * * @package Amadeus\Client\Struct\Fop - * @author Dieter Devlieghere + * @author Dieter Devlieghere */ class AuthenticationDataDetails { @@ -51,6 +51,16 @@ class AuthenticationDataDetails */ public $pares; + /** + * A : attempt processing performed + * N : authentication failed + * U : unable to authenticate + * Y : authentication successful + * + * @var string + */ + public $transStatus; + /** * CADS MasterCard Directory Server * VIDS VISA Directory Server @@ -92,10 +102,12 @@ class AuthenticationDataDetails * @param string|null $paresStatus * @param string|null $company */ - public function __construct($veresStatus, $paresStatus, $company) + public function __construct($veresStatus, $paresStatus, $company, $transactionsStatus, $authenticationIndicator) { - $this->veres = $veresStatus; - $this->pares = $paresStatus; - $this->creditCardCompany = $company; + $this->veres = $veresStatus; + $this->pares = $paresStatus; + $this->creditCardCompany = $company; + $this->transStatus = $transactionsStatus; + $this->authenticationIndicator = $authenticationIndicator; } } diff --git a/src/Amadeus/Client/Struct/Fop/CardSupplementaryCriteriaDetails.php b/src/Amadeus/Client/Struct/Fop/CardSupplementaryCriteriaDetails.php new file mode 100644 index 000000000..a20fd6a0b --- /dev/null +++ b/src/Amadeus/Client/Struct/Fop/CardSupplementaryCriteriaDetails.php @@ -0,0 +1,52 @@ + + */ +class CardSupplementaryCriteriaDetails +{ + /** + * @var string + */ + public $attributeType; + + /** + * @var string + */ + public $attributeDescription; + + /** + * @param string $attributeType + * @param string $attributeDescription + */ + public function __construct($attributeType, $attributeDescription) + { + $this->attributeType = $attributeType; + $this->attributeDescription = $attributeDescription; + } +} diff --git a/src/Amadeus/Client/Struct/Fop/CardSupplementaryData.php b/src/Amadeus/Client/Struct/Fop/CardSupplementaryData.php index b88af2eb7..55ec800c2 100644 --- a/src/Amadeus/Client/Struct/Fop/CardSupplementaryData.php +++ b/src/Amadeus/Client/Struct/Fop/CardSupplementaryData.php @@ -30,4 +30,16 @@ */ class CardSupplementaryData { + public $criteriaSetType; + + /** + * @var CardSupplementaryCriteriaDetails + */ + public $criteriaDetails; + + public function __construct($setType, $attributeType, $attributeDescription) + { + $this->criteriaSetType = $setType; + $this->criteriaDetails = new CardSupplementaryCriteriaDetails($attributeType, $attributeDescription); + } } diff --git a/src/Amadeus/Client/Struct/Fop/CreateFormOfPayment/GroupUsage14.php b/src/Amadeus/Client/Struct/Fop/CreateFormOfPayment/GroupUsage14.php index 1f58da2ae..2d02faae0 100644 --- a/src/Amadeus/Client/Struct/Fop/CreateFormOfPayment/GroupUsage14.php +++ b/src/Amadeus/Client/Struct/Fop/CreateFormOfPayment/GroupUsage14.php @@ -41,10 +41,10 @@ class GroupUsage14 extends GroupUsage /** * GroupUsage constructor. * - * @param string $fopType AttributeDetails::TYPE_* + * @param string $attributeType AttributeDetails::TYPE_* */ - public function __construct($fopType) + public function __construct($attributeType) { - $this->attributeDetails = new AttributeDetails($fopType); + $this->attributeDetails = new AttributeDetails($attributeType); } } diff --git a/src/Amadeus/Client/Struct/Fop/CreditCardDetailedData.php b/src/Amadeus/Client/Struct/Fop/CreditCardDetailedData.php index 6889d572f..52a374171 100644 --- a/src/Amadeus/Client/Struct/Fop/CreditCardDetailedData.php +++ b/src/Amadeus/Client/Struct/Fop/CreditCardDetailedData.php @@ -22,6 +22,7 @@ namespace Amadeus\Client\Struct\Fop; +use Amadeus\Client\RequestOptions\Fop\CreditCardSupplementaryData; use Amadeus\Client\RequestOptions\Fop\ThreeDSecureInfo; use Amadeus\Client\Struct\WsMessageUtility; @@ -79,8 +80,9 @@ class CreditCardDetailedData extends WsMessageUtility * @param string $approvalCode * @param string $approvalSource * @param ThreeDSecureInfo|null $threeDSecure + * @param CreditCardSupplementaryData[] $cardSupplementaryData */ - public function __construct($approvalCode, $approvalSource, $threeDSecure = null) + public function __construct($approvalCode, $approvalSource, $threeDSecure = null, $cardSupplementaryData = null) { if (!empty($approvalCode)) { $this->approvalDetails = new ApprovalDetails($approvalCode, $approvalSource); @@ -89,5 +91,15 @@ public function __construct($approvalCode, $approvalSource, $threeDSecure = null if ($threeDSecure instanceof ThreeDSecureInfo) { $this->tdsInformation = new TdsInformation($threeDSecure); } + + if (is_array($cardSupplementaryData)) { + foreach ($cardSupplementaryData as $cardSupplementaryDatum) { + $this->cardSupplementaryData[] = new CardSupplementaryData( + $cardSupplementaryDatum->setType, + $cardSupplementaryDatum->attributeType, + $cardSupplementaryDatum->attributeDescription + ); + } + } } } diff --git a/src/Amadeus/Client/Struct/Fop/GroupUsage.php b/src/Amadeus/Client/Struct/Fop/GroupUsage.php index f5aecf17d..d2c8ab8ed 100644 --- a/src/Amadeus/Client/Struct/Fop/GroupUsage.php +++ b/src/Amadeus/Client/Struct/Fop/GroupUsage.php @@ -38,10 +38,10 @@ class GroupUsage /** * GroupUsage constructor. * - * @param string $fopType AttributeDetails::TYPE_* + * @param string $attributeType AttributeDetails::TYPE_* */ - public function __construct($fopType) + public function __construct($attributeType) { - $this->attributeDetails[] = new AttributeDetails($fopType); + $this->attributeDetails[] = new AttributeDetails($attributeType); } } diff --git a/src/Amadeus/Client/Struct/Fop/MopDescription.php b/src/Amadeus/Client/Struct/Fop/MopDescription.php index 5884f1ee6..dd926feb9 100644 --- a/src/Amadeus/Client/Struct/Fop/MopDescription.php +++ b/src/Amadeus/Client/Struct/Fop/MopDescription.php @@ -118,6 +118,7 @@ protected function loadPaymentModule(MopInfo $options) { if ($this->checkAnyNotEmpty( $options->fopType, + $options->attributeType, $options->payMerchant, $options->payments, $options->installmentsInfo, @@ -127,10 +128,16 @@ protected function loadPaymentModule(MopInfo $options) $options->payIds, $options->paySupData )) { + + /** + * for backwards compatibility use `$options->fopType` as default for `$attributeType` + */ + $attributeType = $options->attributeType ?: $options->fopType; + if ($this instanceof MopDescription14) { - $this->paymentModule = new PaymentModule14($options->fopType); + $this->paymentModule = new PaymentModule14($attributeType); } else { - $this->paymentModule = new PaymentModule($options->fopType); + $this->paymentModule = new PaymentModule($attributeType); } $this->paymentModule->loadPaymentData($options); @@ -179,7 +186,8 @@ protected function loadMopInformation(MopInfo $options) $this->paymentModule->mopDetailedData->creditCardDetailedData = new CreditCardDetailedData( $options->creditCardInfo->approvalCode, $options->creditCardInfo->sourceOfApproval, - $options->creditCardInfo->threeDSecure + $options->creditCardInfo->threeDSecure, + $options->creditCardInfo->supplementaryData ); } } diff --git a/src/Amadeus/Client/Struct/Fop/PaymentModule.php b/src/Amadeus/Client/Struct/Fop/PaymentModule.php index 8acc811b4..6fe210e71 100644 --- a/src/Amadeus/Client/Struct/Fop/PaymentModule.php +++ b/src/Amadeus/Client/Struct/Fop/PaymentModule.php @@ -73,14 +73,14 @@ class PaymentModule extends WsMessageUtility /** * PaymentModule constructor. * - * @param string $fopType + * @param string $attributeType */ - public function __construct($fopType) + public function __construct($attributeType) { if ($this instanceof PaymentModule14) { - $this->groupUsage = new GroupUsage14($fopType); + $this->groupUsage = new GroupUsage14($attributeType); } else { - $this->groupUsage = new GroupUsage($fopType); + $this->groupUsage = new GroupUsage($attributeType); } } diff --git a/src/Amadeus/Client/Struct/Fop/TdsInformation.php b/src/Amadeus/Client/Struct/Fop/TdsInformation.php index 3003b4249..7a4da98bf 100644 --- a/src/Amadeus/Client/Struct/Fop/TdsInformation.php +++ b/src/Amadeus/Client/Struct/Fop/TdsInformation.php @@ -59,11 +59,14 @@ public function __construct(ThreeDSecureInfo $options) $this->acsURL = new AcsUrl($options->acsUrl); } - if ($this->checkAnyNotEmpty($options->veresStatus, $options->paresStatus, $options->creditCardCompany)) { + if ($this->checkAnyNotEmpty($options->veresStatus, $options->paresStatus, $options->creditCardCompany, $options->transactionsStatus, $options->authenticationIndicator, $options->tdsVersion)) { $this->authenticationData = new AuthenticationData( $options->veresStatus, $options->paresStatus, - $options->creditCardCompany + $options->creditCardCompany, + $options->transactionsStatus, + $options->authenticationIndicator, + $options->tdsVersion ); } @@ -76,6 +79,33 @@ public function __construct(ThreeDSecureInfo $options) ); } + if (!empty($options->tdsServerTransactionId)) { + $this->tdsBlobData[] = new TdsBlobData( + TdsReferenceDetails::REG_THREEDS_SERVER_TRANSACTION_ID, + $options->tdsServerTransactionId, + $options->tdsServerTransactionIdDataType, + $options->tdsServerTransactionIdLength + ); + } + + if (!empty($options->tdsAuthenticationVerificationCode)) { + $this->tdsBlobData[] = new TdsBlobData( + $options->tdsAuthenticationVerificationCodeReference, + $options->tdsAuthenticationVerificationCode, + $options->tdsAuthenticationVerificationCodeDataType, + $options->tdsAuthenticationVerificationCodeLength + ); + } + + if (!empty($options->directoryServerTransactionId)) { + $this->tdsBlobData[] = new TdsBlobData( + TdsReferenceDetails::REG_DIRECTORY_SERVER_TRANSACTION_ID, + $options->directoryServerTransactionId, + $options->directoryServerTransactionIdDataType, + $options->directoryServerTransactionIdLength + ); + } + if (!empty($options->paresAuthResponse)) { $this->tdsBlobData[] = new TdsBlobData( TdsReferenceDetails::REF_PARES, diff --git a/src/Amadeus/Client/Struct/Fop/TdsReferenceDetails.php b/src/Amadeus/Client/Struct/Fop/TdsReferenceDetails.php index 23303c9a0..236f9130a 100644 --- a/src/Amadeus/Client/Struct/Fop/TdsReferenceDetails.php +++ b/src/Amadeus/Client/Struct/Fop/TdsReferenceDetails.php @@ -34,6 +34,8 @@ class TdsReferenceDetails const REF_VISA_CARD = 'CAVV'; const REF_MASTERCARD = 'AVVV'; const REF_THREEDS_TRANSACTION_IDENTIFIER = 'XID'; + const REG_THREEDS_SERVER_TRANSACTION_ID = '3DS_SERVER_TRANSACTIONID'; + const REG_DIRECTORY_SERVER_TRANSACTION_ID = 'DS_TRANSACTIONID'; /** * @var string diff --git a/tests/Amadeus/Client/Struct/Fop/CreateFormOfPaymentTest.php b/tests/Amadeus/Client/Struct/Fop/CreateFormOfPaymentTest.php index b43e845ab..689a32af9 100644 --- a/tests/Amadeus/Client/Struct/Fop/CreateFormOfPaymentTest.php +++ b/tests/Amadeus/Client/Struct/Fop/CreateFormOfPaymentTest.php @@ -23,6 +23,7 @@ namespace Test\Amadeus\Client\Struct\Fop; use Amadeus\Client\RequestOptions\Fop\CreditCardInfo; +use Amadeus\Client\RequestOptions\Fop\CreditCardSupplementaryData; use Amadeus\Client\RequestOptions\Fop\DataOrSwitch; use Amadeus\Client\RequestOptions\Fop\ElementRef; use Amadeus\Client\RequestOptions\Fop\FraudScreeningOptions; @@ -780,7 +781,7 @@ public function testCanMakeMessageWithManualApprovalCode() $msg = new CreateFormOfPayment($opt); - $this->assertEmpty( $msg->fopGroup[0]->pnrElementAssociation); + $this->assertEmpty($msg->fopGroup[0]->pnrElementAssociation); $this->assertCount(1, $msg->fopGroup[0]->passengerAssociation); $this->assertEquals(PassengerReference::TYPE_ADULT, $msg->fopGroup[0]->passengerAssociation[0]->passengerReference->type); @@ -1089,7 +1090,7 @@ public function testCanMakeMessageWithObFeesComputation() $this->assertEquals(TransactionDetails::TRANS_AUTH_ON_TICKET_MCO_EMD, $msg->transactionContext->transactionDetails->code); $this->assertEquals('O', $msg->transactionContext->transactionDetails->issueIndicator); - $this->assertEmpty( $msg->fopGroup[0]->pnrElementAssociation); + $this->assertEmpty($msg->fopGroup[0]->pnrElementAssociation); $this->assertEmpty($msg->fopGroup[0]->passengerAssociation); $this->assertEquals('NCE', $msg->fopGroup[0]->pricingTicketingDetails->locationDetails->city); @@ -1247,6 +1248,70 @@ public function testCanMakeMessageWith3dSecurePayment() $this->assertEquals(2996, $msg->fopGroup[0]->mopDescription[0]->paymentModule->mopDetailedData->creditCardDetailedData->tdsInformation->tdsBlobData[1]->tdsBlbData->dataLength); } + + public function testCanMakeMessageWithExternalAuthentication() + { + $opt = new FopCreateFopOptions([ + 'transactionCode' => FopCreateFopOptions::TRANS_CREATE_FORM_OF_PAYMENT, + 'fopGroup' => [ + new Group([ + 'mopInfo' => [ + new MopInfo([ + 'fopType' => 'CC', + 'attributeType' => AttributeDetails::TYPE_FP_ELEMENT, + 'payMerchant' => 'EW', + 'mopPaymentType' => MopInfo::MOP_PAY_TYPE_CREDIT_CARD, + 'creditCardInfo' => new CreditCardInfo([ + 'name' => 'Name Surname', + 'cardNumber' => 'XXXXXXXXXXXX0003', + 'vendorCode' => 'VI', + 'expiryDate' => '1020', + 'securityId' => '999', + 'threeDSecure' => new ThreeDSecureInfo([ + 'transactionsStatus' => ThreeDSecureInfo::PARES_AUTHENTICATION_SUCCESSFUL, + 'tdsVersion' => '2.0.1', + 'creditCardCompany' => ThreeDSecureInfo::CC_COMP_VISA_DIRECTORY_SERVER, + 'authenticationIndicator' => '05', + 'tdsServerTransactionId' => 'U0RTRzNTRUczNEdTR1NFUldXRkNXRkRXRUZFRw==', + 'tdsServerTransactionIdLength' => 28, + 'directoryServerTransactionId' => 'Q2pENDJ0Tll0WlZ6VFcwSEVvdDVIRGt4TXpFPQ', + 'directoryServerTransactionIdLength' => 28, + 'tdsAuthenticationVerificationCode' => 'QUFBQkJYbGprUUFBQUFBRUFXT1JBQUFBQUFBPQ', + 'tdsAuthenticationVerificationCodeLength' => 28, + 'tdsAuthenticationVerificationCodeReference' => ThreeDSecureInfo::AUTHENTICATION_VERIFICATION_CODE_VISA + ]), + 'supplementaryData' => [ + new CreditCardSupplementaryData([ + 'setType' => CreditCardSupplementaryData::SET_TYPE_3DS, + 'attributeType' => CreditCardSupplementaryData::ATTRIBUTE_TYPE_EXTERNAL_AUTHENTICATION, + 'attributeDescription' => CreditCardSupplementaryData::ATTRIBUTE_DESCRIPTION_Y, + ]) + ] + ]), + 'sequenceNr' => 1, + 'fopCode' => 'CCVI', + 'fopStatus' => MopInfo::STATUS_NEW, + ]) + ] + ]) + ] + ]); + + $msg = new CreateFormOfPayment($opt); + + $this->assertInstanceOf('\Amadeus\Client\Struct\Fop\CardSupplementaryData', $msg->fopGroup[0]->mopDescription[0]->paymentModule->mopDetailedData->creditCardDetailedData->cardSupplementaryData[0]); + $this->assertInstanceOf('\Amadeus\Client\Struct\Fop\CardSupplementaryCriteriaDetails', $msg->fopGroup[0]->mopDescription[0]->paymentModule->mopDetailedData->creditCardDetailedData->cardSupplementaryData[0]->criteriaDetails); + $this->assertSame(CreditCardSupplementaryData::SET_TYPE_3DS, $msg->fopGroup[0]->mopDescription[0]->paymentModule->mopDetailedData->creditCardDetailedData->cardSupplementaryData[0]->criteriaSetType); + $this->assertSame(CreditCardSupplementaryData::ATTRIBUTE_TYPE_EXTERNAL_AUTHENTICATION, $msg->fopGroup[0]->mopDescription[0]->paymentModule->mopDetailedData->creditCardDetailedData->cardSupplementaryData[0]->criteriaDetails->attributeType); + $this->assertSame(CreditCardSupplementaryData::ATTRIBUTE_DESCRIPTION_Y, $msg->fopGroup[0]->mopDescription[0]->paymentModule->mopDetailedData->creditCardDetailedData->cardSupplementaryData[0]->criteriaDetails->attributeDescription); + + $this->assertSame(AttributeDetails::TYPE_FP_ELEMENT, $msg->fopGroup[0]->mopDescription[0]->paymentModule->groupUsage->attributeDetails[0]->attributeType); + $this->assertSame('2.0.1', $msg->fopGroup[0]->mopDescription[0]->paymentModule->mopDetailedData->creditCardDetailedData->tdsInformation->authenticationData->tdsVersion); + $this->assertSame(ThreeDSecureInfo::PARES_AUTHENTICATION_SUCCESSFUL, $msg->fopGroup[0]->mopDescription[0]->paymentModule->mopDetailedData->creditCardDetailedData->tdsInformation->authenticationData->authenticationDataDetails->transStatus); + $this->assertSame('05', $msg->fopGroup[0]->mopDescription[0]->paymentModule->mopDetailedData->creditCardDetailedData->tdsInformation->authenticationData->authenticationDataDetails->authenticationIndicator); + + } + public function testCreateFopMessageGithubIssue163() { $options = new FopCreateFopOptions([ diff --git a/tests/Amadeus/Client/Struct/Fop/MopDescriptionTest.php b/tests/Amadeus/Client/Struct/Fop/MopDescriptionTest.php index 8d29d6ad1..165ac4159 100644 --- a/tests/Amadeus/Client/Struct/Fop/MopDescriptionTest.php +++ b/tests/Amadeus/Client/Struct/Fop/MopDescriptionTest.php @@ -22,8 +22,12 @@ namespace Test\Amadeus\Client\Struct\Fop; +use Amadeus\Client\RequestOptions\Fop\CreditCardInfo; +use Amadeus\Client\RequestOptions\Fop\CreditCardSupplementaryData; use Amadeus\Client\RequestOptions\Fop\DataOrSwitch; use Amadeus\Client\RequestOptions\Fop\MopInfo; +use Amadeus\Client\RequestOptions\Fop\ThreeDSecureInfo; +use Amadeus\Client\Struct\Fop\AttributeDetails; use Amadeus\Client\Struct\Fop\MopDescription; use Test\Amadeus\BaseTestCase; @@ -70,4 +74,39 @@ public function testCanConstructWithSwitches() $this->assertEquals('APM', $obj->mopDetails->pnrSupplementaryData[0]->dataAndSwitchMap->criteriaDetails[2]->attributeType); $this->assertEquals('1', $obj->mopDetails->pnrSupplementaryData[0]->dataAndSwitchMap->criteriaDetails[2]->attributeDescription); } + + public function testCanConstructWithThreeDSecureVersionTwo() + { + $mopInfo = new MopInfo([ + 'sequenceNr' => 1, + 'fopCode' => 'CCVI', + 'fopType' => 'CC', + 'fopStatus' => MopInfo::STATUS_NEW, + 'attributeType' => AttributeDetails::TYPE_FP_ELEMENT, + 'payMerchant' => 'EW', + 'mopPaymentType' => MopInfo::MOP_PAY_TYPE_CREDIT_CARD, + 'creditCardInfo' => new CreditCardInfo([ + 'name' => 'Name Surname', + 'cardNumber' => 'XXXXXXXXXXXX0003', + 'vendorCode' => 'VI', + 'expiryDate' => '1020', + 'securityId' => '999', + 'supplementaryData' => [ + new CreditCardSupplementaryData([ + 'setType' => CreditCardSupplementaryData::SET_TYPE_3DS, + 'attributeType' => CreditCardSupplementaryData::ATTRIBUTE_TYPE_EXTERNAL_AUTHENTICATION, + 'attributeDescription' => CreditCardSupplementaryData::ATTRIBUTE_DESCRIPTION_Y, + ]) + ], + 'threeDSecure' => new ThreeDSecureInfo([ + 'transactionsStatus' => ThreeDSecureInfo::PARES_AUTHENTICATION_SUCCESSFUL + ]) + ]) + ]); + + $obj = new MopDescription($mopInfo); + + $this->assertSame(AttributeDetails::TYPE_FP_ELEMENT, $obj->paymentModule->groupUsage->attributeDetails[0]->attributeType); + $this->assertSame(CreditCardSupplementaryData::SET_TYPE_3DS, $obj->paymentModule->mopDetailedData->creditCardDetailedData->cardSupplementaryData[0]->criteriaSetType); + } } diff --git a/tests/Amadeus/Client/Struct/Fop/TdsInformationTest.php b/tests/Amadeus/Client/Struct/Fop/TdsInformationTest.php index 377f57842..f6481bd7d 100644 --- a/tests/Amadeus/Client/Struct/Fop/TdsInformationTest.php +++ b/tests/Amadeus/Client/Struct/Fop/TdsInformationTest.php @@ -55,4 +55,29 @@ public function testCanConstructWithAcsUrl() $this->assertEquals('http://dummy.acs.url', $obj->acsURL->communication->internetAddress); $this->assertEquals(Communication::QUAL_WWW, $obj->acsURL->communication->adressQualifier); } + + public function testCanConstructWithThreeDSecureVersionTwo() + { + $options = new ThreeDSecureInfo([ + 'transactionsStatus' => ThreeDSecureInfo::PARES_AUTHENTICATION_SUCCESSFUL, + 'tdsVersion' => '2.0.1', + 'creditCardCompany' => ThreeDSecureInfo::CC_COMP_VISA_DIRECTORY_SERVER, + 'authenticationIndicator' => '05', + 'tdsServerTransactionId' => 'U0RTRzNTRUczNEdTR1NFUldXRkNXRkRXRUZFRw==', + 'tdsServerTransactionIdLength' => 28, + 'directoryServerTransactionId' => 'Q2pENDJ0Tll0WlZ6VFcwSEVvdDVIRGt4TXpFPQ', + 'directoryServerTransactionIdLength' => 28, + 'tdsAuthenticationVerificationCode' => 'QUFBQkJYbGprUUFBQUFBRUFXT1JBQUFBQUFBPQ', + 'tdsAuthenticationVerificationCodeLength' => 28, + 'tdsAuthenticationVerificationCodeReference' => ThreeDSecureInfo::AUTHENTICATION_VERIFICATION_CODE_VISA + ]); + + $obj = new TdsInformation($options); + + $this->assertEquals(ThreeDSecureInfo::PARES_AUTHENTICATION_SUCCESSFUL, $obj->authenticationData->authenticationDataDetails->transStatus); + $this->assertEquals('2.0.1', $obj->authenticationData->tdsVersion); + $this->assertEquals('U0RTRzNTRUczNEdTR1NFUldXRkNXRkRXRUZFRw==', $obj->tdsBlobData[0]->tdsBlbData->binaryData); + $this->assertEquals('QUFBQkJYbGprUUFBQUFBRUFXT1JBQUFBQUFBPQ', $obj->tdsBlobData[1]->tdsBlbData->binaryData); + $this->assertEquals('Q2pENDJ0Tll0WlZ6VFcwSEVvdDVIRGt4TXpFPQ', $obj->tdsBlobData[2]->tdsBlbData->binaryData); + } }