Skip to content

Commit 041c78c

Browse files
committed
fix(auth): Update SubscriptionUpgrade and SubscriptionSubsequentInvoice emails to handle credits
- updates the subscriptionUpgrade and subscriptionSubsequentInvoice email templates to handle credit amounts Closes: FXA-11636
1 parent 2973610 commit 041c78c

File tree

14 files changed

+263
-78
lines changed

14 files changed

+263
-78
lines changed

packages/fxa-auth-server/lib/payments/stripe.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3303,7 +3303,7 @@ export class StripeHelper extends StripeHelperBase {
33033303
id: invoiceId,
33043304
number: invoiceNumber,
33053305
currency: paymentProratedCurrency,
3306-
amount_due: invoiceAmountDue,
3306+
total: invoiceTotal,
33073307
} = invoice;
33083308

33093309
// https://github.com/mozilla/subhub/blob/e224feddcdcbafaf0f3cd7d52691d29d94157de5/src/hub/vendor/customer.py#L643
@@ -3344,7 +3344,7 @@ export class StripeHelper extends StripeHelperBase {
33443344
paymentAmountNewCurrency: nextInvoiceCurrency,
33453345
invoiceNumber,
33463346
invoiceId,
3347-
paymentProratedInCents: invoiceAmountDue,
3347+
paymentProratedInCents: invoiceTotal,
33483348
paymentProratedCurrency,
33493349
};
33503350
}

packages/fxa-auth-server/lib/senders/email.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -2147,10 +2147,11 @@ module.exports = function (log, config, bounces, statsd) {
21472147
message.acceptLanguage
21482148
),
21492149
paymentProrated: this._getLocalizedCurrencyString(
2150-
paymentProratedInCents,
2150+
Math.abs(paymentProratedInCents),
21512151
paymentProratedCurrency,
21522152
message.acceptLanguage
21532153
),
2154+
paymentProratedInCents,
21542155
productPaymentCycleNew,
21552156
productPaymentCycleOld,
21562157
icon: productIconURLNew,
@@ -2717,8 +2718,9 @@ module.exports = function (log, config, bounces, statsd) {
27172718
invoiceLink,
27182719
invoiceNumber,
27192720
invoiceDate,
2721+
invoiceTotalInCents,
27202722
invoiceTotal: this._getLocalizedCurrencyString(
2721-
invoiceTotalInCents,
2723+
Math.abs(invoiceTotalInCents),
27222724
invoiceTotalCurrency,
27232725
message.acceptLanguage
27242726
),

packages/fxa-auth-server/lib/senders/emails/partials/subscriptionCharges/en.ftl

+4-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ subscriptionFirstInvoiceDiscount-content-discount-repeating = { $discountDuratio
2323
# Variables:
2424
# $invoiceTaxAmount (String) - The amount of the tax of the subscription invoice, including currency, e.g. $2.00
2525
subscriptionCharges-content-tax = Taxes & fees: { $invoiceTaxAmount }
26-
# Variables:
27-
# $invoiceDateOnly (String) - The date of the next invoice, e.g. 01/20/2016
28-
# $invoiceTotal (String) - The amount, after discount, of the subscription invoice, including currency, e.g. $8.00
26+
## Variables:
27+
## $invoiceDateOnly (String) - The date of the next invoice, e.g. 01/20/2016
28+
## $invoiceTotal (String) - The amount, after discount, of the subscription invoice, including currency, e.g. $8.00
2929
subscriptionFirstInvoice-content-charge = Charged { $invoiceTotal } on { $invoiceDateOnly }
30+
subscriptionFirstInvoice-content-credit = You have received an account credit of { $invoiceTotal }, which will be applied to your future invoices.

packages/fxa-auth-server/lib/senders/emails/partials/subscriptionCharges/index.mjml

+9-3
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,13 @@
5555
<% } %>
5656

5757
<mj-text css-class="text-body-no-bottom-margin">
58-
<span data-l10n-id="subscriptionFirstInvoice-content-charge" data-l10n-args="<%= JSON.stringify({invoiceDateOnly, invoiceTotal}) %>">
59-
Charged <%- invoiceTotal %> on <%- invoiceDateOnly %>
60-
</span>
58+
<% if (locals.invoiceTotalInCents >= 0 ) { %>
59+
<span data-l10n-id="subscriptionFirstInvoice-content-charge" data-l10n-args="<%= JSON.stringify({invoiceDateOnly, invoiceTotal}) %>">
60+
Charged <%- invoiceTotal %> on <%- invoiceDateOnly %>
61+
</span>
62+
<% } else { %>
63+
<span data-l10n-id="subscriptionFirstInvoice-content-credit" data-l10n-args="<%= JSON.stringify({invoiceTotal}) %>">
64+
You have received an account credit of <%- invoiceTotal %>, which will be applied to your future invoices.
65+
</span>
66+
<% } %>
6167
</mj-text>

packages/fxa-auth-server/lib/senders/emails/partials/subscriptionCharges/index.txt

+4
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@ subscriptionFirstInvoice-content-invoice-number-plaintext = "Invoice Number: <%-
1919
subscriptionFirstInvoiceDiscount-content-discount = "Discount: -<%- invoiceDiscountAmount %>"
2020
<% } %>
2121
<% } %>
22+
<% if (invoiceTotalInCents >= 0 ) { %>
2223
subscriptionFirstInvoice-content-charge = "Charged <%- invoiceTotal %> on <%- invoiceDateOnly %>"
24+
<% } else { %>
25+
subscriptionFirstInvoice-content-credit = "You have received an account credit of <%- invoiceTotal %>, which will be applied to your future invoices."
26+
<% } %>

packages/fxa-auth-server/lib/senders/emails/templates/_versions.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"subscriptionAccountFinishSetup": 2,
33
"subscriptionReactivation": 2,
44
"subscriptionRenewalReminder": 2,
5-
"subscriptionUpgrade": 4,
5+
"subscriptionUpgrade": 5,
66
"subscriptionDowngrade": 2,
77
"subscriptionPaymentExpired": 3,
88
"subscriptionsPaymentExpired": 3,
@@ -13,7 +13,7 @@
1313
"subscriptionCancellation": 3,
1414
"subscriptionFailedPaymentsCancellation": 2,
1515
"subscriptionReplaced": 1,
16-
"subscriptionSubsequentInvoice": 3,
16+
"subscriptionSubsequentInvoice": 4,
1717
"subscriptionFirstInvoice": 3,
1818
"downloadSubscription": 2,
1919
"fraudulentAccountDeletion": 1,

packages/fxa-auth-server/lib/senders/emails/templates/subscriptionSubsequentInvoice/en.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ subscriptionSubsequentInvoice-title = Thank you for being a subscriber!
66
# $productName (String) - The name of the subscribed product, e.g. Mozilla VPN
77
subscriptionSubsequentInvoice-content-received = We received your latest payment for { $productName }.
88
# Variables:
9-
# $nextInvoiceDateOnly (String) - The date of the next invoice, e.g. 2016/01/20
9+
# $nextInvoiceDateOnly (String) - The date of the next invoice, e.g. 5/9/2025 (US), 09/05/2025 (UK)
1010
subscriptionSubsequentInvoice-content-next-invoice = Next Invoice: { $nextInvoiceDateOnly }

packages/fxa-auth-server/lib/senders/emails/templates/subscriptionSubsequentInvoice/index.stories.ts

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const createStory = subplatStoryWithProps(
1616
productName: 'Firefox Fortress',
1717
invoiceDateOnly: '12/14/2021',
1818
invoiceNumber: '8675309',
19+
invoiceTotalInCents: 2000,
1920
invoiceTotal: '$20.00',
2021
invoiceSubtotal: null,
2122
invoiceTaxAmount: null,

packages/fxa-auth-server/lib/senders/emails/templates/subscriptionUpgrade/en.ftl

+34-7
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,40 @@ subscriptionUpgrade-title = Thank you for upgrading!
88
# $productName (String) - The name of the new subscribed product, e.g. Mozilla VPN
99
subscriptionUpgrade-upgrade-info-2 = You have successfully upgraded to { $productName }.
1010
11-
# Variables:
12-
# $paymentAmountOld (String) - The amount of the previous subscription payment, including currency, e.g. $10.00
13-
# $paymentAmountNew (String) - The amount of the new subscription payment, including currency, e.g. $10.00
14-
# $productPaymentCycleNew (String) - The interval of time from the end of one payment statement date to the next payment statement date of the new subscription, e.g. month
15-
# $productPaymentCycleOld (String) - The interval of time from the end of one payment statement date to the next payment statement date of the old subscription, e.g. month
16-
# $paymentProrated (String) - The one time fee to reflect the higher charge for the remainder of the payment cycle, including currency, e.g. $10.00
17-
subscriptionUpgrade-content-charge-info-different-cycle-2 = You have been charged a one-time fee of { $paymentProrated } to reflect your subscription’s higher price for the remainder of this { $productPaymentCycleOld }. Starting with your next bill, your charge will change from { $paymentAmountOld } per { $productPaymentCycleOld } to { $paymentAmountNew } per { $productPaymentCycleNew }.
11+
## Variables:
12+
## $paymentAmountOld (String) - The amount of the previous subscription payment, including currency, e.g. $10.00
13+
## $paymentAmountNew (String) - The amount of the new subscription payment, including currency, e.g. $10.00
14+
## $productPaymentCycleNew (String) - The interval of time from the end of one payment statement date to the next payment statement date of the new subscription, e.g. month
15+
## $productPaymentCycleOld (String) - The interval of time from the end of one payment statement date to the next payment statement date of the old subscription, e.g. month
16+
## $paymentProrated (String) - The one time fee to reflect the higher charge for the remainder of the payment cycle, including currency, e.g. $10.00
17+
## $productPaymentCycleOldPronoun (String) - The pronoun of the old subscription payment cycle, e.g. this
18+
subscriptionUpgrade-content-charge-prorated =
19+
You have been charged a one-time fee of { $paymentProrated } to reflect your subscription’s higher price for the remainder of { $productPaymentCycleOldPronoun ->
20+
[masculine] this
21+
[feminine] this
22+
*[other] this
23+
} { $productPaymentCycleOld ->
24+
[day] day
25+
[month] month
26+
[6-month] 6-month
27+
[year] year
28+
*[other] billing period
29+
}.
30+
subscriptionUpgrade-content-charge-credit = You have received an account credit in the amount of { $paymentProrated }.
31+
subscriptionUpgrade-content-starting =
32+
Starting with your next bill, your charge will change from { $paymentAmountOld } per { $productPaymentCycleOld ->
33+
[day] day
34+
[month] month
35+
[6-month] 6-month
36+
[year] year
37+
*[other] billing period
38+
} to { $paymentAmountNew } per { $productPaymentCycleNew ->
39+
[day] day
40+
[month] month
41+
[6-month] 6-month
42+
[year] year
43+
*[other] billing period
44+
}.
1845
1946
# Variables:
2047
# $productName (String) - The name of the new subscribed product, e.g. Mozilla VPN

packages/fxa-auth-server/lib/senders/emails/templates/subscriptionUpgrade/index.mjml

+6-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@
1515
</mj-text>
1616

1717
<mj-text css-class="text-body">
18-
<span data-l10n-id="subscriptionUpgrade-content-charge-info-different-cycle-2" data-l10n-args="<%= JSON.stringify({paymentAmountNew, paymentAmountOld, paymentProrated, productPaymentCycleNew, productPaymentCycleOld}) %>">You have been charged a one-time fee of <%- paymentProrated %> to reflect your subscription’s higher price for the remainder of this <%- productPaymentCycleOld %>. Starting with your next bill, your charge will change from <%- paymentAmountOld %> per <%- productPaymentCycleOld %> to <%- paymentAmountNew %> per <%- productPaymentCycleNew %>.</span>
18+
<% if (locals.paymentProratedInCents < 0) { %>
19+
<span data-l10n-id="subscriptionUpgrade-content-charge-credit" data-l10n-args="<%= JSON.stringify({paymentProrated}) %>">You have received an account credit in the amount of <%- paymentProrated %>.</span>
20+
<% } else if (locals.paymentProratedInCents > 0) { %>
21+
<span data-l10n-id="subscriptionUpgrade-content-charge-prorated" data-l10n-args="<%= JSON.stringify({paymentProrated, productPaymentCycleOld, productPaymentCycleOldPronoun}) %>">You have been charged a one-time fee of <%- paymentProrated %> to reflect your subscription’s higher price for the remainder of <%- productPaymentCycleOldPronoun %> <%- productPaymentCycleOld %>.</span>
22+
<% } %>
23+
<span data-l10n-id="subscriptionUpgrade-content-starting" data-l10n-args="<%= JSON.stringify({paymentAmountNew, paymentAmountOld, productPaymentCycleNew, productPaymentCycleOld}) %>">Starting with your next bill, your charge will change from <%- paymentAmountOld %> per <%- productPaymentCycleOld %> to <%- paymentAmountNew %> per <%- productPaymentCycleNew %>.</span>
1924
</mj-text>
2025

2126
<mj-text css-class="text-body">

packages/fxa-auth-server/lib/senders/emails/templates/subscriptionUpgrade/index.stories.ts

+24-1
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,32 @@ const createStory = subplatStoryWithProps(
2121
productNameOld: 'Product Name A',
2222
productPaymentCycleNew: 'year',
2323
productPaymentCycleOld: 'month',
24+
productPaymentCycleOldPronoun: 'this',
2425
paymentProrated: '$60.00',
2526
subscriptionSupportUrl: 'http://localhost:3030/support',
2627
}
2728
);
2829

29-
export const Default = createStory();
30+
export const PositiveProrated = createStory(
31+
{
32+
paymentProrated: '$60.00',
33+
paymentProratedInCents: 6000,
34+
},
35+
'Charge - Prorated amount is positive'
36+
);
37+
38+
export const NegativeProrated = createStory(
39+
{
40+
paymentProrated: '$60.00',
41+
paymentProratedInCents: -6000,
42+
},
43+
'Credit - Prorated amount is negative'
44+
);
45+
46+
export const NoProrated = createStory(
47+
{
48+
paymentProrated: '$0.00',
49+
paymentProratedInCents: 0,
50+
},
51+
'Prorated amount is zero'
52+
);

packages/fxa-auth-server/lib/senders/emails/templates/subscriptionUpgrade/index.txt

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@ subscriptionUpgrade-title = "Thank you for upgrading!"
44

55
subscriptionUpgrade-upgrade-info-2 = "You have successfully upgraded to <%- productName %>."
66

7-
subscriptionUpgrade-content-charge-info-different-cycle-2 = "You have been charged a one-time fee of <%- paymentProrated %> to reflect your subscription’s higher price for the remainder of this <%- productPaymentCycleOld %>. Starting with your next bill, your charge will change from <%- paymentAmountOld %> per <%- productPaymentCycleOld %> to <%- paymentAmountNew %> per <%- productPaymentCycleNew %>."
7+
<% if (locals.paymentProratedInCents < 0) { %>
8+
subscriptionUpgrade-content-charge-credit = "You have received an account credit in the amount of <%- paymentProrated %>."
9+
<% } else if (locals.paymentProratedInCents > 0) { %>
10+
subscriptionUpgrade-content-charge-prorated = "You have been charged a one-time fee of <%- paymentProrated %> to reflect your subscription’s higher price for the remainder of <%- productPaymentCycleOldPronoun %> <%- productPaymentCycleOld %>."
11+
<% } %>
12+
13+
subscriptionUpgrade-content-starting = "Starting with your next bill, your charge will change from <%- paymentAmountOld %> per <%- productPaymentCycleOld %> to <%- paymentAmountNew %> per <%- productPaymentCycleNew %>."
14+
815

916
subscriptionUpgrade-existing = "If any of your existing subscriptions overlap with this upgrade, we’ll handle them and send you a separate email with the details. If your new plan includes products that require installation, we’ll send you a separate email with setup instructions."
1017

packages/fxa-auth-server/test/local/payments/stripe.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6333,7 +6333,7 @@ describe('#integration - StripeHelper', () => {
63336333
paymentAmountNewCurrency: upcomingInvoice.currency,
63346334
paymentAmountNewInCents: upcomingInvoice.total,
63356335
paymentProratedCurrency: mockInvoice.currency,
6336-
paymentProratedInCents: mockInvoice.amount_due,
6336+
paymentProratedInCents: mockInvoice.total,
63376337
invoiceNumber: mockInvoice.number,
63386338
invoiceId: mockInvoice.id,
63396339
});

0 commit comments

Comments
 (0)