class OrderPaymentIntentSubscriber in Commerce Stripe 8
Subscribes to order events to syncronize orders with their payment intents.
Payment intents contain the amount which should be charged during a transaction. When a payment intent is confirmed server or client side, that amount is what is charged. To ensure a proper charge amount, we must update the payment intent amount whenever an order is updated.
Hierarchy
- class \Drupal\commerce_stripe\EventSubscriber\OrderPaymentIntentSubscriber implements \Symfony\Component\EventDispatcher\EventSubscriberInterface, DestructableInterface
Expanded class hierarchy of OrderPaymentIntentSubscriber
1 file declares its use of OrderPaymentIntentSubscriber
- DecoratedOrderPaymentIntentSubscriber.php in tests/
modules/ commerce_stripe_test/ src/ EventSubscriber/ DecoratedOrderPaymentIntentSubscriber.php
1 string reference to 'OrderPaymentIntentSubscriber'
1 service uses OrderPaymentIntentSubscriber
File
- src/
EventSubscriber/ OrderPaymentIntentSubscriber.php, line 25
Namespace
Drupal\commerce_stripe\EventSubscriberView source
class OrderPaymentIntentSubscriber implements EventSubscriberInterface, DestructableInterface {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The intent IDs that need updating.
*
* @var int[]
*/
protected $updateList = [];
/**
* Constructs a new OrderEventsSubscriber object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [
OrderEvents::ORDER_UPDATE => 'onOrderUpdate',
];
}
/**
* {@inheritdoc}
*/
public function destruct() {
foreach ($this->updateList as $intent_id => $amount) {
try {
$intent = PaymentIntent::retrieve($intent_id);
// You may only update the amount of a PaymentIntent with one of the
// following statuses: requires_payment_method, requires_confirmation.
if (in_array($intent->status, [
PaymentIntent::STATUS_REQUIRES_PAYMENT_METHOD,
PaymentIntent::STATUS_REQUIRES_CONFIRMATION,
], TRUE)) {
PaymentIntent::update($intent_id, [
'amount' => $amount,
]);
}
} catch (StripeError $e) {
// Allow sync errors to silently fail.
}
}
}
/**
* Ensures the Stripe payment intent is up to date.
*
* @param \Drupal\commerce_order\Event\OrderEvent $event
* The event.
*/
public function onOrderUpdate(OrderEvent $event) {
$order = $event
->getOrder();
$gateway = $order
->get('payment_gateway');
if ($gateway
->isEmpty() || !$gateway->entity instanceof PaymentGatewayInterface) {
return;
}
$plugin = $gateway->entity
->getPlugin();
if (!$plugin instanceof StripeInterface) {
return;
}
$intent_id = $order
->getData('stripe_intent');
if ($intent_id === NULL) {
return;
}
$total_price = $order
->getTotalPrice();
if ($total_price !== NULL) {
$amount = $this
->toMinorUnits($order
->getTotalPrice());
$this->updateList[$intent_id] = $amount;
}
}
/**
* Converts the given amount to its minor units.
*
* For example, 9.99 USD becomes 999.
*
* @todo Remove after https://www.drupal.org/node/2944281 is fixed.
*
* @param \Drupal\commerce_price\Price $amount
* The amount.
*
* @return int
* The amount in minor units, as an integer.
*/
protected function toMinorUnits(Price $amount) {
$currency_storage = $this->entityTypeManager
->getStorage('commerce_currency');
/** @var \Drupal\commerce_price\Entity\CurrencyInterface $currency */
$currency = $currency_storage
->load($amount
->getCurrencyCode());
$fraction_digits = $currency
->getFractionDigits();
$number = $amount
->getNumber();
if ($fraction_digits > 0) {
$number = Calculator::multiply($number, pow(10, $fraction_digits));
}
return round($number, 0);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
OrderPaymentIntentSubscriber:: |
protected | property | The entity type manager. | |
OrderPaymentIntentSubscriber:: |
protected | property | The intent IDs that need updating. | |
OrderPaymentIntentSubscriber:: |
public | function |
Performs destruct operations. Overrides DestructableInterface:: |
1 |
OrderPaymentIntentSubscriber:: |
public static | function | Returns an array of event names this subscriber wants to listen to. | |
OrderPaymentIntentSubscriber:: |
public | function | Ensures the Stripe payment intent is up to date. | |
OrderPaymentIntentSubscriber:: |
protected | function | Converts the given amount to its minor units. | |
OrderPaymentIntentSubscriber:: |
public | function | Constructs a new OrderEventsSubscriber object. |