paymentTokenFactory = $paymentTokenFactory; $this->paymentExtensionFactory = $paymentExtensionFactory; $this->config = $config; $this->subjectReader = $subjectReader; $this->serializer = $serializer ?: ObjectManager::getInstance()->get(Json::class); } /** * @inheritdoc */ public function handle(array $handlingSubject, array $response) { $paymentDO = $this->subjectReader->readPayment($handlingSubject); $transaction = $this->subjectReader->readTransaction($response); $payment = $paymentDO->getPayment(); // add vault payment token entity to extension attributes $paymentToken = $this->getVaultPaymentToken($transaction); if (null !== $paymentToken) { $extensionAttributes = $this->getExtensionAttributes($payment); $extensionAttributes->setVaultPaymentToken($paymentToken); } } /** * Get vault payment token entity * * @param \Braintree\Transaction $transaction * @return PaymentTokenInterface|null */ protected function getVaultPaymentToken(Transaction $transaction) { // Check token existing in gateway response $token = $transaction->creditCardDetails->token; if (empty($token)) { return null; } /** @var PaymentTokenInterface $paymentToken */ $paymentToken = $this->paymentTokenFactory->create(PaymentTokenFactoryInterface::TOKEN_TYPE_CREDIT_CARD); $paymentToken->setGatewayToken($token); $paymentToken->setExpiresAt($this->getExpirationDate($transaction)); $paymentToken->setTokenDetails($this->convertDetailsToJSON([ 'type' => $this->getCreditCardType($transaction->creditCardDetails->cardType), 'maskedCC' => $transaction->creditCardDetails->last4, 'expirationDate' => $transaction->creditCardDetails->expirationDate ])); return $paymentToken; } /** * @param Transaction $transaction * @return string */ private function getExpirationDate(Transaction $transaction) { $expDate = new \DateTime( $transaction->creditCardDetails->expirationYear . '-' . $transaction->creditCardDetails->expirationMonth . '-' . '01' . ' ' . '00:00:00', new \DateTimeZone('UTC') ); $expDate->add(new \DateInterval('P1M')); return $expDate->format('Y-m-d 00:00:00'); } /** * Convert payment token details to JSON * @param array $details * @return string */ private function convertDetailsToJSON($details) { $json = $this->serializer->serialize($details); return $json ? $json : '{}'; } /** * Get type of credit card mapped from Braintree * * @param string $type * @return array */ private function getCreditCardType($type) { $replaced = str_replace(' ', '-', strtolower($type)); $mapper = $this->config->getCcTypesMapper(); return $mapper[$replaced]; } /** * Get payment extension attributes * @param InfoInterface $payment * @return OrderPaymentExtensionInterface */ private function getExtensionAttributes(InfoInterface $payment) { $extensionAttributes = $payment->getExtensionAttributes(); if (null === $extensionAttributes) { $extensionAttributes = $this->paymentExtensionFactory->create(); $payment->setExtensionAttributes($extensionAttributes); } return $extensionAttributes; } }