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 { 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()) { return; } $plugin = $gateway->entity->getPlugin(); if (!$plugin instanceof StripeInterface) { return; } $intent_id = $order->getData('stripe_intent'); if ($intent_id !== 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. */ private 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); } }