구독 가격을 $19.99로 설정할 수 없음

  • Discourse-Subscriptions 사용 중
  • 상품에 가격 플랜을 추가하려는 중
  • 가격 입력란에 19.99 입력 (입력란의 동작이 매우 이상해서 이 단계조차 어렵습니다)
  • 제출 시도
  • “Invalid integer 1998.9999999999998” 오류 발생

아직 stable 3.5.3에서만 테스트해 봤지만, beta에서도 코드가 동일합니다.

Code

  @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개의 좋아요

나는 바로 알았어. 40년 전 이상으로 컴퓨터에 대해 배웠지만 변하지 않은 또 하나의 사실이지.

혹은 1센트 단위의 정수를 사용하는 건 어때? 실제로 스트라이프(Stripe)가 그렇게 하는 것 같아. (하지만 네 해결책이 훨씬 적은 코드 수정을 요구하니까, 아마도 네 쪽이 이기는 거겠지.)

2개의 좋아요

네, 맞습니다. unit_amount는 센트 단위이며, amountDollars는 ‘XX.XX’ 형식의 입력 값입니다.
“invalid integer” 오류조차도 Stripe API에서 발생합니다.

우리 둘 다 FDIV 버그에 대해 알고 있을 정도로 나이가 많네요 :wink:

3개의 좋아요

솔직히 말해서, 이 값을 float로 저장하는 것은 잘못된 접근이라고 생각해요. 이 컬럼은 int 타입이어야 하고, 센트 단위로 저장하는 게 맞아요.

3개의 좋아요

그렇습니다. parseFloat는 “소수점 둘째 자리까지 표시되는 통화” 형식의 입력 필드에서 값을 변환하는 데 사용됩니다. unit_amount 객체 속성은 명백히 타입이 없으므로, Math.round()를 사용하라고 제안한 것입니다.

이는 서버 측의 컬럼이 아니라, Stripe API로 전달되는 값입니다.

1개의 좋아요

통화 BCD의 경우, 부동 소수점은 일반적으로 이진 부동 소수점보다 더 적합합니다.

@RGJ 님, 보고해 주셔서 감사합니다. 이 수정으로 해결될 것입니다 :+1:

2개의 좋아요

이 주제는 2일 후 자동으로 닫혔습니다. 더 이상 새 답변을 남길 수 없습니다.