File size: 1,288 Bytes
97ee7cb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
 * Billing-mode resolution for pricing-card CTAs (#4946 round 4).
 *
 * Pure and React-free so the annual-toggle contract is directly unit-
 * testable: with the page-level toggle on "Annual", a tier that has no
 * annual product (API Business) must still check out its monthly product
 * — but EXPLICITLY, with `billedMonthlyOnly` driving a visible "billed
 * monthly" note on the card. Silently selling the monthly product from
 * an annual-selected state is the bug this module exists to prevent.
 */

export interface BillingModeTier {
  monthlyProductId?: string;
  annualProductId?: string;
}

export interface ResolvedCheckoutProduct {
  productId: string;
  /**
   * True when the user is in annual mode but this tier only exists as a
   * monthly product — the card must say so next to the price.
   */
  billedMonthlyOnly: boolean;
}

export function resolveCheckoutProduct(
  tier: BillingModeTier,
  billing: 'monthly' | 'annual',
): ResolvedCheckoutProduct | null {
  if (!tier.monthlyProductId) return null;
  if (billing === 'annual' && tier.annualProductId) {
    return { productId: tier.annualProductId, billedMonthlyOnly: false };
  }
  return {
    productId: tier.monthlyProductId,
    billedMonthlyOnly: billing === 'annual' && !tier.annualProductId,
  };
}