@edx/frontend-app-subscription-checkout 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/app.js +6 -3
  2. package/dist/app.js.map +1 -1
  3. package/dist/checkoutPage/CheckoutPage.js +2 -1
  4. package/dist/checkoutPage/CheckoutPage.js.map +1 -1
  5. package/dist/components/CartSummary/CartSummary.d.ts +12 -2
  6. package/dist/components/CartSummary/CartSummary.js +17 -17
  7. package/dist/components/CartSummary/CartSummary.js.map +1 -1
  8. package/dist/components/CartSummary/Messages.d.ts +10 -0
  9. package/dist/components/CartSummary/Messages.js +12 -2
  10. package/dist/components/CartSummary/Messages.js.map +1 -1
  11. package/dist/components/Checkout/Checkout.d.ts +10 -2
  12. package/dist/components/Checkout/Checkout.js +43 -5
  13. package/dist/components/Checkout/Checkout.js.map +1 -1
  14. package/dist/components/CheckoutGate/CheckoutGate.d.ts +4 -2
  15. package/dist/components/CheckoutGate/CheckoutGate.js +5 -4
  16. package/dist/components/CheckoutGate/CheckoutGate.js.map +1 -1
  17. package/dist/components/CountryUnavailableModal/CountryUnavailableModal.d.ts +9 -0
  18. package/dist/components/CountryUnavailableModal/CountryUnavailableModal.js +10 -0
  19. package/dist/components/CountryUnavailableModal/CountryUnavailableModal.js.map +1 -0
  20. package/dist/components/CountryUnavailableModal/Messages.d.ts +18 -0
  21. package/dist/components/CountryUnavailableModal/Messages.js +20 -0
  22. package/dist/components/CountryUnavailableModal/Messages.js.map +1 -0
  23. package/dist/components/EnrollmentSummary/EnrollmentSummary.d.ts +3 -2
  24. package/dist/components/EnrollmentSummary/EnrollmentSummary.js +5 -3
  25. package/dist/components/EnrollmentSummary/EnrollmentSummary.js.map +1 -1
  26. package/dist/components/EnrollmentSummary/Messages.js +2 -2
  27. package/dist/components/EnrollmentSummary/Messages.js.map +1 -1
  28. package/dist/components/PaymentForm/PaymentForm.js +3 -3
  29. package/dist/components/PaymentForm/PaymentForm.js.map +1 -1
  30. package/dist/constants.d.ts +2 -1
  31. package/dist/constants.js +201 -196
  32. package/dist/constants.js.map +1 -1
  33. package/dist/data/hooks/useCheckout.js +5 -0
  34. package/dist/data/hooks/useCheckout.js.map +1 -1
  35. package/dist/data/hooks/useCheckoutMutations.d.ts +3 -1
  36. package/dist/data/hooks/useCheckoutMutations.js +7 -4
  37. package/dist/data/hooks/useCheckoutMutations.js.map +1 -1
  38. package/dist/routes.js +1 -1
  39. package/dist/routes.js.map +1 -1
  40. package/dist/styles/components/cartSummary.scss +4 -0
  41. package/dist/styles/components/paymentForm.scss +4 -0
  42. package/dist/utils/billingDetails.d.ts +1 -1
  43. package/dist/utils/billingDetails.js +6 -5
  44. package/dist/utils/billingDetails.js.map +1 -1
  45. package/dist/utils/cartApi.js +11 -9
  46. package/dist/utils/cartApi.js.map +1 -1
  47. package/dist/utils/provision.js +2 -2
  48. package/dist/utils/provision.js.map +1 -1
  49. package/dist/utils/queries.d.ts +1 -1
  50. package/dist/utils/queries.js +0 -2
  51. package/dist/utils/queries.js.map +1 -1
  52. package/package.json +2 -2
@@ -2,11 +2,12 @@ import type { CourseDetail } from '../../types';
2
2
  export interface EnrollmentSummaryProps {
3
3
  productTitle?: string;
4
4
  productBlurb?: string;
5
- /** e.g. "39" */
5
+ /** e.g. "59" or "396" from getBillingPlans */
6
6
  amount?: string;
7
7
  /** e.g. "USD" */
8
8
  currency?: string;
9
- cycleToShow?: string;
9
+ /** Billing cycle for the purchased plan. */
10
+ cycleToShow?: 'monthly' | 'annual';
10
11
  /** When set, shows the enrolled course card below the purchase summary. */
11
12
  course?: CourseDetail | null;
12
13
  onStartCourse?: () => void;
@@ -4,18 +4,20 @@ import { useIntl } from '@openedx/frontend-base';
4
4
  import { EdxUnlimitedLogo } from '../BrandMarks/BrandMarks';
5
5
  import CourseEnrollmentCard from '../CourseEnrollmentCard/CourseEnrollmentCard';
6
6
  import messages from './Messages';
7
- const EnrollmentSummary = ({ productTitle = 'edX Subscription', productBlurb = 'Subscribe and get access to hundreds of courses and programs.', amount, currency = 'USD', cycleToShow = 'monthly', course = null, onStartCourse, }) => {
7
+ const EnrollmentSummary = ({ productTitle = 'edX Plus', productBlurb = 'Access to hundreds of courses and programs.', amount, currency = 'USD', cycleToShow = 'monthly', course = null, onStartCourse, }) => {
8
8
  const { formatMessage } = useIntl();
9
9
  const isMonthly = cycleToShow === 'monthly';
10
10
  const frequency = isMonthly ? 'month' : 'year';
11
11
  const cycleLabel = isMonthly
12
12
  ? formatMessage(messages.monthlySubscription)
13
13
  : formatMessage(messages.annualSubscription);
14
- return (_jsxs("div", { className: "enrollment-summary", children: [_jsxs(Card, { className: "enrollment-summary", children: [_jsxs(Card.Section, { children: [_jsx("p", { className: "font-weight-bold mb-3", children: formatMessage(messages.purchaseSummary) }), _jsxs("div", { className: "d-flex align-items-start mb-3", children: [_jsx(EdxUnlimitedLogo, {}), _jsxs("div", { children: [_jsx("p", { className: "font-weight-bold mb-1", style: { fontSize: '0.9rem' }, children: productTitle }), _jsx("p", { className: "text-muted mb-0", style: { fontSize: '0.82rem' }, children: productBlurb })] })] }), _jsxs("div", { className: "d-flex justify-content-between align-items-center mb-1", children: [_jsx("span", { className: "small text-muted", children: cycleLabel }), amount && (_jsx("span", { className: "small font-weight-bold", children: formatMessage(messages.priceDisplay, {
14
+ return (_jsxs("div", { className: "enrollment-summary", children: [_jsxs(Card, { className: "enrollment-summary__card p-3", children: [_jsx(Card.Section, { className: "p-0 pb-3", children: _jsx("p", { className: "font-weight-bold mb-0 text-gray-900", children: formatMessage(messages.purchaseSummary) }) }), _jsx(Card.Divider, {}), _jsx(Card.Section, { className: "p-0 py-3", children: _jsxs("div", { className: "d-flex align-items-start", children: [_jsx(EdxUnlimitedLogo, {}), _jsxs("div", { children: [_jsx("p", { className: "font-weight-bold mb-0 text-primary-500", children: productTitle }), _jsx("p", { className: "small mb-0 text-gray-900", children: productBlurb })] })] }) }), _jsx(Card.Divider, {}), _jsx(Card.Section, { className: "p-0 pt-3 pb-2", children: _jsxs("div", { className: "d-flex justify-content-between align-items-start", children: [_jsx("span", { className: "small text-gray-900", children: cycleLabel }), _jsx("span", { className: "small text-gray-900 font-weight-bold", children: amount
15
+ ? formatMessage(messages.priceDisplay, {
15
16
  amount,
16
17
  frequency,
17
18
  currency,
18
- }) }))] })] }), _jsx(Card.Divider, {}), _jsxs(Card.Section, { className: "d-flex justify-content-between align-items-center", children: [_jsx("span", { className: "font-weight-bold", children: formatMessage(messages.todaysTotal) }), _jsx("span", { className: "font-weight-bold text-success", children: formatMessage(messages.todaysTotalValue) })] })] }), course && (_jsx(CourseEnrollmentCard, { course: course, variant: "success", onStartCourse: onStartCourse }))] }));
19
+ })
20
+ : null })] }) }), _jsxs(Card.Section, { className: "d-flex justify-content-between align-items-center px-0 pt-1", children: [_jsx("span", { className: "font-weight-bold text-gray-900", children: formatMessage(messages.todaysTotal) }), _jsx("span", { className: "font-weight-bold mb-0 text-success", children: formatMessage(messages.todaysTotalValue) })] })] }), course && (_jsx(CourseEnrollmentCard, { course: course, variant: "success", onStartCourse: onStartCourse }))] }));
19
21
  };
20
22
  export default EnrollmentSummary;
21
23
  //# sourceMappingURL=EnrollmentSummary.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EnrollmentSummary.js","sourceRoot":"","sources":["../../../src/components/EnrollmentSummary/EnrollmentSummary.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,oBAAoB,MAAM,8CAA8C,CAAC;AAEhF,OAAO,QAAQ,MAAM,YAAY,CAAC;AAelC,MAAM,iBAAiB,GAAG,CAAC,EACzB,YAAY,GAAG,kBAAkB,EACjC,YAAY,GAAG,+DAA+D,EAC9E,MAAM,EACN,QAAQ,GAAG,KAAK,EAChB,WAAW,GAAG,SAAS,EACvB,MAAM,GAAG,IAAI,EACb,aAAa,GACU,EAAE,EAAE;IAC3B,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,MAAM,SAAS,GAAG,WAAW,KAAK,SAAS,CAAC;IAC5C,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/C,MAAM,UAAU,GAAG,SAAS;QAC1B,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAC7C,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAE/C,OAAO,CACL,eAAK,SAAS,EAAC,oBAAoB,aACjC,MAAC,IAAI,IAAC,SAAS,EAAC,oBAAoB,aAClC,MAAC,IAAI,CAAC,OAAO,eACX,YAAG,SAAS,EAAC,uBAAuB,YACjC,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,GACtC,EAEJ,eAAK,SAAS,EAAC,+BAA+B,aAC5C,KAAC,gBAAgB,KAAG,EACpB,0BACE,YAAG,SAAS,EAAC,uBAAuB,EAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAC/D,YAAY,GACX,EACJ,YAAG,SAAS,EAAC,iBAAiB,EAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,YAC1D,YAAY,GACX,IACA,IACF,EAEN,eAAK,SAAS,EAAC,wDAAwD,aACrE,eAAM,SAAS,EAAC,kBAAkB,YAAE,UAAU,GAAQ,EACrD,MAAM,IAAI,CACT,eAAM,SAAS,EAAC,wBAAwB,YACrC,aAAa,CAAC,QAAQ,CAAC,YAAY,EAAE;4CACpC,MAAM;4CACN,SAAS;4CACT,QAAQ;yCACT,CAAC,GACG,CACR,IACG,IACO,EAEf,KAAC,IAAI,CAAC,OAAO,KAAG,EAEhB,MAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,mDAAmD,aACzE,eAAM,SAAS,EAAC,kBAAkB,YAC/B,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,GAC/B,EACP,eAAM,SAAS,EAAC,+BAA+B,YAC5C,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,GACpC,IACM,IACV,EAEN,MAAM,IAAI,CACT,KAAC,oBAAoB,IACnB,MAAM,EAAE,MAAM,EACd,OAAO,EAAC,SAAS,EACjB,aAAa,EAAE,aAAa,GAC5B,CACH,IACG,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,iBAAiB,CAAC","sourcesContent":["import React from 'react';\nimport { Card } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport { EdxUnlimitedLogo } from '../BrandMarks/BrandMarks';\nimport CourseEnrollmentCard from '../CourseEnrollmentCard/CourseEnrollmentCard';\nimport type { CourseDetail } from '../../types';\nimport messages from './Messages';\n\nexport interface EnrollmentSummaryProps {\n productTitle?: string,\n productBlurb?: string,\n /** e.g. \"39\" */\n amount?: string,\n /** e.g. \"USD\" */\n currency?: string,\n cycleToShow?: string,\n /** When set, shows the enrolled course card below the purchase summary. */\n course?: CourseDetail | null,\n onStartCourse?: () => void,\n}\n\nconst EnrollmentSummary = ({\n productTitle = 'edX Subscription',\n productBlurb = 'Subscribe and get access to hundreds of courses and programs.',\n amount,\n currency = 'USD',\n cycleToShow = 'monthly',\n course = null,\n onStartCourse,\n}: EnrollmentSummaryProps) => {\n const { formatMessage } = useIntl();\n\n const isMonthly = cycleToShow === 'monthly';\n const frequency = isMonthly ? 'month' : 'year';\n const cycleLabel = isMonthly\n ? formatMessage(messages.monthlySubscription)\n : formatMessage(messages.annualSubscription);\n\n return (\n <div className=\"enrollment-summary\">\n <Card className=\"enrollment-summary\">\n <Card.Section>\n <p className=\"font-weight-bold mb-3\">\n {formatMessage(messages.purchaseSummary)}\n </p>\n\n <div className=\"d-flex align-items-start mb-3\">\n <EdxUnlimitedLogo />\n <div>\n <p className=\"font-weight-bold mb-1\" style={{ fontSize: '0.9rem' }}>\n {productTitle}\n </p>\n <p className=\"text-muted mb-0\" style={{ fontSize: '0.82rem' }}>\n {productBlurb}\n </p>\n </div>\n </div>\n\n <div className=\"d-flex justify-content-between align-items-center mb-1\">\n <span className=\"small text-muted\">{cycleLabel}</span>\n {amount && (\n <span className=\"small font-weight-bold\">\n {formatMessage(messages.priceDisplay, {\n amount,\n frequency,\n currency,\n })}\n </span>\n )}\n </div>\n </Card.Section>\n\n <Card.Divider />\n\n <Card.Section className=\"d-flex justify-content-between align-items-center\">\n <span className=\"font-weight-bold\">\n {formatMessage(messages.todaysTotal)}\n </span>\n <span className=\"font-weight-bold text-success\">\n {formatMessage(messages.todaysTotalValue)}\n </span>\n </Card.Section>\n </Card>\n\n {course && (\n <CourseEnrollmentCard\n course={course}\n variant=\"success\"\n onStartCourse={onStartCourse}\n />\n )}\n </div>\n );\n};\n\nexport default EnrollmentSummary;\n"]}
1
+ {"version":3,"file":"EnrollmentSummary.js","sourceRoot":"","sources":["../../../src/components/EnrollmentSummary/EnrollmentSummary.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,oBAAoB,MAAM,8CAA8C,CAAC;AAEhF,OAAO,QAAQ,MAAM,YAAY,CAAC;AAgBlC,MAAM,iBAAiB,GAAG,CAAC,EACzB,YAAY,GAAG,UAAU,EACzB,YAAY,GAAG,6CAA6C,EAC5D,MAAM,EACN,QAAQ,GAAG,KAAK,EAChB,WAAW,GAAG,SAAS,EACvB,MAAM,GAAG,IAAI,EACb,aAAa,GACU,EAAE,EAAE;IAC3B,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,MAAM,SAAS,GAAG,WAAW,KAAK,SAAS,CAAC;IAC5C,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/C,MAAM,UAAU,GAAG,SAAS;QAC1B,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAC7C,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAE/C,OAAO,CACL,eAAK,SAAS,EAAC,oBAAoB,aACjC,MAAC,IAAI,IAAC,SAAS,EAAC,8BAA8B,aAC5C,KAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,UAAU,YAChC,YAAG,SAAS,EAAC,qCAAqC,YAC/C,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,GACtC,GACS,EAEf,KAAC,IAAI,CAAC,OAAO,KAAG,EAEhB,KAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,UAAU,YAChC,eAAK,SAAS,EAAC,0BAA0B,aACvC,KAAC,gBAAgB,KAAG,EACpB,0BACE,YAAG,SAAS,EAAC,wCAAwC,YAClD,YAAY,GACX,EACJ,YAAG,SAAS,EAAC,0BAA0B,YAAE,YAAY,GAAK,IACtD,IACF,GACO,EAEf,KAAC,IAAI,CAAC,OAAO,KAAG,EAEhB,KAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,eAAe,YACrC,eAAK,SAAS,EAAC,kDAAkD,aAC/D,eAAM,SAAS,EAAC,qBAAqB,YAAE,UAAU,GAAQ,EACzD,eAAM,SAAS,EAAC,sCAAsC,YACnD,MAAM;wCACL,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,YAAY,EAAE;4CACnC,MAAM;4CACN,SAAS;4CACT,QAAQ;yCACT,CAAC;wCACJ,CAAC,CAAC,IAAI,GACH,IACH,GACO,EAEf,MAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,6DAA6D,aACnF,eAAM,SAAS,EAAC,gCAAgC,YAC7C,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,GAC/B,EACP,eAAM,SAAS,EAAC,oCAAoC,YACjD,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,GACpC,IACM,IACV,EAEN,MAAM,IAAI,CACT,KAAC,oBAAoB,IACnB,MAAM,EAAE,MAAM,EACd,OAAO,EAAC,SAAS,EACjB,aAAa,EAAE,aAAa,GAC5B,CACH,IACG,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,iBAAiB,CAAC","sourcesContent":["import React from 'react';\nimport { Card } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport { EdxUnlimitedLogo } from '../BrandMarks/BrandMarks';\nimport CourseEnrollmentCard from '../CourseEnrollmentCard/CourseEnrollmentCard';\nimport type { CourseDetail } from '../../types';\nimport messages from './Messages';\n\nexport interface EnrollmentSummaryProps {\n productTitle?: string,\n productBlurb?: string,\n /** e.g. \"59\" or \"396\" from getBillingPlans */\n amount?: string,\n /** e.g. \"USD\" */\n currency?: string,\n /** Billing cycle for the purchased plan. */\n cycleToShow?: 'monthly' | 'annual',\n /** When set, shows the enrolled course card below the purchase summary. */\n course?: CourseDetail | null,\n onStartCourse?: () => void,\n}\n\nconst EnrollmentSummary = ({\n productTitle = 'edX Plus',\n productBlurb = 'Access to hundreds of courses and programs.',\n amount,\n currency = 'USD',\n cycleToShow = 'monthly',\n course = null,\n onStartCourse,\n}: EnrollmentSummaryProps) => {\n const { formatMessage } = useIntl();\n\n const isMonthly = cycleToShow === 'monthly';\n const frequency = isMonthly ? 'month' : 'year';\n const cycleLabel = isMonthly\n ? formatMessage(messages.monthlySubscription)\n : formatMessage(messages.annualSubscription);\n\n return (\n <div className=\"enrollment-summary\">\n <Card className=\"enrollment-summary__card p-3\">\n <Card.Section className=\"p-0 pb-3\">\n <p className=\"font-weight-bold mb-0 text-gray-900\">\n {formatMessage(messages.purchaseSummary)}\n </p>\n </Card.Section>\n\n <Card.Divider />\n\n <Card.Section className=\"p-0 py-3\">\n <div className=\"d-flex align-items-start\">\n <EdxUnlimitedLogo />\n <div>\n <p className=\"font-weight-bold mb-0 text-primary-500\">\n {productTitle}\n </p>\n <p className=\"small mb-0 text-gray-900\">{productBlurb}</p>\n </div>\n </div>\n </Card.Section>\n\n <Card.Divider />\n\n <Card.Section className=\"p-0 pt-3 pb-2\">\n <div className=\"d-flex justify-content-between align-items-start\">\n <span className=\"small text-gray-900\">{cycleLabel}</span>\n <span className=\"small text-gray-900 font-weight-bold\">\n {amount\n ? formatMessage(messages.priceDisplay, {\n amount,\n frequency,\n currency,\n })\n : null}\n </span>\n </div>\n </Card.Section>\n\n <Card.Section className=\"d-flex justify-content-between align-items-center px-0 pt-1\">\n <span className=\"font-weight-bold text-gray-900\">\n {formatMessage(messages.todaysTotal)}\n </span>\n <span className=\"font-weight-bold mb-0 text-success\">\n {formatMessage(messages.todaysTotalValue)}\n </span>\n </Card.Section>\n </Card>\n\n {course && (\n <CourseEnrollmentCard\n course={course}\n variant=\"success\"\n onStartCourse={onStartCourse}\n />\n )}\n </div>\n );\n};\n\nexport default EnrollmentSummary;\n"]}
@@ -17,8 +17,8 @@ const messages = defineMessages({
17
17
  },
18
18
  priceDisplay: {
19
19
  id: 'checkout.enrollmentSummary.priceDisplay',
20
- defaultMessage: '${amount}/{frequency} USD',
21
- description: 'Price display in the purchase summary',
20
+ defaultMessage: '${amount}/{frequency} {currency}',
21
+ description: 'Price display in the purchase summary e.g. $396/year USD',
22
22
  },
23
23
  todaysTotal: {
24
24
  id: 'checkout.enrollmentSummary.todaysTotal',
@@ -1 +1 @@
1
- {"version":3,"file":"Messages.js","sourceRoot":"","sources":["../../../src/components/EnrollmentSummary/Messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,eAAe,EAAE;QACf,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,kBAAkB;QAClC,WAAW,EAAE,6DAA6D;KAC3E;IACD,mBAAmB,EAAE;QACnB,EAAE,EAAE,gDAAgD;QACpD,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,qDAAqD;KACnE;IACD,kBAAkB,EAAE;QAClB,EAAE,EAAE,+CAA+C;QACnD,cAAc,EAAE,qBAAqB;QACrC,WAAW,EAAE,oDAAoD;KAClE;IACD,YAAY,EAAE;QACZ,EAAE,EAAE,yCAAyC;QAC7C,cAAc,EAAE,2BAA2B;QAC3C,WAAW,EAAE,uCAAuC;KACrD;IACD,WAAW,EAAE;QACX,EAAE,EAAE,wCAAwC;QAC5C,cAAc,EAAE,eAAe;QAC/B,WAAW,EAAE,6BAA6B;KAC3C;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,6CAA6C;QACjD,cAAc,EAAE,IAAI;QACpB,WAAW,EAAE,yCAAyC;KACvD;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n purchaseSummary: {\n id: 'checkout.enrollmentSummary.purchaseSummary',\n defaultMessage: 'Purchase summary',\n description: 'Heading for the purchase summary card on the success screen',\n },\n monthlySubscription: {\n id: 'checkout.enrollmentSummary.monthlySubscription',\n defaultMessage: 'Monthly subscription',\n description: 'Label for monthly billing cycle in purchase summary',\n },\n annualSubscription: {\n id: 'checkout.enrollmentSummary.annualSubscription',\n defaultMessage: 'Annual subscription',\n description: 'Label for annual billing cycle in purchase summary',\n },\n priceDisplay: {\n id: 'checkout.enrollmentSummary.priceDisplay',\n defaultMessage: '${amount}/{frequency} USD',\n description: 'Price display in the purchase summary',\n },\n todaysTotal: {\n id: 'checkout.enrollmentSummary.todaysTotal',\n defaultMessage: \"Today's total\",\n description: \"Label for today's total row\",\n },\n todaysTotalValue: {\n id: 'checkout.enrollmentSummary.todaysTotalValue',\n defaultMessage: '$0',\n description: \"Today's total value during trial period\",\n },\n});\n\nexport default messages;\n"]}
1
+ {"version":3,"file":"Messages.js","sourceRoot":"","sources":["../../../src/components/EnrollmentSummary/Messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,eAAe,EAAE;QACf,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,kBAAkB;QAClC,WAAW,EAAE,6DAA6D;KAC3E;IACD,mBAAmB,EAAE;QACnB,EAAE,EAAE,gDAAgD;QACpD,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,qDAAqD;KACnE;IACD,kBAAkB,EAAE;QAClB,EAAE,EAAE,+CAA+C;QACnD,cAAc,EAAE,qBAAqB;QACrC,WAAW,EAAE,oDAAoD;KAClE;IACD,YAAY,EAAE;QACZ,EAAE,EAAE,yCAAyC;QAC7C,cAAc,EAAE,kCAAkC;QAClD,WAAW,EAAE,0DAA0D;KACxE;IACD,WAAW,EAAE;QACX,EAAE,EAAE,wCAAwC;QAC5C,cAAc,EAAE,eAAe;QAC/B,WAAW,EAAE,6BAA6B;KAC3C;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,6CAA6C;QACjD,cAAc,EAAE,IAAI;QACpB,WAAW,EAAE,yCAAyC;KACvD;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n purchaseSummary: {\n id: 'checkout.enrollmentSummary.purchaseSummary',\n defaultMessage: 'Purchase summary',\n description: 'Heading for the purchase summary card on the success screen',\n },\n monthlySubscription: {\n id: 'checkout.enrollmentSummary.monthlySubscription',\n defaultMessage: 'Monthly subscription',\n description: 'Label for monthly billing cycle in purchase summary',\n },\n annualSubscription: {\n id: 'checkout.enrollmentSummary.annualSubscription',\n defaultMessage: 'Annual subscription',\n description: 'Label for annual billing cycle in purchase summary',\n },\n priceDisplay: {\n id: 'checkout.enrollmentSummary.priceDisplay',\n defaultMessage: '${amount}/{frequency} {currency}',\n description: 'Price display in the purchase summary e.g. $396/year USD',\n },\n todaysTotal: {\n id: 'checkout.enrollmentSummary.todaysTotal',\n defaultMessage: \"Today's total\",\n description: \"Label for today's total row\",\n },\n todaysTotalValue: {\n id: 'checkout.enrollmentSummary.todaysTotalValue',\n defaultMessage: '$0',\n description: \"Today's total value during trial period\",\n },\n});\n\nexport default messages;\n"]}
@@ -3,7 +3,7 @@ import { useState } from 'react';
3
3
  import { Button, Form, Spinner } from '@openedx/paragon';
4
4
  import { useIntl } from '@openedx/frontend-base';
5
5
  import PaymentFields from '../PaymentFields/PaymentFields';
6
- import { COUNTRIES_REQUIRING_EXTRA_CONFIRM, COUNTRIES } from '../../constants';
6
+ import { COUNTRIES_REQUIRING_EXTRA_CONFIRM, BILLING_COUNTRIES } from '../../constants';
7
7
  import messages from './Messages';
8
8
  const PaymentForm = ({ billing, setField, numberMountRef, expiryMountRef, cvcMountRef, cardError, stripeReady, sessionReady, submitting, onPlaceOrder, priceToShow, cycleToShow, trialEnd, userCountry, }) => {
9
9
  var _a;
@@ -48,9 +48,9 @@ const PaymentForm = ({ billing, setField, numberMountRef, expiryMountRef, cvcMou
48
48
  };
49
49
  return (_jsxs("div", { className: "payment-form bg-white", children: [_jsx("h2", { className: "payment-form__heading font-weight-bold mb-3 text-primary-500", children: formatMessage(messages.selectPaymentMethod) }), _jsxs("p", { className: "payment-form__help small mb-4", children: [_jsx("strong", { className: "d-block text-primary-500", children: formatMessage(messages.needAssistance) }), ' ', _jsx("span", { className: "text-gray-700", children: formatMessage(messages.needAssistanceBody, {
50
50
  link: (_jsx("a", { href: "https://support.edx.org", target: "_blank", rel: "noreferrer", className: "text-gray-700", children: formatMessage(messages.learnerHelpCenter) })),
51
- }) })] }), _jsxs("div", { className: "payment-form__methods mb-4", children: [_jsxs("div", { className: `payment-form__method${paymentMethod === 'card' ? ' payment-form__method--selected' : ''}`, children: [_jsxs("label", { htmlFor: "paymentMethod-card", className: "payment-form__method-header", children: [_jsx("input", { id: "paymentMethod-card", type: "radio", name: "paymentMethod", value: "card", checked: paymentMethod === 'card', onChange: () => setPaymentMethod('card'), className: "payment-form__radio" }), _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M0 4C0 3.46957 0.210714 2.96086 0.585786 2.58579C0.960859 2.21071 1.46957 2 2 2H14C14.5304 2 15.0391 2.21071 15.4142 2.58579C15.7893 2.96086 16 3.46957 16 4H0ZM0 6V12C0 12.5304 0.210714 13.0391 0.585786 13.4142C0.960859 13.7893 1.46957 14 2 14H14C14.5304 14 15.0391 13.7893 15.4142 13.4142C15.7893 13.0391 16 12.5304 16 12V6H0ZM3 11C3 10.7348 3.10536 10.4804 3.29289 10.2929C3.48043 10.1054 3.73478 10 4 10H5C5.26522 10 5.51957 10.1054 5.70711 10.2929C5.89464 10.4804 6 10.7348 6 11C6 11.2652 5.89464 11.5196 5.70711 11.7071C5.51957 11.8946 5.26522 12 5 12H4C3.73478 12 3.48043 11.8946 3.29289 11.7071C3.10536 11.5196 3 11.2652 3 11Z", fill: "#0270DE" }) }), _jsx("span", { className: "payment-form__method-name text-info-500", children: formatMessage(messages.card) })] }), paymentMethod === 'card' && (_jsxs("div", { className: "payment-form__card-panel", children: [_jsx(PaymentFields, { numberMountRef: numberMountRef, expiryMountRef: expiryMountRef, cvcMountRef: cvcMountRef, cardError: cardError }), _jsxs(Form.Group, { controlId: "country", className: "mt-3 mb-0 payment__field--country", children: [_jsx(Form.Label, { className: "small m-0 x-small", children: formatMessage(messages.country) }), _jsx(Form.Control, { as: "select", value: billing.country, onChange: (e) => setField('country', e.target.value), children: COUNTRIES.map((country) => {
51
+ }) })] }), _jsxs("div", { className: "payment-form__methods mb-4", children: [_jsxs("div", { className: `payment-form__method${paymentMethod === 'card' ? ' payment-form__method--selected' : ''}`, children: [_jsxs("label", { htmlFor: "paymentMethod-card", className: "payment-form__method-header", children: [_jsx("input", { id: "paymentMethod-card", type: "radio", name: "paymentMethod", value: "card", checked: paymentMethod === 'card', onChange: () => setPaymentMethod('card'), className: "payment-form__radio" }), _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M0 4C0 3.46957 0.210714 2.96086 0.585786 2.58579C0.960859 2.21071 1.46957 2 2 2H14C14.5304 2 15.0391 2.21071 15.4142 2.58579C15.7893 2.96086 16 3.46957 16 4H0ZM0 6V12C0 12.5304 0.210714 13.0391 0.585786 13.4142C0.960859 13.7893 1.46957 14 2 14H14C14.5304 14 15.0391 13.7893 15.4142 13.4142C15.7893 13.0391 16 12.5304 16 12V6H0ZM3 11C3 10.7348 3.10536 10.4804 3.29289 10.2929C3.48043 10.1054 3.73478 10 4 10H5C5.26522 10 5.51957 10.1054 5.70711 10.2929C5.89464 10.4804 6 10.7348 6 11C6 11.2652 5.89464 11.5196 5.70711 11.7071C5.51957 11.8946 5.26522 12 5 12H4C3.73478 12 3.48043 11.8946 3.29289 11.7071C3.10536 11.5196 3 11.2652 3 11Z", fill: "#0270DE" }) }), _jsx("span", { className: "payment-form__method-name text-info-500", children: formatMessage(messages.card) })] }), paymentMethod === 'card' && (_jsxs("div", { className: "payment-form__card-panel", children: [_jsx(PaymentFields, { numberMountRef: numberMountRef, expiryMountRef: expiryMountRef, cvcMountRef: cvcMountRef, cardError: cardError }), _jsxs(Form.Group, { controlId: "country", className: "mt-3 mb-0 payment__field--country", children: [_jsx(Form.Label, { className: "small m-0 x-small", children: formatMessage(messages.country) }), _jsx(Form.Control, { as: "select", value: billing.country, onChange: (e) => setField('country', e.target.value), children: BILLING_COUNTRIES.map((country) => {
52
52
  return (_jsx("option", { value: country[0], children: country[1] }, country[0]));
53
- }) })] })] }))] }), _jsx("div", { className: `my-3 payment-form__method${paymentMethod === 'googlepay' ? ' payment-form__method--selected' : ''}`, children: _jsxs("label", { htmlFor: "paymentMethod-googlepay", className: "payment-form__method-header", children: [_jsx("input", { id: "paymentMethod-googlepay", type: "radio", name: "paymentMethod", value: "googlepay", checked: paymentMethod === 'googlepay', onChange: () => setPaymentMethod('googlepay'), className: "payment-form__radio" }), _jsx("span", { className: "payment-form__method-icon payment-form__method-icon--gpay", "aria-hidden": "true", children: "G" }), _jsx("span", { className: "payment-form__method-name", children: formatMessage(messages.googlePay) })] }) }), _jsx("div", { className: `payment-form__method${paymentMethod === 'paypal' ? ' payment-form__method--selected' : ''}`, children: _jsxs("label", { htmlFor: "paymentMethod-paypal", className: "payment-form__method-header", children: [_jsx("input", { id: "paymentMethod-paypal", type: "radio", name: "paymentMethod", value: "paypal", checked: paymentMethod === 'paypal', onChange: () => setPaymentMethod('paypal'), className: "payment-form__radio" }), _jsx("span", { className: "payment-form__method-icon payment-form__method-icon--paypal", "aria-hidden": "true", children: "P" }), _jsx("span", { className: "payment-form__method-name", children: formatMessage(messages.paypal) })] }) })] }), _jsx("p", { className: "payment-form__terms text-gray-700 mb-3", children: formatMessage(messages.termsNotice, {
53
+ }) })] })] }))] }), _jsx("div", { className: `my-3 payment-form__method payment-form__method--hidden${paymentMethod === 'googlepay' ? ' payment-form__method--selected' : ''}`, children: _jsxs("label", { htmlFor: "paymentMethod-googlepay", className: "payment-form__method-header", children: [_jsx("input", { id: "paymentMethod-googlepay", type: "radio", name: "paymentMethod", value: "googlepay", checked: paymentMethod === 'googlepay', onChange: () => setPaymentMethod('googlepay'), className: "payment-form__radio" }), _jsx("span", { className: "payment-form__method-icon payment-form__method-icon--gpay", "aria-hidden": "true", children: "G" }), _jsx("span", { className: "payment-form__method-name", children: formatMessage(messages.googlePay) })] }) }), _jsx("div", { className: `payment-form__method payment-form__method--hidden${paymentMethod === 'paypal' ? ' payment-form__method--selected' : ''}`, children: _jsxs("label", { htmlFor: "paymentMethod-paypal", className: "payment-form__method-header", children: [_jsx("input", { id: "paymentMethod-paypal", type: "radio", name: "paymentMethod", value: "paypal", checked: paymentMethod === 'paypal', onChange: () => setPaymentMethod('paypal'), className: "payment-form__radio" }), _jsx("span", { className: "payment-form__method-icon payment-form__method-icon--paypal", "aria-hidden": "true", children: "P" }), _jsx("span", { className: "payment-form__method-name", children: formatMessage(messages.paypal) })] }) })] }), _jsx("p", { className: "payment-form__terms text-gray-700 mb-3", children: formatMessage(messages.termsNotice, {
54
54
  renewalDate: trialEnd !== null && trialEnd !== void 0 ? trialEnd : '{date}',
55
55
  price: amount,
56
56
  frequency,
@@ -1 +1 @@
1
- {"version":3,"file":"PaymentForm.js","sourceRoot":"","sources":["../../../src/components/PaymentForm/PaymentForm.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState } from 'react';\nimport type { Ref } from 'react';\nimport { Button, Form, Spinner } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport PaymentFields from '../PaymentFields/PaymentFields';\nimport type { BillingInfo, CheckoutConsent } from '../../types';\nimport type { PlanPrice } from '../../utils/billingDetails';\nimport { COUNTRIES_REQUIRING_EXTRA_CONFIRM, COUNTRIES } from '../../constants';\nimport messages from './Messages';\n\ntype PaymentMethod = 'card' | 'googlepay' | 'paypal';\n\nexport interface PaymentFormProps {\n billing: BillingInfo,\n setField: (field: keyof BillingInfo, value: string) => void,\n numberMountRef: Ref<HTMLDivElement>,\n expiryMountRef: Ref<HTMLDivElement>,\n cvcMountRef: Ref<HTMLDivElement>,\n cardError: string,\n stripeReady: boolean,\n sessionReady: boolean,\n submitting: boolean,\n onPlaceOrder: (consent: CheckoutConsent) => void,\n priceToShow: PlanPrice | null,\n cycleToShow: string,\n trialEnd?: string,\n userCountry?: string | null,\n}\n\nconst PaymentForm = ({\n billing,\n setField,\n numberMountRef,\n expiryMountRef,\n cvcMountRef,\n cardError,\n stripeReady,\n sessionReady,\n submitting,\n onPlaceOrder,\n priceToShow,\n cycleToShow,\n trialEnd,\n userCountry,\n}: PaymentFormProps) => {\n const { formatMessage } = useIntl();\n const [paymentMethod, setPaymentMethod] = useState<PaymentMethod>('card');\n const [confirmed, setConfirmed] = useState(false);\n const [ukCaConfirmed, setUkCaConfirmed] = useState(false);\n\n const showExtraConfirm\n = !!userCountry && COUNTRIES_REQUIRING_EXTRA_CONFIRM.includes(userCountry);\n\n const busy = submitting || !stripeReady || !sessionReady;\n\n let buttonLabel = formatMessage(messages.confirmSubscription);\n if (submitting) buttonLabel = formatMessage(messages.processing);\n else if (!sessionReady) buttonLabel = formatMessage(messages.loadingPayment);\n else if (!stripeReady) buttonLabel = formatMessage(messages.loadingPayment);\n\n const amount = priceToShow?.amount ?? '';\n const frequency = cycleToShow === 'annual' ? 'year' : 'month';\n\n const buildConsent = (): CheckoutConsent => {\n const termsText = formatMessage(messages.termsNotice, {\n renewalDate: trialEnd ?? '{date}',\n price: amount,\n frequency,\n termsLink: formatMessage(messages.termsOfUse),\n refundLink: formatMessage(messages.refundPolicy),\n });\n const recurringText = formatMessage(messages.recurringConfirm, {\n cycle: cycleToShow,\n price: amount,\n frequency,\n });\n const consentParts = [termsText, recurringText];\n if (showExtraConfirm) {\n consentParts.push(formatMessage(messages.ukCaResidentConfirm));\n }\n return {\n tConsentRecurring: confirmed,\n tConsentUkCa: showExtraConfirm ? ukCaConfirmed : null,\n tConsentAt: new Date().toISOString(),\n tConsentText: consentParts.join('\\n\\n'),\n };\n };\n\n return (\n <div className=\"payment-form bg-white\">\n <h2 className=\"payment-form__heading font-weight-bold mb-3 text-primary-500\">\n {formatMessage(messages.selectPaymentMethod)}\n </h2>\n\n <p className=\"payment-form__help small mb-4\">\n <strong className=\"d-block text-primary-500\">\n {formatMessage(messages.needAssistance)}\n </strong>{' '}\n <span className=\"text-gray-700\">\n {formatMessage(messages.needAssistanceBody, {\n link: (\n <a\n href=\"https://support.edx.org\"\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-gray-700\"\n >\n {formatMessage(messages.learnerHelpCenter)}\n </a>\n ),\n })}\n </span>\n </p>\n\n {/* ── Payment method accordion ── */}\n <div className=\"payment-form__methods mb-4\">\n {/* ── Card ── */}\n <div\n className={`payment-form__method${paymentMethod === 'card' ? ' payment-form__method--selected' : ''}`}\n >\n {/* Header row — always visible */}\n <label\n htmlFor=\"paymentMethod-card\"\n className=\"payment-form__method-header\"\n >\n <input\n id=\"paymentMethod-card\"\n type=\"radio\"\n name=\"paymentMethod\"\n value=\"card\"\n checked={paymentMethod === 'card'}\n onChange={() => setPaymentMethod('card')}\n className=\"payment-form__radio\"\n />\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M0 4C0 3.46957 0.210714 2.96086 0.585786 2.58579C0.960859 2.21071 1.46957 2 2 2H14C14.5304 2 15.0391 2.21071 15.4142 2.58579C15.7893 2.96086 16 3.46957 16 4H0ZM0 6V12C0 12.5304 0.210714 13.0391 0.585786 13.4142C0.960859 13.7893 1.46957 14 2 14H14C14.5304 14 15.0391 13.7893 15.4142 13.4142C15.7893 13.0391 16 12.5304 16 12V6H0ZM3 11C3 10.7348 3.10536 10.4804 3.29289 10.2929C3.48043 10.1054 3.73478 10 4 10H5C5.26522 10 5.51957 10.1054 5.70711 10.2929C5.89464 10.4804 6 10.7348 6 11C6 11.2652 5.89464 11.5196 5.70711 11.7071C5.51957 11.8946 5.26522 12 5 12H4C3.73478 12 3.48043 11.8946 3.29289 11.7071C3.10536 11.5196 3 11.2652 3 11Z\"\n fill=\"#0270DE\"\n />\n </svg>\n <span className=\"payment-form__method-name text-info-500\">\n {formatMessage(messages.card)}\n </span>\n </label>\n\n {/* Expanded panel — only when selected */}\n {paymentMethod === 'card' && (\n <div className=\"payment-form__card-panel\">\n <PaymentFields\n numberMountRef={numberMountRef}\n expiryMountRef={expiryMountRef}\n cvcMountRef={cvcMountRef}\n cardError={cardError}\n />\n <Form.Group\n controlId=\"country\"\n className=\"mt-3 mb-0 payment__field--country\"\n >\n <Form.Label className=\"small m-0 x-small\">\n {formatMessage(messages.country)}\n </Form.Label>\n <Form.Control\n as=\"select\"\n value={billing.country}\n onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>\n setField('country', e.target.value)}\n >\n {COUNTRIES.map((country) => {\n return (\n <option key={country[0]} value={country[0]}>\n {country[1]}\n </option>\n );\n })}\n </Form.Control>\n </Form.Group>\n </div>\n )}\n </div>\n\n {/* ── Google Pay ── */}\n <div\n className={`my-3 payment-form__method${paymentMethod === 'googlepay' ? ' payment-form__method--selected' : ''}`}\n >\n <label\n htmlFor=\"paymentMethod-googlepay\"\n className=\"payment-form__method-header\"\n >\n <input\n id=\"paymentMethod-googlepay\"\n type=\"radio\"\n name=\"paymentMethod\"\n value=\"googlepay\"\n checked={paymentMethod === 'googlepay'}\n onChange={() => setPaymentMethod('googlepay')}\n className=\"payment-form__radio\"\n />\n <span\n className=\"payment-form__method-icon payment-form__method-icon--gpay\"\n aria-hidden=\"true\"\n >\n G\n </span>\n <span className=\"payment-form__method-name\">\n {formatMessage(messages.googlePay)}\n </span>\n </label>\n </div>\n\n {/* ── PayPal ── */}\n <div\n className={`payment-form__method${paymentMethod === 'paypal' ? ' payment-form__method--selected' : ''}`}\n >\n <label\n htmlFor=\"paymentMethod-paypal\"\n className=\"payment-form__method-header\"\n >\n <input\n id=\"paymentMethod-paypal\"\n type=\"radio\"\n name=\"paymentMethod\"\n value=\"paypal\"\n checked={paymentMethod === 'paypal'}\n onChange={() => setPaymentMethod('paypal')}\n className=\"payment-form__radio\"\n />\n <span\n className=\"payment-form__method-icon payment-form__method-icon--paypal\"\n aria-hidden=\"true\"\n >\n P\n </span>\n <span className=\"payment-form__method-name\">\n {formatMessage(messages.paypal)}\n </span>\n </label>\n </div>\n </div>\n\n {/* ── Terms ── */}\n <p className=\"payment-form__terms text-gray-700 mb-3\">\n {formatMessage(messages.termsNotice, {\n renewalDate: trialEnd ?? '{date}',\n price: amount,\n frequency,\n termsLink: (\n <a\n className=\"text-gray-700\"\n href=\"/terms\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {formatMessage(messages.termsOfUse)}\n </a>\n ),\n refundLink: (\n <a\n className=\"text-gray-700\"\n href=\"/refund-policy\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {formatMessage(messages.refundPolicy)}\n </a>\n ),\n })}\n </p>\n\n {/* ── Checkboxes ── */}\n <Form.Group controlId=\"recurringConfirm\" className=\"mb-2\">\n <Form.Checkbox\n id=\"recurringConfirm\"\n checked={confirmed}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n setConfirmed(e.target.checked)}\n >\n <span className=\"text-gray-700\">\n {formatMessage(messages.recurringConfirm, {\n cycle: cycleToShow,\n price: amount,\n frequency,\n })}\n </span>\n </Form.Checkbox>\n </Form.Group>\n\n {showExtraConfirm && (\n <Form.Group controlId=\"ukCaConfirm\" className=\"mb-4\">\n <Form.Checkbox\n id=\"ukCaConfirm\"\n checked={ukCaConfirmed}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n setUkCaConfirmed(e.target.checked)}\n >\n <span className=\"text-gray-700\">\n {formatMessage(messages.ukCaResidentConfirm)}\n </span>\n </Form.Checkbox>\n </Form.Group>\n )}\n\n {/* ── Submit ── */}\n <Button\n variant=\"brand\"\n className=\"payment-form__submit\"\n onClick={() => onPlaceOrder(buildConsent())}\n disabled={\n !stripeReady\n || submitting\n || !confirmed\n || (showExtraConfirm && !ukCaConfirmed)\n }\n >\n {busy && (\n <Spinner\n animation=\"border\"\n size=\"sm\"\n className=\"mr-2\"\n screenReaderText={formatMessage(messages.spinnerScreenReaderText)}\n />\n )}\n {buttonLabel}\n </Button>\n </div>\n );\n};\n\nexport default PaymentForm;\n"]}
1
+ {"version":3,"file":"PaymentForm.js","sourceRoot":"","sources":["../../../src/components/PaymentForm/PaymentForm.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState } from 'react';\nimport type { Ref } from 'react';\nimport { Button, Form, Spinner } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport PaymentFields from '../PaymentFields/PaymentFields';\nimport type { BillingInfo, CheckoutConsent } from '../../types';\nimport type { PlanPrice } from '../../utils/billingDetails';\nimport { COUNTRIES_REQUIRING_EXTRA_CONFIRM, BILLING_COUNTRIES } from '../../constants';\nimport messages from './Messages';\n\ntype PaymentMethod = 'card' | 'googlepay' | 'paypal';\n\nexport interface PaymentFormProps {\n billing: BillingInfo,\n setField: (field: keyof BillingInfo, value: string) => void,\n numberMountRef: Ref<HTMLDivElement>,\n expiryMountRef: Ref<HTMLDivElement>,\n cvcMountRef: Ref<HTMLDivElement>,\n cardError: string,\n stripeReady: boolean,\n sessionReady: boolean,\n submitting: boolean,\n onPlaceOrder: (consent: CheckoutConsent) => void,\n priceToShow: PlanPrice | null,\n cycleToShow: string,\n trialEnd?: string,\n userCountry?: string | null,\n}\n\nconst PaymentForm = ({\n billing,\n setField,\n numberMountRef,\n expiryMountRef,\n cvcMountRef,\n cardError,\n stripeReady,\n sessionReady,\n submitting,\n onPlaceOrder,\n priceToShow,\n cycleToShow,\n trialEnd,\n userCountry,\n}: PaymentFormProps) => {\n const { formatMessage } = useIntl();\n const [paymentMethod, setPaymentMethod] = useState<PaymentMethod>('card');\n const [confirmed, setConfirmed] = useState(false);\n const [ukCaConfirmed, setUkCaConfirmed] = useState(false);\n\n const showExtraConfirm\n = !!userCountry && COUNTRIES_REQUIRING_EXTRA_CONFIRM.includes(userCountry);\n\n const busy = submitting || !stripeReady || !sessionReady;\n\n let buttonLabel = formatMessage(messages.confirmSubscription);\n if (submitting) buttonLabel = formatMessage(messages.processing);\n else if (!sessionReady) buttonLabel = formatMessage(messages.loadingPayment);\n else if (!stripeReady) buttonLabel = formatMessage(messages.loadingPayment);\n\n const amount = priceToShow?.amount ?? '';\n const frequency = cycleToShow === 'annual' ? 'year' : 'month';\n\n const buildConsent = (): CheckoutConsent => {\n const termsText = formatMessage(messages.termsNotice, {\n renewalDate: trialEnd ?? '{date}',\n price: amount,\n frequency,\n termsLink: formatMessage(messages.termsOfUse),\n refundLink: formatMessage(messages.refundPolicy),\n });\n const recurringText = formatMessage(messages.recurringConfirm, {\n cycle: cycleToShow,\n price: amount,\n frequency,\n });\n const consentParts = [termsText, recurringText];\n if (showExtraConfirm) {\n consentParts.push(formatMessage(messages.ukCaResidentConfirm));\n }\n return {\n tConsentRecurring: confirmed,\n tConsentUkCa: showExtraConfirm ? ukCaConfirmed : null,\n tConsentAt: new Date().toISOString(),\n tConsentText: consentParts.join('\\n\\n'),\n };\n };\n\n return (\n <div className=\"payment-form bg-white\">\n <h2 className=\"payment-form__heading font-weight-bold mb-3 text-primary-500\">\n {formatMessage(messages.selectPaymentMethod)}\n </h2>\n\n <p className=\"payment-form__help small mb-4\">\n <strong className=\"d-block text-primary-500\">\n {formatMessage(messages.needAssistance)}\n </strong>{' '}\n <span className=\"text-gray-700\">\n {formatMessage(messages.needAssistanceBody, {\n link: (\n <a\n href=\"https://support.edx.org\"\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-gray-700\"\n >\n {formatMessage(messages.learnerHelpCenter)}\n </a>\n ),\n })}\n </span>\n </p>\n\n {/* ── Payment method accordion ── */}\n <div className=\"payment-form__methods mb-4\">\n {/* ── Card ── */}\n <div\n className={`payment-form__method${paymentMethod === 'card' ? ' payment-form__method--selected' : ''}`}\n >\n {/* Header row — always visible */}\n <label\n htmlFor=\"paymentMethod-card\"\n className=\"payment-form__method-header\"\n >\n <input\n id=\"paymentMethod-card\"\n type=\"radio\"\n name=\"paymentMethod\"\n value=\"card\"\n checked={paymentMethod === 'card'}\n onChange={() => setPaymentMethod('card')}\n className=\"payment-form__radio\"\n />\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M0 4C0 3.46957 0.210714 2.96086 0.585786 2.58579C0.960859 2.21071 1.46957 2 2 2H14C14.5304 2 15.0391 2.21071 15.4142 2.58579C15.7893 2.96086 16 3.46957 16 4H0ZM0 6V12C0 12.5304 0.210714 13.0391 0.585786 13.4142C0.960859 13.7893 1.46957 14 2 14H14C14.5304 14 15.0391 13.7893 15.4142 13.4142C15.7893 13.0391 16 12.5304 16 12V6H0ZM3 11C3 10.7348 3.10536 10.4804 3.29289 10.2929C3.48043 10.1054 3.73478 10 4 10H5C5.26522 10 5.51957 10.1054 5.70711 10.2929C5.89464 10.4804 6 10.7348 6 11C6 11.2652 5.89464 11.5196 5.70711 11.7071C5.51957 11.8946 5.26522 12 5 12H4C3.73478 12 3.48043 11.8946 3.29289 11.7071C3.10536 11.5196 3 11.2652 3 11Z\"\n fill=\"#0270DE\"\n />\n </svg>\n <span className=\"payment-form__method-name text-info-500\">\n {formatMessage(messages.card)}\n </span>\n </label>\n\n {/* Expanded panel — only when selected */}\n {paymentMethod === 'card' && (\n <div className=\"payment-form__card-panel\">\n <PaymentFields\n numberMountRef={numberMountRef}\n expiryMountRef={expiryMountRef}\n cvcMountRef={cvcMountRef}\n cardError={cardError}\n />\n <Form.Group\n controlId=\"country\"\n className=\"mt-3 mb-0 payment__field--country\"\n >\n <Form.Label className=\"small m-0 x-small\">\n {formatMessage(messages.country)}\n </Form.Label>\n <Form.Control\n as=\"select\"\n value={billing.country}\n onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>\n setField('country', e.target.value)}\n >\n {BILLING_COUNTRIES.map((country) => {\n return (\n <option key={country[0]} value={country[0]}>\n {country[1]}\n </option>\n );\n })}\n </Form.Control>\n </Form.Group>\n </div>\n )}\n </div>\n\n {/* ── Google Pay (hidden for now) ── */}\n <div\n className={`my-3 payment-form__method payment-form__method--hidden${paymentMethod === 'googlepay' ? ' payment-form__method--selected' : ''}`}\n >\n <label\n htmlFor=\"paymentMethod-googlepay\"\n className=\"payment-form__method-header\"\n >\n <input\n id=\"paymentMethod-googlepay\"\n type=\"radio\"\n name=\"paymentMethod\"\n value=\"googlepay\"\n checked={paymentMethod === 'googlepay'}\n onChange={() => setPaymentMethod('googlepay')}\n className=\"payment-form__radio\"\n />\n <span\n className=\"payment-form__method-icon payment-form__method-icon--gpay\"\n aria-hidden=\"true\"\n >\n G\n </span>\n <span className=\"payment-form__method-name\">\n {formatMessage(messages.googlePay)}\n </span>\n </label>\n </div>\n\n {/* ── PayPal (hidden for now) ── */}\n <div\n className={`payment-form__method payment-form__method--hidden${paymentMethod === 'paypal' ? ' payment-form__method--selected' : ''}`}\n >\n <label\n htmlFor=\"paymentMethod-paypal\"\n className=\"payment-form__method-header\"\n >\n <input\n id=\"paymentMethod-paypal\"\n type=\"radio\"\n name=\"paymentMethod\"\n value=\"paypal\"\n checked={paymentMethod === 'paypal'}\n onChange={() => setPaymentMethod('paypal')}\n className=\"payment-form__radio\"\n />\n <span\n className=\"payment-form__method-icon payment-form__method-icon--paypal\"\n aria-hidden=\"true\"\n >\n P\n </span>\n <span className=\"payment-form__method-name\">\n {formatMessage(messages.paypal)}\n </span>\n </label>\n </div>\n </div>\n\n {/* ── Terms ── */}\n <p className=\"payment-form__terms text-gray-700 mb-3\">\n {formatMessage(messages.termsNotice, {\n renewalDate: trialEnd ?? '{date}',\n price: amount,\n frequency,\n termsLink: (\n <a\n className=\"text-gray-700\"\n href=\"/terms\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {formatMessage(messages.termsOfUse)}\n </a>\n ),\n refundLink: (\n <a\n className=\"text-gray-700\"\n href=\"/refund-policy\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {formatMessage(messages.refundPolicy)}\n </a>\n ),\n })}\n </p>\n\n {/* ── Checkboxes ── */}\n <Form.Group controlId=\"recurringConfirm\" className=\"mb-2\">\n <Form.Checkbox\n id=\"recurringConfirm\"\n checked={confirmed}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n setConfirmed(e.target.checked)}\n >\n <span className=\"text-gray-700\">\n {formatMessage(messages.recurringConfirm, {\n cycle: cycleToShow,\n price: amount,\n frequency,\n })}\n </span>\n </Form.Checkbox>\n </Form.Group>\n\n {showExtraConfirm && (\n <Form.Group controlId=\"ukCaConfirm\" className=\"mb-4\">\n <Form.Checkbox\n id=\"ukCaConfirm\"\n checked={ukCaConfirmed}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n setUkCaConfirmed(e.target.checked)}\n >\n <span className=\"text-gray-700\">\n {formatMessage(messages.ukCaResidentConfirm)}\n </span>\n </Form.Checkbox>\n </Form.Group>\n )}\n\n {/* ── Submit ── */}\n <Button\n variant=\"brand\"\n className=\"payment-form__submit\"\n onClick={() => onPlaceOrder(buildConsent())}\n disabled={\n !stripeReady\n || submitting\n || !confirmed\n || (showExtraConfirm && !ukCaConfirmed)\n }\n >\n {busy && (\n <Spinner\n animation=\"border\"\n size=\"sm\"\n className=\"mr-2\"\n screenReaderText={formatMessage(messages.spinnerScreenReaderText)}\n />\n )}\n {buttonLabel}\n </Button>\n </div>\n );\n};\n\nexport default PaymentForm;\n"]}
@@ -44,7 +44,8 @@ export declare const ALLOWED_CHECKOUT_COUNTRIES: readonly string[];
44
44
  * Add or remove codes here to control which residents see the second checkbox.
45
45
  */
46
46
  export declare const COUNTRIES_REQUIRING_EXTRA_CONFIRM: readonly string[];
47
- export declare const COUNTRIES: readonly (readonly [string, string])[];
47
+ /** Billing country dropdown options. Swap back to COUNTRIES when expanding internationally. */
48
+ export declare const BILLING_COUNTRIES: readonly (readonly [string, string])[];
48
49
  export declare const STRIPE_FIELD_STYLE: CSSProperties;
49
50
  export declare const STRIPE_ELEMENT_OPTS: {
50
51
  style: {