好吧,不确定您使用的是哪个版本,但最近实现了最新的条纹元素..
加载条带脚本的服务
import { Injectable } from '@angular/core';
interface Scripts {
name: string;
src: string;
}
declare var document: any;
@Injectable({ providedIn: 'root' })
export class DynamicScriptLoaderService {
private scripts: any = {};
constructor() {}
loadScript(src: string) {
return new Promise((resolve, reject) => {
if (!this.scripts[src]) {
this.scripts[src] = true;
//load script
let script = document.createElement('script');
script.type = 'text/javascript';
script.src = src;
if (script.readyState) {
//IE
script.onreadystatechange = () => {
if (script.readyState === 'loaded' || script.readyState === 'complete') {
script.onreadystatechange = null;
resolve({ script: src, loaded: true, status: 'Loaded' });
}
};
} else {
//Others
script.onload = () => {
resolve({ script: name, loaded: true, status: 'Loaded' });
};
}
script.onerror = (error: any) => resolve({ script: name, loaded: false, status: 'Loaded' });
document.getElementsByTagName('head')[0].appendChild(script);
} else {
resolve({ script: name, loaded: true, status: 'Already Loaded' });
}
});
}
}
零件
import { Component, OnInit, ChangeDetectionStrategy, Input, ViewChild, Inject, Output, EventEmitter } from '@angular/core';
import { UserService } from 'shared-components/lib/app-material/user.service';
import { PublicProductService } from '../../public-product.service';
import { DynamicScriptLoaderService } from 'shared-components/lib/app-material/script-loader';
import { BehaviorSubject } from 'rxjs';
import { FormControl, Validators } from '@angular/forms';
import { STRIPE_PUBLIC_KEY } from 'shared-components/lib/common';
declare var Stripe: any;
@Component({
selector: 'flm-stripe',
templateUrl: './stripe.component.html',
styleUrls: ['./stripe.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class StripeComponent implements OnInit {
@Input() order;
stripe: any;
card: any;
sendingRequest$ = new BehaviorSubject(false);
error$ = new BehaviorSubject(null);
nameOnCardControl = new FormControl(null, Validators.required);
@Output() complete = new EventEmitter();
@ViewChild('cardNumber') cardNumber;
@ViewChild('expiry') expiry;
@ViewChild('cvc') cvc;
constructor(
private productService: PublicProductService,
private scriptoader: DynamicScriptLoaderService,
private userservice: UserService,
@Inject(STRIPE_PUBLIC_KEY) private publicKey: string
) {
super();
this.nameOnCardControl.setValue(this.userservice.user.fullName);
}
ngOnInit() {
this.scriptoader.loadScript('https://js.stripe.com/v3/').then(() => {
this.stripe = Stripe(this.publicKey);
var elements = this.stripe.elements();
// Custom styling can be passed to options when creating an Element.
// (Note that this demo uses a wider set of styles than the guide below.)
var style = {
base: {
iconColor: '#666EE8',
color: '#3eb5f1',
lineHeight: '40px',
fontWeight: 300,
fontFamily: 'Roboto, "Helvetica Neue", sans-serif',
fontSize: '16px',
'::placeholder': {
color: '#3eb5f1'
}
},
invalid: {
color: '#e4584c',
iconColor: '#e4584c'
}
};
// Create an instance of the card Element.
this.card = elements.create('cardNumber', { style: style });
// Add an instance of the card Element into the `card-element` <div>.
this.card.mount(this.cardNumber.nativeElement);
elements.create('cardExpiry', { style: style }).mount(this.expiry.nativeElement);
elements.create('cardCvc', { style: style }).mount(this.cvc.nativeElement);
});
}
pay(event) {
if (event) {
event.preventDefault();
}
this.sendingRequest$.next(true);
/// REad this how to create intent https://stripe.com/docs/payments/payment-intents
this.productService.getPaymentData(this.order.Id, 'Stripe').safeSubscribe(this, resp => {
this.stripe
.handleCardPayment(resp.Data, this.card, {
payment_method_data: {
billing_details: {
name: this.nameOnCardControl.value
}
}
})
.then(result => {
this.error$.next(null);
this.sendingRequest$.next(false);
if (result.error) {
this.error$.next(result.error.message);
} else {
this.complete.next(true);
}
});
});
}
}
模板
<form (ngSubmit)="pay($event)" method="post" id="payment-form">
<div class="group">
<label>
<span>{{ 'Order_NameOnCard' | translate }}</span>
<div class="field">
<input class="field" placeholder="{{ 'Order_NameOnCard' | translate }}" [formControl]="nameOnCardControl" />
</div>
</label>
<label>
<span>Card number</span>
<div #cardNumber class="field"></div>
<span class="brand"><i class="pf pf-credit-card" id="brand-icon"></i></span>
</label>
<label>
<span>Expiry date</span>
<div #expiry class="field"></div>
</label>
<label>
<span>CVC</span>
<div #cvc class="field"></div>
</label>
</div>
<!-- Used to display form errors. -->
<div role="alert" class="error visible ">
<ng-container *ngIf="error$ | async">{{ error$ | async }}</ng-container>
</div>
<flm-button-progress
class="w100p"
[inProgress]="sendingRequest$ | async"
analyticsOn="click"
analyticsCategory="Payment"
analyticsEvent="Stripe"
>
{{ 'Order_Pay' | translate }}
<i class="fa fa-arrow-right"></i>
</flm-button-progress>
</form>
注意:我正在使用我自己的 safeSubscribe 自定义取消订阅 ngDestroy,请将其更改为订阅并自行管理取消订阅。
typings.d.ts - 也应该有效,但这取决于您的设置以及根文件夹对您的意义。