Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 58 additions & 3 deletions apps/payments/api/.env
Original file line number Diff line number Diff line change
@@ -1,3 +1,58 @@
TEST_OVERRIDE="default override value"
TEST_DEFAULT="default value"
TEST_NESTED_CONFIG__TEST_NESTED="nested value"
# MySQLConfig
MYSQL_CONFIG__DATABASE=fxa
MYSQL_CONFIG__HOST=::1
MYSQL_CONFIG__PORT=3306
MYSQL_CONFIG__USER=root
MYSQL_CONFIG__PASSWORD=
MYSQL_CONFIG__CONNECTION_LIMIT_MIN=
MYSQL_CONFIG__CONNECTION_LIMIT_MAX=20
MYSQL_CONFIG__ACQUIRE_TIMEOUT_MILLIS=

# Stripe Config
STRIPE_CONFIG__API_KEY=11233
STRIPE_CONFIG__WEBHOOK_SECRET=11233
STRIPE_CONFIG__TAX_IDS={}

# PayPal Config
PAYPAL_CLIENT_CONFIG__SANDBOX=true
PAYPAL_CLIENT_CONFIG__USER=ASDF
PAYPAL_CLIENT_CONFIG__PWD=ASDF
PAYPAL_CLIENT_CONFIG__SIGNATURE=ASDF
PAYPAL_CLIENT_CONFIG__RETRY_OPTIONS__RETRIES=1
PAYPAL_CLIENT_CONFIG__RETRY_OPTIONS__MIN_TIMEOUT=1
PAYPAL_CLIENT_CONFIG__RETRY_OPTIONS__FACTOR=1

# Strapi Config
STRAPI_CLIENT_CONFIG__GRAPHQL_API_URI=https://example.com
STRAPI_CLIENT_CONFIG__API_KEY=PLACEHOLDER
STRAPI_CLIENT_CONFIG__MEM_CACHE_T_T_L=
STRAPI_CLIENT_CONFIG__FIRESTORE_CACHE_COLLECTION_NAME=strapiClientQueryCacheCollection
STRAPI_CLIENT_CONFIG__FIRESTORE_CACHE_T_T_L=
STRAPI_CLIENT_CONFIG__FIRESTORE_OFFLINE_CACHE_T_T_L=

# Firestore Config
FIRESTORE_CONFIG__CREDENTIALS__CLIENT_EMAIL=
FIRESTORE_CONFIG__CREDENTIALS__PRIVATE_KEY=
FIRESTORE_CONFIG__KEY_FILENAME=
FIRESTORE_CONFIG__PROJECT_ID=

# Currency Config
CURRENCY_CONFIG__TAX_IDS={ "EUR": "EU1234", "CHF": "CH1234" }
CURRENCY_CONFIG__CURRENCIES_TO_COUNTRIES={ "USD": ["US", "GB", "NZ", "MY", "SG", "CA", "AS", "GU", "MP", "PR", "VI"], "EUR": ["FR", "DE"] }

# StatsD Config
STATS_D_CONFIG__SAMPLE_RATE=
STATS_D_CONFIG__MAX_BUFFER_SIZE=
STATS_D_CONFIG__HOST=
STATS_D_CONFIG__PORT=
STATS_D_CONFIG__PREFIX=

# Stripe Events Config
STRIPE_EVENTS_CONFIG__FIRESTORE_STRIPE_EVENT_STORE_COLLECTION_NAME=stripeEvents

# Glean Config
GLEAN_CONFIG__ENABLED=false
GLEAN_CONFIG__APPLICATION_ID=
GLEAN_CONFIG__VERSION=0.0.0
GLEAN_CONFIG__CHANNEL='development'
GLEAN_CONFIG__LOGGER_APP_NAME='fxa-payments-next'
67 changes: 64 additions & 3 deletions apps/payments/api/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,41 @@
import { Module } from '@nestjs/common';
import { Logger, Module } from '@nestjs/common';
import { TypedConfigModule, dotenvLoader } from 'nest-typed-config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { RootConfig } from '../config';
import {
StripeEventManager,
StripeWebhooksController,
StripeWebhookService,
SubscriptionEventsService,
} from '@fxa/payments/webhooks';
import { FirestoreProvider } from '@fxa/shared/db/firestore';
import { StripeClient } from '@fxa/payments/stripe';
import { StatsDProvider } from '@fxa/shared/metrics/statsd';
import {
CustomerManager,
InvoiceManager,
PaymentMethodManager,
PriceManager,
SubscriptionManager,
} from '@fxa/payments/customer';
import {
PaypalBillingAgreementManager,
PayPalClient,
PaypalClientConfig,
PaypalCustomerManager,
} from '@fxa/payments/paypal';
import { CurrencyManager } from '@fxa/payments/currency';
import { AccountDatabaseNestFactory } from '@fxa/shared/db/mysql/account';
import { AccountManager } from '@fxa/shared/account/account';
import { CartManager } from '@fxa/payments/cart';
import { ProductConfigurationManager, StrapiClient } from '@fxa/shared/cms';
import {
MockPaymentsGleanFactory,
PaymentsGleanManager,
} from '@fxa/payments/metrics';
import { PaymentsGleanFactory } from '@fxa/payments/metrics/provider';
import { PaymentsEmitterService } from '@fxa/payments/events';

@Module({
imports: [
Expand All @@ -18,7 +51,35 @@ import { RootConfig } from '../config';
}),
}),
],
controllers: [AppController],
providers: [AppService],
controllers: [AppController, StripeWebhooksController],
providers: [
Logger,
AccountDatabaseNestFactory,
AccountManager,
AppService,
ProductConfigurationManager,
CartManager,
SubscriptionEventsService,
PaymentsGleanFactory,
PaymentsGleanManager,
PaymentsEmitterService,
PriceManager,
FirestoreProvider,
StatsDProvider,
StripeClient,
PayPalClient,
PaypalClientConfig,
SubscriptionManager,
CustomerManager,
InvoiceManager,
PaymentMethodManager,
CurrencyManager,
StripeWebhookService,
StripeEventManager,
PaypalBillingAgreementManager,
PaypalCustomerManager,
StrapiClient,
MockPaymentsGleanFactory,
],
})
export class AppModule {}
10 changes: 2 additions & 8 deletions apps/payments/api/src/app/app.service.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
import { Injectable } from '@nestjs/common';
import { RootConfig, TestNestedConfig } from '../config';
import { RootConfig } from '../config';

@Injectable()
export class AppService {
constructor(
private config: RootConfig,
private nestedConfig: TestNestedConfig
) {}
constructor(private config: RootConfig) {}

getData(): {
message: string;
config: RootConfig;
nestedConfigOnly: TestNestedConfig;
} {
console.log('All config', this.config);
console.log('Nested only', this.nestedConfig);
return {
message: 'Hello API',
config: this.config,
nestedConfigOnly: this.nestedConfig,
};
}
}
62 changes: 51 additions & 11 deletions apps/payments/api/src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,59 @@
import { Type } from 'class-transformer';
import { IsString, ValidateNested } from 'class-validator';
import { IsDefined, ValidateNested } from 'class-validator';

export class TestNestedConfig {
@IsString()
public readonly testNested!: string;
}
import { CurrencyConfig } from '@fxa/payments/currency';
import { PaymentsGleanConfig } from '@fxa/payments/metrics';
import { PaypalClientConfig } from '@fxa/payments/paypal';
import { StripeConfig } from '@fxa/payments/stripe';
import { StrapiClientConfig } from '@fxa/shared/cms';
import { MySQLConfig } from '@fxa/shared/db/mysql/core';
import { StripeEventConfig } from '@fxa/payments/webhooks';
import { StatsDConfig } from '@fxa/shared/metrics/statsd';
import { FirestoreConfig } from 'libs/shared/db/firestore/src/lib/firestore.config';

export class RootConfig {
@IsString()
public readonly testOverride!: string;
@Type(() => MySQLConfig)
@ValidateNested()
@IsDefined()
public readonly mysqlConfig!: Partial<MySQLConfig>;

@Type(() => PaymentsGleanConfig)
@ValidateNested()
@IsDefined()
public readonly gleanConfig!: Partial<PaymentsGleanConfig>;

@Type(() => StripeConfig)
@ValidateNested()
@IsDefined()
public readonly stripeConfig!: Partial<StripeConfig>;

@Type(() => PaypalClientConfig)
@ValidateNested()
@IsDefined()
public readonly paypalClientConfig!: Partial<PaypalClientConfig>;

@IsString()
public readonly testDefault!: string;
@Type(() => CurrencyConfig)
@ValidateNested()
@IsDefined()
public readonly currencyConfig!: Partial<CurrencyConfig>;

@Type(() => FirestoreConfig)
@ValidateNested()
@IsDefined()
public readonly firestoreConfig!: Partial<FirestoreConfig>;

@Type(() => StatsDConfig)
@ValidateNested()
@IsDefined()
public readonly statsDConfig!: Partial<StatsDConfig>;

@Type(() => StrapiClientConfig)
@ValidateNested()
@IsDefined()
public readonly strapiClientConfig!: Partial<StrapiClientConfig>;

@Type(() => TestNestedConfig)
@Type(() => StripeEventConfig)
@ValidateNested()
public readonly testNestedConfig!: TestNestedConfig;
@IsDefined()
public readonly stripeEventsConfig!: Partial<StripeEventConfig>;
}
4 changes: 3 additions & 1 deletion apps/payments/api/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { NestFactory } from '@nestjs/core';
import { AppModule } from './app/app.module';

async function bootstrap() {
const app = await NestFactory.create(AppModule);
const app = await NestFactory.create(AppModule, {
rawBody: true,
});
const globalPrefix = 'api';
app.setGlobalPrefix(globalPrefix);
const port = process.env.PORT || 3000;
Expand Down
3 changes: 3 additions & 0 deletions apps/payments/next/.env
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ CONTENT_SERVER_CLIENT_CONFIG__URL=http://localhost:3030
# GoogleClient Config
GOOGLE_CLIENT_CONFIG__GOOGLE_MAPS_API_KEY=

# Stripe Events Config
STRIPE_EVENTS_CONFIG__FIRESTORE_STRIPE_EVENT_STORE_COLLECTION_NAME=stripeEvents

# Feature flags
FEATURE_FLAG_SUB_MANAGE=true

Expand Down
2 changes: 2 additions & 0 deletions libs/payments/metrics/src/lib/glean/glean.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { faker } from '@faker-js/faker';
import { Provider } from '@nestjs/common';
import { Type } from 'class-transformer';
import { IsBoolean, IsEnum, IsString } from 'class-validator';

enum GleanChannel {
Expand All @@ -12,6 +13,7 @@ enum GleanChannel {
}

export class PaymentsGleanConfig {
@Type(() => Boolean)
@IsBoolean()
enabled!: boolean;

Expand Down
4 changes: 4 additions & 0 deletions libs/payments/paypal/src/lib/paypal.client.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@ import { Type } from 'class-transformer';
import { IsBoolean, IsNumber, IsString, ValidateNested } from 'class-validator';

export class PaypalRetryConfig {
@Type(() => Number)
@IsNumber()
public readonly retries!: number;

@Type(() => Number)
@IsNumber()
public readonly minTimeout!: number;

@Type(() => Number)
@IsNumber()
public readonly factor!: number;
}

export class PaypalClientConfig {
@Type(() => Boolean)
@IsBoolean()
public readonly sandbox!: boolean;

Expand Down
20 changes: 12 additions & 8 deletions libs/payments/stripe/src/lib/factories/event.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,43 @@ import { StripeSubscription } from '../stripe.client.types';

// TODO - Create generic factory
export const StripeEventCustomerSubscriptionCreatedFactory = (
override?: Partial<Stripe.Event>,
dataObjectOverride?: Partial<StripeSubscription>
): Stripe.Event => ({
id: 'evt_123',
object: 'event',
api_version: '2019-02-19',
created: faker.date.past().getTime(),
livemode: false,
request: null,
pending_webhooks: 0,
...override,
type: 'customer.subscription.created',
data: {
object: {
...StripeSubscriptionFactory(),
...dataObjectOverride,
},
},
livemode: false,
request: null,
pending_webhooks: 0,
type: 'customer.subscription.created',
});

export const StripeEventCustomerSubscriptionDeletedFactory = (
override?: Partial<Stripe.Event>,
dataObjectOverride?: Partial<StripeSubscription>
): Stripe.Event => ({
id: 'evt_123',
object: 'event',
api_version: '2019-02-19',
created: faker.date.past().getTime(),
livemode: false,
request: null,
pending_webhooks: 0,
...override,
type: 'customer.subscription.deleted',
data: {
object: {
...StripeSubscriptionFactory(),
...dataObjectOverride,
},
},
livemode: false,
request: null,
pending_webhooks: 0,
type: 'customer.subscription.deleted',
});
16 changes: 11 additions & 5 deletions libs/payments/ui/src/lib/nestapp/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ import { GoogleClientConfig } from '@fxa/google';
import { MySQLConfig } from '@fxa/shared/db/mysql/core';
import { GeoDBConfig, GeoDBManagerConfig } from '@fxa/shared/geodb';
import { LocationConfig } from '@fxa/payments/eligibility';
import { PaypalClientConfig } from 'libs/payments/paypal/src/lib/paypal.client.config';
import { PaypalClientConfig } from '@fxa/payments/paypal';
import { StripeConfig } from '@fxa/payments/stripe';
import { StrapiClientConfig } from '@fxa/shared/cms';
import { FirestoreConfig } from 'libs/shared/db/firestore/src/lib/firestore.config';
import { StatsDConfig } from 'libs/shared/metrics/statsd/src/lib/statsd.config';
import { StatsDConfig } from '@fxa/shared/metrics/statsd';
import { PaymentsGleanConfig } from '@fxa/payments/metrics';
import { CurrencyConfig } from 'libs/payments/currency/src/lib/currency.config';
import { CurrencyConfig } from '@fxa/payments/currency';
import { ProfileClientConfig } from '@fxa/profile/client';
import { ContentServerClientConfig } from '@fxa/payments/content-server';
import { NotifierSnsConfig } from '@fxa/shared/notifier';
import { AppleIapClientConfig, GoogleIapClientConfig } from '@fxa/payments/iap';
import { TracingConfig } from './tracing.config';
import { StripeEventConfig } from '@fxa/payments/webhooks';
import { FirestoreConfig } from 'libs/shared/db/firestore/src/lib/firestore.config';

export class RootConfig {
@Type(() => MySQLConfig)
Expand All @@ -41,7 +42,7 @@ export class RootConfig {
@ValidateNested()
@IsDefined()
public readonly stripeConfig!: Partial<StripeConfig>;

@Type(() => TracingConfig)
@ValidateNested()
@IsDefined()
Expand Down Expand Up @@ -107,6 +108,11 @@ export class RootConfig {
@IsDefined()
public readonly googleClientConfig!: Partial<GoogleClientConfig>;

@Type(() => StripeEventConfig)
@ValidateNested()
@IsDefined()
public readonly stripeEventsConfig!: Partial<StripeEventConfig>;

@Type(() => LocationConfig)
@ValidateNested()
@IsDefined()
Expand Down
Loading