mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-28 17:27:50 +01:00
handleCardPayment for incomplete payments
This commit is contained in:
parent
18608a8b63
commit
a4571a2617
2
jslib
2
jslib
@ -1 +1 @@
|
||||
Subproject commit 393f6c9c20fb7eded5008b65242ea44e69bc349c
|
||||
Subproject commit e28e820286870df0111bd4feb8a219a3ae360ba7
|
@ -203,6 +203,9 @@
|
||||
<h2 class="spaced-header mb-4">{{'paymentInformation' | i18n}}</h2>
|
||||
<app-payment [hideCredit]="true"></app-payment>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!createOrganization">
|
||||
<app-payment [showMethods]="false"></app-payment>
|
||||
</ng-container>
|
||||
<small class="text-muted font-italic mt-2 d-block" *ngIf="!createOrganization">
|
||||
{{'paymentCharged' | i18n : (interval | i18n) }}</small>
|
||||
</ng-container>
|
||||
|
@ -169,7 +169,10 @@ export class OrganizationPlansComponent {
|
||||
} else {
|
||||
request.planType = this.plans[this.plan].annualPlanType;
|
||||
}
|
||||
await this.apiService.postOrganizationUpgrade(this.organizationId, request);
|
||||
const result = await this.apiService.postOrganizationUpgrade(this.organizationId, request);
|
||||
if (!result.success && result.paymentIntentClientSecret != null) {
|
||||
await this.paymentComponent.handleStripeCardPayment(result.paymentIntentClientSecret, null);
|
||||
}
|
||||
orgId = this.organizationId;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div class="mb-4 text-lg" *ngIf="showOptions">
|
||||
<div class="mb-4 text-lg" *ngIf="showOptions && showMethods">
|
||||
<div class="form-check form-check-inline mr-4">
|
||||
<input class="form-check-input" type="radio" name="Method" id="method-card" [value]="paymentMethodType.Card"
|
||||
[(ngModel)]="method" (change)="changeMethod()">
|
||||
@ -24,7 +24,7 @@
|
||||
<i class="fa fa-fw fa-dollar"></i> {{'accountCredit' | i18n}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<ng-container *ngIf="method === paymentMethodType.Card">
|
||||
<ng-container *ngIf="showMethods && method === paymentMethodType.Card">
|
||||
<div class="row">
|
||||
<div class="form-group col-4">
|
||||
<label for="stripe-card-number-element">{{'number' | i18n}}</label>
|
||||
@ -50,7 +50,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="method === paymentMethodType.BankAccount">
|
||||
<ng-container *ngIf="showMethods && method === paymentMethodType.BankAccount">
|
||||
<app-callout type="warning" title="{{'verifyBankAccount' | i18n}}">
|
||||
{{'verifyBankAccountInitialDesc' | i18n}} {{'verifyBankAccountFailureWarning' | i18n}}
|
||||
</app-callout>
|
||||
@ -81,13 +81,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="method === paymentMethodType.PayPal">
|
||||
<ng-container *ngIf="showMethods && method === paymentMethodType.PayPal">
|
||||
<div class="mb-3">
|
||||
<div id="bt-dropin-container" class="mb-1"></div>
|
||||
<small class="text-muted">{{'paypalClickSubmit' | i18n}}</small>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="method === paymentMethodType.Credit">
|
||||
<ng-container *ngIf="showMethods && method === paymentMethodType.Credit">
|
||||
<app-callout type="note">
|
||||
{{'makeSureEnoughCredit' | i18n}}
|
||||
</app-callout>
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
|
||||
import { PaymentMethodType } from 'jslib/enums/paymentMethodType';
|
||||
|
||||
import { ApiService } from 'jslib/abstractions/api.service';
|
||||
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
|
||||
|
||||
import { WebConstants } from '../../services/webConstants';
|
||||
@ -34,6 +35,7 @@ const StripeElementClasses = {
|
||||
templateUrl: 'payment.component.html',
|
||||
})
|
||||
export class PaymentComponent implements OnInit {
|
||||
@Input() showMethods = true;
|
||||
@Input() showOptions = true;
|
||||
@Input() method = PaymentMethodType.Card;
|
||||
@Input() hideBank = false;
|
||||
@ -60,7 +62,7 @@ export class PaymentComponent implements OnInit {
|
||||
private stripeCardExpiryElement: any = null;
|
||||
private stripeCardCvcElement: any = null;
|
||||
|
||||
constructor(private platformUtilsService: PlatformUtilsService) {
|
||||
constructor(private platformUtilsService: PlatformUtilsService, private apiService: ApiService) {
|
||||
this.stripeScript = window.document.createElement('script');
|
||||
this.stripeScript.src = 'https://js.stripe.com/v3/';
|
||||
this.stripeScript.async = true;
|
||||
@ -162,30 +164,60 @@ export class PaymentComponent implements OnInit {
|
||||
reject(err.message);
|
||||
});
|
||||
} else if (this.method === PaymentMethodType.Card || this.method === PaymentMethodType.BankAccount) {
|
||||
let sourceObj: any = null;
|
||||
let createObj: any = null;
|
||||
if (this.method === PaymentMethodType.Card) {
|
||||
sourceObj = this.stripeCardNumberElement;
|
||||
this.apiService.postSetupPayment().then((clientSecret) =>
|
||||
this.stripe.handleCardSetup(clientSecret, this.stripeCardNumberElement))
|
||||
.then((result: any) => {
|
||||
if (result.error) {
|
||||
reject(result.error.message);
|
||||
} else if (result.setupIntent && result.setupIntent.status === 'succeeded') {
|
||||
resolve([result.setupIntent.payment_method, this.method]);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
sourceObj = 'bank_account';
|
||||
createObj = this.bank;
|
||||
this.stripe.createToken('bank_account', this.bank).then((result: any) => {
|
||||
if (result.error) {
|
||||
reject(result.error.message);
|
||||
} else if (result.token && result.token.id != null) {
|
||||
resolve([result.token.id, this.method]);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
}
|
||||
this.stripe.createToken(sourceObj, createObj).then((result: any) => {
|
||||
if (result.error) {
|
||||
reject(result.error.message);
|
||||
} else if (result.token && result.token.id != null) {
|
||||
resolve([result.token.id, this.method]);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
handleStripeCardPayment(clientSecret: string, successCallback: () => Promise<any>): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.showMethods && this.stripeCardNumberElement == null) {
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
const handleCardPayment = () => this.showMethods ?
|
||||
this.stripe.handleCardPayment(clientSecret, this.stripeCardNumberElement) :
|
||||
this.stripe.handleCardPayment(clientSecret);
|
||||
return handleCardPayment().then(async (result: any) => {
|
||||
if (result.error) {
|
||||
reject(result.error.message);
|
||||
} else if (result.paymentIntent && result.paymentIntent.status === 'succeeded') {
|
||||
if (successCallback != null) {
|
||||
await successCallback();
|
||||
}
|
||||
resolve();
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private setStripeElement() {
|
||||
window.setTimeout(() => {
|
||||
if (this.method === PaymentMethodType.Card) {
|
||||
if (this.showMethods && this.method === PaymentMethodType.Card) {
|
||||
if (this.stripeCardNumberElement == null) {
|
||||
this.stripeCardNumberElement = this.stripeElements.create('cardNumber', {
|
||||
style: StripeElementStyle,
|
||||
|
@ -84,8 +84,13 @@ export class PremiumComponent implements OnInit {
|
||||
}
|
||||
fd.append('additionalStorageGb', (this.additionalStorage || 0).toString());
|
||||
return this.apiService.postPremium(fd);
|
||||
}).then(() => {
|
||||
return this.finalizePremium();
|
||||
}).then((paymentResponse) => {
|
||||
if (!paymentResponse.success && paymentResponse.paymentIntentClientSecret != null) {
|
||||
return this.paymentComponent.handleStripeCardPayment(paymentResponse.paymentIntentClientSecret,
|
||||
() => this.finalizePremium());
|
||||
} else {
|
||||
return this.finalizePremium();
|
||||
}
|
||||
});
|
||||
}
|
||||
await this.formPromise;
|
||||
|
Loading…
Reference in New Issue
Block a user