зеркало из https://github.com/mozilla/fxa.git
feat(stripe): polish pr to update `prePaySteps` and `createPlainCustomer`
Because: * We want to clean up our code and make sure our methods are created and updated appropriately. This commit: * Is a follow up to https://github.com/mozilla/fxa/pull/16924 comments and Slack messages between the SubPlat SWEs. * Updates `StripeManager.createPlainCustomer`. * Updates `CheckoutService.prePaySteps` to add `AccountCustomerManager.createAccountCustomer`. * Updates all applicable tests.
This commit is contained in:
Родитель
257a254305
Коммит
2a0fb52594
|
@ -20,6 +20,8 @@ import {
|
|||
StripeSubscriptionFactory,
|
||||
TaxAddressFactory,
|
||||
InvoicePreviewFactory,
|
||||
AccountCustomerManager,
|
||||
ResultAccountCustomerFactory,
|
||||
} from '@fxa/payments/stripe';
|
||||
import {
|
||||
PayPalClient,
|
||||
|
@ -68,6 +70,7 @@ describe('CheckoutService', () => {
|
|||
let eligibilityService: EligibilityService;
|
||||
let contentfulService: ContentfulService;
|
||||
let accountManager: AccountManager;
|
||||
let accountCustomerManager: AccountCustomerManager;
|
||||
|
||||
beforeEach(async () => {
|
||||
const moduleRef = await Test.createTestingModule({
|
||||
|
@ -81,6 +84,7 @@ describe('CheckoutService', () => {
|
|||
StripeConfig,
|
||||
PaypalClientConfig,
|
||||
AccountManager,
|
||||
AccountCustomerManager,
|
||||
MockAccountDatabaseNestFactory,
|
||||
CartManager,
|
||||
ContentfulManager,
|
||||
|
@ -104,6 +108,7 @@ describe('CheckoutService', () => {
|
|||
stripeManager = moduleRef.get(StripeManager);
|
||||
contentfulService = moduleRef.get(ContentfulService);
|
||||
accountManager = moduleRef.get(AccountManager);
|
||||
accountCustomerManager = moduleRef.get(AccountCustomerManager);
|
||||
checkoutService = moduleRef.get(CheckoutService);
|
||||
});
|
||||
|
||||
|
@ -140,6 +145,13 @@ describe('CheckoutService', () => {
|
|||
})
|
||||
);
|
||||
|
||||
const mockAccountCustomer = StripeResponseFactory(
|
||||
ResultAccountCustomerFactory({
|
||||
uid: uid,
|
||||
stripeCustomerId: mockCart.stripeCustomerId,
|
||||
})
|
||||
);
|
||||
|
||||
const mockPrice = StripePriceFactory();
|
||||
|
||||
const mockPromotionCode = StripeResponseFactory(
|
||||
|
@ -151,10 +163,13 @@ describe('CheckoutService', () => {
|
|||
jest
|
||||
.spyOn(stripeManager, 'createPlainCustomer')
|
||||
.mockResolvedValue(mockCustomer);
|
||||
jest.spyOn(cartManager, 'updateFreshCart').mockResolvedValue();
|
||||
jest
|
||||
.spyOn(stripeManager, 'fetchActiveCustomer')
|
||||
.mockResolvedValue(mockCustomer);
|
||||
jest
|
||||
.spyOn(accountCustomerManager, 'createAccountCustomer')
|
||||
.mockResolvedValue(mockAccountCustomer);
|
||||
jest.spyOn(cartManager, 'updateFreshCart').mockResolvedValue();
|
||||
jest
|
||||
.spyOn(eligibilityService, 'checkEligibility')
|
||||
.mockResolvedValue(EligibilityStatus.CREATE);
|
||||
|
@ -248,6 +263,16 @@ describe('CheckoutService', () => {
|
|||
stripeCustomerId: mockCart.stripeCustomerId,
|
||||
});
|
||||
});
|
||||
|
||||
it('creates an account customer', () => {
|
||||
expect(
|
||||
accountCustomerManager.createAccountCustomer
|
||||
).toHaveBeenCalledWith({
|
||||
uid: uid,
|
||||
stripeCustomerId: mockCart.stripeCustomerId,
|
||||
updatedAt: Date.now(),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('success - with new stripe customer stub account', () => {
|
||||
|
@ -267,6 +292,7 @@ describe('CheckoutService', () => {
|
|||
|
||||
it('creates a new stripe customer stub account', () => {
|
||||
expect(stripeManager.createPlainCustomer).toHaveBeenCalledWith({
|
||||
uid: uid,
|
||||
email: mockCart.email,
|
||||
taxAddress: mockCart.taxAddress,
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ import { Injectable } from '@nestjs/common';
|
|||
import { EligibilityService } from '@fxa/payments/eligibility';
|
||||
import { PayPalManager, PaypalCustomerManager } from '@fxa/payments/paypal';
|
||||
import {
|
||||
AccountCustomerManager,
|
||||
StripeClient,
|
||||
StripeManager,
|
||||
StripeSubscription,
|
||||
|
@ -34,7 +35,8 @@ export class CheckoutService {
|
|||
private cartManager: CartManager,
|
||||
private eligibilityService: EligibilityService,
|
||||
private contentfulService: ContentfulService,
|
||||
private accountManager: AccountManager
|
||||
private accountManager: AccountManager,
|
||||
private accountCustomerManager: AccountCustomerManager
|
||||
) {}
|
||||
|
||||
async prePaySteps(cart: ResultCart, locale: string) {
|
||||
|
@ -45,20 +47,6 @@ export class CheckoutService {
|
|||
throw new CartEmailNotFoundError(cart.id);
|
||||
}
|
||||
|
||||
// if stripeCustomerId not found, create stub stripe account
|
||||
if (!cart.stripeCustomerId) {
|
||||
customer = await this.stripeManager.createPlainCustomer({
|
||||
email: cart.email,
|
||||
taxAddress: taxAddress,
|
||||
});
|
||||
|
||||
stripeCustomerId = customer.id;
|
||||
} else {
|
||||
stripeCustomerId = cart.stripeCustomerId;
|
||||
|
||||
customer = await this.stripeManager.fetchActiveCustomer(stripeCustomerId);
|
||||
}
|
||||
|
||||
// if uid not found, create stub account customer
|
||||
// TODO: update hardcoded verifierVersion
|
||||
// https://mozilla-hub.atlassian.net/browse/FXA-9693
|
||||
|
@ -72,6 +60,29 @@ export class CheckoutService {
|
|||
uid = cart.uid;
|
||||
}
|
||||
|
||||
// if stripeCustomerId not found, create plain stripe account
|
||||
if (!cart.stripeCustomerId) {
|
||||
customer = await this.stripeManager.createPlainCustomer({
|
||||
uid: uid,
|
||||
email: cart.email,
|
||||
taxAddress: taxAddress,
|
||||
});
|
||||
|
||||
stripeCustomerId = customer.id;
|
||||
} else {
|
||||
stripeCustomerId = cart.stripeCustomerId;
|
||||
customer = await this.stripeManager.fetchActiveCustomer(stripeCustomerId);
|
||||
}
|
||||
|
||||
// create accountCustomer if it does not exist
|
||||
if (!cart.uid) {
|
||||
await this.accountCustomerManager.createAccountCustomer({
|
||||
uid: uid,
|
||||
stripeCustomerId: stripeCustomerId,
|
||||
updatedAt: Date.now(),
|
||||
});
|
||||
}
|
||||
|
||||
// update cart
|
||||
// TODO: update code so it's conditional only when cart data needs to be updated
|
||||
// NOTE: originally done as two separate calls dependent on if
|
||||
|
|
|
@ -96,22 +96,11 @@ describe('StripeManager', () => {
|
|||
});
|
||||
|
||||
describe('createPlainCustomer', () => {
|
||||
it('create a stub customer from Stripe', async () => {
|
||||
const mockCustomer = StripeResponseFactory(StripeCustomerFactory());
|
||||
|
||||
jest
|
||||
.spyOn(stripeClient, 'customersCreate')
|
||||
.mockResolvedValue(mockCustomer);
|
||||
|
||||
const result = await stripeManager.createPlainCustomer({});
|
||||
|
||||
expect(result).toEqual(mockCustomer);
|
||||
});
|
||||
|
||||
it('create a stub customer with args from Stripe', async () => {
|
||||
it('creates a plain customer from Stripe', async () => {
|
||||
const taxAddress = TaxAddressFactory();
|
||||
const mockCustomer = StripeResponseFactory(
|
||||
StripeCustomerFactory({
|
||||
name: faker.person.fullName(),
|
||||
shipping: {
|
||||
name: '',
|
||||
address: {
|
||||
|
@ -131,7 +120,9 @@ describe('StripeManager', () => {
|
|||
.mockResolvedValue(mockCustomer);
|
||||
|
||||
const result = await stripeManager.createPlainCustomer({
|
||||
uid: faker.string.uuid(),
|
||||
email: faker.internet.email(),
|
||||
displayName: faker.person.fullName(),
|
||||
taxAddress: taxAddress,
|
||||
});
|
||||
|
||||
|
|
|
@ -76,20 +76,36 @@ export class StripeManager {
|
|||
/**
|
||||
* Create customer stub account
|
||||
*/
|
||||
async createPlainCustomer(args: { email?: string; taxAddress?: TaxAddress }) {
|
||||
if (args.taxAddress) {
|
||||
return this.client.customersCreate({
|
||||
shipping: {
|
||||
name: args.email || '',
|
||||
address: {
|
||||
country: args.taxAddress.countryCode,
|
||||
postal_code: args.taxAddress.postalCode,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
async createPlainCustomer(args: {
|
||||
uid: string;
|
||||
email: string;
|
||||
displayName?: string;
|
||||
taxAddress?: TaxAddress;
|
||||
}) {
|
||||
const { uid, email, displayName, taxAddress } = args;
|
||||
|
||||
return this.client.customersCreate();
|
||||
const shipping = taxAddress
|
||||
? {
|
||||
name: email,
|
||||
address: {
|
||||
country: taxAddress.countryCode,
|
||||
postal_code: taxAddress.postalCode,
|
||||
},
|
||||
}
|
||||
: undefined;
|
||||
|
||||
const stripeCustomer = await this.client.customersCreate({
|
||||
email,
|
||||
name: displayName || '',
|
||||
description: uid,
|
||||
metadata: {
|
||||
userid: uid,
|
||||
geoip_date: new Date().toString(),
|
||||
},
|
||||
shipping,
|
||||
});
|
||||
|
||||
return stripeCustomer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче