Не удалось установить цену подписки $19.99

  • Использование Discourse-Subscriptions
  • Попытка добавить тарифный план к продукту
  • Введите 19.99 в поле цены (это уже сложно, так как поле ввода ведёт себя очень странно)
  • Попробуйте отправить форму
  • Получите ошибку «Invalid integer 1998.9999999999998»

Пока я тестировал это только на стабильной версии 3.5.3, но код в бета-версии тот же.

Код

  @computed("unit_amount")
  get amountDollars() {
    return parseFloat(this.get("unit_amount") / 100).toFixed(2);
  }

  set amountDollars(value) {
    const decimal = parseFloat(value) * 100;
    this.set("unit_amount", decimal);
  }

Проблема с числами с плавающей запятой в JavaScript / IEEE-754:

-> parseFloat("19.99")*100
<- 1998.9999999999998

Предлагаемое исправление: const decimal = Math.round(Number(value) * 100)

Мой главный вопрос: почему никто этого не заметил? Разве кто-то раньше не устанавливал цену в $19.99?

Кстати, я также часто получаю NaN, например, когда полностью очищаю поле ввода.

2 лайка

I knew right away. One more thing I learned about computers 40+ years ago that’s not changed.

Or use 1-cent integers? I think that’s what Stripe does, actually. (But your solution requires changing much less code, so I guess it wins.)

2 лайка

Yes, that’s what it does, unit_amount are cents and the amountDollars is an ‘XX.XX’ input value.
The “invalid integer” error even comes from the Stripe API.

I guess we’re both old enough to know about the FDIV bug :wink:

3 лайка

honestly I think storing this in a float is misguided this column should be an int and stored in cents

3 лайка

It is, the parseFloat is used to convert from/to input field which is “currency with two decimals”. The unit_amount object property is obviously typeless though, hence my suggestion to use Math.round()

It is not a column server side, it is passed to the Stripe API.

1 лайк

For currency BCD floating point is generally better than binary floating point.

Спасибо @RGJ за отчет — это должно исправить проблему :+1:

2 лайка

Эта тема была автоматически закрыта через 2 дня. Новые ответы больше не принимаются.