无法读取未定义的 属性 'configure'
Cannot read property 'configure' of undefined
我收到错误:
core.js:5882 ERROR TypeError: Cannot read property 'configure' of
undefined
当我在 Angular 中为万事达卡实施 Hosted Session Integration
时 2. 这是我的代码:
付款-detail.component.ts
import { AfterViewInit, Component, OnInit } from '@angular/core';
declare var $: any;
@Component({
selector: 'app-payment-detail',
templateUrl: './payment-detail.component.html',
styleUrls: ['./payment-detail.component.css'],
})
export class PaymentDetailComponent implements OnInit, AfterViewInit {
// PaymentSession: any;
constructor() {}
ngAfterViewInit(): void {
$.getScript(
'https://ap-gateway.mastercard.com/form/version/57/merchant/<MERCHANTID>/session.js?debug=true',
function () {
$.PaymentSession.configure({
fields: {
// Attach hosted fields to your payment page
card: {
number: '#card-number',
securityCode: '#security-code',
expiryMonth: '#expiry-month',
expiryYear: '#expiry-year',
nameOnCard: '#cardholder-name',
},
giftCard: {
number: '#gift-card-number',
pin: '#gift-card-pin',
},
ach: {
accountType: '#ach-account-type',
bankAccountHolder: '#ach-account-holder',
bankAccountNumber: '#ach-account-number',
routingNumber: '#ach-routing-number',
},
},
frameEmbeddingMitigation: ['javascript'],
callbacks: {
initialized: function (response) {
// HANDLE INITIALIZATION RESPONSE
if (response.status === 'ok') {
document.getElementById('visaCheckoutButton').style.display =
'block';
}
},
formSessionUpdate: function (response) {
// HANDLE RESPONSE FOR UPDATE SESSION
if (response.status) {
if ('ok' == response.status) {
console.log(
'Session updated with data: ' + response.session.id
);
//check if the security code was provided by the user
if (response.sourceOfFunds.provided.card.securityCode) {
console.log('Security code was provided.');
}
//check if the user entered a MasterCard credit card
if (
response.sourceOfFunds.provided.card.scheme == 'MASTERCARD'
) {
console.log('The user entered a MasterCard credit card.');
}
} else if ('fields_in_error' == response.status) {
console.log('Session update failed with field errors.');
if (response.errors.cardNumber) {
console.log('Card number invalid or missing.');
}
if (response.errors.expiryYear) {
console.log('Expiry year invalid or missing.');
}
if (response.errors.expiryMonth) {
console.log('Expiry month invalid or missing.');
}
if (response.errors.securityCode) {
console.log('Security code invalid.');
}
if (response.errors.number) {
console.log('Gift card number invalid or missing.');
}
if (response.errors.pin) {
console.log('Pin invalid or missing.');
}
if (response.errors.bankAccountHolder) {
console.log('Bank account holder invalid.');
}
if (response.errors.bankAccountNumber) {
console.log('Bank account number invalid.');
}
if (response.errors.routingNumber) {
console.log('Routing number invalid.');
}
} else if ('request_timeout' == response.status) {
console.log(
'Session update failed with request timeout: ' +
response.errors.message
);
} else if ('system_error' == response.status) {
console.log(
'Session update failed with system error: ' +
response.errors.message
);
}
} else {
console.log('Session update failed: ' + response);
}
},
visaCheckout: function (response) {
// HANDLE VISA CHECKOUT RESPONSE
},
amexExpressCheckout: function (response) {
// HANDLE AMEX EXPRESS CHECKOUT RESPONSE
},
},
interaction: {
displayControl: {
formatCard: 'EMBOSSED',
invalidFieldCharacters: 'REJECT',
},
},
order: {
amount: 10.0,
currency: 'AUD',
},
wallets: {
visaCheckout: {
enabled: true,
// Add Visa Checkout API specific attributes here
countryCode: 'AU',
displayName: 'Display name',
locale: 'en_au',
logoUrl: 'http://logo.logo',
payment: {
cardBrands: ['VISA'],
},
review: {
buttonAction: 'Pay',
message: 'Message',
},
shipping: {
acceptedRegions: ['AU'],
collectShipping: true,
},
},
amexExpressCheckout: {
enabled: true,
// Add Amex Express Checkout API specific attributes here
initTags: {
theme: 'responsive',
env: 'qa',
disable_btn: 'false',
button_color: 'light',
client_id:
'<MSO Client Id from the Amex Express Checkout configuration page in Merchant Administration>',
},
},
},
});
}
);
}
ngOnInit(): void {
}
load(): void {}
}
付款-detail.component.html
<div>Please enter your payment details:</div>
<div>Card Number: <input type="text" id="card-number" class="input-field" value="5123450000000008" readonly></div>
<div>Expiry Month:<input type="text" id="expiry-month" class="input-field" value="05"></div>
<div>Expiry Year:<input type="text" id="expiry-year" class="input-field" value="21"></div>
<div>Security Code:<input type="text" id="security-code" class="input-field" value="1234" readonly></div>
<div><button id="payButton" onclick="pay();">Pay Now</button></div>
如果我从 $.PaymentSession.configure
中删除 $.
,我将无法找到 PaymentSession。
更新
我按照 Maxine Lafarie 的建议使用了这段代码:
$.getScript( "your-script", function( data, textStatus, jqxhr ) {
console.log( data ); // Data returned
console.log( textStatus ); // Success
console.log( jqxhr.status ); // 200
console.log( "Load was performed." );
});
这是结果:
undefined payment-detail.component.ts:31 success
payment-detail.component.ts:32 200 payment-detail.component.ts:33 Load
was performed.
将 url 粘贴到浏览器我得到一个脚本:
您是否绑定记录了 $.getScript
的响应?
你可以这样做:
$.getScript( "your-script", function( data, textStatus, jqxhr ) {
console.log( data ); // Data returned
console.log( textStatus ); // Success
console.log( jqxhr.status ); // 200
console.log( "Load was performed." );
});
无论如何,我不知道您是在整个应用程序中使用 jQuery 还是只是为了 getScript
方法的“好处”,但我建议您避免混合使用Angular 和 jQ,因为 Angular 绝对可以做 jQuery 能做的所有事情。
如果您想以 Angular 方式加载第 3 方脚本,您可以 .
所以检查是否:
- jQuery 被很好地导入 and/or 在你调用它时加载到你的组件中
- 调用
$.getScript
方法后,您有一些成功日志
- 导入第 3 方脚本的 Angular 方法有效(可能更好)
编辑:
自从您导入脚本后,您就可以这样调用全局 属性:
$.PaymentSession.configure
但我认为你必须这样称呼它:PaymentSession.configure
我收到错误:
core.js:5882 ERROR TypeError: Cannot read property 'configure' of undefined
当我在 Angular 中为万事达卡实施 Hosted Session Integration
时 2. 这是我的代码:
付款-detail.component.ts
import { AfterViewInit, Component, OnInit } from '@angular/core';
declare var $: any;
@Component({
selector: 'app-payment-detail',
templateUrl: './payment-detail.component.html',
styleUrls: ['./payment-detail.component.css'],
})
export class PaymentDetailComponent implements OnInit, AfterViewInit {
// PaymentSession: any;
constructor() {}
ngAfterViewInit(): void {
$.getScript(
'https://ap-gateway.mastercard.com/form/version/57/merchant/<MERCHANTID>/session.js?debug=true',
function () {
$.PaymentSession.configure({
fields: {
// Attach hosted fields to your payment page
card: {
number: '#card-number',
securityCode: '#security-code',
expiryMonth: '#expiry-month',
expiryYear: '#expiry-year',
nameOnCard: '#cardholder-name',
},
giftCard: {
number: '#gift-card-number',
pin: '#gift-card-pin',
},
ach: {
accountType: '#ach-account-type',
bankAccountHolder: '#ach-account-holder',
bankAccountNumber: '#ach-account-number',
routingNumber: '#ach-routing-number',
},
},
frameEmbeddingMitigation: ['javascript'],
callbacks: {
initialized: function (response) {
// HANDLE INITIALIZATION RESPONSE
if (response.status === 'ok') {
document.getElementById('visaCheckoutButton').style.display =
'block';
}
},
formSessionUpdate: function (response) {
// HANDLE RESPONSE FOR UPDATE SESSION
if (response.status) {
if ('ok' == response.status) {
console.log(
'Session updated with data: ' + response.session.id
);
//check if the security code was provided by the user
if (response.sourceOfFunds.provided.card.securityCode) {
console.log('Security code was provided.');
}
//check if the user entered a MasterCard credit card
if (
response.sourceOfFunds.provided.card.scheme == 'MASTERCARD'
) {
console.log('The user entered a MasterCard credit card.');
}
} else if ('fields_in_error' == response.status) {
console.log('Session update failed with field errors.');
if (response.errors.cardNumber) {
console.log('Card number invalid or missing.');
}
if (response.errors.expiryYear) {
console.log('Expiry year invalid or missing.');
}
if (response.errors.expiryMonth) {
console.log('Expiry month invalid or missing.');
}
if (response.errors.securityCode) {
console.log('Security code invalid.');
}
if (response.errors.number) {
console.log('Gift card number invalid or missing.');
}
if (response.errors.pin) {
console.log('Pin invalid or missing.');
}
if (response.errors.bankAccountHolder) {
console.log('Bank account holder invalid.');
}
if (response.errors.bankAccountNumber) {
console.log('Bank account number invalid.');
}
if (response.errors.routingNumber) {
console.log('Routing number invalid.');
}
} else if ('request_timeout' == response.status) {
console.log(
'Session update failed with request timeout: ' +
response.errors.message
);
} else if ('system_error' == response.status) {
console.log(
'Session update failed with system error: ' +
response.errors.message
);
}
} else {
console.log('Session update failed: ' + response);
}
},
visaCheckout: function (response) {
// HANDLE VISA CHECKOUT RESPONSE
},
amexExpressCheckout: function (response) {
// HANDLE AMEX EXPRESS CHECKOUT RESPONSE
},
},
interaction: {
displayControl: {
formatCard: 'EMBOSSED',
invalidFieldCharacters: 'REJECT',
},
},
order: {
amount: 10.0,
currency: 'AUD',
},
wallets: {
visaCheckout: {
enabled: true,
// Add Visa Checkout API specific attributes here
countryCode: 'AU',
displayName: 'Display name',
locale: 'en_au',
logoUrl: 'http://logo.logo',
payment: {
cardBrands: ['VISA'],
},
review: {
buttonAction: 'Pay',
message: 'Message',
},
shipping: {
acceptedRegions: ['AU'],
collectShipping: true,
},
},
amexExpressCheckout: {
enabled: true,
// Add Amex Express Checkout API specific attributes here
initTags: {
theme: 'responsive',
env: 'qa',
disable_btn: 'false',
button_color: 'light',
client_id:
'<MSO Client Id from the Amex Express Checkout configuration page in Merchant Administration>',
},
},
},
});
}
);
}
ngOnInit(): void {
}
load(): void {}
}
付款-detail.component.html
<div>Please enter your payment details:</div>
<div>Card Number: <input type="text" id="card-number" class="input-field" value="5123450000000008" readonly></div>
<div>Expiry Month:<input type="text" id="expiry-month" class="input-field" value="05"></div>
<div>Expiry Year:<input type="text" id="expiry-year" class="input-field" value="21"></div>
<div>Security Code:<input type="text" id="security-code" class="input-field" value="1234" readonly></div>
<div><button id="payButton" onclick="pay();">Pay Now</button></div>
如果我从 $.PaymentSession.configure
中删除 $.
,我将无法找到 PaymentSession。
更新
我按照 Maxine Lafarie 的建议使用了这段代码:
$.getScript( "your-script", function( data, textStatus, jqxhr ) {
console.log( data ); // Data returned
console.log( textStatus ); // Success
console.log( jqxhr.status ); // 200
console.log( "Load was performed." );
});
这是结果:
undefined payment-detail.component.ts:31 success payment-detail.component.ts:32 200 payment-detail.component.ts:33 Load was performed.
将 url 粘贴到浏览器我得到一个脚本:
您是否绑定记录了 $.getScript
的响应?
你可以这样做:
$.getScript( "your-script", function( data, textStatus, jqxhr ) {
console.log( data ); // Data returned
console.log( textStatus ); // Success
console.log( jqxhr.status ); // 200
console.log( "Load was performed." );
});
无论如何,我不知道您是在整个应用程序中使用 jQuery 还是只是为了 getScript
方法的“好处”,但我建议您避免混合使用Angular 和 jQ,因为 Angular 绝对可以做 jQuery 能做的所有事情。
如果您想以 Angular 方式加载第 3 方脚本,您可以
所以检查是否:
- jQuery 被很好地导入 and/or 在你调用它时加载到你的组件中
- 调用
$.getScript
方法后,您有一些成功日志 - 导入第 3 方脚本的 Angular 方法有效(可能更好)
编辑:
自从您导入脚本后,您就可以这样调用全局 属性:
$.PaymentSession.configure
但我认为你必须这样称呼它:PaymentSession.configure