commerce_signifyd-1.0.x-dev/src/Signifyd/SignifydAbstract.php
src/Signifyd/SignifydAbstract.php
<?php
namespace Drupal\commerce_signifyd\Signifyd;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_payment\Entity\PaymentMethodInterface;
use Drupal\commerce_signifyd\Entity\SignifydCaseInterface;
use Drupal\commerce_signifyd\SignifydClientInterface;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Site\Settings;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Class ServiceAbstract.
*
* Abstract class for services classes.
*
* @package Drupal\commerce_signifyd\Signifyd
*/
abstract class SignifydAbstract {
/**
* The Signifyd client.
*
* @var \Drupal\commerce_signifyd\SignifydClientInterface
*/
protected $signifydClient;
/**
* The logger.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* The config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The signifyd configuration.
*
* @var null|string
*/
protected $signifydSettings;
/**
* Determine if requests needs to be logged.
*
* @var null|bool
*/
protected $logging;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The Signifyd team storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $teamStorage;
/**
* The order storage.
*
* @var \Drupal\commerce_order\OrderStorage
*/
protected $orderStorage;
/**
* The event dispatcher.
*
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* The Signifyd team id.
*/
protected string $signifydTeamId;
/**
* Constructs a new SignifydCase object.
*
* @param \Drupal\commerce_signifyd\SignifydClientInterface $signifyd_client
* The Signifyd http client.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
* @param \Psr\Log\LoggerInterface $logger
* The logger.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
* The event dispatcher.
*/
public function __construct(SignifydClientInterface $signifyd_client, ConfigFactoryInterface $config_factory, LoggerInterface $logger, EntityTypeManagerInterface $entity_type_manager, ModuleHandlerInterface $module_handler, EventDispatcherInterface $event_dispatcher) {
$this->signifydClient = $signifyd_client;
$this->configFactory = $config_factory;
$this->logger = $logger;
$this->entityTypeManager = $entity_type_manager;
$this->moduleHandler = $module_handler;
$this->signifydSettings = $config_factory->get('commerce_signifyd.settings');
$this->signifydTeamId = $this->signifydSettings->get('team');
$this->logging = $this->signifydSettings->get('logging');
$this->teamStorage = $entity_type_manager->getStorage('signifyd_team');
$this->orderStorage = $entity_type_manager->getStorage('commerce_order');
$this->eventDispatcher = $event_dispatcher;
}
/**
* Map Drupal payment status to Signifyd.
*
* @param string $type
* The payment status.
*
* @return string
* Return mapped Signifyd value.
*/
protected function mapPaymentType($type) {
$signifyd_mapping = [
'new' => 'PREAUTHORIZATION',
'authorization' => 'AUTHORIZATION',
'authorization_voided' => NULL,
'authorization_expired' => NULL,
'completed' => 'SALE',
'partially_refunded' => NULL,
'refunded' => NULL,
];
return $signifyd_mapping[$type] ?? NULL;
}
/**
* Returns the transactions.
*
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The order.
*
* @return array
* The transactions.
*/
protected function getTransactions(OrderInterface $order) {
$transactions = [];
/** @var \Drupal\commerce_payment\Entity\PaymentInterface $payment */
foreach ($this->getPayments($order) as $payment) {
$checkout_payment_details = [];
$payment_method = $payment->getPaymentMethod();
if ($payment_method instanceof PaymentMethodInterface) {
$payment_gateway = $payment_method->getPaymentGatewayId();
if ($payment_method->getType()->getPluginId() === 'credit_card') {
$checkout_payment_details = [
'cardLast4' => $payment_method->get('card_number')->value,
'cardExpiryMonth' => $payment_method->get('card_exp_month')->value,
'cardExpiryYear' => $payment_method->get('card_exp_year')->value,
];
}
}
if ($billing_profile = $payment->getOrder()->getBillingProfile()) {
if (!$billing_profile->get('address')->isEmpty()) {
/** @var \Drupal\address\Plugin\Field\FieldType\AddressItem $address */
$address = $billing_profile->get('address')->first();
$checkout_payment_details['billingAddress'] = [
'streetAddress' => $address->getAddressLine1(),
'unit' => $address->getAddressLine2(),
'city' => $address->getLocality(),
'provinceCode' => $address->getAdministrativeArea(),
'postalCode' => $address->getPostalCode(),
'countryCode' => $address->getCountryCode(),
];
$checkout_payment_details['holderName'] = $address->getGivenName() . ' ' . $address->getFamilyName();
}
}
/** @var \Drupal\address\AddressInterface $payment_billing_profile_address */
$payment_type = $this->mapPaymentType($payment->getState()->getId());
$transactions[] = [
'transactionId' => $payment->getRemoteId(),
'createdAt' => date(DATE_ATOM, $payment->getAuthorizedTime()),
'gateway' => $payment_gateway ?? $payment->getPaymentGatewayId(),
'paymentMethod' => $payment_method->type->value ? strtoupper($payment_method->type->value) : 'CREDIT_CARD',
'type' => $payment_type ?? 'SALE',
'gatewayStatusCode' => $payment_type === 'PREAUTHORIZATION' ? 'PENDING' : 'SUCCESS',
'currency' => $payment->getAmount()->getCurrencyCode(),
'amount' => $payment->getAmount()->getNumber(),
'avsResponseCode' => $payment->getAvsResponseCode(),
'checkoutPaymentDetails' => $checkout_payment_details,
];
}
return $transactions;
}
/**
* Returns payments for the order.
*
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The order.
*
* @return array
* Associative array of data.
*/
protected function getPayments(OrderInterface $order) {
/** @var \Drupal\commerce_payment\PaymentStorageInterface $payments_storage */
$payments_storage = $this->entityTypeManager->getStorage('commerce_payment');
return $payments_storage->loadMultipleByOrder($order);
}
/**
* Writing log entries.
*
* @param \Drupal\commerce_signifyd\Entity\SignifydCaseInterface $signifyd_case
* The Signifyd case.
* @param string $action
* The Signifyd action.
*/
protected function createWebhookLog(SignifydCaseInterface $signifyd_case, $action) {
$order = $signifyd_case->getOrder();
if (!$order) {
return;
}
$commerce_log = $this->entityTypeManager->getStorage('commerce_log');
$log_template_id = 'signifyd_case_' . str_replace(['cases/', '/*'], ['', ''], $action);
$commerce_log->generate($order, $log_template_id, [
'url' => SignifydClientInterface::SIGNIFYD_WEB_URL . 'orders/' . $signifyd_case->id(),
'case_id' => $signifyd_case->id(),
'score' => $signifyd_case->getScore(),
'guarantee' => $signifyd_case->getGuarantee(),
'decision' => $signifyd_case->getDecision(),
])->save();
}
/**
* Get Signifyd team.
*
* @return \Drupal\commerce_signifyd\Entity\SignifydTeamInterface
* The default Signifyd team.
*/
protected function getSignifydTeam() {
return $this->teamStorage->load($this->signifydTeamId);
}
/**
* Generate unique id used for orderSessionId and device fingerprint.
*
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The commerce order.
*
* @return string
* Return unique id.
*/
public static function getOrderSessionId(OrderInterface $order) {
return Crypt::hmacBase64((sprintf('Drupal-H%s-0%s-U%s', $order->getIpAddress(), $order->id(), $order->getCustomerId())), Settings::getHashSalt());
}
}
