recurly-pricing.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import { SubscriptionPricingState } from '@recurly/recurly-js'
  2. import { PriceForDisplayData } from '../../../../../types/subscription/plan'
  3. import { CurrencyCode } from '../../../../../types/subscription/currency'
  4. import { getRecurlyGroupPlanCode } from './recurly-group-plan-code'
  5. import { debugConsole } from '@/utils/debugging'
  6. import { formatCurrency } from '@/shared/utils/currency'
  7. function queryRecurlyPlanPrice(planCode: string, currency: CurrencyCode) {
  8. return new Promise(resolve => {
  9. recurly.Pricing.Subscription()
  10. .plan(planCode, { quantity: 1 })
  11. .currency(currency)
  12. .catch(debugConsole.error)
  13. .done(response => {
  14. if (response) {
  15. resolve(response)
  16. } else {
  17. resolve(undefined)
  18. }
  19. })
  20. })
  21. }
  22. export function formatPriceForDisplayData(
  23. price: string,
  24. taxRate: number,
  25. currencyCode: CurrencyCode,
  26. locale: string
  27. ): PriceForDisplayData {
  28. const totalPriceExTax = parseFloat(price)
  29. let taxAmount = totalPriceExTax * taxRate
  30. if (isNaN(taxAmount)) {
  31. taxAmount = 0
  32. }
  33. const totalWithTax = totalPriceExTax + taxAmount
  34. return {
  35. totalForDisplay: formatCurrency(totalWithTax, currencyCode, locale, true),
  36. totalAsNumber: totalWithTax,
  37. subtotal: formatCurrency(totalPriceExTax, currencyCode, locale),
  38. tax: formatCurrency(taxAmount, currencyCode, locale),
  39. includesTax: taxAmount !== 0,
  40. }
  41. }
  42. function getPerUserDisplayPrice(
  43. totalPrice: number,
  44. currency: CurrencyCode,
  45. size: string,
  46. locale: string
  47. ): string {
  48. return formatCurrency(totalPrice / parseInt(size), currency, locale, true)
  49. }
  50. export async function loadDisplayPriceWithTaxPromise(
  51. planCode: string,
  52. currencyCode: CurrencyCode,
  53. taxRate: number,
  54. locale: string
  55. ) {
  56. if (!recurly) return
  57. const price = (await queryRecurlyPlanPrice(
  58. planCode,
  59. currencyCode
  60. )) as SubscriptionPricingState['price']
  61. if (price)
  62. return formatPriceForDisplayData(
  63. price.next.total,
  64. taxRate,
  65. currencyCode,
  66. locale
  67. )
  68. }
  69. export async function loadGroupDisplayPriceWithTaxPromise(
  70. groupPlanCode: string,
  71. currencyCode: CurrencyCode,
  72. taxRate: number,
  73. size: string,
  74. usage: string,
  75. locale: string
  76. ) {
  77. if (!recurly) return
  78. const planCode = getRecurlyGroupPlanCode(groupPlanCode, size, usage)
  79. const price = await loadDisplayPriceWithTaxPromise(
  80. planCode,
  81. currencyCode,
  82. taxRate,
  83. locale
  84. )
  85. if (price) {
  86. price.perUserDisplayPrice = getPerUserDisplayPrice(
  87. price.totalAsNumber,
  88. currencyCode,
  89. size,
  90. locale
  91. )
  92. }
  93. return price
  94. }