Skip to content

Commit

Permalink
feat/issue-2898: Modify transactional emails
Browse files Browse the repository at this point in the history
  • Loading branch information
lesleyjanenorton committed Feb 27, 2021
1 parent f144d5f commit b6d8612
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 88 deletions.
18 changes: 13 additions & 5 deletions packages/fxa-auth-server/lib/payments/stripe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,18 @@ export class StripeHelper {
return await this.stripe.paymentMethods.retrieve(paymentMethodId);
}

getPaymentProvider(customer: Stripe.Customer) {
const subscription = customer.subscriptions?.data.find(
(sub: { status: string }) => ['active', 'past_due'].includes(sub.status)
);
if (subscription) {
return subscription.collection_method === 'send_invoice'
? 'paypal'
: 'stripe';
}
return 'not_chosen';
}

async detachPaymentMethod(
paymentMethodId: string
): Promise<Stripe.PaymentMethod> {
Expand Down Expand Up @@ -1307,7 +1319,6 @@ export class StripeHelper {
created: invoiceDate,
currency: invoiceTotalCurrency,
total: invoiceTotalInCents,
collection_method,
lines: {
data: [
{
Expand All @@ -1327,10 +1338,7 @@ export class StripeHelper {
charge,
});

/* needs de-dupe */
const payment_provider =
collection_method === 'send_invoice' ? 'paypal' : 'stripe';
/* */
const payment_provider = this.getPaymentProvider(customer);

return {
uid,
Expand Down
19 changes: 5 additions & 14 deletions packages/fxa-auth-server/lib/routes/subscriptions/stripe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,22 +299,13 @@ export class StripeHandler {
return activeSubscriptions;
}

getPaymentProvider(customer: Stripe.Customer) {
const subscription = customer.subscriptions?.data.find(
(sub: { status: string }) => ['active', 'past_due'].includes(sub.status)
);
if (subscription) {
return subscription.collection_method === 'send_invoice'
? 'paypal'
: 'stripe';
}
return 'not_chosen';
}
/**
* Extracts billing details if a customer has a source on file.
*/
extractBillingDetails(customer: Stripe.Customer) {
const defaultPayment = customer.invoice_settings.default_payment_method;
const paymentProvider = this.stripeHelper.getPaymentProvider(customer);

if (defaultPayment) {
if (typeof defaultPayment === 'string') {
// This should always be expanded here.
Expand All @@ -324,7 +315,7 @@ export class StripeHandler {
if (defaultPayment.card) {
return {
billing_name: defaultPayment.billing_details.name,
payment_provider: this.getPaymentProvider(customer),
payment_provider: paymentProvider,
payment_type: defaultPayment.card.funding,
last4: defaultPayment.card.last4,
exp_month: defaultPayment.card.exp_month,
Expand All @@ -340,7 +331,7 @@ export class StripeHandler {
if (src.object === 'card') {
return {
billing_name: src.name,
payment_provider: this.getPaymentProvider(customer),
payment_provider: paymentProvider,
payment_type: src.funding,
last4: src.last4,
exp_month: src.exp_month,
Expand All @@ -351,7 +342,7 @@ export class StripeHandler {
}

return {
payment_provider: this.getPaymentProvider(customer),
payment_provider: paymentProvider,
};
}

Expand Down
44 changes: 44 additions & 0 deletions packages/fxa-auth-server/test/local/payments/stripe.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,50 @@ describe('StripeHelper', () => {
});
});

describe('getPaymentProvider', () => {
let customerExpanded;
beforeEach(() => {
customerExpanded = deepCopy(customer1);
});
describe('returns correct value based on collection_method', () => {
describe('when collection_method is "send_invoice"', () => {
it('payment_provider is "paypal"', async () => {
subscription2.collection_method = 'send_invoice';
customerExpanded.subscriptions.data[0] = subscription2;
assert(
stripeHelper.getPaymentProvider(customerExpanded) === 'paypal'
);
});
});
describe('when the customer has a canceled subscription', () => {
it('payment_provider is "not_chosen"', async () => {
customerExpanded.subscriptions.data[0] = cancelledSubscription;
assert(
stripeHelper.getPaymentProvider(customerExpanded) === 'not_chosen'
);
});
});
describe('when the customer has no subscriptions', () => {
it('payment_provider is "not_chosen"', async () => {
customerExpanded.subscriptions.data = [];
assert(
stripeHelper.getPaymentProvider(customerExpanded) === 'not_chosen'
);
});
});
describe('when collection_method is "instant"', () => {
it('payment_provider is "stripe"', async () => {
subscription2.collection_method = 'instant';
customerExpanded.subscriptions.data[0] = subscription2;
assert.equal(
stripeHelper.getPaymentProvider(customerExpanded),
'stripe'
);
});
});
});
});

describe('detachPaymentMethod', () => {
it('calls the Stripe api', async () => {
const paymentMethodId = 'pm_9001';
Expand Down
107 changes: 38 additions & 69 deletions packages/fxa-auth-server/test/local/routes/subscriptions/stripe.js
Original file line number Diff line number Diff line change
Expand Up @@ -1343,12 +1343,41 @@ describe('DirectStripeRoutes', () => {
);
});

describe('customer has payment_provider property', () => {
it('calls getPaymentProvider once to determine payment_provider', async () => {
directStripeRoutesInstance.stripeHelper.fetchCustomer.resolves(
customer
);
await directStripeRoutesInstance.getCustomer(VALID_REQUEST);
sinon.assert.calledOnceWithExactly(
directStripeRoutesInstance.stripeHelper.getPaymentProvider,
customer
);
});
it('payment_provider === value returned by getPaymentProvider', async () => {
directStripeRoutesInstance.stripeHelper.fetchCustomer.resolves(
customer
);
directStripeRoutesInstance.stripeHelper.getPaymentProvider.returns(
'not_chosen'
);

const actual = await directStripeRoutesInstance.getCustomer(
VALID_REQUEST
);
assert(actual.payment_provider === 'not_chosen');
});
});

describe('customer has payment sources', () => {
describe('default invoice payment method is a card object', () => {
it('adds payment method data to the response', async () => {
directStripeRoutesInstance.stripeHelper.fetchCustomer.resolves(
customerPMIExpanded
);
directStripeRoutesInstance.stripeHelper.getPaymentProvider.returns(
'not_chosen'
);

const defaultInvoice =
customerPMIExpanded.invoice_settings.default_payment_method;
Expand Down Expand Up @@ -1398,6 +1427,9 @@ describe('DirectStripeRoutes', () => {
directStripeRoutesInstance.stripeHelper.fetchCustomer.resolves(
customer
);
directStripeRoutesInstance.stripeHelper.getPaymentProvider.returns(
'not_chosen'
);

const expected = {
subscriptions: [],
Expand All @@ -1423,6 +1455,9 @@ describe('DirectStripeRoutes', () => {
directStripeRoutesInstance.stripeHelper.fetchCustomer.resolves(
customer
);
directStripeRoutesInstance.stripeHelper.getPaymentProvider.returns(
'not_chosen'
);

const expected = {
subscriptions: [],
Expand All @@ -1443,6 +1478,9 @@ describe('DirectStripeRoutes', () => {
directStripeRoutesInstance.stripeHelper.fetchCustomer.resolves(
customer
);
directStripeRoutesInstance.stripeHelper.getPaymentProvider.returns(
'not_chosen'
);

const expected = {
subscriptions: [],
Expand Down Expand Up @@ -1475,75 +1513,6 @@ describe('DirectStripeRoutes', () => {
}
});
});
describe('has payment_provider property', () => {
describe('payment_provider property has correct value', () => {
let customerExpanded;
beforeEach(() => {
customerExpanded = deepCopy(customerPMIExpanded);
});
describe('when collection_method is "instant"', () => {
it('payment_provider is "stripe"', async () => {
directStripeRoutesInstance.stripeHelper.subscriptionsToResponse.resolves(
[subscription2]
);
customerExpanded.subscriptions.data[0] = subscription2;
directStripeRoutesInstance.stripeHelper.fetchCustomer.resolves(
customerExpanded
);
const customerActual = await directStripeRoutesInstance.getCustomer(
VALID_REQUEST
);
assert(customerActual.payment_provider === 'stripe');
});
});
describe('when collection_method is "send_invoice"', () => {
it('payment_provider is "paypal"', async () => {
subscription2.collection_method = 'send_invoice';
directStripeRoutesInstance.stripeHelper.subscriptionsToResponse.resolves(
[subscription2]
);
customerExpanded.subscriptions.data[0] = subscription2;
directStripeRoutesInstance.stripeHelper.fetchCustomer.resolves(
customerExpanded
);
const actual = await directStripeRoutesInstance.getCustomer(
VALID_REQUEST
);
assert(actual.payment_provider === 'paypal');
});
});
describe('when the customer has a canceled subscription', () => {
it('payment_provider is "not_chosen"', async () => {
directStripeRoutesInstance.stripeHelper.subscriptionsToResponse.resolves(
[cancelledSubscription]
);
customerExpanded.subscriptions.data[0] = cancelledSubscription;
directStripeRoutesInstance.stripeHelper.fetchCustomer.resolves(
customerExpanded
);
const actual = await directStripeRoutesInstance.getCustomer(
VALID_REQUEST
);
assert(actual.payment_provider === 'not_chosen');
});
});
describe('when the customer has no subscriptions', () => {
it('payment_provider is "not_chosen"', async () => {
directStripeRoutesInstance.stripeHelper.subscriptionsToResponse.resolves(
[]
);
customerExpanded.subscriptions.data = [];
directStripeRoutesInstance.stripeHelper.fetchCustomer.resolves(
customerExpanded
);
const actual = await directStripeRoutesInstance.getCustomer(
VALID_REQUEST
);
assert(actual.payment_provider === 'not_chosen');
});
});
});
});
});

describe('sendSubscriptionStatusToSqs', () => {
Expand Down

0 comments on commit b6d8612

Please sign in to comment.