From 16efb08e19cb6c579deba11e119ef6409d28eae3 Mon Sep 17 00:00:00 2001 From: Braintree Date: Wed, 8 Nov 2023 00:15:11 +0000 Subject: [PATCH] 6.15.0 Co-authored-by: Sara Vasquez Co-authored-by: Debra Do --- CHANGELOG.md | 7 + lib/Braintree/MetaCheckoutCard.php | 100 +++++++ lib/Braintree/MetaCheckoutToken.php | 101 +++++++ lib/Braintree/PaymentInstrumentType.php | 2 + lib/Braintree/PaymentMethodGateway.php | 1 + .../Result/UsBankAccountVerification.php | 16 + lib/Braintree/Test/Nonces.php | 111 +++---- lib/Braintree/Transaction.php | 18 ++ .../Transaction/MetaCheckoutCardDetails.php | 24 ++ .../Transaction/MetaCheckoutTokenDetails.php | 24 ++ lib/Braintree/TransactionGateway.php | 4 + lib/Braintree/VenmoProfileData.php | 11 + lib/Braintree/Version.php | 2 +- lib/Braintree/WebhookTestingGateway.php | 14 + tests/integration/PaymentMethodNonceTest.php | 28 ++ .../PaymentMethodWithUsBankAccountTest.php | 65 +++- tests/integration/TransactionTest.php | 280 ++++++++++++++++++ tests/unit/EnrichedCustomerDataTest.php | 12 +- tests/unit/MetaCheckoutCardTest.php | 47 +++ tests/unit/MetaCheckoutTokenTest.php | 47 +++ ...tMethodCustomerDataUpdatedMetadataTest.php | 12 +- tests/unit/PaymentMethodTest.php | 1 + tests/unit/TransactionTest.php | 30 ++ tests/unit/UsBankAccountVerificationTest.php | 5 + tests/unit/VenmoProfileDataTest.php | 12 +- tests/unit/WebhookNotificationTest.php | 14 + 26 files changed, 927 insertions(+), 61 deletions(-) create mode 100644 lib/Braintree/MetaCheckoutCard.php create mode 100644 lib/Braintree/MetaCheckoutToken.php create mode 100644 lib/Braintree/Transaction/MetaCheckoutCardDetails.php create mode 100644 lib/Braintree/Transaction/MetaCheckoutTokenDetails.php create mode 100644 tests/unit/MetaCheckoutCardTest.php create mode 100644 tests/unit/MetaCheckoutTokenTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 55aac45d..17b5df65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 6.15.0 +* Add `billingAddress` and `shippingAddress` to `VenmoProfileData` for `PaymentMethodCustomerDataUpdated` webhook +* Add `MetaCheckoutCard` and `MetaCheckoutToken` payment methods +* Add `MetaCheckoutCardDetails` and `MetaCheckoutTokenDetails` to Transaction object +* Add `verificationAddOns` and `additionalProcessorResponse` to `PaymentMethodCreate` for ACH Network Check +* Add `dateOfBirth` and `countryCode` to `industry_data` + ## 6.14.0 * Add `arrivalDate` and `ticketIssuerAddress` to Transaction object * Add `SUBSCRIPTION_BILLING_SKIPPED` WebhookNotification diff --git a/lib/Braintree/MetaCheckoutCard.php b/lib/Braintree/MetaCheckoutCard.php new file mode 100644 index 00000000..f1542ab8 --- /dev/null +++ b/lib/Braintree/MetaCheckoutCard.php @@ -0,0 +1,100 @@ +default; + } + + /** + * checks whether the card is expired based on the current date + * + * @return boolean + */ + public function isExpired() + { + return $this->expired; + } + + /** + * sets instance properties from an array of values + * + * @param array $creditCardAttribs array of creditcard data + * + * @return void + */ + protected function _initialize($creditCardAttribs) + { + // set the attributes + $this->_attributes = $creditCardAttribs; + + $this->_set('expirationDate', $this->expirationMonth . '/' . $this->expirationYear); + $this->_set('maskedNumber', $this->bin . '******' . $this->last4); + + if (isset($creditCardAttribs['verifications']) && count($creditCardAttribs['verifications']) > 0) { + $verifications = $creditCardAttribs['verifications']; + usort($verifications, [$this, '_compareCreatedAtOnVerifications']); + + $this->_set('verification', CreditCardVerification::factory($verifications[0])); + } + } + + private function _compareCreatedAtOnVerifications($verificationAttrib1, $verificationAttrib2) + { + return ($verificationAttrib2['createdAt'] < $verificationAttrib1['createdAt']) ? -1 : 1; + } + + /** + * returns false if comparing object is not a MetaCheckoutCard, + * or is a MetaCheckoutCard with a different id + * + * @param object $otherMetaCheckoutCard customer to compare against + * + * @return boolean + */ + public function isEqual($otherMetaCheckoutCard) + { + return !($otherMetaCheckoutCard instanceof self) ? false : $this->token === $otherMetaCheckoutCard->token; + } + + // phpcs:ignore PEAR.Commenting.FunctionComment.Missing + public function __toString() + { + return __CLASS__ . '[' . + Util::attributesToString($this->_attributes) . ']'; + } + + /** + * Creates an instance from given attributes + * + * @param array $attributes response object attributes + * + * @return MetaCheckoutCard + */ + public static function factory($attributes) + { + $defaultAttributes = [ + 'bin' => '', + 'expirationMonth' => '', + 'expirationYear' => '', + 'last4' => '', + ]; + + $instance = new self(); + $instance->_initialize(array_merge($defaultAttributes, $attributes)); + return $instance; + } +} diff --git a/lib/Braintree/MetaCheckoutToken.php b/lib/Braintree/MetaCheckoutToken.php new file mode 100644 index 00000000..b2efe765 --- /dev/null +++ b/lib/Braintree/MetaCheckoutToken.php @@ -0,0 +1,101 @@ +default; + } + + /** + * checks whether the card is expired based on the current date + * + * @return boolean + */ + public function isExpired() + { + return $this->expired; + } + + /** + * sets instance properties from an array of values + * + * @param array $creditCardAttribs array of creditcard data + * + * @return void + */ + protected function _initialize($creditCardAttribs) + { + // set the attributes + $this->_attributes = $creditCardAttribs; + + + $this->_set('expirationDate', $this->expirationMonth . '/' . $this->expirationYear); + $this->_set('maskedNumber', $this->bin . '******' . $this->last4); + + if (isset($creditCardAttribs['verifications']) && count($creditCardAttribs['verifications']) > 0) { + $verifications = $creditCardAttribs['verifications']; + usort($verifications, [$this, '_compareCreatedAtOnVerifications']); + + $this->_set('verification', CreditCardVerification::factory($verifications[0])); + } + } + + private function _compareCreatedAtOnVerifications($verificationAttrib1, $verificationAttrib2) + { + return ($verificationAttrib2['createdAt'] < $verificationAttrib1['createdAt']) ? -1 : 1; + } + + /** + * returns false if comparing object is not a MetaCheckoutToken, + * or is a MetaCheckoutToken with a different id + * + * @param object $otherMetaCheckoutToken customer to compare against + * + * @return boolean + */ + public function isEqual($otherMetaCheckoutToken) + { + return !($otherMetaCheckoutToken instanceof self) ? false : $this->token === $otherMetaCheckoutToken->token; + } + + // phpcs:ignore PEAR.Commenting.FunctionComment.Missing + public function __toString() + { + return __CLASS__ . '[' . + Util::attributesToString($this->_attributes) . ']'; + } + + /** + * Creates an instance from given attributes + * + * @param array $attributes response object attributes + * + * @return MetaCheckoutToken + */ + public static function factory($attributes) + { + $defaultAttributes = [ + 'bin' => '', + 'expirationMonth' => '', + 'expirationYear' => '', + 'last4' => '', + ]; + + $instance = new self(); + $instance->_initialize(array_merge($defaultAttributes, $attributes)); + return $instance; + } +} diff --git a/lib/Braintree/PaymentInstrumentType.php b/lib/Braintree/PaymentInstrumentType.php index 76ac079c..a95ea9f1 100644 --- a/lib/Braintree/PaymentInstrumentType.php +++ b/lib/Braintree/PaymentInstrumentType.php @@ -13,6 +13,8 @@ class PaymentInstrumentType const CREDIT_CARD = 'credit_card'; const GOOGLE_PAY_CARD = 'android_pay_card'; const LOCAL_PAYMENT = 'local_payment'; + const META_CHECKOUT_CARD = 'meta_checkout_card'; + const META_CHECKOUT_TOKEN = 'meta_checkout_token'; const PAYPAL_ACCOUNT = 'paypal_account'; const PAYPAL_HERE = 'paypal_here'; const SAMSUNG_PAY_CARD = 'samsung_pay_card'; diff --git a/lib/Braintree/PaymentMethodGateway.php b/lib/Braintree/PaymentMethodGateway.php index c4921d5a..8cf4207c 100644 --- a/lib/Braintree/PaymentMethodGateway.php +++ b/lib/Braintree/PaymentMethodGateway.php @@ -152,6 +152,7 @@ private static function baseSignature() 'skipAdvancedFraudChecking', 'usBankAccountVerificationMethod', 'verificationAccountType', + 'verificationAddOns', 'verificationAmount', 'verificationMerchantAccountId', 'verifyCard', diff --git a/lib/Braintree/Result/UsBankAccountVerification.php b/lib/Braintree/Result/UsBankAccountVerification.php index 47d71a6b..c416b5f5 100644 --- a/lib/Braintree/Result/UsBankAccountVerification.php +++ b/lib/Braintree/Result/UsBankAccountVerification.php @@ -24,11 +24,15 @@ class UsBankAccountVerification extends Base const VERIFIED = 'verified'; const PENDING = 'pending'; + // Verification Method const TOKENIZED_CHECK = 'tokenized_check'; const NETWORK_CHECK = 'network_check'; const INDEPENDENT_CHECK = 'independent_check'; const MICRO_TRANSFERS = 'micro_transfers'; + // Verification Add Ons + const CUSTOMER_VERIFICATION = 'customer_verification'; + private $_gatewayRejectionReason; private $_status; @@ -103,4 +107,16 @@ public static function allVerificationMethods() UsBankAccountVerification::MICRO_TRANSFERS, ]; } + + /** + * returns an array of all possible US Bank Account Verification Add Ons + * + * @return array + */ + public static function allVerificationAddOns() + { + return [ + UsBankAccountVerification::CUSTOMER_VERIFICATION, + ]; + } } diff --git a/lib/Braintree/Test/Nonces.php b/lib/Braintree/Test/Nonces.php index 482389e1..7ee68034 100644 --- a/lib/Braintree/Test/Nonces.php +++ b/lib/Braintree/Test/Nonces.php @@ -15,75 +15,78 @@ class Nonces { // phpcs:disable Generic.Files.LineLength - public static $transactable = "fake-valid-nonce"; - public static $consumed = "fake-consumed-nonce"; - public static $paypalOneTimePayment = "fake-paypal-one-time-nonce"; - // NEXT_MAJOR_VERSION - no longer supported in the Gateway, remove this constant - public static $paypalFuturePayment = "fake-paypal-future-nonce"; - public static $paypalBillingAgreement = "fake-paypal-billing-agreement-nonce"; - public static $applePayVisa = "fake-apple-pay-visa-nonce"; - public static $applePayMasterCard = "fake-apple-pay-visa-nonce"; + public static $abstractTransactable = "fake-abstract-transactable-nonce"; public static $applePayAmEx = "fake-apple-pay-amex-nonce"; + public static $applePayMasterCard = "fake-apple-pay-visa-nonce"; + public static $applePayVisa = "fake-apple-pay-visa-nonce"; + public static $consumed = "fake-consumed-nonce"; + public static $europe = "fake-europe-bank-account-nonce"; + public static $gatewayRejectedFraud = "fake-gateway-rejected-fraud-nonce"; + public static $gatewayRejectedTokenIssuance = "fake-token-issuance-error-venmo-account-nonce"; public static $googlePay = "fake-android-pay-nonce"; + public static $googlePayAmEx = "fake-android-pay-amex-nonce"; public static $googlePayDiscover = "fake-android-pay-discover-nonce"; - public static $googlePayVisa = "fake-android-pay-visa-nonce"; public static $googlePayMasterCard = "fake-android-pay-mastercard-nonce"; - public static $googlePayAmEx = "fake-android-pay-amex-nonce"; - public static $abstractTransactable = "fake-abstract-transactable-nonce"; - public static $europe = "fake-europe-bank-account-nonce"; + public static $googlePayVisa = "fake-android-pay-visa-nonce"; + public static $localPayment = "fake-local-payment-method-nonce"; + public static $luhnInvalid = "fake-luhn-invalid-nonce"; + public static $metaCheckoutCard = "fake-meta-checkout-card-nonce"; + public static $metaCheckoutToken = "fake-meta-checkout-token-nonce"; + public static $paypalBillingAgreement = "fake-paypal-billing-agreement-nonce"; + // NEXT_MAJOR_VERSION - no longer supported in the Gateway, remove this constant + public static $paypalFuturePayment = "fake-paypal-future-nonce"; + public static $paypalFuturePaymentRefreshToken = "fake-paypal-future-refresh-token-nonce"; + public static $paypalOneTimePayment = "fake-paypal-one-time-nonce"; + public static $processorDeclinedAmEx = "fake-processor-declined-amex-nonce"; + public static $processorDeclinedDiscover = "fake-processor-declined-discover-nonce"; + public static $processorDeclinedMasterCard = "fake-processor-declined-mastercard-nonce"; + public static $processorDeclinedVisa = "fake-processor-declined-visa-nonce"; + public static $processorFailureJCB = "fake-processor-failure-jcb-nonce"; + public static $samsungPayAmEx = "tokensam_fake_american_express"; + public static $samsungPayDiscover = "tokensam_fake_discover"; + public static $samsungPayMasterCard = "tokensam_fake_mastercard"; + public static $samsungPayVisa = "tokensam_fake_visa"; + public static $sepa = "fake-sepa-bank-account-nonce"; public static $sepaDirectDebit = "fake-sepa-direct-debit-nonce"; - public static $transactableVisa = "fake-valid-visa-nonce"; - public static $transactableAmEx = "fake-valid-amex-nonce"; - public static $transactableMasterCard = "fake-valid-mastercard-nonce"; - public static $transactableDiscover = "fake-valid-discover-nonce"; - public static $transactableJCB = "fake-valid-jcb-nonce"; - public static $transactableMaestro = "fake-valid-maestro-nonce"; - public static $transactableDinersClub = "fake-valid-dinersclub-nonce"; - public static $transactablePrepaid = "fake-valid-prepaid-nonce"; - public static $transactableCommercial = "fake-valid-commercial-nonce"; - public static $transactableDurbinRegulated = "fake-valid-durbin-regulated-nonce"; - public static $transactableHealthcare = "fake-valid-healthcare-nonce"; - public static $transactableDebit = "fake-valid-debit-nonce"; - public static $transactablePayroll = "fake-valid-payroll-nonce"; + public static $threeDSecureTwoVisaErrorOnLookup = "fake-three-d-secure-two-visa-error-on-lookup-nonce"; + public static $threeDSecureTwoVisaSuccessfulFrictionlessAuthentication = "fake-three-d-secure-two-visa-successful-frictionless-authentication-nonce"; + public static $threeDSecureTwoVisaSuccessfulStepUpAuthentication = "fake-three-d-secure-two-visa-successful-step-up-authentication-nonce"; + public static $threeDSecureTwoVisaTimeoutOnLookup = "fake-three-d-secure-two-visa-timeout-on-lookup-nonce"; + public static $threeDSecureVisaAttemptsNonParticipating = "fake-three-d-secure-visa-attempts-non-participating-nonce"; + public static $threeDSecureVisaAuthenticationUnavailable = "fake-three-d-secure-visa-authentication-unavailable-nonce"; + public static $threeDSecureVisaBypassedAuthentication = "fake-three-d-secure-visa-bypassed-authentication-nonce"; + public static $threeDSecureVisaFailedAuthentication = "fake-three-d-secure-visa-failed-authentication-nonce"; + public static $threeDSecureVisaFailedSignature = "fake-three-d-secure-visa-failed-signature-nonce"; public static $threeDSecureVisaFullAuthenticationNonce = "fake-three-d-secure-visa-full-authentication-nonce"; public static $threeDSecureVisaLookupTimeout = "fake-three-d-secure-visa-lookup-timeout-nonce"; - public static $threeDSecureVisaFailedSignature = "fake-three-d-secure-visa-failed-signature-nonce"; - public static $threeDSecureVisaFailedAuthentication = "fake-three-d-secure-visa-failed-authentication-nonce"; - public static $threeDSecureVisaAttemptsNonParticipating = "fake-three-d-secure-visa-attempts-non-participating-nonce"; + public static $threeDSecureVisaMPIAuthenticateError = "fake-three-d-secure-visa-mpi-authenticate-error-nonce"; + public static $threeDSecureVisaMPILookupError = "fake-three-d-secure-visa-mpi-lookup-error-nonce"; public static $threeDSecureVisaNoteEnrolled = "fake-three-d-secure-visa-not-enrolled-nonce"; public static $threeDSecureVisaUnavailable = "fake-three-d-secure-visa-unavailable-nonce"; - public static $threeDSecureVisaMPILookupError = "fake-three-d-secure-visa-mpi-lookup-error-nonce"; - public static $threeDSecureVisaMPIAuthenticateError = "fake-three-d-secure-visa-mpi-authenticate-error-nonce"; - public static $threeDSecureVisaAuthenticationUnavailable = "fake-three-d-secure-visa-authentication-unavailable-nonce"; - public static $threeDSecureVisaBypassedAuthentication = "fake-three-d-secure-visa-bypassed-authentication-nonce"; - public static $threeDSecureTwoVisaSuccessfulFrictionlessAuthentication = "fake-three-d-secure-two-visa-successful-frictionless-authentication-nonce"; - public static $threeDSecureTwoVisaSuccessfulStepUpAuthentication = "fake-three-d-secure-two-visa-successful-step-up-authentication-nonce"; - public static $threeDSecureTwoVisaErrorOnLookup = "fake-three-d-secure-two-visa-error-on-lookup-nonce"; - public static $threeDSecureTwoVisaTimeoutOnLookup = "fake-three-d-secure-two-visa-timeout-on-lookup-nonce"; - public static $transactableNoIndicators = "fake-valid-no-indicators-nonce"; - public static $transactableUnknownIndicators = "fake-valid-unknown-indicators-nonce"; - public static $transactableCountryOfIssuanceUSA = "fake-valid-country-of-issuance-usa-nonce"; + public static $transactable = "fake-valid-nonce"; + public static $transactableAmEx = "fake-valid-amex-nonce"; + public static $transactableCommercial = "fake-valid-commercial-nonce"; public static $transactableCountryOfIssuanceCAD = "fake-valid-country-of-issuance-cad-nonce"; + public static $transactableCountryOfIssuanceUSA = "fake-valid-country-of-issuance-usa-nonce"; + public static $transactableDebit = "fake-valid-debit-nonce"; + public static $transactableDinersClub = "fake-valid-dinersclub-nonce"; + public static $transactableDiscover = "fake-valid-discover-nonce"; + public static $transactableDurbinRegulated = "fake-valid-durbin-regulated-nonce"; + public static $transactableHealthcare = "fake-valid-healthcare-nonce"; public static $transactableIssuingBankNetworkOnly = "fake-valid-issuing-bank-network-only-nonce"; - public static $processorDeclinedVisa = "fake-processor-declined-visa-nonce"; - public static $processorDeclinedMasterCard = "fake-processor-declined-mastercard-nonce"; - public static $processorDeclinedAmEx = "fake-processor-declined-amex-nonce"; - public static $processorDeclinedDiscover = "fake-processor-declined-discover-nonce"; - public static $processorFailureJCB = "fake-processor-failure-jcb-nonce"; - public static $luhnInvalid = "fake-luhn-invalid-nonce"; - public static $localPayment = "fake-local-payment-method-nonce"; - public static $paypalFuturePaymentRefreshToken = "fake-paypal-future-refresh-token-nonce"; - public static $sepa = "fake-sepa-bank-account-nonce"; - public static $gatewayRejectedFraud = "fake-gateway-rejected-fraud-nonce"; - public static $gatewayRejectedTokenIssuance = "fake-token-issuance-error-venmo-account-nonce"; + public static $transactableJCB = "fake-valid-jcb-nonce"; + public static $transactableMaestro = "fake-valid-maestro-nonce"; + public static $transactableMasterCard = "fake-valid-mastercard-nonce"; + public static $transactableNoIndicators = "fake-valid-no-indicators-nonce"; + public static $transactablePayroll = "fake-valid-payroll-nonce"; + public static $transactablePrepaid = "fake-valid-prepaid-nonce"; + public static $transactableUnknownIndicators = "fake-valid-unknown-indicators-nonce"; + public static $transactableVisa = "fake-valid-visa-nonce"; + public static $usBankAccount = "fake-us-bank-account-nonce"; public static $venmoAccount = "fake-venmo-account-nonce"; public static $visaCheckoutAmEx = "fake-visa-checkout-amex-nonce"; public static $visaCheckoutDiscover = "fake-visa-checkout-discover-nonce"; public static $visaCheckoutMasterCard = "fake-visa-checkout-mastercard-nonce"; public static $visaCheckoutVisa = "fake-visa-checkout-visa-nonce"; - public static $samsungPayAmEx = "tokensam_fake_american_express"; - public static $samsungPayDiscover = "tokensam_fake_discover"; - public static $samsungPayMasterCard = "tokensam_fake_mastercard"; - public static $samsungPayVisa = "tokensam_fake_visa"; // phpcs:enable Generic.Files.LineLength } diff --git a/lib/Braintree/Transaction.php b/lib/Braintree/Transaction.php index b79fb25d..fbdb31e1 100644 --- a/lib/Braintree/Transaction.php +++ b/lib/Braintree/Transaction.php @@ -233,6 +233,24 @@ protected function _initialize($transactionAttribs) ); } + if (isset($transactionAttribs['metaCheckoutCard'])) { + $this->_set( + 'metaCheckoutCardDetails', + new Transaction\MetaCheckoutCardDetails( + $transactionAttribs['metaCheckoutCard'] + ) + ); + } + + if (isset($transactionAttribs['metaCheckoutToken'])) { + $this->_set( + 'metaCheckoutTokenDetails', + new Transaction\MetaCheckoutTokenDetails( + $transactionAttribs['metaCheckoutToken'] + ) + ); + } + if (isset($transactionAttribs['visaCheckoutCard'])) { $this->_set( 'visaCheckoutCardDetails', diff --git a/lib/Braintree/Transaction/MetaCheckoutCardDetails.php b/lib/Braintree/Transaction/MetaCheckoutCardDetails.php new file mode 100644 index 00000000..abedc46e --- /dev/null +++ b/lib/Braintree/Transaction/MetaCheckoutCardDetails.php @@ -0,0 +1,24 @@ +_attributes['expirationDate'] = $this->expirationMonth . '/' . $this->expirationYear; + $this->_attributes['maskedNumber'] = $this->bin . '******' . $this->last4; + } +} diff --git a/lib/Braintree/Transaction/MetaCheckoutTokenDetails.php b/lib/Braintree/Transaction/MetaCheckoutTokenDetails.php new file mode 100644 index 00000000..1bacad8f --- /dev/null +++ b/lib/Braintree/Transaction/MetaCheckoutTokenDetails.php @@ -0,0 +1,24 @@ +_attributes['expirationDate'] = $this->expirationMonth . '/' . $this->expirationYear; + $this->_attributes['maskedNumber'] = $this->bin . '******' . $this->last4; + } +} diff --git a/lib/Braintree/TransactionGateway.php b/lib/Braintree/TransactionGateway.php index 5c01f66e..2f5d501d 100644 --- a/lib/Braintree/TransactionGateway.php +++ b/lib/Braintree/TransactionGateway.php @@ -228,6 +228,8 @@ public static function createSignature() 'folioNumber', 'checkInDate', 'checkOutDate', + 'countryCode', + 'dateOfBirth', 'travelPackage', 'departureDate', 'lodgingCheckInDate', @@ -343,7 +345,9 @@ public static function submitForSettlementSignature() 'arrivalDate', 'checkInDate', 'checkOutDate', + 'countryCode', 'customerCode', + 'dateOfBirth', 'departureDate', 'fareAmount', 'feeAmount', diff --git a/lib/Braintree/VenmoProfileData.php b/lib/Braintree/VenmoProfileData.php index a9920d7c..cb4355dd 100644 --- a/lib/Braintree/VenmoProfileData.php +++ b/lib/Braintree/VenmoProfileData.php @@ -25,6 +25,17 @@ public static function factory($attributes) protected function _initialize($venmoProfileDataAttribs) { $this->_attributes = $venmoProfileDataAttribs; + + $billingAddress = isset($venmoProfileDataAttribs['billingAddress']) ? + Address::factory($venmoProfileDataAttribs['billingAddress']) : + null; + + $shippingAddress = isset($venmoProfileDataAttribs['shippingAddress']) ? + Address::factory($venmoProfileDataAttribs['shippingAddress']) : + null; + + $this->_set('billingAddress', $billingAddress); + $this->_set('shippingAddress', $shippingAddress); } // phpcs:ignore PEAR.Commenting.FunctionComment.Missing diff --git a/lib/Braintree/Version.php b/lib/Braintree/Version.php index d76f5e54..d5a4f030 100644 --- a/lib/Braintree/Version.php +++ b/lib/Braintree/Version.php @@ -9,7 +9,7 @@ class Version { const MAJOR = 6; - const MINOR = 14; + const MINOR = 15; const TINY = 0; protected function __construct() diff --git a/lib/Braintree/WebhookTestingGateway.php b/lib/Braintree/WebhookTestingGateway.php index 914de24e..c4151881 100644 --- a/lib/Braintree/WebhookTestingGateway.php +++ b/lib/Braintree/WebhookTestingGateway.php @@ -823,6 +823,20 @@ private static function _paymentMethodCustomerDataUpdatedSampleXml($id) Doe 1231231234 john.doe@paypal.com + + billing-street-address + billing-extended-address + billing-locality + billing-region + billing-code + + + shipping-street-address + shipping-extended-address + shipping-locality + shipping-region + shipping-code + diff --git a/tests/integration/PaymentMethodNonceTest.php b/tests/integration/PaymentMethodNonceTest.php index 0453eaa3..bb5fe8ef 100644 --- a/tests/integration/PaymentMethodNonceTest.php +++ b/tests/integration/PaymentMethodNonceTest.php @@ -237,6 +237,34 @@ public function testFind_returnsBinDataForCommercialNonce() $this->assertEquals(Braintree\CreditCard::COMMERCIAL_YES, $nonce->binData->commercial); } + public function testFind_nonceShowsMetaCheckoutCardDetails() + { + $nonce = Braintree\PaymentMethodNonce::find(Braintree\Test\Nonces::$metaCheckoutCard); + $details = $nonce->details; + + $this->assertEquals('401288', $details["bin"]); + $this->assertEquals('81', $details["lastTwo"]); + $this->assertEquals('1881', $details["lastFour"]); + $this->assertEquals('Visa', $details["cardType"]); + $this->assertEquals('Meta Checkout Card Cardholder', $details["cardholderName"]); + $this->assertEquals('2024', $details["expirationYear"]); + $this->assertEquals('12', $details["expirationMonth"]); + } + + public function testFind_nonceShowsMetaCheckoutTokenDetails() + { + $nonce = Braintree\PaymentMethodNonce::find(Braintree\Test\Nonces::$metaCheckoutToken); + $details = $nonce->details; + + $this->assertEquals('401288', $details["bin"]); + $this->assertEquals('81', $details["lastTwo"]); + $this->assertEquals('1881', $details["lastFour"]); + $this->assertEquals('Visa', $details["cardType"]); + $this->assertEquals('Meta Checkout Token Cardholder', $details["cardholderName"]); + $this->assertEquals('2024', $details["expirationYear"]); + $this->assertEquals('12', $details["expirationMonth"]); + } + public function testFind_returnsBinDataForDebitNonce() { $nonce = Braintree\PaymentMethodNonce::find(Braintree\Test\Nonces::$transactableDebit); diff --git a/tests/integration/PaymentMethodWithUsBankAccountTest.php b/tests/integration/PaymentMethodWithUsBankAccountTest.php index f7187c30..ef64a1ab 100644 --- a/tests/integration/PaymentMethodWithUsBankAccountTest.php +++ b/tests/integration/PaymentMethodWithUsBankAccountTest.php @@ -42,7 +42,7 @@ public function testCreate_fromUsBankAccountNonceWithVerification() $customer = Braintree\Customer::createNoValidate(); $result = Braintree\PaymentMethod::create([ 'customerId' => $customer->id, - 'paymentMethodNonce' => Test\Helper::generateValidUsBankAccountNonce('1000000000'), + 'paymentMethodNonce' => Braintree\Test\Nonces::$usBankAccount, 'options' => [ 'verificationMerchantAccountId' => Test\Helper::usBankMerchantAccount(), 'usBankAccountVerificationMethod' => Braintree\Result\UsBankAccountVerification::NETWORK_CHECK, @@ -50,11 +50,40 @@ public function testCreate_fromUsBankAccountNonceWithVerification() ]); $usBankAccount = $result->paymentMethod; - $this->assertEquals('021000021', $usBankAccount->routingNumber); + $this->assertEquals('123456789', $usBankAccount->routingNumber); $this->assertEquals('0000', $usBankAccount->last4); $this->assertEquals('checking', $usBankAccount->accountType); $this->assertEquals('Dan Schulman', $usBankAccount->accountHolderName); - $this->assertMatchesRegularExpression('/CHASE/', $usBankAccount->bankName); + $this->assertEquals('Wells Fargo', $usBankAccount->bankName); + $this->assertEquals(true, $usBankAccount->verified); + + $this->assertEquals(1, count($usBankAccount->verifications)); + + $verification = $usBankAccount->verifications[0]; + + $this->assertEquals(Braintree\Result\UsBankAccountVerification::VERIFIED, $verification->status); + $this->assertEquals(Braintree\Result\UsBankAccountVerification::NETWORK_CHECK, $verification->verificationMethod); + } + + public function testCreate_fromUsBankAccountNonceWithVerificationAddOns() + { + $customer = Braintree\Customer::createNoValidate(); + $result = Braintree\PaymentMethod::create([ + 'customerId' => $customer->id, + 'paymentMethodNonce' => Braintree\Test\Nonces::$usBankAccount, + 'options' => [ + 'verificationMerchantAccountId' => Test\Helper::usBankMerchantAccount(), + 'usBankAccountVerificationMethod' => Braintree\Result\UsBankAccountVerification::NETWORK_CHECK, + 'verificationAddOns' => Braintree\Result\UsBankAccountVerification::CUSTOMER_VERIFICATION, + ] + ]); + + $usBankAccount = $result->paymentMethod; + $this->assertEquals('123456789', $usBankAccount->routingNumber); + $this->assertEquals('0000', $usBankAccount->last4); + $this->assertEquals('checking', $usBankAccount->accountType); + $this->assertEquals('Dan Schulman', $usBankAccount->accountHolderName); + $this->assertEquals('Wells Fargo', $usBankAccount->bankName); $this->assertEquals(true, $usBankAccount->verified); $this->assertEquals(1, count($usBankAccount->verifications)); @@ -63,6 +92,36 @@ public function testCreate_fromUsBankAccountNonceWithVerification() $this->assertEquals(Braintree\Result\UsBankAccountVerification::VERIFIED, $verification->status); $this->assertEquals(Braintree\Result\UsBankAccountVerification::NETWORK_CHECK, $verification->verificationMethod); + $this->assertEquals("1000", $verification->processorResponseCode); + } + + public function testCreate_returnsAdditionalProcessorResponseForFailedVerification() + { + $customer = Braintree\Customer::createNoValidate(); + $result = Braintree\PaymentMethod::create([ + 'customerId' => $customer->id, + 'paymentMethodNonce' => Test\Helper::generateValidUsBankAccountNonce('1000000005'), + 'options' => [ + 'verificationMerchantAccountId' => Test\Helper::usBankMerchantAccount(), + 'usBankAccountVerificationMethod' => Braintree\Result\UsBankAccountVerification::NETWORK_CHECK, + ] + ]); + + $usBankAccount = $result->paymentMethod; + $this->assertEquals('0005', $usBankAccount->last4); + $this->assertEquals('checking', $usBankAccount->accountType); + $this->assertEquals('Dan Schulman', $usBankAccount->accountHolderName); + $this->assertEquals('JPMORGAN CHASE', $usBankAccount->bankName); + $this->assertEquals(false, $usBankAccount->verified); + + $this->assertEquals(1, count($usBankAccount->verifications)); + + $verification = $usBankAccount->verifications[0]; + + $this->assertEquals(Braintree\Result\UsBankAccountVerification::PROCESSOR_DECLINED, $verification->status); + $this->assertEquals(Braintree\Result\UsBankAccountVerification::NETWORK_CHECK, $verification->verificationMethod); + $this->assertEquals("2061", $verification->processorResponseCode); + $this->assertEquals("Invalid routing number", $verification->additionalProcessorResponse); } public function testCreate_fromPlaidUsBankAccountNonce() diff --git a/tests/integration/TransactionTest.php b/tests/integration/TransactionTest.php index 563a3c9d..5061376a 100644 --- a/tests/integration/TransactionTest.php +++ b/tests/integration/TransactionTest.php @@ -1760,6 +1760,56 @@ public function testSale_withLineItemsValidationErrorTooManyLineItems() ); } + public function testCreateMetaCheckoutCardTxnWithFakeNonce() + { + $result = Braintree\Transaction::sale([ + 'amount' => '47.00', + 'paymentMethodNonce' => Braintree\Test\Nonces::$metaCheckoutCard + ]); + + $this->assertTrue($result->success); + $transaction = $result->transaction; + $details = $transaction->metaCheckoutCardDetails; + $this->assertSame('401288', $details->bin); + $this->assertSame('Visa', $details->cardType); + $this->assertSame('Meta Checkout Card Cardholder', $details->cardholderName); + $this->assertSame('https://assets.braintreegateway.com/payment_method_logo/visa.png?environment=development', $details->imageUrl); + $this->assertSame('container123', $details->containerId); + $this->assertSame('US', $details->customerLocation); + $this->assertSame('12/2024', $details->expirationDate); + $this->assertSame('12', $details->expirationMonth); + $this->assertSame('2024', $details->expirationYear); + $this->assertSame('1881', $details->last4); + $this->assertSame('401288******1881', $details->maskedNumber); + $this->assertSame('No', $details->prepaid); + } + + public function testCreateMetaCheckoutTokenTxnWithFakeNonce() + { + $result = Braintree\Transaction::sale([ + 'amount' => '47.00', + 'paymentMethodNonce' => Braintree\Test\Nonces::$metaCheckoutToken + ]); + + $this->assertTrue($result->success); + $transaction = $result->transaction; + $details = $transaction->metaCheckoutTokenDetails; + $this->assertSame('401288', $details->bin); + $this->assertSame('Visa', $details->cardType); + $this->assertSame('Meta Checkout Token Cardholder', $details->cardholderName); + $this->assertSame('https://assets.braintreegateway.com/payment_method_logo/visa.png?environment=development', $details->imageUrl); + $this->assertSame('container123', $details->containerId); + $this->assertSame('AlhlvxmN2ZKuAAESNFZ4GoABFA==', $details->cryptogram); + $this->assertSame('07', $details->ecommerceIndicator); + $this->assertSame('US', $details->customerLocation); + $this->assertSame('12/2024', $details->expirationDate); + $this->assertSame('12', $details->expirationMonth); + $this->assertSame('2024', $details->expirationYear); + $this->assertSame('1881', $details->last4); + $this->assertSame('401288******1881', $details->maskedNumber); + $this->assertSame('No', $details->prepaid); + } + public function testCreateTransactionUsingFakeApplePayNonce() { $result = Braintree\Transaction::sale([ @@ -3049,6 +3099,120 @@ public function testSubmitForSettlement_withDescriptor() $this->assertEquals('ebay.com', $submitResult->transaction->descriptor->url); } + public function testSubmitForSettlement_withIndustryDataFlight() + { + $nonce = Braintree\Test\Nonces::$paypalOneTimePayment; + $transactionResult = Braintree\Transaction::sale([ + 'amount' => Braintree\Test\TransactionAmounts::$authorize, + 'paymentMethodNonce' => $nonce + ]); + + $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transactionResult->transaction->status); + $submitResult = Braintree\Transaction::submitForSettlement($transactionResult->transaction->id, '50.00', [ + + 'industry' => [ + 'industryType' => Braintree\Transaction::TRAVEL_AND_FLIGHT_INDUSTRY, + 'data' => [ + 'countryCode' => 'US', + 'dateOfBirth' => '2012-12-12', + 'passengerFirstName' => 'John', + 'passengerLastName' => 'Doe', + 'passengerMiddleInitial' => 'M', + 'passengerTitle' => 'Mr.', + 'issuedDate' => '2018-01-01', + 'travelAgencyName' => 'Expedia', + 'travelAgencyCode' => '12345678', + 'ticketNumber' => 'ticket-number', + 'issuingCarrierCode' => 'AA', + 'customerCode' => 'customer-code', + 'fareAmount' => '70.00', + 'feeAmount' => '10.00', + 'taxAmount' => '20.00', + 'restrictedTicket' => false, + 'legs' => [ + [ + 'conjunctionTicket' => 'CJ0001', + 'exchangeTicket' => 'ET0001', + 'couponNumber' => '1', + 'serviceClass' => 'Y', + 'carrierCode' => 'AA', + 'fareBasisCode' => 'W', + 'flightNumber' => 'AA100', + 'departureDate' => '2018-01-02', + 'departureAirportCode' => 'MDW', + 'departureTime' => '08:00', + 'arrivalAirportCode' => 'ATX', + 'arrivalTime' => '10:00', + 'stopoverPermitted' => false, + 'fareAmount' => '35.00', + 'feeAmount' => '5.00', + 'taxAmount' => '10.00', + 'endorsementOrRestrictions' => 'NOT REFUNDABLE' + ], + [ + 'conjunctionTicket' => 'CJ0002', + 'exchangeTicket' => 'ET0002', + 'couponNumber' => '1', + 'serviceClass' => 'Y', + 'carrierCode' => 'AA', + 'fareBasisCode' => 'W', + 'flightNumber' => 'AA200', + 'departureDate' => '2018-01-03', + 'departureAirportCode' => 'ATX', + 'departureTime' => '12:00', + 'arrivalAirportCode' => 'MDW', + 'arrivalTime' => '14:00', + 'stopoverPermitted' => false, + 'fareAmount' => '35.00', + 'feeAmount' => '5.00', + 'taxAmount' => '10.00', + 'endorsementOrRestrictions' => 'NOT REFUNDABLE' + ] + ] + ] + ] + + ]); + $this->assertEquals(true, $submitResult->success); + $this->assertEquals(Braintree\Transaction::SETTLING, $submitResult->transaction->status); + $this->assertEquals('50.00', $submitResult->transaction->amount); + } + + public function testSubmitForSettlement_withTravelFlightIndustryDataValidation() + { + $nonce = Braintree\Test\Nonces::$paypalOneTimePayment; + $transactionResult = Braintree\Transaction::sale([ + 'amount' => Braintree\Test\TransactionAmounts::$authorize, + 'paymentMethodNonce' => $nonce + ]); + + $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transactionResult->transaction->status); + $result = Braintree\Transaction::submitForSettlement($transactionResult->transaction->id, '50.00', [ + 'industry' => [ + 'industryType' => Braintree\Transaction::TRAVEL_AND_FLIGHT_INDUSTRY, + 'data' => [ + 'fareAmount' => '-1.23', + 'legs' => [ + [ + 'fareAmount' => '-1.23' + ] + ] + ] + ] + ]); + $this->assertFalse($result->success); + $transaction = $result->transaction; + + $this->assertEquals( + Braintree\Error\Codes::INDUSTRY_DATA_TRAVEL_FLIGHT_FARE_AMOUNT_CANNOT_BE_NEGATIVE, + $result->errors->forKey('transaction')->forKey('industry')->onAttribute('fareAmount')[0]->code + ); + $this->assertEquals( + Braintree\Error\Codes::INDUSTRY_DATA_LEG_TRAVEL_FLIGHT_FARE_AMOUNT_CANNOT_BE_NEGATIVE, + $result->errors->forKey('transaction')->forKey('industry')->forKey('legs')->forKey('index0')->onAttribute('fareAmount')[0]->code + ); + } + public function testSubmitForSettlement_withInvalidParams() { $transaction = Braintree\Transaction::saleNoValidate([ @@ -5646,6 +5810,8 @@ public function testSale_withTravelFlightIndustryData() 'industry' => [ 'industryType' => Braintree\Transaction::TRAVEL_AND_FLIGHT_INDUSTRY, 'data' => [ + 'countryCode' => 'US', + 'dateOfBirth' => '2012-12-12', 'passengerFirstName' => 'John', 'passengerLastName' => 'Doe', 'passengerMiddleInitial' => 'M', @@ -6076,6 +6242,120 @@ public function testSubmitForPartialSettlement_withDescriptor() $this->assertEquals('ebay.com', $submitResult->transaction->descriptor->url); } + public function testSubmitForPartialSettlement_withIndustryDataFlight() + { + $nonce = Braintree\Test\Nonces::$paypalOneTimePayment; + $transactionResult = Braintree\Transaction::sale([ + 'amount' => Braintree\Test\TransactionAmounts::$authorize, + 'paymentMethodNonce' => $nonce + ]); + + $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transactionResult->transaction->status); + + $params = [ + 'industry' => [ + 'industryType' => Braintree\Transaction::TRAVEL_AND_FLIGHT_INDUSTRY, + 'data' => [ + 'countryCode' => 'US', + 'dateOfBirth' => '2012-12-12', + 'passengerFirstName' => 'John', + 'passengerLastName' => 'Doe', + 'passengerMiddleInitial' => 'M', + 'passengerTitle' => 'Mr.', + 'issuedDate' => '2018-01-01', + 'travelAgencyName' => 'Expedia', + 'travelAgencyCode' => '12345678', + 'ticketNumber' => 'ticket-number', + 'issuingCarrierCode' => 'AA', + 'customerCode' => 'customer-code', + 'fareAmount' => '70.00', + 'feeAmount' => '10.00', + 'taxAmount' => '20.00', + 'restrictedTicket' => false, + 'legs' => [ + [ + 'conjunctionTicket' => 'CJ0001', + 'exchangeTicket' => 'ET0001', + 'couponNumber' => '1', + 'serviceClass' => 'Y', + 'carrierCode' => 'AA', + 'fareBasisCode' => 'W', + 'flightNumber' => 'AA100', + 'departureDate' => '2018-01-02', + 'departureAirportCode' => 'MDW', + 'departureTime' => '08:00', + 'arrivalAirportCode' => 'ATX', + 'arrivalTime' => '10:00', + 'stopoverPermitted' => false, + 'fareAmount' => '35.00', + 'feeAmount' => '5.00', + 'taxAmount' => '10.00', + 'endorsementOrRestrictions' => 'NOT REFUNDABLE' + ], + [ + 'conjunctionTicket' => 'CJ0002', + 'exchangeTicket' => 'ET0002', + 'couponNumber' => '1', + 'serviceClass' => 'Y', + 'carrierCode' => 'AA', + 'fareBasisCode' => 'W', + 'flightNumber' => 'AA200', + 'departureDate' => '2018-01-03', + 'departureAirportCode' => 'ATX', + 'departureTime' => '12:00', + 'arrivalAirportCode' => 'MDW', + 'arrivalTime' => '14:00', + 'stopoverPermitted' => false, + 'fareAmount' => '35.00', + 'feeAmount' => '5.00', + 'taxAmount' => '10.00', + 'endorsementOrRestrictions' => 'NOT REFUNDABLE' + ] + ] + ] + ] + ]; + + $submitResult = Braintree\Transaction::submitForPartialSettlement($transactionResult->transaction->id, '20.00', $params); + $this->assertEquals(true, $submitResult->success); + $this->assertEquals(Braintree\Transaction::SETTLING, $submitResult->transaction->status); + } + + public function testSubmitForPartialSettlement_withTravelFlightIndustryDataValidation() + { + $nonce = Braintree\Test\Nonces::$paypalOneTimePayment; + $transactionResult = Braintree\Transaction::sale([ + 'amount' => Braintree\Test\TransactionAmounts::$authorize, + 'paymentMethodNonce' => $nonce + ]); + + $this->assertEquals(Braintree\Transaction::AUTHORIZED, $transactionResult->transaction->status); + $result = Braintree\Transaction::submitForPartialSettlement($transactionResult->transaction->id, '20.00', [ + 'industry' => [ + 'industryType' => Braintree\Transaction::TRAVEL_AND_FLIGHT_INDUSTRY, + 'data' => [ + 'fareAmount' => '-1.23', + 'legs' => [ + [ + 'fareAmount' => '-1.23' + ] + ] + ] + ] + ]); + $this->assertFalse($result->success); + $transaction = $result->transaction; + + $this->assertEquals( + Braintree\Error\Codes::INDUSTRY_DATA_TRAVEL_FLIGHT_FARE_AMOUNT_CANNOT_BE_NEGATIVE, + $result->errors->forKey('transaction')->forKey('industry')->onAttribute('fareAmount')[0]->code + ); + $this->assertEquals( + Braintree\Error\Codes::INDUSTRY_DATA_LEG_TRAVEL_FLIGHT_FARE_AMOUNT_CANNOT_BE_NEGATIVE, + $result->errors->forKey('transaction')->forKey('industry')->forKey('legs')->forKey('index0')->onAttribute('fareAmount')[0]->code + ); + } + public function testSubmitForPartialSettlement_withInvalidParams() { $transaction = Braintree\Transaction::saleNoValidate([ diff --git a/tests/unit/EnrichedCustomerDataTest.php b/tests/unit/EnrichedCustomerDataTest.php index ab971a4c..170de249 100644 --- a/tests/unit/EnrichedCustomerDataTest.php +++ b/tests/unit/EnrichedCustomerDataTest.php @@ -18,12 +18,22 @@ public function testFactory() public function testToString() { + $address = [ + "streetAddress" => "a-street-address", + "extendedAddress" => "an-extended-address", + "locality" => "a-locality", + "region" => "a-region", + "postalCode" => "a-code", + ]; + $profileDataParams = [ "username" => "venmo_username", "firstName" => "John", "lastName" => "Doe", "phoneNumber" => "1231231234", "email" => "john.doe@paypal.com", + "billingAddress" => $address, + "shippingAddress" => $address, ]; $enrichedCustomerDataParams = [ @@ -33,6 +43,6 @@ public function testToString() $enrichedCustomerData = Braintree\EnrichedCustomerData::factory($enrichedCustomerDataParams); - $this->assertEquals("Braintree\EnrichedCustomerData[fieldsUpdated=0=username, profileData=Braintree\VenmoProfileData[username=venmo_username, firstName=John, lastName=Doe, phoneNumber=1231231234, email=john.doe@paypal.com]]", (string) $enrichedCustomerData); + $this->assertEquals("Braintree\EnrichedCustomerData[fieldsUpdated=0=username, profileData=Braintree\VenmoProfileData[username=venmo_username, firstName=John, lastName=Doe, phoneNumber=1231231234, email=john.doe@paypal.com, billingAddress=Braintree\Address[streetAddress=a-street-address, extendedAddress=an-extended-address, locality=a-locality, region=a-region, postalCode=a-code], shippingAddress=Braintree\Address[streetAddress=a-street-address, extendedAddress=an-extended-address, locality=a-locality, region=a-region, postalCode=a-code]]]", (string) $enrichedCustomerData); } } diff --git a/tests/unit/MetaCheckoutCardTest.php b/tests/unit/MetaCheckoutCardTest.php new file mode 100644 index 00000000..3dd82812 --- /dev/null +++ b/tests/unit/MetaCheckoutCardTest.php @@ -0,0 +1,47 @@ + '', + 'expirationMonth' => '', + 'expirationYear' => '', + 'last4' => '', + ]; + + $creditCard = Braintree\MetaCheckoutCard::factory([]); + + $this->assertInstanceOf(Braintree\MetaCheckoutCard::class, $creditCard); + $this->assertEquals($defaultAttributes['bin'], $creditCard->bin); + $this->assertEquals($defaultAttributes['expirationMonth'], $creditCard->expirationMonth); + $this->assertEquals($defaultAttributes['expirationYear'], $creditCard->expirationYear); + $this->assertEquals($defaultAttributes['last4'], $creditCard->last4); + } + + public function testFactoryCreatesInstanceWithProvidedAttributes() + { + $attributes = [ + 'bin' => '1234', + 'expirationMonth' => '12', + 'expirationYear' => '25', + 'last4' => '5678', + ]; + + $creditCard = Braintree\MetaCheckoutCard::factory($attributes); + + $this->assertInstanceOf(Braintree\MetaCheckoutCard::class, $creditCard); + $this->assertEquals($attributes['bin'], $creditCard->bin); + $this->assertEquals($attributes['expirationMonth'], $creditCard->expirationMonth); + $this->assertEquals($attributes['expirationYear'], $creditCard->expirationYear); + $this->assertEquals($attributes['last4'], $creditCard->last4); + } +} diff --git a/tests/unit/MetaCheckoutTokenTest.php b/tests/unit/MetaCheckoutTokenTest.php new file mode 100644 index 00000000..88d219b3 --- /dev/null +++ b/tests/unit/MetaCheckoutTokenTest.php @@ -0,0 +1,47 @@ + '', + 'expirationMonth' => '', + 'expirationYear' => '', + 'last4' => '', + ]; + + $creditCard = Braintree\MetaCheckoutToken::factory([]); + + $this->assertInstanceOf(Braintree\MetaCheckoutToken::class, $creditCard); + $this->assertEquals($defaultAttributes['bin'], $creditCard->bin); + $this->assertEquals($defaultAttributes['expirationMonth'], $creditCard->expirationMonth); + $this->assertEquals($defaultAttributes['expirationYear'], $creditCard->expirationYear); + $this->assertEquals($defaultAttributes['last4'], $creditCard->last4); + } + + public function testFactoryCreatesInstanceWithProvidedAttributes() + { + $attributes = [ + 'bin' => '1234', + 'expirationMonth' => '12', + 'expirationYear' => '25', + 'last4' => '5678', + ]; + + $creditCard = Braintree\MetaCheckoutToken::factory($attributes); + + $this->assertInstanceOf(Braintree\MetaCheckoutToken::class, $creditCard); + $this->assertEquals($attributes['bin'], $creditCard->bin); + $this->assertEquals($attributes['expirationMonth'], $creditCard->expirationMonth); + $this->assertEquals($attributes['expirationYear'], $creditCard->expirationYear); + $this->assertEquals($attributes['last4'], $creditCard->last4); + } +} diff --git a/tests/unit/PaymentMethodCustomerDataUpdatedMetadataTest.php b/tests/unit/PaymentMethodCustomerDataUpdatedMetadataTest.php index 699ad6c3..2a32c784 100644 --- a/tests/unit/PaymentMethodCustomerDataUpdatedMetadataTest.php +++ b/tests/unit/PaymentMethodCustomerDataUpdatedMetadataTest.php @@ -18,12 +18,22 @@ public function testFactory() public function testToString() { + $address = [ + "streetAddress" => "a-street-address", + "extendedAddress" => "an-extended-address", + "locality" => "a-locality", + "region" => "a-region", + "postalCode" => "a-code" + ]; + $profileDataParams = [ "username" => "venmo_username", "firstName" => "John", "lastName" => "Doe", "phoneNumber" => "1231231234", "email" => "john.doe@paypal.com", + "billingAddress" => $address, + "shippingAddress" => $address, ]; $enrichedCustomerDataParams = [ @@ -62,6 +72,6 @@ public function testToString() $paymentMethodCustomerDataUpdatedMetadata = Braintree\PaymentMethodCustomerDataUpdatedMetadata::factory($paymentMethodCustomerDataUpdatedMetadataParams); - $this->assertEquals('Braintree\PaymentMethodCustomerDataUpdatedMetadata[token=TOKEN-12345, paymentMethod=paymentMethod=venmoAccount=createdAt=2018-10-11T21:28:37Z, updatedAt=2018-10-11T21:28:37Z, default=1, imageUrl=https://assets.braintreegateway.com/payment_method_logo/mastercard.png?environment=test, token=venmo_account, sourceDescription=Venmo Account: venmojoe, username=venmojoe, venmoUserId=456, subscriptions=, customerId=venmo_customer_id, globalId=cGF5bWVudG1ldGhvZF92ZW5tb2FjY291bnQ, datetimeUpdated=2022-01-01T21:28:37Z, enrichedCustomerData=Braintree\EnrichedCustomerData[fieldsUpdated=0=username, profileData=Braintree\VenmoProfileData[username=venmo_username, firstName=John, lastName=Doe, phoneNumber=1231231234, email=john.doe@paypal.com]]]', (string) $paymentMethodCustomerDataUpdatedMetadata); + $this->assertEquals('Braintree\PaymentMethodCustomerDataUpdatedMetadata[token=TOKEN-12345, paymentMethod=paymentMethod=venmoAccount=createdAt=2018-10-11T21:28:37Z, updatedAt=2018-10-11T21:28:37Z, default=1, imageUrl=https://assets.braintreegateway.com/payment_method_logo/mastercard.png?environment=test, token=venmo_account, sourceDescription=Venmo Account: venmojoe, username=venmojoe, venmoUserId=456, subscriptions=, customerId=venmo_customer_id, globalId=cGF5bWVudG1ldGhvZF92ZW5tb2FjY291bnQ, datetimeUpdated=2022-01-01T21:28:37Z, enrichedCustomerData=Braintree\EnrichedCustomerData[fieldsUpdated=0=username, profileData=Braintree\VenmoProfileData[username=venmo_username, firstName=John, lastName=Doe, phoneNumber=1231231234, email=john.doe@paypal.com, billingAddress=Braintree\Address[streetAddress=a-street-address, extendedAddress=an-extended-address, locality=a-locality, region=a-region, postalCode=a-code], shippingAddress=Braintree\Address[streetAddress=a-street-address, extendedAddress=an-extended-address, locality=a-locality, region=a-region, postalCode=a-code]]]]', (string) $paymentMethodCustomerDataUpdatedMetadata); } } diff --git a/tests/unit/PaymentMethodTest.php b/tests/unit/PaymentMethodTest.php index 07e6ab79..ebed752b 100644 --- a/tests/unit/PaymentMethodTest.php +++ b/tests/unit/PaymentMethodTest.php @@ -34,6 +34,7 @@ public function testCreateSignature() 'skipAdvancedFraudChecking', 'usBankAccountVerificationMethod', 'verificationAccountType', + 'verificationAddOns', 'verificationAmount', 'verificationMerchantAccountId', 'verifyCard', diff --git a/tests/unit/TransactionTest.php b/tests/unit/TransactionTest.php index 618cea8d..8c334ee2 100644 --- a/tests/unit/TransactionTest.php +++ b/tests/unit/TransactionTest.php @@ -106,6 +106,36 @@ public function testSaleWithoutSkipAdvancedFraudCheckingOption() ]); } + public function testTransactionWithMetaCheckoutCardAttributes() + { + $transaction = Braintree\Transaction::factory([ + 'amount' => '420', + 'metaCheckoutCard' => [ + 'expirationMonth' => "12", + 'expirationYear' => "2024", + 'bin' => "401288", + 'last4' => "1881", + ] + ]); + + $this->assertTrue($transaction->metaCheckoutCardDetails instanceof Braintree\Transaction\MetaCheckoutCardDetails); + } + + public function testTransactionWithMetaCheckoutTokenAttributes() + { + $transaction = Braintree\Transaction::factory([ + 'amount' => '420', + 'metaCheckoutToken' => [ + 'expirationMonth' => "12", + 'expirationYear' => "2024", + 'bin' => "401288", + 'last4' => "1881", + ] + ]); + + $this->assertTrue($transaction->metaCheckoutTokenDetails instanceof Braintree\Transaction\MetaCheckoutTokenDetails); + } + public function testTransactionWithSepaDebitAccountDetail() { $transaction = Braintree\Transaction::factory([ diff --git a/tests/unit/UsBankAccountVerificationTest.php b/tests/unit/UsBankAccountVerificationTest.php index 7ddf1cb0..94ddbbf6 100644 --- a/tests/unit/UsBankAccountVerificationTest.php +++ b/tests/unit/UsBankAccountVerificationTest.php @@ -15,6 +15,7 @@ public function testAttributes() $verification = Braintree\UsBankAccountVerification::factory([ 'status' => Braintree\Result\UsBankAccountVerification::VERIFIED, 'verificationMethod' => Braintree\Result\UsBankAccountVerification::NETWORK_CHECK, + 'verificationAddOns' => Braintree\Result\UsBankAccountVerification::CUSTOMER_VERIFICATION, 'usBankAccount' => [ 'token' => 'abc123', ], @@ -25,6 +26,10 @@ public function testAttributes() Braintree\Result\UsBankAccountVerification::NETWORK_CHECK, $verification->verificationMethod ); + $this->assertEquals( + Braintree\Result\UsBankAccountVerification::CUSTOMER_VERIFICATION, + $verification->verificationAddOns + ); $this->assertEquals( 'abc123', diff --git a/tests/unit/VenmoProfileDataTest.php b/tests/unit/VenmoProfileDataTest.php index c4f570cc..762fdd50 100644 --- a/tests/unit/VenmoProfileDataTest.php +++ b/tests/unit/VenmoProfileDataTest.php @@ -18,16 +18,26 @@ public function testFactory() public function testToString() { + $address = [ + "streetAddress" => "a-street-address", + "extendedAddress" => "an-extended-address", + "locality" => "a-locality", + "region" => "a-region", + "postalCode" => "a-code", + ]; + $profileDataParams = [ "username" => "venmo_username", "firstName" => "John", "lastName" => "Doe", "phoneNumber" => "1231231234", "email" => "john.doe@paypal.com", + "billingAddress" => $address, + "shippingAddress" => $address ]; $profileData = Braintree\VenmoProfileData::factory($profileDataParams); - $this->assertEquals("Braintree\VenmoProfileData[username=venmo_username, firstName=John, lastName=Doe, phoneNumber=1231231234, email=john.doe@paypal.com]", (string) $profileData); + $this->assertEquals("Braintree\VenmoProfileData[username=venmo_username, firstName=John, lastName=Doe, phoneNumber=1231231234, email=john.doe@paypal.com, billingAddress=Braintree\Address[streetAddress=a-street-address, extendedAddress=an-extended-address, locality=a-locality, region=a-region, postalCode=a-code], shippingAddress=Braintree\Address[streetAddress=a-street-address, extendedAddress=an-extended-address, locality=a-locality, region=a-region, postalCode=a-code]]", (string) $profileData); } } diff --git a/tests/unit/WebhookNotificationTest.php b/tests/unit/WebhookNotificationTest.php index dfbc7d60..05eb4096 100644 --- a/tests/unit/WebhookNotificationTest.php +++ b/tests/unit/WebhookNotificationTest.php @@ -1170,5 +1170,19 @@ public function testPaymentMethodCustomerDataUpdatedWebhook() $this->assertEquals('Doe', $profileData->lastName); $this->assertEquals('1231231234', $profileData->phoneNumber); $this->assertEquals('john.doe@paypal.com', $profileData->email); + + $billingAddress = $profileData->billingAddress; + $this->assertEquals('billing-street-address', $billingAddress->streetAddress); + $this->assertEquals('billing-extended-address', $billingAddress->extendedAddress); + $this->assertEquals('billing-locality', $billingAddress->locality); + $this->assertEquals('billing-region', $billingAddress->region); + $this->assertEquals('billing-code', $billingAddress->postalCode); + + $shippingAddress = $profileData->shippingAddress; + $this->assertEquals('shipping-street-address', $shippingAddress->streetAddress); + $this->assertEquals('shipping-extended-address', $shippingAddress->extendedAddress); + $this->assertEquals('shipping-locality', $shippingAddress->locality); + $this->assertEquals('shipping-region', $shippingAddress->region); + $this->assertEquals('shipping-code', $shippingAddress->postalCode); } }