我如何在角度分量中添加平方付款形式并从相应的ts文件访问?
我的html代码是-
<h2>Pay with a Credit Card</h2>
<label for="sq-card-number">Card Number:</label>
<div id="sq-card-number"></div>
<label for="sq-cvv">CVV:</label>
<div id="sq-cvv"></div>
<label for="sq-expiration-date">Expiration Date:</label>
<div id="sq-expiration-date"></div>
<label for="sq-postal-code">Postal Code:</label>
<div id="sq-postal-code"></div>
<button id="sq-creditcard" class="btn-main button-credit-card"
(click)="requestCardNonce($event)">Pay with card</button>
<input type="hidden" id="sq-id" name="sq-id">
<input type="hidden" id="card-nonce" name="nonce">
在打字稿中ngafterviewInit我用过这个
ngAfterViewInit() {
jQuery.getScript('https://js.squareupsandbox.com/v2/paymentform').done(() => {
var applicationId = "sandbox-xxxx-xxxxxxxxxxx";
// Set the location ID
var locationId = "xxxxxxxxxxxx";
this.sqPaymentForm = new SqPaymentForm({
// Initialize the payment form elements
//TODO: Replace with your sandbox application ID
applicationId: applicationId,
inputClass: 'sq-input',
autoBuild: false,
// Customize the CSS for SqPaymentForm iframe elements
inputStyles: [{
fontSize: '16px',
lineHeight: '24px',
padding: '16px',
placeholderColor: '#a0a0a0',
backgroundColor: 'transparent',
}],
// Initialize the credit card placeholders
cardNumber: {
elementId: 'sq-card-number',
placeholder: 'Card Number'
},
cvv: {
elementId: 'sq-cvv',
placeholder: 'CVV'
},
expirationDate: {
elementId: 'sq-expiration-date',
placeholder: 'MM/YY'
},
postalCode: {
elementId: 'sq-postal-code',
placeholder: 'Postal'
},
// SqPaymentForm callback functions
callbacks: {
/*
* callback function: cardNonceResponseReceived
* Triggered when: SqPaymentForm completes a card nonce request
*/
cardNonceResponseReceived: function (errors, nonce, cardData) {
if (errors) {
// Log errors from nonce generation to the browser developer console.
console.error('Encountered errors:');
errors.forEach(function (error) {
console.error(' ' + error.message);
});
alert('Encountered errors, check browser developer console for more details');
return;
}
alert(`The generated nonce is:\n${nonce}`);
//TODO: Replace alert with code in step 2.1
}
}
});
//TODO: paste code from step 1.1.4
this.sqPaymentForm.build();
});
}
并且在单击付款按钮时将其称为
requestCardNonce(event) {
// Don't submit the form until SqPaymentForm returns with a nonce
event.preventDefault();
// Request a nonce from the SqPaymentForm object
this.sqPaymentForm.requestCardNonce();
}
页面加载后出现此错误-
vendor.js:55969 ERROR ElementNotFoundError: SqPaymentForm element with id 'sq-card-number' not found. Has the DOM finished loading?
See: https://developer.squareup.com/docs/payment-form/payment-form-walkthrough#12-embed-sqpaymentform-in-a-static-web-page
at t.value (https://js.squareupsandbox.com/v2/paymentform?_=1583834837437:1:91257)
at t.value (https://js.squareupsandbox.com/v2/paymentform?_=1583834837437:1:90726)
at t.value (https://js.squareupsandbox.com/v2/paymentform?_=1583834837437:1:90611)
at t.value (https://js.squareupsandbox.com/v2/paymentform?_=1583834837437:1:88895)
at yt.initializePaymentMethod (https://js.squareupsandbox.com/v2/paymentform?_=1583834837437:1:144318)
at yt.mainIframeLoaded (https://js.squareupsandbox.com/v2/paymentform?_=1583834837437:1:144514)
at t._onload (https://js.squareupsandbox.com/v2/paymentform?_=1583834837437:1:143174)
at t.value (https://js.squareupsandbox.com/v2/paymentform?_=1583834837437:1:87769)
at f.onload (https://js.squareupsandbox.com/v2/paymentform?_=1583834837437:1:84829)
at HTMLIFrameElement.wrapFn (http://localhost:4200/polyfills.js:7941:39)
有人可以建议我如何以角度实施这种方形支付系统吗?我在网上搜索,但找不到合适的解决方案。提前感谢!
您可以使用服务来加载脚本:
// src\app\services\dynamic-script-loader.service.ts
import {Injectable} from '@angular/core';
interface Scripts {
name: string;
src: string;
}
export const ScriptStore: Scripts[] = [
{name: 'square-sandbox', src: 'https://js.squareupsandbox.com/v2/paymentform'},
{name: 'square', src: 'https://js.squareup.com/v2/paymentform'}
];
@Injectable({
providedIn: 'root'
})
export class
- DynamicScriptLoaderService
{
private scripts: any = {};
constructor() {
ScriptStore.forEach((script: any) => {
this.scripts[script.name] = {
loaded: false,
src: script.src
};
});
}
loadScripts(...scripts: string[]): Promise<any> {
const promises: any[] = [];
scripts.forEach((script) => promises.push(this.loadScript(script)));
return Promise.all(promises);
}
loadScript(name: string) {
return new Promise((resolve, reject) => {
if (!this.scripts[name].loaded) {
// load script
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = this.scripts[name].src;
// @ts-ignore
if (script.readyState) { // IE
// @ts-ignore
script.onreadystatechange = () => {
// @ts-ignore
if (script.readyState === 'loaded' || script.readyState === 'complete') {
// @ts-ignore
script.onreadystatechange = null;
this.scripts[name].loaded = true;
resolve({script: name, loaded: true, status: 'Loaded'});
}
};
} else { // Others
script.onload = () => {
this.scripts[name].loaded = true;
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 {
console.warn('Already Loaded...')
resolve({script: name, loaded: true, status: 'Already Loaded'});
}
});
}
isAlreadyLoaded(name): boolean {
return this.scripts[name]?.loaded;
}
}
然后通过autoBuild = false在您的组件中使用它:
declare var SqPaymentForm: any;
...
export class MyComponent implements OnInit, OnDestroy {
paymentForm: any;
constructor(
private dsls: DynamicScriptLoaderService,
...
){}
...
await this.dsls.loadScript(scriptName); // <-- use in ngOnInit
...
this.paymentForm = new SqPaymentForm({
autoBuild: false, //<-- !important too
...
});
this.paymentForm.build();
this.paymentForm.requestCardNonce();
...
还有他的HTML
<div id="sq-card-number"></div></div>
<div id="sq-cvv" class="sq-input-small"></div>
<div id="sq-expiration-date" class="sq-input-small"></div>
<div id="sq-postal-code" class="sq-input-small"></div>