From 4fa31b8f2b2f34aefd943873a71731355df3d04c Mon Sep 17 00:00:00 2001
From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com>
Date: Wed, 11 Sep 2024 09:48:22 -0400
Subject: [PATCH] Use payment-v2.component in change-plan-dialog.component when
FF is on (#10976)
---
.../change-plan-dialog.component.html | 9 ++-
.../change-plan-dialog.component.ts | 70 +++++++++++++++----
.../shared/payment/payment-v2.component.ts | 2 +-
3 files changed, 66 insertions(+), 15 deletions(-)
diff --git a/apps/web/src/app/billing/organizations/change-plan-dialog.component.html b/apps/web/src/app/billing/organizations/change-plan-dialog.component.html
index 1c92cbf663..c893f3832d 100644
--- a/apps/web/src/app/billing/organizations/change-plan-dialog.component.html
+++ b/apps/web/src/app/billing/organizations/change-plan-dialog.component.html
@@ -62,7 +62,7 @@
class="tw-px-2 tw-py-4"
[ngClass]="{
'tw-py-1': !(selectableProduct === selectedPlan),
- 'tw-py-0': selectableProduct === selectedPlan,
+ 'tw-py-0': selectableProduct === selectedPlan
}"
>
@@ -308,9 +308,14 @@
+
+
();
constructor(
@@ -171,9 +179,15 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
private messagingService: MessagingService,
private formBuilder: FormBuilder,
private organizationApiService: OrganizationApiServiceAbstraction,
+ private configService: ConfigService,
+ private billingApiService: BillingApiServiceAbstraction,
) {}
async ngOnInit(): Promise {
+ this.deprecateStripeSourcesAPI = await this.configService.getFeatureFlag(
+ FeatureFlag.AC2476_DeprecateStripeSourcesAPI,
+ );
+
if (this.dialogParams.organizationId) {
this.currentPlanName = this.resolvePlanName(this.dialogParams.productTierType);
this.sub =
@@ -595,7 +609,16 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
}
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";
// Bank Account payments are only available for US customers
if (
@@ -616,7 +639,7 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
const doSubmit = async (): Promise => {
let orgId: string = null;
- orgId = await this.updateOrganization(orgId);
+ orgId = await this.updateOrganization();
this.toastService.showToast({
variant: "success",
title: null,
@@ -650,12 +673,15 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
this.dialogRef.close();
};
- private async updateOrganization(orgId: string) {
+ private async updateOrganization() {
const request = new OrganizationUpgradeRequest();
if (this.selectedPlan.productTier !== ProductTierType.Families) {
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 =
this.selectedPlan.PasswordManager.hasPremiumAccessOption &&
this.formGroup.controls.premiumAccessAddon.value;
@@ -669,13 +695,33 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
this.buildSecretsManagerRequest(request);
if (this.upgradeRequiresPaymentMethod || this.showPayment) {
- 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);
+ if (this.deprecateStripeSourcesAPI) {
+ const tokenizedPaymentSource = await this.paymentV2Component.tokenize();
+ const updatePaymentMethodRequest = new UpdatePaymentMethodRequest();
+ updatePaymentMethodRequest.paymentSource = tokenizedPaymentSource;
+ updatePaymentMethodRequest.taxInformation = {
+ country: this.taxComponent.country,
+ 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
diff --git a/apps/web/src/app/billing/shared/payment/payment-v2.component.ts b/apps/web/src/app/billing/shared/payment/payment-v2.component.ts
index 8d7e8d7a0c..fa2b53fc7b 100644
--- a/apps/web/src/app/billing/shared/payment/payment-v2.component.ts
+++ b/apps/web/src/app/billing/shared/payment/payment-v2.component.ts
@@ -86,7 +86,7 @@ export class PaymentV2Component implements OnInit, OnDestroy {
/** Programmatically select the provided payment method. */
select = (paymentMethod: PaymentMethodType) => {
- this.formGroup.value.paymentMethod = paymentMethod;
+ this.formGroup.get("paymentMethod").patchValue(paymentMethod);
};
protected submit = async () => {