Many gateways need to send amounts in minor units (9.99 USD sent as 999, for example).
Square, Stripe, Ingenico for example.
They also tend to implement this the wrong way, multiplying by 100 instead of getting the fraction digits from the currency.
Case in point: #2913605: Yen currency is processed incorrectly (100x the input value).

So, let's add a toMinorUnits() helper to simplify this:

  /**
   * Converts the given amount to its minor units.
   *
   * For example, 9.99 USD becomes 999.
   *
   * @param \Drupal\commerce_price\Price $amount
   *   The amount.
   *
   * @return int
   *   The amount in minor units.
   */
  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);
  }

I thought about adding such a helper to Price directly, but we'd still need to get $fraction_digits from somewhere, and then round, so it wouldn't save a lot.

Comments

bojanz created an issue. See original summary.

  • bojanz committed 59a6f5d on 8.x-2.x
    Issue #2928972 by bojanz: Add PaymentGatewayBase::toMinorUnits()
    
bojanz’s picture

Status: Active » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.