Merge pull request #5436 from mempool/nymkappa/fix-bitcoin-payment
[btcpay] better handling for invoice expiration
This commit is contained in:
commit
edf7798587
@ -10,6 +10,10 @@
|
|||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<app-mempool-error *ngIf="paymentErrorMessage" [error]="paymentErrorMessage"></app-mempool-error>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div *ngIf="paymentStatus === 2">
|
<div *ngIf="paymentStatus === 2">
|
||||||
|
|
||||||
<form [formGroup]="paymentForm">
|
<form [formGroup]="paymentForm">
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
|
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { Subscription, of, catchError } from 'rxjs';
|
||||||
import { Subscription, of, timer } from 'rxjs';
|
import { retry, tap } from 'rxjs/operators';
|
||||||
import { filter, repeat, retry, switchMap, take, tap } from 'rxjs/operators';
|
|
||||||
import { ServicesApiServices } from '@app/services/services-api.service';
|
import { ServicesApiServices } from '@app/services/services-api.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -18,30 +17,17 @@ export class BitcoinInvoiceComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
@Output() completed = new EventEmitter();
|
@Output() completed = new EventEmitter();
|
||||||
|
|
||||||
paymentForm: FormGroup;
|
paymentForm: FormGroup;
|
||||||
requestSubscription: Subscription | undefined;
|
|
||||||
paymentStatusSubscription: Subscription | undefined;
|
paymentStatusSubscription: Subscription | undefined;
|
||||||
paymentStatus = 1; // 1 - Waiting for invoice | 2 - Pending payment | 3 - Payment completed
|
paymentStatus = 1; // 1 - Waiting for invoice | 2 - Pending payment | 3 - Payment completed
|
||||||
paramMapSubscription: Subscription | undefined;
|
paymentErrorMessage: string = '';
|
||||||
invoiceSubscription: Subscription | undefined;
|
|
||||||
invoiceTimeout; // Wait for angular to load all the things before making a request
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private apiService: ServicesApiServices,
|
private apiService: ServicesApiServices,
|
||||||
private sanitizer: DomSanitizer,
|
private sanitizer: DomSanitizer
|
||||||
private activatedRoute: ActivatedRoute
|
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
if (this.requestSubscription) {
|
|
||||||
this.requestSubscription.unsubscribe();
|
|
||||||
}
|
|
||||||
if (this.paramMapSubscription) {
|
|
||||||
this.paramMapSubscription.unsubscribe();
|
|
||||||
}
|
|
||||||
if (this.invoiceSubscription) {
|
|
||||||
this.invoiceSubscription.unsubscribe();
|
|
||||||
}
|
|
||||||
if (this.paymentStatusSubscription) {
|
if (this.paymentStatusSubscription) {
|
||||||
this.paymentStatusSubscription.unsubscribe();
|
this.paymentStatusSubscription.unsubscribe();
|
||||||
}
|
}
|
||||||
@ -72,15 +58,39 @@ export class BitcoinInvoiceComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
} else {
|
} else {
|
||||||
this.paymentStatus = 4;
|
this.paymentStatus = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.monitorPendingInvoice();
|
||||||
|
}
|
||||||
|
|
||||||
|
monitorPendingInvoice(): void {
|
||||||
|
if (!this.invoice) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.paymentStatusSubscription) {
|
||||||
|
this.paymentStatusSubscription.unsubscribe();
|
||||||
|
}
|
||||||
this.paymentStatusSubscription = this.apiService.getPaymentStatus$(this.invoice.btcpayInvoiceId).pipe(
|
this.paymentStatusSubscription = this.apiService.getPaymentStatus$(this.invoice.btcpayInvoiceId).pipe(
|
||||||
retry({ delay: () => timer(2000)}),
|
tap(result => {
|
||||||
repeat({delay: 2000}),
|
if (result.status === 204) { // Manually trigger an error in that case so we can retry
|
||||||
filter((response) => response.status !== 204 && response.status !== 404),
|
throw result;
|
||||||
take(1),
|
} else if (result.status === 200) { // Invoice settled
|
||||||
).subscribe(() => {
|
|
||||||
this.paymentStatus = 3;
|
this.paymentStatus = 3;
|
||||||
this.completed.emit();
|
this.completed.emit();
|
||||||
});
|
}
|
||||||
|
}),
|
||||||
|
catchError(err => {
|
||||||
|
if (err.status === 204 || err.status === 504) {
|
||||||
|
throw err; // Will trigger the retry
|
||||||
|
} else if (err.status === 400) {
|
||||||
|
this.paymentErrorMessage = 'Invoice has expired';
|
||||||
|
} else if (err.status === 404) {
|
||||||
|
this.paymentErrorMessage = 'Invoice is no longer valid';
|
||||||
|
}
|
||||||
|
this.paymentStatus = -1;
|
||||||
|
return of(null);
|
||||||
|
}),
|
||||||
|
retry({ delay: 1000 }),
|
||||||
|
).subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
get availableMethods(): string[] {
|
get availableMethods(): string[] {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user