recurly-pricing.ts 2.5 KB

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