1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-11 10:10:25 +01:00

Use payment-v2.component in change-plan-dialog.component when FF is on (#10976)

This commit is contained in:
Alex Morask 2024-09-11 09:48:22 -04:00 committed by GitHub
parent aa2a2d3ed0
commit 4fa31b8f2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 66 additions and 15 deletions

View File

@ -62,7 +62,7 @@
class="tw-px-2 tw-py-4" class="tw-px-2 tw-py-4"
[ngClass]="{ [ngClass]="{
'tw-py-1': !(selectableProduct === selectedPlan), 'tw-py-1': !(selectableProduct === selectedPlan),
'tw-py-0': selectableProduct === selectedPlan, 'tw-py-0': selectableProduct === selectedPlan
}" }"
> >
<h3 class="tw-text-lg tw-font-bold"> <h3 class="tw-text-lg tw-font-bold">
@ -308,9 +308,14 @@
<a></a> <a></a>
</p> </p>
<app-payment <app-payment
*ngIf="upgradeRequiresPaymentMethod || showPayment" *ngIf="(upgradeRequiresPaymentMethod || showPayment) && !deprecateStripeSourcesAPI"
[hideCredit]="true" [hideCredit]="true"
></app-payment> ></app-payment>
<app-payment-v2
*ngIf="(upgradeRequiresPaymentMethod || showPayment) && deprecateStripeSourcesAPI"
[showAccountCredit]="false"
>
</app-payment-v2>
<app-tax-info <app-tax-info
*ngIf="showPayment || upgradeRequiresPaymentMethod" *ngIf="showPayment || upgradeRequiresPaymentMethod"
(onCountryChanged)="changedCountry()" (onCountryChanged)="changedCountry()"

View File

@ -21,22 +21,27 @@ import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request"; import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request";
import { OrganizationUpgradeRequest } from "@bitwarden/common/admin-console/models/request/organization-upgrade.request"; import { OrganizationUpgradeRequest } from "@bitwarden/common/admin-console/models/request/organization-upgrade.request";
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions";
import { import {
PaymentMethodType, PaymentMethodType,
PlanInterval,
PlanType, PlanType,
ProductTierType, ProductTierType,
PlanInterval,
} from "@bitwarden/common/billing/enums"; } from "@bitwarden/common/billing/enums";
import { PaymentRequest } from "@bitwarden/common/billing/models/request/payment.request"; import { PaymentRequest } from "@bitwarden/common/billing/models/request/payment.request";
import { UpdatePaymentMethodRequest } from "@bitwarden/common/billing/models/request/update-payment-method.request";
import { BillingResponse } from "@bitwarden/common/billing/models/response/billing.response"; import { BillingResponse } from "@bitwarden/common/billing/models/response/billing.response";
import { OrganizationSubscriptionResponse } from "@bitwarden/common/billing/models/response/organization-subscription.response"; import { OrganizationSubscriptionResponse } from "@bitwarden/common/billing/models/response/organization-subscription.response";
import { PlanResponse } from "@bitwarden/common/billing/models/response/plan.response"; import { PlanResponse } from "@bitwarden/common/billing/models/response/plan.response";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { DialogService, ToastService } from "@bitwarden/components"; import { DialogService, ToastService } from "@bitwarden/components";
import { PaymentV2Component } from "../shared/payment/payment-v2.component";
import { PaymentComponent } from "../shared/payment/payment.component"; import { PaymentComponent } from "../shared/payment/payment.component";
import { TaxInfoComponent } from "../shared/tax-info.component"; import { TaxInfoComponent } from "../shared/tax-info.component";
@ -80,6 +85,7 @@ interface OnSuccessArgs {
}) })
export class ChangePlanDialogComponent implements OnInit, OnDestroy { export class ChangePlanDialogComponent implements OnInit, OnDestroy {
@ViewChild(PaymentComponent) paymentComponent: PaymentComponent; @ViewChild(PaymentComponent) paymentComponent: PaymentComponent;
@ViewChild(PaymentV2Component) paymentV2Component: PaymentV2Component;
@ViewChild(TaxInfoComponent) taxComponent: TaxInfoComponent; @ViewChild(TaxInfoComponent) taxComponent: TaxInfoComponent;
@Input() acceptingSponsorship = false; @Input() acceptingSponsorship = false;
@ -155,6 +161,8 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
totalOpened: boolean = false; totalOpened: boolean = false;
currentPlan: PlanResponse; currentPlan: PlanResponse;
deprecateStripeSourcesAPI: boolean;
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
constructor( constructor(
@ -171,9 +179,15 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
private messagingService: MessagingService, private messagingService: MessagingService,
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private organizationApiService: OrganizationApiServiceAbstraction, private organizationApiService: OrganizationApiServiceAbstraction,
private configService: ConfigService,
private billingApiService: BillingApiServiceAbstraction,
) {} ) {}
async ngOnInit(): Promise<void> { async ngOnInit(): Promise<void> {
this.deprecateStripeSourcesAPI = await this.configService.getFeatureFlag(
FeatureFlag.AC2476_DeprecateStripeSourcesAPI,
);
if (this.dialogParams.organizationId) { if (this.dialogParams.organizationId) {
this.currentPlanName = this.resolvePlanName(this.dialogParams.productTierType); this.currentPlanName = this.resolvePlanName(this.dialogParams.productTierType);
this.sub = this.sub =
@ -595,7 +609,16 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
} }
changedCountry() { changedCountry() {
if (this.paymentComponent && this.taxComponent) { if (this.deprecateStripeSourcesAPI && this.paymentV2Component && this.taxComponent) {
this.paymentV2Component.showBankAccount = this.taxComponent.country === "US";
if (
!this.paymentV2Component.showBankAccount &&
this.paymentV2Component.selected === PaymentMethodType.BankAccount
) {
this.paymentV2Component.select(PaymentMethodType.Card);
}
} else if (this.paymentComponent && this.taxComponent) {
this.paymentComponent!.hideBank = this.taxComponent?.taxFormGroup?.value.country !== "US"; this.paymentComponent!.hideBank = this.taxComponent?.taxFormGroup?.value.country !== "US";
// Bank Account payments are only available for US customers // Bank Account payments are only available for US customers
if ( if (
@ -616,7 +639,7 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
const doSubmit = async (): Promise<string> => { const doSubmit = async (): Promise<string> => {
let orgId: string = null; let orgId: string = null;
orgId = await this.updateOrganization(orgId); orgId = await this.updateOrganization();
this.toastService.showToast({ this.toastService.showToast({
variant: "success", variant: "success",
title: null, title: null,
@ -650,12 +673,15 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
this.dialogRef.close(); this.dialogRef.close();
}; };
private async updateOrganization(orgId: string) { private async updateOrganization() {
const request = new OrganizationUpgradeRequest(); const request = new OrganizationUpgradeRequest();
if (this.selectedPlan.productTier !== ProductTierType.Families) { if (this.selectedPlan.productTier !== ProductTierType.Families) {
request.additionalSeats = this.organization.seats; request.additionalSeats = this.organization.seats;
} }
request.additionalStorageGb = this.organization.maxStorageGb; if (this.organization.maxStorageGb > this.selectedPlan.PasswordManager.baseStorageGb) {
request.additionalStorageGb =
this.organization.maxStorageGb - this.selectedPlan.PasswordManager.baseStorageGb;
}
request.premiumAccessAddon = request.premiumAccessAddon =
this.selectedPlan.PasswordManager.hasPremiumAccessOption && this.selectedPlan.PasswordManager.hasPremiumAccessOption &&
this.formGroup.controls.premiumAccessAddon.value; this.formGroup.controls.premiumAccessAddon.value;
@ -669,13 +695,33 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
this.buildSecretsManagerRequest(request); this.buildSecretsManagerRequest(request);
if (this.upgradeRequiresPaymentMethod || this.showPayment) { if (this.upgradeRequiresPaymentMethod || this.showPayment) {
const tokenResult = await this.paymentComponent.createPaymentToken(); if (this.deprecateStripeSourcesAPI) {
const paymentRequest = new PaymentRequest(); const tokenizedPaymentSource = await this.paymentV2Component.tokenize();
paymentRequest.paymentToken = tokenResult[0]; const updatePaymentMethodRequest = new UpdatePaymentMethodRequest();
paymentRequest.paymentMethodType = tokenResult[1]; updatePaymentMethodRequest.paymentSource = tokenizedPaymentSource;
paymentRequest.country = this.taxComponent.taxFormGroup?.value.country; updatePaymentMethodRequest.taxInformation = {
paymentRequest.postalCode = this.taxComponent.taxFormGroup?.value.postalCode; country: this.taxComponent.country,
await this.organizationApiService.updatePayment(this.organizationId, paymentRequest); postalCode: this.taxComponent.postalCode,
taxId: this.taxComponent.taxId,
line1: this.taxComponent.line1,
line2: this.taxComponent.line2,
city: this.taxComponent.city,
state: this.taxComponent.state,
};
await this.billingApiService.updateOrganizationPaymentMethod(
this.organizationId,
updatePaymentMethodRequest,
);
} else {
const tokenResult = await this.paymentComponent.createPaymentToken();
const paymentRequest = new PaymentRequest();
paymentRequest.paymentToken = tokenResult[0];
paymentRequest.paymentMethodType = tokenResult[1];
paymentRequest.country = this.taxComponent.taxFormGroup?.value.country;
paymentRequest.postalCode = this.taxComponent.taxFormGroup?.value.postalCode;
await this.organizationApiService.updatePayment(this.organizationId, paymentRequest);
}
} }
// Backfill pub/priv key if necessary // Backfill pub/priv key if necessary

View File

@ -86,7 +86,7 @@ export class PaymentV2Component implements OnInit, OnDestroy {
/** Programmatically select the provided payment method. */ /** Programmatically select the provided payment method. */
select = (paymentMethod: PaymentMethodType) => { select = (paymentMethod: PaymentMethodType) => {
this.formGroup.value.paymentMethod = paymentMethod; this.formGroup.get("paymentMethod").patchValue(paymentMethod);
}; };
protected submit = async () => { protected submit = async () => {