/** * Returns customer credit cards if applicable * * @return \Braintree_Customer|boolean */ public function getLoggedInCustomerCards() { $applicableCards = []; $useVault = (bool) (int) $this->scopeConfig->getValue(self::CONFIG_PATH_VAULT, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $this->sessionQuote->getStoreId()); if ($useVault) { $storedCards = false; if ($this->sessionQuote->getCustomerId()) { $customerId = $this->paymentHelper->generateCustomerId($this->sessionQuote->getCustomerId(), $this->sessionQuote->getQuote()->getCustomerEmail()); try { $storedCards = $this->braintreeCustomerAdapter->find($customerId)->creditCards; } catch (\Braintree_Exception $e) { $this->_logger->critical($e); } } if ($storedCards) { $country = $this->sessionQuote->getQuote()->getBillingAddress()->getCountryId(); $cardTypes = $this->paymentHelper->getCcAvailableCardTypes($country); $applicableCards = []; foreach ($storedCards as $card) { if (isset($cardTypes[$this->paymentHelper->getCcTypeCodeByName($card->cardType)])) { $applicableCards[] = $card; } } } } return $applicableCards; }
/** * Delete Braintree customer when Magento customer is deleted * * @param \Magento\Framework\Event\Observer $observer * @return $this */ public function execute(\Magento\Framework\Event\Observer $observer) { if (!$this->config->isActive()) { return $this; } $customer = $observer->getEvent()->getCustomer(); $customerId = $this->helper->generateCustomerId($customer->getId(), $customer->getEmail()); if ($this->vault->exists($customerId)) { $this->vault->deleteCustomer($customerId); } return $this; }
/** * @param string $params * @dataProvider dataProcessNonce */ public function testProcessNonceException($params = null, $exceptionMessage = null) { $this->customerSessionMock->expects($this->any())->method('getCustomerId')->willReturn($params['customerId']); $countryCollectionMock = $this->getMockBuilder('\\Magento\\Directory\\Model\\Resource\\Country\\Collection')->disableOriginalConstructor()->getMock(); $countryCollectionMock->expects($this->any())->method('addCountryCodeFilter')->willReturn($countryCollectionMock); $this->countryFactoryMock->expects($this->any())->method('create')->willReturn($countryCollectionMock); $this->configMock->expects($this->any())->method('canUseForCountry')->willReturn($params['canUseForCountry']); $this->configMock->expects($this->any())->method('canUseCcTypeForCountry')->willReturn($params['canUseCcTypeForCountry']); $this->helperMock->expects($this->any())->method('generateCustomerId')->willReturn($params['customerId']); $this->customerMock->expects($this->any())->method('load')->willReturn($this->customerMock); $this->customerFactoryMock->expects($this->any())->method('create')->willReturn($this->customerMock); if (is_object($params['paymentMethodObj'])) { if (!$params['optionsArray']['update']) { $this->braintreePaymentMethodMock->expects($this->once())->method('create')->willReturn($params['paymentMethodObj']); } else { $this->braintreePaymentMethodMock->expects($this->once())->method('update')->willReturn($params['paymentMethodObj']); } if (!$params['paymentMethodObj']->success) { $this->errorHelperMock->expects($this->once())->method('parseBraintreeError')->willReturn(new \Magento\Framework\Phrase($exceptionMessage)); } else { $this->errorHelperMock->expects($this->never())->method('parseBraintreeError'); } } try { $this->model->processNonce($params['nonce'], $params['optionsArray'], $params['billingAddress']); } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->assertEquals($exceptionMessage, $e->getMessage()); } }
/** * @param \Magento\Framework\DataObject $paymentObject * @param int $storeId * @return array * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ protected function setupPaymentObject(\Magento\Framework\DataObject $paymentObject, $storeId) { $customerId = '12'; $customerEmail = '*****@*****.**'; $company = 'NA'; $phone = '3316655'; $fax = '3316677'; $orderId = '100000024'; $street = '1201 N 1st Stree'; $street2 = 'build 45'; $city = 'San Jose'; $region = 'California'; $regionCode = 'CA'; $regionId = 65; $postcode = '63241'; $countryId = 'US'; $addressData = ['firstname' => self::FNAME, 'lastname' => self::LNAME, 'company' => $company, 'telephone' => $phone, 'fax' => $fax, 'street' => [$street, $street2], 'city' => $city, 'region' => $region, 'region_id' => $regionId, 'postcode' => $postcode, 'country_id' => $countryId, 'address_type' => 'billing']; $billingAddress = new \Magento\Framework\DataObject($addressData); $addressData['address_type'] = 'shipping'; $shippingAddress = new \Magento\Framework\DataObject($addressData); $order = $this->setupOrderMock($billingAddress, $shippingAddress, $customerEmail, $orderId, $customerId, $storeId); $paymentObject->setOrder($order); $this->helperMock->expects($this->once())->method('generateCustomerId')->with($customerId, $customerEmail)->willReturn(self::CUSTOMER_ID); $regionMock = $this->getMockBuilder('Magento\\Directory\\Model\\Region')->disableOriginalConstructor()->setMethods(['getId', 'getCode', 'load'])->getMock(); $regionMock->expects($this->any())->method('getId')->willReturn($regionId); $regionMock->expects($this->any())->method('getCode')->willReturn($regionCode); $regionMock->expects($this->any())->method('load')->with($regionId)->willReturnSelf(); $this->regionFactoryMock->expects($this->any())->method('create')->willReturn($regionMock); $braintreeAddressData = ['firstName' => self::FNAME, 'lastName' => self::LNAME, 'company' => $company, 'streetAddress' => $street, 'extendedAddress' => $street2, 'locality' => $city, 'region' => $regionCode, 'postalCode' => $postcode, 'countryCodeAlpha2' => $countryId]; return ['channel' => self::CHANNEL, 'orderId' => $orderId, 'customer' => ['firstName' => self::FNAME, 'lastName' => self::LNAME, 'company' => $company, 'phone' => $phone, 'fax' => $fax, 'email' => $customerEmail], 'billing' => $braintreeAddressData, 'shipping' => $braintreeAddressData]; }
/** * @param string $token * @return bool|string */ public function getSavedCardType($token) { $ccType = false; $useCache = $this->config->useVault(); $cachedValues = $useCache ? $this->cache->load(self::CACHE_KEY_CREDIT_CARDS) : false; if ($cachedValues) { try { $cachedValues = unserialize($cachedValues); } catch (\Exception $e) { $cachedValues = []; } if (array_key_exists($token, $cachedValues)) { return $cachedValues[$token]; } } try { $creditCard = $this->braintreeCreditCard->find($token); $this->debug($token); $this->debug($creditCard); $ccType = $this->braintreeHelper->getCcTypeCodeByName($creditCard->cardType); if (!empty($cachedValues)) { $cachedValues = array_merge($cachedValues, [$token => $ccType]); } else { $cachedValues = [$token => $ccType]; } if ($useCache) { $this->cache->save(serialize($cachedValues), self::CACHE_KEY_CREDIT_CARDS); } } catch (\Exception $e) { $this->logger->critical($e); } return $ccType; }
/** * @return array|void */ public function getConfig() { if (!$this->config->isActive()) { return []; } $config = parent::getConfig(); $clientToken = $this->config->getClientToken(); $useVault = $this->config->useVault(); $selectedCardToken = null; $storedCardOptions = []; if ($useVault) { $storedCards = $this->getStoredCards(); if (count($storedCards) == 0) { $useVault = false; } else { foreach ($storedCards as $creditCard) { $storedCardOptions[] = ['token' => $creditCard->token, 'maskedNumber' => $creditCard->maskedNumber . ' - ' . $creditCard->cardType, 'selected' => $creditCard->default, 'type' => $this->dataHelper->getCcTypeCodeByName($creditCard->cardType)]; if ($creditCard->default) { $selectedCardToken = $creditCard->token; } } } } $config = array_merge_recursive($config, ['payment' => ['braintree' => ['clientToken' => $clientToken, 'useVault' => $useVault, 'canSaveCard' => $this->canSaveCard(), 'show3dSecure' => $this->show3dSecure(), 'storedCards' => $storedCardOptions, 'selectedCardToken' => $selectedCardToken, 'creditCardExpMonth' => (int) $this->dataHelper->getTodayMonth(), 'creditCardExpYear' => (int) $this->dataHelper->getTodayYear(), 'countrySpecificCardTypes' => $this->config->getCountrySpecificCardTypeConfig(), 'isFraudDetectionEnabled' => $this->config->isFraudDetectionEnabled(), 'isCcDetectionEnabled' => $this->config->isCcDetectionEnabled(), 'availableCardTypes' => $this->getCcAvailableCcTypes(), 'braintreeDataJs' => $this->config->getBraintreeDataJs(), 'ajaxGenerateNonceUrl' => $this->getAjaxGenerateNonceUrl()]]]); return $config; }
/** * @param bool $isActive * @param bool $isExistingCustomer * @param bool $deleteCustomer * @dataProvider deleteBraintreeCustomerDataProvider */ public function testDeleteBraintreeCustomer($isActive, $isExistingCustomer, $deleteCustomer) { $braintreeCustoemrId = 'braintreeCustomerId'; $customerId = '10002'; $customerEmail = '*****@*****.**'; $this->configMock->expects($this->once())->method('isActive')->willReturn($isActive); $customer = new \Magento\Framework\DataObject(['id' => $customerId, 'email' => $customerEmail]); $this->helperMock->expects($this->any())->method('generateCustomerId')->with($customerId, $customerEmail)->willReturn($braintreeCustoemrId); $observer = new \Magento\Framework\Event\Observer(['event' => new \Magento\Framework\DataObject(['customer' => $customer])]); $this->vaultMock->expects($this->any())->method('exists')->with($braintreeCustoemrId)->willReturn($isExistingCustomer); if ($deleteCustomer) { $this->vaultMock->expects($this->once())->method('deleteCustomer')->with($braintreeCustoemrId); } else { $this->vaultMock->expects($this->never())->method('deleteCustomer'); } $this->assertEquals($this->deleteBraintreeCustomerObserver, $this->deleteBraintreeCustomerObserver->execute($observer)); }
/** * Magento will consider a transaction for voiding only if it is an authorization * Braintree allows voiding captures too * * Lookup an authorization transaction using parent transaction id, if set * * @param Payment $subject * @param callable $proceed * * @return \Magento\Sales\Model\Order\Payment\Transaction|false * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function aroundGetAuthorizationTransaction(Payment $subject, \Closure $proceed) { if ($subject->getMethodInstance()->getCode() != PaymentMethod::METHOD_CODE) { return $proceed(); } $invoice = $this->registry->registry('current_invoice'); if ($invoice && $invoice->getId()) { $transactionId = $this->paymentHelper->clearTransactionId($invoice->getTransactionId()); $collection = $this->salesTransactionCollectionFactory->create()->addFieldToFilter('txn_id', ['eq' => $transactionId]); if ($collection->getSize() < 1) { return $proceed(); } else { return $collection->getFirstItem(); } } return $proceed(); }
/** * @param array $data * @param array $expected * @dataProvider getCcAvailableCardTypesDataProvider */ public function testGetCcAvailableCardTypes($data, $expected) { $this->braintreeCcConfig->expects($this->any())->method('getConfigData')->willReturn($data['cctypes']); $this->braintreeCcConfig->expects($this->any())->method('getCountrySpecificCardTypeConfig')->willReturn($data['cctypesCountrySpecific']); $this->braintreeCcConfig->expects($this->any())->method('getApplicableCardTypes')->willReturn($data['applicableCards']); $this->paymentConfig->expects($this->any())->method('getCcTypes')->willReturn($data['ccTypes']); $result = $this->model->getCcAvailableCardTypes($data['country']); $this->assertEquals($expected, $result); }
protected function setupTransactionIds($orderId, $transactionIds) { $transactionCollectionMock = $this->getMockBuilder('\\Magento\\Sales\\Model\\ResourceModel\\Order\\Payment\\Transaction\\Collection')->disableOriginalConstructor()->getMock(); $transactionCollectionMock->expects($this->once())->method('addFieldToSelect')->with('txn_id')->willReturnSelf(); $transactionCollectionMock->expects($this->once())->method('addOrderIdFilter')->with($orderId)->willReturnSelf(); $transactionCollectionMock->expects($this->once())->method('addTxnTypeFilter')->with([PaymentTransaction::TYPE_AUTH, PaymentTransaction::TYPE_CAPTURE])->willReturnSelf(); $transactionCollectionMock->expects($this->once())->method('getColumnValues')->with('txn_id')->willReturn($transactionIds); $this->salesTransactionCollectionFactoryMock->expects($this->at(0))->method('create')->willReturn($transactionCollectionMock); $this->helperMock->expects($this->any())->method('clearTransactionId')->willReturnArgument(0); }
/** * @param array $data * @param boolean|array $expected * @dataProvider getLoggedInCustomerCardsDataProvider */ public function testGetLoggedInCustomerCards($data, $expected) { $this->sessionQuote->expects($this->once())->method('getStoreId')->willReturn(1); $this->scopeConfig->expects($this->any())->method('getValue')->willReturn($data['vault']); if ($data['vault']) { $this->sessionQuote->expects($this->any())->method('getCustomerId')->willReturn(1); $this->paymentHelper->expects($this->any())->method('generateCustomerId')->willReturn(1); $this->paymentHelper->expects($this->any())->method('getCcAvailableCardTypes')->willReturn(['VI' => "VISA", 'MC' => "MasterCard"]); $this->paymentHelper->expects($this->any())->method('getCcTypeCodeByName')->willReturn(count($expected) ? 'VI' : false); $ccobj = json_decode(json_encode(['creditCards' => null])); $ccobj->creditCards[] = json_decode(json_encode(['cardType' => 'AE'])); $ccobj->creditCards[] = json_decode(json_encode(['cardType' => 'VI'])); $ccobj->creditCards[] = json_decode(json_encode(['cardType' => 'MC'])); $this->braintreeCustomerAdapter->expects($this->any())->method('find')->willReturn($ccobj); $billing = $this->getMockBuilder('\\Magento\\Quote\\Model\\Quote\\Address')->disableOriginalConstructor()->setMethods(['getCountryId'])->getMock(); $billing->expects($this->once())->method('getCountryId')->willReturn("US"); $quote = $this->getMockBuilder('\\Magento\\Quote\\Model\\Quote')->disableOriginalConstructor()->setMethods(['getBillingAddress'])->getMock(); $this->sessionQuote->expects($this->any())->method('getCustomerEmail')->willReturn("*****@*****.**"); $quote->expects($this->any())->method('getBillingAddress')->willReturn($billing); $this->sessionQuote->expects($this->any())->method('getQuote')->willReturn($quote); } $result = $this->model->getLoggedInCustomerCards(); $this->assertEquals($expected, $result); }
/** * @dataProvider getConfigDataProvider */ public function testGetConfig($configData, $vaultData, $tokenNonceMap, $expectedResult) { foreach ($configData as $key => $value) { $this->configMock->expects($this->any())->method($key)->willReturn($value); } foreach ($vaultData as $key => $value) { $this->vaultMock->expects($this->any())->method($key)->willReturn($value); } $this->vaultMock->expects($this->any())->method('generatePaymentMethodToken')->willReturnMap($tokenNonceMap); $cardTypeMap = [['Visa', 'VI'], ['Master Card', 'MA'], ['American Express', 'AE'], ['Discover Card', 'DI']]; $this->helperMock->expects($this->any())->method('getCcTypeCodeByName')->willReturnMap($cardTypeMap); $this->helperMock->expects($this->once())->method('getTodayMonth')->willReturn(self::TODAY_MONTH); $this->helperMock->expects($this->once())->method('getTodayYear')->willReturn(self::TODAY_YEAR); $this->helperMock->expects($this->once())->method('getCcAvailableCardTypes')->willReturn($this->availableCardTypes); $this->customerSessionMock->expects($this->any())->method('isLoggedIn')->willReturn(true); $this->urlBuilderMock->expects($this->once())->method('getUrl')->with('braintree/creditcard/generate')->willReturn(self::PAYMENT_NONCE_GENERATION_URL); $this->assertEquals($expectedResult, $this->model->getConfig()); }
/** * @dataProvider getConfigDataProvider */ public function testGetConfig($configData, $vaultData, $tokenNonceMap, $expectedResult) { foreach ($configData as $key => $value) { $this->configMock->expects($this->any())->method($key)->willReturn($value); } foreach ($vaultData as $key => $value) { $this->vaultMock->expects($this->any())->method($key)->willReturn($value); } $this->vaultMock->expects($this->any())->method('generatePaymentMethodToken')->willReturnMap($tokenNonceMap); $quoteMock = $this->getMockBuilder('\\Magento\\Quote\\Model\\Quote')->disableOriginalConstructor()->getMock(); $quoteMock->expects($this->once())->method('getBillingAddress')->willReturn(new \Magento\Framework\Object(['country_id' => 'US'])); $this->checkoutSessionMock->expects($this->once())->method('getQuote')->willReturn($quoteMock); $cardTypeMap = [['Visa', 'VI'], ['Master Card', 'MA'], ['American Express', 'AE'], ['Discover Card', 'DI']]; $this->helperMock->expects($this->any())->method('getCcTypeCodeByName')->willReturnMap($cardTypeMap); $this->helperMock->expects($this->once())->method('getTodayMonth')->willReturn(self::TODAY_MONTH); $this->helperMock->expects($this->once())->method('getTodayYear')->willReturn(self::TODAY_YEAR); $this->helperMock->expects($this->once())->method('getCcAvailableCardTypes')->willReturn($this->availableCardTypes); $this->customerSessionMock->expects($this->any())->method('isLoggedIn')->willReturn(true); $this->urlBuilderMock->expects($this->once())->method('getUrl')->with('braintree/creditcard/generate')->willReturn(self::PAYMENT_NONCE_GENERATION_URL); $this->assertEquals($expectedResult, $this->model->getConfig()); }
public function testAroundGetAuthorizationTransactionNoInvoiceTransaction() { $result = 'result'; $transactionId = 're45gf'; $transaction = 'invoice_transaction'; $proceed = function () use($result) { return $result; }; $methodInstanceMock = $this->getMock('\\Magento\\Payment\\Model\\MethodInterface'); $methodInstanceMock->expects($this->once())->method('getCode')->willReturn(PaymentMethod::METHOD_CODE); $invoiceMock = $this->getMockBuilder('\\Magento\\Sales\\Model\\Order\\Invoice')->disableOriginalConstructor()->getMock(); $invoiceMock->expects($this->once())->method('getId')->willReturn(1004); $invoiceMock->expects($this->once())->method('getTransactionId')->willReturn($transactionId); $this->helperMock->expects($this->once())->method('clearTransactionId')->with($transactionId)->willReturn($transactionId); $collectionMock = $this->getMockBuilder('\\Magento\\Sales\\Model\\ResourceModel\\Order\\Payment\\Transaction\\Collection')->disableOriginalConstructor()->getMock(); $this->transactionCollectionFactoryMock->expects($this->once())->method('create')->willReturn($collectionMock); $collectionMock->expects($this->once())->method('addFieldToFilter')->with('txn_id', ['eq' => $transactionId])->willReturnSelf(); $collectionMock->expects($this->once())->method('getSize')->willReturn(0); $collectionMock->expects($this->never())->method('getFirstItem')->willReturn($transaction); $this->registryMock->expects($this->once())->method('registry')->with('current_invoice')->willReturn($invoiceMock); $payment = $this->getMockBuilder('\\Magento\\Sales\\Model\\Order\\Payment')->disableOriginalConstructor()->getMock(); $payment->expects($this->once())->method('getMethodInstance')->willReturn($methodInstanceMock); $this->assertEquals($result, $this->model->aroundGetAuthorizationTransaction($payment, $proceed)); }
/** * Retrieve available credit card types * * @return array */ public function getCcAvailableTypes() { return $this->dataHelper->getCcAvailableCardTypes(); }
/** * Retrieve today year * * @return string */ public function getTodayYear() { return $this->dataHelper->getTodayYear(); }
/** * @param InfoInterface $payment * @return array */ protected function getTransactionsToVoid(InfoInterface $payment) { $transactionIds = []; $invoice = $this->_registry->registry('current_invoice'); if ($invoice && $invoice->getId() && $invoice->getTransactionId()) { $transactionIds[] = $this->braintreeHelper->clearTransactionId($invoice->getTransactionId()); } else { $collection = $this->salesTransactionCollectionFactory->create()->addFieldToSelect('txn_id')->addOrderIdFilter($payment->getOrder()->getId())->addTxnTypeFilter([PaymentTransaction::TYPE_AUTH, PaymentTransaction::TYPE_CAPTURE]); $fetchedIds = $collection->getColumnValues('txn_id'); foreach ($fetchedIds as $transactionId) { $txnId = $this->braintreeHelper->clearTransactionId($transactionId); if (!in_array($txnId, $transactionIds)) { $transactionIds[] = $txnId; } } } return $transactionIds; }