1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-14 23:33:31 +00:00

[PM-25463] Work towards complete usage of Payments domain (#16532)

* Use payment domain

* Fixing lint and test issue

* Fix organization plans tax issue

* PM-26297: Use existing billing address for tax calculation if it exists

* PM-26344: Check existing payment method on submit
This commit is contained in:
Alex Morask
2025-10-01 10:26:47 -05:00
committed by GitHub
parent 147b511d64
commit d9d8050998
117 changed files with 1505 additions and 5212 deletions

View File

@@ -77,14 +77,10 @@ import {
} from "../auth/models/response/two-factor-web-authn.response";
import { TwoFactorYubiKeyResponse } from "../auth/models/response/two-factor-yubi-key.response";
import { BitPayInvoiceRequest } from "../billing/models/request/bit-pay-invoice.request";
import { PaymentRequest } from "../billing/models/request/payment.request";
import { TaxInfoUpdateRequest } from "../billing/models/request/tax-info-update.request";
import { BillingHistoryResponse } from "../billing/models/response/billing-history.response";
import { BillingPaymentResponse } from "../billing/models/response/billing-payment.response";
import { PaymentResponse } from "../billing/models/response/payment.response";
import { PlanResponse } from "../billing/models/response/plan.response";
import { SubscriptionResponse } from "../billing/models/response/subscription.response";
import { TaxInfoResponse } from "../billing/models/response/tax-info.response";
import { KeyConnectorUserKeyRequest } from "../key-management/key-connector/models/key-connector-user-key.request";
import { SetKeyConnectorKeyRequest } from "../key-management/key-connector/models/set-key-connector-key.request";
import { DeleteRecoverRequest } from "../models/request/delete-recover.request";
@@ -171,10 +167,8 @@ export abstract class ApiService {
abstract getProfile(): Promise<ProfileResponse>;
abstract getUserSubscription(): Promise<SubscriptionResponse>;
abstract getTaxInfo(): Promise<TaxInfoResponse>;
abstract putProfile(request: UpdateProfileRequest): Promise<ProfileResponse>;
abstract putAvatar(request: UpdateAvatarRequest): Promise<ProfileResponse>;
abstract putTaxInfo(request: TaxInfoUpdateRequest): Promise<any>;
abstract postPrelogin(request: PreloginRequest): Promise<PreloginResponse>;
abstract postEmailToken(request: EmailTokenRequest): Promise<any>;
abstract postEmail(request: EmailRequest): Promise<any>;
@@ -185,7 +179,6 @@ export abstract class ApiService {
abstract postPremium(data: FormData): Promise<PaymentResponse>;
abstract postReinstatePremium(): Promise<any>;
abstract postAccountStorage(request: StorageRequest): Promise<PaymentResponse>;
abstract postAccountPayment(request: PaymentRequest): Promise<void>;
abstract postAccountLicense(data: FormData): Promise<any>;
abstract postAccountKeys(request: KeysRequest): Promise<any>;
abstract postAccountVerifyEmail(): Promise<any>;
@@ -209,7 +202,6 @@ export abstract class ApiService {
abstract getLastAuthRequest(): Promise<AuthRequestResponse>;
abstract getUserBillingHistory(): Promise<BillingHistoryResponse>;
abstract getUserBillingPayment(): Promise<BillingPaymentResponse>;
abstract getCipher(id: string): Promise<CipherResponse>;
abstract getFullCipherDetails(id: string): Promise<CipherResponse>;

View File

@@ -3,21 +3,17 @@ import { OrganizationSsoRequest } from "../../../auth/models/request/organizatio
import { SecretVerificationRequest } from "../../../auth/models/request/secret-verification.request";
import { ApiKeyResponse } from "../../../auth/models/response/api-key.response";
import { OrganizationSsoResponse } from "../../../auth/models/response/organization-sso.response";
import { ExpandedTaxInfoUpdateRequest } from "../../../billing/models/request/expanded-tax-info-update.request";
import { OrganizationNoPaymentMethodCreateRequest } from "../../../billing/models/request/organization-no-payment-method-create-request";
import { OrganizationSmSubscriptionUpdateRequest } from "../../../billing/models/request/organization-sm-subscription-update.request";
import { OrganizationSubscriptionUpdateRequest } from "../../../billing/models/request/organization-subscription-update.request";
import { PaymentRequest } from "../../../billing/models/request/payment.request";
import { SecretsManagerSubscribeRequest } from "../../../billing/models/request/sm-subscribe.request";
import { BillingHistoryResponse } from "../../../billing/models/response/billing-history.response";
import { BillingResponse } from "../../../billing/models/response/billing.response";
import { OrganizationSubscriptionResponse } from "../../../billing/models/response/organization-subscription.response";
import { PaymentResponse } from "../../../billing/models/response/payment.response";
import { TaxInfoResponse } from "../../../billing/models/response/tax-info.response";
import { ImportDirectoryRequest } from "../../../models/request/import-directory.request";
import { SeatRequest } from "../../../models/request/seat.request";
import { StorageRequest } from "../../../models/request/storage.request";
import { VerifyBankRequest } from "../../../models/request/verify-bank.request";
import { ListResponse } from "../../../models/response/list.response";
import { OrganizationApiKeyType } from "../../enums";
import { OrganizationCollectionManagementUpdateRequest } from "../../models/request/organization-collection-management-update.request";
@@ -45,7 +41,6 @@ export abstract class OrganizationApiServiceAbstraction {
): Promise<OrganizationResponse>;
abstract createLicense(data: FormData): Promise<OrganizationResponse>;
abstract save(id: string, request: OrganizationUpdateRequest): Promise<OrganizationResponse>;
abstract updatePayment(id: string, request: PaymentRequest): Promise<void>;
abstract upgrade(id: string, request: OrganizationUpgradeRequest): Promise<PaymentResponse>;
abstract updatePasswordManagerSeats(
id: string,
@@ -57,7 +52,6 @@ export abstract class OrganizationApiServiceAbstraction {
): Promise<ProfileOrganizationResponse>;
abstract updateSeats(id: string, request: SeatRequest): Promise<PaymentResponse>;
abstract updateStorage(id: string, request: StorageRequest): Promise<PaymentResponse>;
abstract verifyBank(id: string, request: VerifyBankRequest): Promise<void>;
abstract reinstate(id: string): Promise<void>;
abstract leave(id: string): Promise<void>;
abstract delete(id: string, request: SecretVerificationRequest): Promise<void>;
@@ -76,8 +70,6 @@ export abstract class OrganizationApiServiceAbstraction {
organizationApiKeyType?: OrganizationApiKeyType,
): Promise<ListResponse<OrganizationApiKeyInformationResponse>>;
abstract rotateApiKey(id: string, request: OrganizationApiKeyRequest): Promise<ApiKeyResponse>;
abstract getTaxInfo(id: string): Promise<TaxInfoResponse>;
abstract updateTaxInfo(id: string, request: ExpandedTaxInfoUpdateRequest): Promise<void>;
abstract getKeys(id: string): Promise<OrganizationKeysResponse>;
abstract updateKeys(
id: string,

View File

@@ -1,7 +1,19 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { ExpandedTaxInfoUpdateRequest } from "../../../../billing/models/request/expanded-tax-info-update.request";
import { TokenizedPaymentSourceRequest } from "../../../../billing/models/request/tokenized-payment-source.request";
interface TokenizedPaymentMethod {
type: "bankAccount" | "card" | "payPal";
token: string;
}
interface BillingAddress {
country: string;
postalCode: string;
line1: string | null;
line2: string | null;
city: string | null;
state: string | null;
taxId: { code: string; value: string } | null;
}
export class ProviderSetupRequest {
name: string;
@@ -9,6 +21,6 @@ export class ProviderSetupRequest {
billingEmail: string;
token: string;
key: string;
taxInfo: ExpandedTaxInfoUpdateRequest;
paymentSource?: TokenizedPaymentSourceRequest;
paymentMethod: TokenizedPaymentMethod;
billingAddress: BillingAddress;
}

View File

@@ -7,21 +7,17 @@ import { OrganizationSsoRequest } from "../../../auth/models/request/organizatio
import { SecretVerificationRequest } from "../../../auth/models/request/secret-verification.request";
import { ApiKeyResponse } from "../../../auth/models/response/api-key.response";
import { OrganizationSsoResponse } from "../../../auth/models/response/organization-sso.response";
import { ExpandedTaxInfoUpdateRequest } from "../../../billing/models/request/expanded-tax-info-update.request";
import { OrganizationNoPaymentMethodCreateRequest } from "../../../billing/models/request/organization-no-payment-method-create-request";
import { OrganizationSmSubscriptionUpdateRequest } from "../../../billing/models/request/organization-sm-subscription-update.request";
import { OrganizationSubscriptionUpdateRequest } from "../../../billing/models/request/organization-subscription-update.request";
import { PaymentRequest } from "../../../billing/models/request/payment.request";
import { SecretsManagerSubscribeRequest } from "../../../billing/models/request/sm-subscribe.request";
import { BillingHistoryResponse } from "../../../billing/models/response/billing-history.response";
import { BillingResponse } from "../../../billing/models/response/billing.response";
import { OrganizationSubscriptionResponse } from "../../../billing/models/response/organization-subscription.response";
import { PaymentResponse } from "../../../billing/models/response/payment.response";
import { TaxInfoResponse } from "../../../billing/models/response/tax-info.response";
import { ImportDirectoryRequest } from "../../../models/request/import-directory.request";
import { SeatRequest } from "../../../models/request/seat.request";
import { StorageRequest } from "../../../models/request/storage.request";
import { VerifyBankRequest } from "../../../models/request/verify-bank.request";
import { ListResponse } from "../../../models/response/list.response";
import { SyncService } from "../../../vault/abstractions/sync/sync.service.abstraction";
import { OrganizationApiServiceAbstraction } from "../../abstractions/organization/organization-api.service.abstraction";
@@ -143,10 +139,6 @@ export class OrganizationApiService implements OrganizationApiServiceAbstraction
return data;
}
async updatePayment(id: string, request: PaymentRequest): Promise<void> {
return this.apiService.send("POST", "/organizations/" + id + "/payment", request, true, false);
}
async upgrade(id: string, request: OrganizationUpgradeRequest): Promise<PaymentResponse> {
const r = await this.apiService.send(
"POST",
@@ -208,16 +200,6 @@ export class OrganizationApiService implements OrganizationApiServiceAbstraction
return new PaymentResponse(r);
}
async verifyBank(id: string, request: VerifyBankRequest): Promise<void> {
await this.apiService.send(
"POST",
"/organizations/" + id + "/verify-bank",
request,
true,
false,
);
}
async reinstate(id: string): Promise<void> {
return this.apiService.send("POST", "/organizations/" + id + "/reinstate", null, true, false);
}
@@ -299,16 +281,6 @@ export class OrganizationApiService implements OrganizationApiServiceAbstraction
return new ApiKeyResponse(r);
}
async getTaxInfo(id: string): Promise<TaxInfoResponse> {
const r = await this.apiService.send("GET", "/organizations/" + id + "/tax", null, true, true);
return new TaxInfoResponse(r);
}
async updateTaxInfo(id: string, request: ExpandedTaxInfoUpdateRequest): Promise<void> {
// Can't broadcast anything because the response doesn't have content
return this.apiService.send("PUT", "/organizations/" + id + "/tax", request, true, false);
}
async getKeys(id: string): Promise<OrganizationKeysResponse> {
const r = await this.apiService.send("GET", "/organizations/" + id + "/keys", null, true, true);
return new OrganizationKeysResponse(r);

View File

@@ -1,19 +1,12 @@
import { TaxInfoResponse } from "@bitwarden/common/billing/models/response/tax-info.response";
import { OrganizationCreateRequest } from "../../admin-console/models/request/organization-create.request";
import { ProviderOrganizationOrganizationDetailsResponse } from "../../admin-console/models/response/provider/provider-organization.response";
import { SubscriptionCancellationRequest } from "../../billing/models/request/subscription-cancellation.request";
import { OrganizationBillingMetadataResponse } from "../../billing/models/response/organization-billing-metadata.response";
import { PlanResponse } from "../../billing/models/response/plan.response";
import { ListResponse } from "../../models/response/list.response";
import { PaymentMethodType } from "../enums";
import { CreateClientOrganizationRequest } from "../models/request/create-client-organization.request";
import { ExpandedTaxInfoUpdateRequest } from "../models/request/expanded-tax-info-update.request";
import { UpdateClientOrganizationRequest } from "../models/request/update-client-organization.request";
import { UpdatePaymentMethodRequest } from "../models/request/update-payment-method.request";
import { VerifyBankAccountRequest } from "../models/request/verify-bank-account.request";
import { InvoicesResponse } from "../models/response/invoices.response";
import { PaymentMethodResponse } from "../models/response/payment-method.response";
import { ProviderSubscriptionResponse } from "../models/response/provider-subscription-response";
export abstract class BillingApiServiceAbstraction {
@@ -29,14 +22,10 @@ export abstract class BillingApiServiceAbstraction {
request: CreateClientOrganizationRequest,
): Promise<void>;
abstract createSetupIntent(paymentMethodType: PaymentMethodType): Promise<string>;
abstract getOrganizationBillingMetadata(
organizationId: string,
): Promise<OrganizationBillingMetadataResponse>;
abstract getOrganizationPaymentMethod(organizationId: string): Promise<PaymentMethodResponse>;
abstract getPlans(): Promise<ListResponse<PlanResponse>>;
abstract getProviderClientInvoiceReport(providerId: string, invoiceId: string): Promise<string>;
@@ -49,44 +38,12 @@ export abstract class BillingApiServiceAbstraction {
abstract getProviderSubscription(providerId: string): Promise<ProviderSubscriptionResponse>;
abstract getProviderTaxInformation(providerId: string): Promise<TaxInfoResponse>;
abstract updateOrganizationPaymentMethod(
organizationId: string,
request: UpdatePaymentMethodRequest,
): Promise<void>;
abstract updateOrganizationTaxInformation(
organizationId: string,
request: ExpandedTaxInfoUpdateRequest,
): Promise<void>;
abstract updateProviderClientOrganization(
providerId: string,
organizationId: string,
request: UpdateClientOrganizationRequest,
): Promise<any>;
abstract updateProviderPaymentMethod(
providerId: string,
request: UpdatePaymentMethodRequest,
): Promise<void>;
abstract updateProviderTaxInformation(
providerId: string,
request: ExpandedTaxInfoUpdateRequest,
): Promise<void>;
abstract verifyOrganizationBankAccount(
organizationId: string,
request: VerifyBankAccountRequest,
): Promise<void>;
abstract verifyProviderBankAccount(
providerId: string,
request: VerifyBankAccountRequest,
): Promise<void>;
abstract restartSubscription(
organizationId: string,
request: OrganizationCreateRequest,

View File

@@ -3,7 +3,6 @@ import { UserId } from "@bitwarden/user-core";
import { OrganizationResponse } from "../../admin-console/models/response/organization.response";
import { InitiationPath } from "../../models/request/reference-event.request";
import { PaymentMethodType, PlanType } from "../enums";
import { PaymentSourceResponse } from "../models/response/payment-source.response";
export type OrganizationInformation = {
name: string;
@@ -45,8 +44,6 @@ export type SubscriptionInformation = {
};
export abstract class OrganizationBillingServiceAbstraction {
abstract getPaymentSource(organizationId: string): Promise<PaymentSourceResponse>;
abstract purchaseSubscription(
subscription: SubscriptionInformation,
activeUserId: UserId,

View File

@@ -1,23 +0,0 @@
import { CountryListItem } from "../models/domain";
import { PreviewIndividualInvoiceRequest } from "../models/request/preview-individual-invoice.request";
import { PreviewOrganizationInvoiceRequest } from "../models/request/preview-organization-invoice.request";
import { PreviewTaxAmountForOrganizationTrialRequest } from "../models/request/tax";
import { PreviewInvoiceResponse } from "../models/response/preview-invoice.response";
export abstract class TaxServiceAbstraction {
abstract getCountries(): CountryListItem[];
abstract isCountrySupported(country: string): Promise<boolean>;
abstract previewIndividualInvoice(
request: PreviewIndividualInvoiceRequest,
): Promise<PreviewInvoiceResponse>;
abstract previewOrganizationInvoice(
request: PreviewOrganizationInvoiceRequest,
): Promise<PreviewInvoiceResponse>;
abstract previewTaxAmountForOrganizationTrial: (
request: PreviewTaxAmountForOrganizationTrialRequest,
) => Promise<number>;
}

View File

@@ -1,6 +0,0 @@
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
export enum BitwardenProductType {
PasswordManager = 0,
SecretsManager = 1,
}

View File

@@ -2,7 +2,6 @@ export * from "./payment-method-type.enum";
export * from "./plan-sponsorship-type.enum";
export * from "./plan-type.enum";
export * from "./transaction-type.enum";
export * from "./bitwarden-product-type.enum";
export * from "./product-tier-type.enum";
export * from "./product-type.enum";
export * from "./plan-interval.enum";

View File

@@ -1,29 +0,0 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { TaxInformation } from "../domain/tax-information";
import { TaxInfoUpdateRequest } from "./tax-info-update.request";
export class ExpandedTaxInfoUpdateRequest extends TaxInfoUpdateRequest {
taxId: string;
line1: string;
line2: string;
city: string;
state: string;
static From(taxInformation: TaxInformation): ExpandedTaxInfoUpdateRequest {
if (!taxInformation) {
return null;
}
const request = new ExpandedTaxInfoUpdateRequest();
request.country = taxInformation.country;
request.postalCode = taxInformation.postalCode;
request.taxId = taxInformation.taxId;
request.line1 = taxInformation.line1;
request.line2 = taxInformation.line2;
request.city = taxInformation.city;
request.state = taxInformation.state;
return request;
}
}

View File

@@ -1,10 +0,0 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { PaymentMethodType } from "../../enums";
import { ExpandedTaxInfoUpdateRequest } from "./expanded-tax-info-update.request";
export class PaymentRequest extends ExpandedTaxInfoUpdateRequest {
paymentMethodType: PaymentMethodType;
paymentToken: string;
}

View File

@@ -1,28 +0,0 @@
// @ts-strict-ignore
export class PreviewIndividualInvoiceRequest {
passwordManager: PasswordManager;
taxInformation: TaxInformation;
constructor(passwordManager: PasswordManager, taxInformation: TaxInformation) {
this.passwordManager = passwordManager;
this.taxInformation = taxInformation;
}
}
class PasswordManager {
additionalStorage: number;
constructor(additionalStorage: number) {
this.additionalStorage = additionalStorage;
}
}
class TaxInformation {
postalCode: string;
country: string;
constructor(postalCode: string, country: string) {
this.postalCode = postalCode;
this.country = country;
}
}

View File

@@ -1,55 +0,0 @@
import { PlanSponsorshipType, PlanType } from "../../enums";
export class PreviewOrganizationInvoiceRequest {
organizationId?: string;
passwordManager: PasswordManager;
secretsManager?: SecretsManager;
taxInformation: TaxInformation;
constructor(
passwordManager: PasswordManager,
taxInformation: TaxInformation,
organizationId?: string,
secretsManager?: SecretsManager,
) {
this.organizationId = organizationId;
this.passwordManager = passwordManager;
this.secretsManager = secretsManager;
this.taxInformation = taxInformation;
}
}
class PasswordManager {
plan: PlanType;
sponsoredPlan?: PlanSponsorshipType;
seats: number;
additionalStorage: number;
constructor(plan: PlanType, seats: number, additionalStorage: number) {
this.plan = plan;
this.seats = seats;
this.additionalStorage = additionalStorage;
}
}
class SecretsManager {
seats: number;
additionalMachineAccounts: number;
constructor(seats: number, additionalMachineAccounts: number) {
this.seats = seats;
this.additionalMachineAccounts = additionalMachineAccounts;
}
}
class TaxInformation {
postalCode: string;
country: string;
taxId: string;
constructor(postalCode: string, country: string, taxId: string) {
this.postalCode = postalCode;
this.country = country;
this.taxId = taxId;
}
}

View File

@@ -1,6 +0,0 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
export class TaxInfoUpdateRequest {
country: string;
postalCode: string;
}

View File

@@ -1 +0,0 @@
export * from "./preview-tax-amount-for-organization-trial.request";

View File

@@ -1,11 +0,0 @@
import { PlanType, ProductType } from "../../../enums";
export type PreviewTaxAmountForOrganizationTrialRequest = {
planType: PlanType;
productType: ProductType;
taxInformation: {
country: string;
postalCode: string;
taxId?: string;
};
};

View File

@@ -1,8 +0,0 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { PaymentMethodType } from "../../enums";
export class TokenizedPaymentSourceRequest {
type: PaymentMethodType;
token: string;
}

View File

@@ -1,9 +0,0 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { ExpandedTaxInfoUpdateRequest } from "./expanded-tax-info-update.request";
import { TokenizedPaymentSourceRequest } from "./tokenized-payment-source.request";
export class UpdatePaymentMethodRequest {
paymentSource: TokenizedPaymentSourceRequest;
taxInformation: ExpandedTaxInfoUpdateRequest;
}

View File

@@ -1,7 +0,0 @@
export class VerifyBankAccountRequest {
descriptorCode: string;
constructor(descriptorCode: string) {
this.descriptorCode = descriptorCode;
}
}

View File

@@ -1,17 +0,0 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { BaseResponse } from "../../../models/response/base.response";
import { BillingSourceResponse } from "./billing.response";
export class BillingPaymentResponse extends BaseResponse {
balance: number;
paymentSource: BillingSourceResponse;
constructor(response: any) {
super(response);
this.balance = this.getResponseProperty("Balance");
const paymentSource = this.getResponseProperty("PaymentSource");
this.paymentSource = paymentSource == null ? null : new BillingSourceResponse(paymentSource);
}
}

View File

@@ -1,28 +0,0 @@
import { BaseResponse } from "../../../models/response/base.response";
import { PaymentSourceResponse } from "./payment-source.response";
import { TaxInfoResponse } from "./tax-info.response";
export class PaymentMethodResponse extends BaseResponse {
accountCredit: number;
paymentSource?: PaymentSourceResponse;
subscriptionStatus?: string;
taxInformation?: TaxInfoResponse;
constructor(response: any) {
super(response);
this.accountCredit = this.getResponseProperty("AccountCredit");
const paymentSource = this.getResponseProperty("PaymentSource");
if (paymentSource) {
this.paymentSource = new PaymentSourceResponse(paymentSource);
}
this.subscriptionStatus = this.getResponseProperty("SubscriptionStatus");
const taxInformation = this.getResponseProperty("TaxInformation");
if (taxInformation) {
this.taxInformation = new TaxInfoResponse(taxInformation);
}
}
}

View File

@@ -1,28 +0,0 @@
import { BaseResponse } from "../../../models/response/base.response";
export class TaxIdTypesResponse extends BaseResponse {
taxIdTypes: TaxIdTypeResponse[] = [];
constructor(response: any) {
super(response);
const taxIdTypes = this.getResponseProperty("TaxIdTypes");
if (taxIdTypes && taxIdTypes.length) {
this.taxIdTypes = taxIdTypes.map((t: any) => new TaxIdTypeResponse(t));
}
}
}
export class TaxIdTypeResponse extends BaseResponse {
code: string;
country: string;
description: string;
example: string;
constructor(response: any) {
super(response);
this.code = this.getResponseProperty("Code");
this.country = this.getResponseProperty("Country");
this.description = this.getResponseProperty("Description");
this.example = this.getResponseProperty("Example");
}
}

View File

@@ -1 +0,0 @@
export * from "./preview-tax-amount.response";

View File

@@ -1,11 +0,0 @@
import { BaseResponse } from "../../../../models/response/base.response";
export class PreviewTaxAmountResponse extends BaseResponse {
taxAmount: number;
constructor(response: any) {
super(response);
this.taxAmount = this.getResponseProperty("TaxAmount");
}
}

View File

@@ -1,23 +1,16 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { TaxInfoResponse } from "@bitwarden/common/billing/models/response/tax-info.response";
import { ApiService } from "../../abstractions/api.service";
import { OrganizationCreateRequest } from "../../admin-console/models/request/organization-create.request";
import { ProviderOrganizationOrganizationDetailsResponse } from "../../admin-console/models/response/provider/provider-organization.response";
import { ListResponse } from "../../models/response/list.response";
import { BillingApiServiceAbstraction } from "../abstractions";
import { PaymentMethodType } from "../enums";
import { CreateClientOrganizationRequest } from "../models/request/create-client-organization.request";
import { ExpandedTaxInfoUpdateRequest } from "../models/request/expanded-tax-info-update.request";
import { SubscriptionCancellationRequest } from "../models/request/subscription-cancellation.request";
import { UpdateClientOrganizationRequest } from "../models/request/update-client-organization.request";
import { UpdatePaymentMethodRequest } from "../models/request/update-payment-method.request";
import { VerifyBankAccountRequest } from "../models/request/verify-bank-account.request";
import { InvoicesResponse } from "../models/response/invoices.response";
import { OrganizationBillingMetadataResponse } from "../models/response/organization-billing-metadata.response";
import { PaymentMethodResponse } from "../models/response/payment-method.response";
import { PlanResponse } from "../models/response/plan.response";
import { ProviderSubscriptionResponse } from "../models/response/provider-subscription-response";
@@ -54,21 +47,6 @@ export class BillingApiService implements BillingApiServiceAbstraction {
);
}
async createSetupIntent(type: PaymentMethodType) {
const getPath = () => {
switch (type) {
case PaymentMethodType.BankAccount: {
return "/setup-intent/bank-account";
}
case PaymentMethodType.Card: {
return "/setup-intent/card";
}
}
};
const response = await this.apiService.send("POST", getPath(), null, true, true);
return response as string;
}
async getOrganizationBillingMetadata(
organizationId: string,
): Promise<OrganizationBillingMetadataResponse> {
@@ -83,17 +61,6 @@ export class BillingApiService implements BillingApiServiceAbstraction {
return new OrganizationBillingMetadataResponse(r);
}
async getOrganizationPaymentMethod(organizationId: string): Promise<PaymentMethodResponse> {
const response = await this.apiService.send(
"GET",
"/organizations/" + organizationId + "/billing/payment-method",
null,
true,
true,
);
return new PaymentMethodResponse(response);
}
async getPlans(): Promise<ListResponse<PlanResponse>> {
const r = await this.apiService.send("GET", "/plans", null, false, true);
return new ListResponse(r, PlanResponse);
@@ -145,43 +112,6 @@ export class BillingApiService implements BillingApiServiceAbstraction {
return new ProviderSubscriptionResponse(response);
}
async getProviderTaxInformation(providerId: string): Promise<TaxInfoResponse> {
const response = await this.apiService.send(
"GET",
"/providers/" + providerId + "/billing/tax-information",
null,
true,
true,
);
return new TaxInfoResponse(response);
}
async updateOrganizationPaymentMethod(
organizationId: string,
request: UpdatePaymentMethodRequest,
): Promise<void> {
return await this.apiService.send(
"PUT",
"/organizations/" + organizationId + "/billing/payment-method",
request,
true,
false,
);
}
async updateOrganizationTaxInformation(
organizationId: string,
request: ExpandedTaxInfoUpdateRequest,
): Promise<void> {
return await this.apiService.send(
"PUT",
"/organizations/" + organizationId + "/billing/tax-information",
request,
true,
false,
);
}
async updateProviderClientOrganization(
providerId: string,
organizationId: string,
@@ -196,55 +126,6 @@ export class BillingApiService implements BillingApiServiceAbstraction {
);
}
async updateProviderPaymentMethod(
providerId: string,
request: UpdatePaymentMethodRequest,
): Promise<void> {
return await this.apiService.send(
"PUT",
"/providers/" + providerId + "/billing/payment-method",
request,
true,
false,
);
}
async updateProviderTaxInformation(providerId: string, request: ExpandedTaxInfoUpdateRequest) {
return await this.apiService.send(
"PUT",
"/providers/" + providerId + "/billing/tax-information",
request,
true,
false,
);
}
async verifyOrganizationBankAccount(
organizationId: string,
request: VerifyBankAccountRequest,
): Promise<void> {
return await this.apiService.send(
"POST",
"/organizations/" + organizationId + "/billing/payment-method/verify-bank-account",
request,
true,
false,
);
}
async verifyProviderBankAccount(
providerId: string,
request: VerifyBankAccountRequest,
): Promise<void> {
return await this.apiService.send(
"POST",
"/providers/" + providerId + "/billing/payment-method/verify-bank-account",
request,
true,
false,
);
}
async restartSubscription(
organizationId: string,
request: OrganizationCreateRequest,

View File

@@ -23,7 +23,6 @@ import { OrganizationResponse } from "../../admin-console/models/response/organi
import { EncString } from "../../key-management/crypto/models/enc-string";
import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key";
import { OrgKey } from "../../types/key";
import { PaymentMethodResponse } from "../models/response/payment-method.response";
describe("OrganizationBillingService", () => {
let apiService: jest.Mocked<ApiService>;
@@ -62,47 +61,6 @@ describe("OrganizationBillingService", () => {
return jest.resetAllMocks();
});
describe("getPaymentSource()", () => {
it("given a valid organization id, then it returns a payment source", async () => {
//Arrange
const orgId = "organization-test";
const paymentMethodResponse = {
paymentSource: { type: PaymentMethodType.Card },
} as PaymentMethodResponse;
billingApiService.getOrganizationPaymentMethod.mockResolvedValue(paymentMethodResponse);
//Act
const returnedPaymentSource = await sut.getPaymentSource(orgId);
//Assert
expect(billingApiService.getOrganizationPaymentMethod).toHaveBeenCalledTimes(1);
expect(returnedPaymentSource).toEqual(paymentMethodResponse.paymentSource);
});
it("given an invalid organizationId, it should return undefined", async () => {
//Arrange
const orgId = "invalid-id";
billingApiService.getOrganizationPaymentMethod.mockResolvedValue(null);
//Act
const returnedPaymentSource = await sut.getPaymentSource(orgId);
//Assert
expect(billingApiService.getOrganizationPaymentMethod).toHaveBeenCalledTimes(1);
expect(returnedPaymentSource).toBeUndefined();
});
it("given an API error occurs, then it throws the error", async () => {
// Arrange
const orgId = "error-org";
billingApiService.getOrganizationPaymentMethod.mockRejectedValue(new Error("API Error"));
// Act & Assert
await expect(sut.getPaymentSource(orgId)).rejects.toThrow("API Error");
expect(billingApiService.getOrganizationPaymentMethod).toHaveBeenCalledTimes(1);
});
});
describe("purchaseSubscription()", () => {
it("given valid subscription information, then it returns successful response", async () => {
//Arrange
@@ -118,7 +76,7 @@ describe("OrganizationBillingService", () => {
const organizationResponse = {
name: subscriptionInformation.organization.name,
billingEmail: subscriptionInformation.organization.billingEmail,
planType: subscriptionInformation.plan.type,
planType: subscriptionInformation.plan!.type,
} as OrganizationResponse;
organizationApiService.create.mockResolvedValue(organizationResponse);
@@ -201,8 +159,8 @@ describe("OrganizationBillingService", () => {
const organizationResponse = {
name: subscriptionInformation.organization.name,
plan: { type: subscriptionInformation.plan.type },
planType: subscriptionInformation.plan.type,
plan: { type: subscriptionInformation.plan!.type },
planType: subscriptionInformation.plan!.type,
} as OrganizationResponse;
organizationApiService.createWithoutPayment.mockResolvedValue(organizationResponse);
@@ -262,7 +220,7 @@ describe("OrganizationBillingService", () => {
const organizationResponse = {
name: subscriptionInformation.organization.name,
billingEmail: subscriptionInformation.organization.billingEmail,
planType: subscriptionInformation.plan.type,
planType: subscriptionInformation.plan!.type,
} as OrganizationResponse;
organizationApiService.create.mockResolvedValue(organizationResponse);

View File

@@ -25,7 +25,6 @@ import {
} from "../abstractions";
import { PlanType } from "../enums";
import { OrganizationNoPaymentMethodCreateRequest } from "../models/request/organization-no-payment-method-create-request";
import { PaymentSourceResponse } from "../models/response/payment-source.response";
interface OrganizationKeys {
encryptedKey: EncString;
@@ -45,11 +44,6 @@ export class OrganizationBillingService implements OrganizationBillingServiceAbs
private syncService: SyncService,
) {}
async getPaymentSource(organizationId: string): Promise<PaymentSourceResponse> {
const paymentMethod = await this.billingApiService.getOrganizationPaymentMethod(organizationId);
return paymentMethod?.paymentSource;
}
async purchaseSubscription(
subscription: SubscriptionInformation,
activeUserId: UserId,

View File

@@ -1,318 +0,0 @@
import { PreviewTaxAmountForOrganizationTrialRequest } from "@bitwarden/common/billing/models/request/tax";
import { ApiService } from "../../abstractions/api.service";
import { TaxServiceAbstraction } from "../abstractions/tax.service.abstraction";
import { CountryListItem } from "../models/domain";
import { PreviewIndividualInvoiceRequest } from "../models/request/preview-individual-invoice.request";
import { PreviewOrganizationInvoiceRequest } from "../models/request/preview-organization-invoice.request";
import { PreviewInvoiceResponse } from "../models/response/preview-invoice.response";
export class TaxService implements TaxServiceAbstraction {
constructor(private apiService: ApiService) {}
getCountries(): CountryListItem[] {
return [
{ name: "-- Select --", value: "", disabled: false },
{ name: "United States", value: "US", disabled: false },
{ name: "China", value: "CN", disabled: false },
{ name: "France", value: "FR", disabled: false },
{ name: "Germany", value: "DE", disabled: false },
{ name: "Canada", value: "CA", disabled: false },
{ name: "United Kingdom", value: "GB", disabled: false },
{ name: "Australia", value: "AU", disabled: false },
{ name: "India", value: "IN", disabled: false },
{ name: "", value: "-", disabled: true },
{ name: "Afghanistan", value: "AF", disabled: false },
{ name: "Åland Islands", value: "AX", disabled: false },
{ name: "Albania", value: "AL", disabled: false },
{ name: "Algeria", value: "DZ", disabled: false },
{ name: "American Samoa", value: "AS", disabled: false },
{ name: "Andorra", value: "AD", disabled: false },
{ name: "Angola", value: "AO", disabled: false },
{ name: "Anguilla", value: "AI", disabled: false },
{ name: "Antarctica", value: "AQ", disabled: false },
{ name: "Antigua and Barbuda", value: "AG", disabled: false },
{ name: "Argentina", value: "AR", disabled: false },
{ name: "Armenia", value: "AM", disabled: false },
{ name: "Aruba", value: "AW", disabled: false },
{ name: "Austria", value: "AT", disabled: false },
{ name: "Azerbaijan", value: "AZ", disabled: false },
{ name: "Bahamas", value: "BS", disabled: false },
{ name: "Bahrain", value: "BH", disabled: false },
{ name: "Bangladesh", value: "BD", disabled: false },
{ name: "Barbados", value: "BB", disabled: false },
{ name: "Belarus", value: "BY", disabled: false },
{ name: "Belgium", value: "BE", disabled: false },
{ name: "Belize", value: "BZ", disabled: false },
{ name: "Benin", value: "BJ", disabled: false },
{ name: "Bermuda", value: "BM", disabled: false },
{ name: "Bhutan", value: "BT", disabled: false },
{ name: "Bolivia, Plurinational State of", value: "BO", disabled: false },
{ name: "Bonaire, Sint Eustatius and Saba", value: "BQ", disabled: false },
{ name: "Bosnia and Herzegovina", value: "BA", disabled: false },
{ name: "Botswana", value: "BW", disabled: false },
{ name: "Bouvet Island", value: "BV", disabled: false },
{ name: "Brazil", value: "BR", disabled: false },
{ name: "British Indian Ocean Territory", value: "IO", disabled: false },
{ name: "Brunei Darussalam", value: "BN", disabled: false },
{ name: "Bulgaria", value: "BG", disabled: false },
{ name: "Burkina Faso", value: "BF", disabled: false },
{ name: "Burundi", value: "BI", disabled: false },
{ name: "Cambodia", value: "KH", disabled: false },
{ name: "Cameroon", value: "CM", disabled: false },
{ name: "Cape Verde", value: "CV", disabled: false },
{ name: "Cayman Islands", value: "KY", disabled: false },
{ name: "Central African Republic", value: "CF", disabled: false },
{ name: "Chad", value: "TD", disabled: false },
{ name: "Chile", value: "CL", disabled: false },
{ name: "Christmas Island", value: "CX", disabled: false },
{ name: "Cocos (Keeling) Islands", value: "CC", disabled: false },
{ name: "Colombia", value: "CO", disabled: false },
{ name: "Comoros", value: "KM", disabled: false },
{ name: "Congo", value: "CG", disabled: false },
{ name: "Congo, the Democratic Republic of the", value: "CD", disabled: false },
{ name: "Cook Islands", value: "CK", disabled: false },
{ name: "Costa Rica", value: "CR", disabled: false },
{ name: "Côte d'Ivoire", value: "CI", disabled: false },
{ name: "Croatia", value: "HR", disabled: false },
{ name: "Cuba", value: "CU", disabled: false },
{ name: "Curaçao", value: "CW", disabled: false },
{ name: "Cyprus", value: "CY", disabled: false },
{ name: "Czech Republic", value: "CZ", disabled: false },
{ name: "Denmark", value: "DK", disabled: false },
{ name: "Djibouti", value: "DJ", disabled: false },
{ name: "Dominica", value: "DM", disabled: false },
{ name: "Dominican Republic", value: "DO", disabled: false },
{ name: "Ecuador", value: "EC", disabled: false },
{ name: "Egypt", value: "EG", disabled: false },
{ name: "El Salvador", value: "SV", disabled: false },
{ name: "Equatorial Guinea", value: "GQ", disabled: false },
{ name: "Eritrea", value: "ER", disabled: false },
{ name: "Estonia", value: "EE", disabled: false },
{ name: "Ethiopia", value: "ET", disabled: false },
{ name: "Falkland Islands (Malvinas)", value: "FK", disabled: false },
{ name: "Faroe Islands", value: "FO", disabled: false },
{ name: "Fiji", value: "FJ", disabled: false },
{ name: "Finland", value: "FI", disabled: false },
{ name: "French Guiana", value: "GF", disabled: false },
{ name: "French Polynesia", value: "PF", disabled: false },
{ name: "French Southern Territories", value: "TF", disabled: false },
{ name: "Gabon", value: "GA", disabled: false },
{ name: "Gambia", value: "GM", disabled: false },
{ name: "Georgia", value: "GE", disabled: false },
{ name: "Ghana", value: "GH", disabled: false },
{ name: "Gibraltar", value: "GI", disabled: false },
{ name: "Greece", value: "GR", disabled: false },
{ name: "Greenland", value: "GL", disabled: false },
{ name: "Grenada", value: "GD", disabled: false },
{ name: "Guadeloupe", value: "GP", disabled: false },
{ name: "Guam", value: "GU", disabled: false },
{ name: "Guatemala", value: "GT", disabled: false },
{ name: "Guernsey", value: "GG", disabled: false },
{ name: "Guinea", value: "GN", disabled: false },
{ name: "Guinea-Bissau", value: "GW", disabled: false },
{ name: "Guyana", value: "GY", disabled: false },
{ name: "Haiti", value: "HT", disabled: false },
{ name: "Heard Island and McDonald Islands", value: "HM", disabled: false },
{ name: "Holy See (Vatican City State)", value: "VA", disabled: false },
{ name: "Honduras", value: "HN", disabled: false },
{ name: "Hong Kong", value: "HK", disabled: false },
{ name: "Hungary", value: "HU", disabled: false },
{ name: "Iceland", value: "IS", disabled: false },
{ name: "Indonesia", value: "ID", disabled: false },
{ name: "Iran, Islamic Republic of", value: "IR", disabled: false },
{ name: "Iraq", value: "IQ", disabled: false },
{ name: "Ireland", value: "IE", disabled: false },
{ name: "Isle of Man", value: "IM", disabled: false },
{ name: "Israel", value: "IL", disabled: false },
{ name: "Italy", value: "IT", disabled: false },
{ name: "Jamaica", value: "JM", disabled: false },
{ name: "Japan", value: "JP", disabled: false },
{ name: "Jersey", value: "JE", disabled: false },
{ name: "Jordan", value: "JO", disabled: false },
{ name: "Kazakhstan", value: "KZ", disabled: false },
{ name: "Kenya", value: "KE", disabled: false },
{ name: "Kiribati", value: "KI", disabled: false },
{ name: "Korea, Democratic People's Republic of", value: "KP", disabled: false },
{ name: "Korea, Republic of", value: "KR", disabled: false },
{ name: "Kuwait", value: "KW", disabled: false },
{ name: "Kyrgyzstan", value: "KG", disabled: false },
{ name: "Lao People's Democratic Republic", value: "LA", disabled: false },
{ name: "Latvia", value: "LV", disabled: false },
{ name: "Lebanon", value: "LB", disabled: false },
{ name: "Lesotho", value: "LS", disabled: false },
{ name: "Liberia", value: "LR", disabled: false },
{ name: "Libya", value: "LY", disabled: false },
{ name: "Liechtenstein", value: "LI", disabled: false },
{ name: "Lithuania", value: "LT", disabled: false },
{ name: "Luxembourg", value: "LU", disabled: false },
{ name: "Macao", value: "MO", disabled: false },
{ name: "Macedonia, the former Yugoslav Republic of", value: "MK", disabled: false },
{ name: "Madagascar", value: "MG", disabled: false },
{ name: "Malawi", value: "MW", disabled: false },
{ name: "Malaysia", value: "MY", disabled: false },
{ name: "Maldives", value: "MV", disabled: false },
{ name: "Mali", value: "ML", disabled: false },
{ name: "Malta", value: "MT", disabled: false },
{ name: "Marshall Islands", value: "MH", disabled: false },
{ name: "Martinique", value: "MQ", disabled: false },
{ name: "Mauritania", value: "MR", disabled: false },
{ name: "Mauritius", value: "MU", disabled: false },
{ name: "Mayotte", value: "YT", disabled: false },
{ name: "Mexico", value: "MX", disabled: false },
{ name: "Micronesia, Federated States of", value: "FM", disabled: false },
{ name: "Moldova, Republic of", value: "MD", disabled: false },
{ name: "Monaco", value: "MC", disabled: false },
{ name: "Mongolia", value: "MN", disabled: false },
{ name: "Montenegro", value: "ME", disabled: false },
{ name: "Montserrat", value: "MS", disabled: false },
{ name: "Morocco", value: "MA", disabled: false },
{ name: "Mozambique", value: "MZ", disabled: false },
{ name: "Myanmar", value: "MM", disabled: false },
{ name: "Namibia", value: "NA", disabled: false },
{ name: "Nauru", value: "NR", disabled: false },
{ name: "Nepal", value: "NP", disabled: false },
{ name: "Netherlands", value: "NL", disabled: false },
{ name: "New Caledonia", value: "NC", disabled: false },
{ name: "New Zealand", value: "NZ", disabled: false },
{ name: "Nicaragua", value: "NI", disabled: false },
{ name: "Niger", value: "NE", disabled: false },
{ name: "Nigeria", value: "NG", disabled: false },
{ name: "Niue", value: "NU", disabled: false },
{ name: "Norfolk Island", value: "NF", disabled: false },
{ name: "Northern Mariana Islands", value: "MP", disabled: false },
{ name: "Norway", value: "NO", disabled: false },
{ name: "Oman", value: "OM", disabled: false },
{ name: "Pakistan", value: "PK", disabled: false },
{ name: "Palau", value: "PW", disabled: false },
{ name: "Palestinian Territory, Occupied", value: "PS", disabled: false },
{ name: "Panama", value: "PA", disabled: false },
{ name: "Papua New Guinea", value: "PG", disabled: false },
{ name: "Paraguay", value: "PY", disabled: false },
{ name: "Peru", value: "PE", disabled: false },
{ name: "Philippines", value: "PH", disabled: false },
{ name: "Pitcairn", value: "PN", disabled: false },
{ name: "Poland", value: "PL", disabled: false },
{ name: "Portugal", value: "PT", disabled: false },
{ name: "Puerto Rico", value: "PR", disabled: false },
{ name: "Qatar", value: "QA", disabled: false },
{ name: "Réunion", value: "RE", disabled: false },
{ name: "Romania", value: "RO", disabled: false },
{ name: "Russian Federation", value: "RU", disabled: false },
{ name: "Rwanda", value: "RW", disabled: false },
{ name: "Saint Barthélemy", value: "BL", disabled: false },
{ name: "Saint Helena, Ascension and Tristan da Cunha", value: "SH", disabled: false },
{ name: "Saint Kitts and Nevis", value: "KN", disabled: false },
{ name: "Saint Lucia", value: "LC", disabled: false },
{ name: "Saint Martin (French part)", value: "MF", disabled: false },
{ name: "Saint Pierre and Miquelon", value: "PM", disabled: false },
{ name: "Saint Vincent and the Grenadines", value: "VC", disabled: false },
{ name: "Samoa", value: "WS", disabled: false },
{ name: "San Marino", value: "SM", disabled: false },
{ name: "Sao Tome and Principe", value: "ST", disabled: false },
{ name: "Saudi Arabia", value: "SA", disabled: false },
{ name: "Senegal", value: "SN", disabled: false },
{ name: "Serbia", value: "RS", disabled: false },
{ name: "Seychelles", value: "SC", disabled: false },
{ name: "Sierra Leone", value: "SL", disabled: false },
{ name: "Singapore", value: "SG", disabled: false },
{ name: "Sint Maarten (Dutch part)", value: "SX", disabled: false },
{ name: "Slovakia", value: "SK", disabled: false },
{ name: "Slovenia", value: "SI", disabled: false },
{ name: "Solomon Islands", value: "SB", disabled: false },
{ name: "Somalia", value: "SO", disabled: false },
{ name: "South Africa", value: "ZA", disabled: false },
{ name: "South Georgia and the South Sandwich Islands", value: "GS", disabled: false },
{ name: "South Sudan", value: "SS", disabled: false },
{ name: "Spain", value: "ES", disabled: false },
{ name: "Sri Lanka", value: "LK", disabled: false },
{ name: "Sudan", value: "SD", disabled: false },
{ name: "Suriname", value: "SR", disabled: false },
{ name: "Svalbard and Jan Mayen", value: "SJ", disabled: false },
{ name: "Swaziland", value: "SZ", disabled: false },
{ name: "Sweden", value: "SE", disabled: false },
{ name: "Switzerland", value: "CH", disabled: false },
{ name: "Syrian Arab Republic", value: "SY", disabled: false },
{ name: "Taiwan", value: "TW", disabled: false },
{ name: "Tajikistan", value: "TJ", disabled: false },
{ name: "Tanzania, United Republic of", value: "TZ", disabled: false },
{ name: "Thailand", value: "TH", disabled: false },
{ name: "Timor-Leste", value: "TL", disabled: false },
{ name: "Togo", value: "TG", disabled: false },
{ name: "Tokelau", value: "TK", disabled: false },
{ name: "Tonga", value: "TO", disabled: false },
{ name: "Trinidad and Tobago", value: "TT", disabled: false },
{ name: "Tunisia", value: "TN", disabled: false },
{ name: "Turkey", value: "TR", disabled: false },
{ name: "Turkmenistan", value: "TM", disabled: false },
{ name: "Turks and Caicos Islands", value: "TC", disabled: false },
{ name: "Tuvalu", value: "TV", disabled: false },
{ name: "Uganda", value: "UG", disabled: false },
{ name: "Ukraine", value: "UA", disabled: false },
{ name: "United Arab Emirates", value: "AE", disabled: false },
{ name: "United States Minor Outlying Islands", value: "UM", disabled: false },
{ name: "Uruguay", value: "UY", disabled: false },
{ name: "Uzbekistan", value: "UZ", disabled: false },
{ name: "Vanuatu", value: "VU", disabled: false },
{ name: "Venezuela, Bolivarian Republic of", value: "VE", disabled: false },
{ name: "Viet Nam", value: "VN", disabled: false },
{ name: "Virgin Islands, British", value: "VG", disabled: false },
{ name: "Virgin Islands, U.S.", value: "VI", disabled: false },
{ name: "Wallis and Futuna", value: "WF", disabled: false },
{ name: "Western Sahara", value: "EH", disabled: false },
{ name: "Yemen", value: "YE", disabled: false },
{ name: "Zambia", value: "ZM", disabled: false },
{ name: "Zimbabwe", value: "ZW", disabled: false },
];
}
async isCountrySupported(country: string): Promise<boolean> {
const response = await this.apiService.send(
"GET",
"/tax/is-country-supported?country=" + country,
null,
true,
true,
);
return response;
}
async previewIndividualInvoice(
request: PreviewIndividualInvoiceRequest,
): Promise<PreviewInvoiceResponse> {
const response = await this.apiService.send(
"POST",
"/accounts/billing/preview-invoice",
request,
true,
true,
);
return new PreviewInvoiceResponse(response);
}
async previewOrganizationInvoice(
request: PreviewOrganizationInvoiceRequest,
): Promise<PreviewInvoiceResponse> {
const response = await this.apiService.send(
"POST",
`/invoices/preview-organization`,
request,
true,
true,
);
return new PreviewInvoiceResponse(response);
}
async previewTaxAmountForOrganizationTrial(
request: PreviewTaxAmountForOrganizationTrialRequest,
): Promise<number> {
const response = await this.apiService.send(
"POST",
"/tax/preview-amount/organization-trial",
request,
true,
true,
);
return response as number;
}
}

View File

@@ -23,7 +23,6 @@ export enum FeatureFlag {
/* Billing */
TrialPaymentOptional = "PM-8163-trial-payment",
PM17772_AdminInitiatedSponsorships = "pm-17772-admin-initiated-sponsorships",
PM21881_ManagePaymentDetailsOutsideCheckout = "pm-21881-manage-payment-details-outside-checkout",
PM21821_ProviderPortalTakeover = "pm-21821-provider-portal-takeover",
PM22415_TaxIDWarnings = "pm-22415-tax-id-warnings",
@@ -100,7 +99,6 @@ export const DefaultFeatureFlagValue = {
/* Billing */
[FeatureFlag.TrialPaymentOptional]: FALSE,
[FeatureFlag.PM17772_AdminInitiatedSponsorships]: FALSE,
[FeatureFlag.PM21881_ManagePaymentDetailsOutsideCheckout]: FALSE,
[FeatureFlag.PM21821_ProviderPortalTakeover]: FALSE,
[FeatureFlag.PM22415_TaxIDWarnings]: FALSE,

View File

@@ -90,14 +90,10 @@ import {
} from "../auth/models/response/two-factor-web-authn.response";
import { TwoFactorYubiKeyResponse } from "../auth/models/response/two-factor-yubi-key.response";
import { BitPayInvoiceRequest } from "../billing/models/request/bit-pay-invoice.request";
import { PaymentRequest } from "../billing/models/request/payment.request";
import { TaxInfoUpdateRequest } from "../billing/models/request/tax-info-update.request";
import { BillingHistoryResponse } from "../billing/models/response/billing-history.response";
import { BillingPaymentResponse } from "../billing/models/response/billing-payment.response";
import { PaymentResponse } from "../billing/models/response/payment.response";
import { PlanResponse } from "../billing/models/response/plan.response";
import { SubscriptionResponse } from "../billing/models/response/subscription.response";
import { TaxInfoResponse } from "../billing/models/response/tax-info.response";
import { ClientType, DeviceType } from "../enums";
import { KeyConnectorUserKeyRequest } from "../key-management/key-connector/models/key-connector-user-key.request";
import { SetKeyConnectorKeyRequest } from "../key-management/key-connector/models/set-key-connector-key.request";
@@ -294,11 +290,6 @@ export class ApiService implements ApiServiceAbstraction {
return new SubscriptionResponse(r);
}
async getTaxInfo(): Promise<TaxInfoResponse> {
const r = await this.send("GET", "/accounts/tax", null, true, true);
return new TaxInfoResponse(r);
}
async putProfile(request: UpdateProfileRequest): Promise<ProfileResponse> {
const r = await this.send("PUT", "/accounts/profile", request, true, true);
return new ProfileResponse(r);
@@ -309,10 +300,6 @@ export class ApiService implements ApiServiceAbstraction {
return new ProfileResponse(r);
}
putTaxInfo(request: TaxInfoUpdateRequest): Promise<any> {
return this.send("PUT", "/accounts/tax", request, true, false);
}
async postPrelogin(request: PreloginRequest): Promise<PreloginResponse> {
const env = await firstValueFrom(this.environmentService.environment$);
const r = await this.send(
@@ -365,10 +352,6 @@ export class ApiService implements ApiServiceAbstraction {
return new PaymentResponse(r);
}
postAccountPayment(request: PaymentRequest): Promise<void> {
return this.send("POST", "/accounts/payment", request, true, false);
}
postAccountLicense(data: FormData): Promise<any> {
return this.send("POST", "/accounts/license", data, true, false);
}
@@ -429,11 +412,6 @@ export class ApiService implements ApiServiceAbstraction {
return new BillingHistoryResponse(r);
}
async getUserBillingPayment(): Promise<BillingPaymentResponse> {
const r = await this.send("GET", "/accounts/billing/payment-method", null, true, true);
return new BillingPaymentResponse(r);
}
// Cipher APIs
async getCipher(id: string): Promise<CipherResponse> {