提问人:T M 提问时间:11/16/2023 更新时间:11/16/2023 访问量:34
根据我在应用程序中使用的设计模式,如何实现 PayPal 结帐按钮?
How do I implement a paypal checkout button, given the design patterns that I used in my application?
问:
我遵循了一个很长的教程,并使用 turorial 中的设计模式并排构建了我的应用程序。我现在被困住了,因为我不知道如何在我正在使用的方案中实现PayPal。我使用 rxjs 和 observables 来构建应用程序,诚然我不太了解它们。对不起,如果这是模糊的,我不;不知道还能做什么。PayPal的实现如下...
这是我不明白如何实现的代码。
TS 文件
export class DeposittestComponent implements OnInit {
PAYPAL_CLIENT_ID: string = '##################';
myAmount: any
@ViewChild('paypalRef', { static: true }) private paypalRef!: ElementRef;
ngOnInit(): void {
this.renderPaypalButton();
}
renderPaypalButton() {
let orderRef: string | null = null;
loadScript({ "clientId": this.PAYPAL_CLIENT_ID, currency: 'USD' })
.then((loadedPaypal) => {
if (loadedPaypal) {
const paypal: PayPalNamespace = loadedPaypal;
paypal.Buttons({
style: {
layout: 'vertical',
color: 'blue',
shape: 'rect',
label: 'paypal',
},
createOrder: (data, actions) => {
const postData = {
amount: this.myAmount
};
return fetch(AppSettings.API_ENDPOINT + '/user/create_paypal_transaction', {
method: "post",
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify(postData)
})
.then((response) => response.json())
.then((response) => {
orderRef = response.orderRef;
return response.id;
});
},
onApprove: (data, actions) => {
return fetch(AppSettings.API_ENDPOINT + `/user/orders/${data.orderID}/capture`, {
method: "post",
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json',
},
})
.then((response) => response.json())
.then((orderData) => {
const errorDetail = Array.isArray(orderData.details) && orderData.details[0];
if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
return actions.restart();
}
const transaction = orderData.purchase_units[0].payments.captures[0];
this.paypalRedirect(transaction.status, orderRef);
});
},
onCancel: () => {
//
},
onError: (err) => {
this.paypalRedirect('ERROR', orderRef);
}
}).render(this.paypalRef.nativeElement);
} else {
console.error("");
}
})
.catch((error) => {
console.error("", error);
});
}
paypalRedirect(status: string, orderRef: string | null) {
switch (status) {
case 'COMPLETED':
if (orderRef) {
//this.router.navigate(\['/result/success/' + orderRef\]);
} else {
console.error("");
}
break;
case 'ERROR':
if (orderRef) {
//this.router.navigate(\['/result/error/' + orderRef\]);
} else {
console.error("");
}
break;
default:
console.error("");
break;
}
}
[HTML全文]
<div class="form-group">
<label>Amount</label>
<input type="text" ngModel name="myAmount" (ngModelChange)="myAmount=$event"
value="${{myAmount | number: '.2-2'}}" class="form-control">
</div>
<div #paypalRef></div>
这是我在应用程序中所做的所有其他事情的设计模式。
TS型
export class NewGameAccountComponent implements OnInit {
newGameAccountState$: Observable<State<CustomHttpResponse<any>>>;
private dataSubject = new BehaviorSubject<CustomHttpResponse<any>>(null);
private isLoadingSubject = new BehaviorSubject<boolean>(false);
isLoading$ = this.isLoadingSubject.asObservable();
readonly DataState = DataState;
constructor(private gameAccountsService: GameAccountsService) { }
ngOnInit(): void {
this.newGameAccountState$ = this.gameAccountsService.activeGameAccounts$()
.pipe(
map(response => {
console.log(response);
this.dataSubject.next(response);
return { dataState: DataState.LOADED, appData: response };
}),
startWith({ dataState: DataState.LOADING }),
catchError((error: string) => {
return of({ dataState: DataState.ERROR, error })
})
)
}
createNewGameAccount(newGameAccountForm: NgForm): void {
this.isLoadingSubject.next(true);
this.newGameAccountState$ = this.gameAccountsService.newGameAccount$(newGameAccountForm.value)
.pipe(
map(response => {
console.log(response);
newGameAccountForm.reset({});
this.isLoadingSubject.next(false);
return { dataState: DataState.LOADED, appData: this.dataSubject.value };
}),
startWith({ dataState: DataState.LOADED, appData: this.dataSubject.value }),
catchError((error: string) => {
this.isLoadingSubject.next(false);
return of({ dataState: DataState.LOADED, error })
})
)
}
}
[HTML全文]
<ng-container *ngIf="(newGameAccountState$ | async) as state" [ngSwitch]="state.dataState">
<ng-container *ngSwitchCase="DataState.LOADED">
<app-navbar [user]="state?.appData?.data?.user"></app-navbar>
<section>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<div class="text-center">
<h2><i style="margin-right: 5px;" class="bi bi-person-plus-fill"></i> New Game
Account
</h2>
</div>
<form #newGameAccountForm="ngForm"
(ngSubmit)="createNewGameAccount(newGameAccountForm)">
///LOTS OF INPUTS FOR FORM
<button
[disabled]="state.dataState === DataState.LOADING || newGameAccountForm.invalid || newGameAccountForm.pristine|| (isLoading$ | async)"
type="submit" class="btn btn-primary mt-5">
<span *ngIf="isLoading$ | async" class="spinner-border spinner-border-sm"
role="status" aria-hidden="true" style="margin-right: 5px;"></span>
<span *ngIf="isLoading$ | async">Saving...</span>
<span *ngIf="!(isLoading$ | async)">Save Game Account</span>
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
</ng-container>
</ng-container>
服务
export class GameAccountsService {
private readonly server: string = AppSettings.API_ENDPOINT;
constructor(private http: HttpClient) { }
activeGameAccounts$ = () => <Observable<CustomHttpResponse<User & GameAccount>>>
this.http.get<CustomHttpResponse<User & GameAccount>>
(`${this.server}/user/game_accounts/list_active`)
.pipe(
tap(console.log),
catchError(this.handleError)
);
newGameAccount$ = (gameAccount: GameAccount) => <Observable<CustomHttpResponse<User & GameAccount>>>
this.http.post<CustomHttpResponse<User & GameAccount>>
(`${this.server}/user/game_account/create`, gameAccount)
.pipe(
tap(console.log),
catchError(this.handleError)
);
}
拦截 器
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
private isTokenRefreshing: boolean = false;
private refreshTokenSubject: BehaviorSubject<CustomHttpResponse<Profile>> = new BehaviorSubject(null);
constructor(private userService: UserService) {}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> | Observable<HttpResponse<unknown>>{
if(request.url.includes('verify') || request.url.includes('login') || request.url.includes('register')
|| request.url.includes('refresh') || request.url.includes('resetpassword')|| request.url.includes('reset_password')) {
return next.handle(request);
}
return next.handle(this.addAuthorizationTokenHeader(request, localStorage.getItem(Key.TOKEN)))
.pipe(
catchError((error: HttpErrorResponse) => {
if(error instanceof HttpErrorResponse && error.status === 401 && error.error.reason.includes('expired')) {
return this.handleRefreshToken(request, next);
} else {
return throwError(() => error);
}
})
);
}
有人可以帮帮我吗?简单的事情,比如在使用我使用的模式时甚至让 PayPal 按钮加载,我都逃避了。感谢您的阅读
答: 暂无答案
评论