问题描述
我们使用 stripe v.3 为客户添加信用卡。它适用于所有浏览器 chrome 和 firefox。但是 safari 返回以下错误。
参考错误:找不到变量:元素
在物理 iphone 设备上测试,似乎旧版本无法创建离开输入字段的条纹元素,块状且不显示 CC 信息。检查屏幕截图。
该错误发生在 iOS 11.3.1 及更低版本上。 iframe 显示在源元素中,但未将 .StripeElement 类添加到 dom。
import {
Component,Inject,ViewChild,ElementRef,AfterViewInit,OnDestroy,ChangeDetectorRef,} from '@angular/core';
import { NgForm } from '@angular/forms';
import { MatDialogRef,MAT_DIALOG_DATA } from '@angular/material/dialog';
import { ToastrService } from 'ngx-toastr';
import { PaymentService } from '@services/http/payment.service';
import { StateService } from '@services/Logic/state.service';
import { TranslatePipe } from '@app/pipes/translate.pipe';
@Component({
selector: 'app-add-credit-card-dialog',templateUrl: 'addCreditCard.html',styleUrls: ['addCreditCard.scss','../../dialogs.scss'],})
export class AddCreditCardDialogComponent implements AfterViewInit,OnDestroy {
@ViewChild('cardInfo',{ static: true }) cardInfo: ElementRef;
card: any;
cardHandler = this.onChange.bind(this);
error: string;
cardholderName: string;
constructor(
private cd: ChangeDetectorRef,private toastr: ToastrService,private translatePipe: TranslatePipe,private stateService: StateService,private paymentService: PaymentService,public dialogRef: MatDialogRef<AddCreditCardDialogComponent>,@Inject(MAT_DIALOG_DATA) public data: any
) {}
ngAfterViewInit() {
this.card = elements.create('card');
this.card.mount(this.cardInfo.nativeElement);
this.card.addEventListener('change',this.cardHandler);
// Force the Element frame to paint once it is visible on the page
setTimeout(() => {
this.forceReflow('.StripeElement');
},1000);
}
ngOnDestroy() {
this.card.removeEventListener('change',this.cardHandler);
this.card.destroy();
}
forceReflow(selector) {
const el = document.querySelector(selector);
if (el) {
const initialdisplay = el.style.display;
el.style.display = 'none';
el.offsetHeight;
el.style.display = initialdisplay;
}
}
onChange({ error }) {
if (error) {
this.error = error.message;
} else {
this.error = null;
}
this.cd.detectChanges();
}
async onSubmit(form: NgForm) {
if (!this.cardholderName || this.cardholderName.length === 0) {
return this.toastr.error(this.translatePipe.transform('TOAST_MESSAGES.ERROR.MISSING_CARDHOLDER'));
}
this.stateService.toggleWaitingPage(true);
// create a Setup Intent for this card
const { setupIntent,error } = await stripe.handleCardSetup(
this.data.client_secret,this.card,{
payment_method_data: {
billing_details: { name: this.cardholderName },},}
);
if (error) {
this.toastr.error(error.message);
this.stateService.toggleWaitingPage(false);
} else {
// create a Payment Method from the prevIoUsly created Setup Intent and attach it to the Customer
const paymentMethod = await this.paymentService
.attachPaymentMethod({ payment_method: setupIntent.payment_method })
.toPromise();
this.close(paymentMethod);
}
}
close(data: any = null): void {
this.dialogRef.close(data);
}
}
form {
display: flex;
flex-direction: column;
align-items: center;
width: 95%;
margin: auto;
.form-row {
width: 100%;
margin: 0 0 20px;
Box-shadow: 0 1px 4px 0 rgba(0,0.2);
border-radius: 5px;
padding: 10px;
height: 40px;
#card-errors {
font-size: 12px;
color: #f82e42;
}
}
}
p {
color: #707070;
}
.input_area{
width: 100%;
text-align: center;
padding-bottom: 115px;
}
.body_area{
display: block;
height: 100%;
.attention{
display: flex;
margin: 20px 0px;
height: 100%;
padding: 5px 0px;
background-color: #F6F9FC;
.notranslate {
color: #89b153;
font-size: 18px;
margin-left: 8px;
padding-top: 2px;
padding-right: 5px;
}
p{
text-align: left !important;
margin-bottom: 0px !important;
}
.notranslate{
color: #707070;
place-self: center;
}
}
}
.header_wrapper{
display: block;
height: 100%;
.pinpay{
margin-bottom: unset !important;
font-weight: bold;
font-size: 17px;
color: #4a4a56;
}
.img {
height: 80px;
width: 80px;
margin-top: 10px;
margin: auto;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
Box-shadow: 0 3px 6px 0 rgba(0,0.16);
border-radius: 500px;
@media (max-width: 320px) and (max-height: 438px) { display: none; }
.image-icon{
height: 60px;
width: 60px;
margin-top: 3px;
margin-left: 8.4px;
}
}
}
#cardholder-name {
width: 95%;
margin-bottom: 20px;
Box-shadow: 0 1px 4px 0 rgba(0,0.2);
background: transparent;
border: none;
}
<div class="dialog_container">
<div class="header_row">
<div class="header_left"></div>
<span class="close" (click)="close()">✕</span>
<h5 id="header_title">{{ 'DIALOGS.ADD_CREDIT_CARD.TITLE' | translate }}</h5>
</div>
<div class="header_wrapper">
<div class="img">
</div>
<div style="display: flex; margin-bottom: unset">
<p class="pinpay">PinployPay</p>
<span></span>™
</div>
<p class="pinpay1">Sikker handel</p>
</div>
<div class="body_area">
<div class="attention">
<mat-icon [matTooltip]="'PAGES.SETTINGS.PROFILE.COMPLETION_RATE_INFO' | translate">info</mat-icon>
<p>{{ 'DIALOGS.ADD_CREDIT_CARD.MESSAGE' | translate }}</p>
</div>
<p>
<mat-icon class="notranslate">remove_shopping_cart</mat-icon>{{
'DIALOGS.ADD_CREDIT_CARD.MESSAGE_1' | translate }}
</p>
</div>
<div class="input_area">
<input
id="cardholder-name"
[(ngModel)]="cardholderName"
[placeholder]="'DIALOGS.ADD_CREDIT_CARD.CARDHOLDER' | translate"
/>
<form #checkout="ngForm" (ngSubmit)="onSubmit(checkout)" class="checkout">
<div class="form-row">
<div id="card-info" #cardInfo></div>
<div id="card-errors" role="alert" *ngIf="error">{{ error }}</div>
</div>
<button type="submit" class="pinploy_button_v2_mobile_green">Ok</button>
</form>
</div>
</div>
index.html
<body>
<app-root></app-root>
<script src="https://js.stripe.com/v3/"></script>
<script>
const stripeKey =
window.location.origin === "https://www.pinploy.com"
? "pk_live_******q"
: "pk_test_1P******";
let stripe = Stripe(stripeKey);
let elements = stripe.elements();
</script>
</body>
</html>
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)