Having this issue integrating web payments SDK with my angular app. Everything works up until the card details are supposed to get tokenized here:
async function tokenize(paymentMethod) {
const tokenResult = await paymentMethod.tokenize();
In the browser, I can see the function executing successfully in the network tab in dev tools. I see the card nonce in the response but the code hangs at the await because it seems to never get the response.
Could you provide the code you’re getting this with with steps to reproduce?
All of my code is from the example provided in the web payments sdk documentation.
html:
<form id="payment-form">
<div id="card-container"></div>
<button id="card-button" type="button">Pay $1.00</button>
</form>
<div id="payment-status-container"></div>
typescript file:
const appId = '{app id}';
const locationId = '{location id}';
async function initializeCard(payments) {
const card = await payments.card();
await card.attach('#card-container');
return card;
}
// Call this function to send a payment token, buyer name, and other details
// to the project server code so that a payment can be created with
// Payments API
async function createPayment(token) {
const body = JSON.stringify({
locationId,
sourceId: token,
});
const paymentResponse = await fetch('/payment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body,
});
if (paymentResponse.ok) {
return paymentResponse.json();
}
const errorBody = await paymentResponse.text();
throw new Error(errorBody);
}
// This function tokenizes a payment method.
// The ‘error’ thrown from this async function denotes a failed tokenization,
// which is due to buyer error (such as an expired card). It is up to the
// developer to handle the error and provide the buyer the chance to fix
// their mistakes.
async function tokenize(paymentMethod) {
console.log(paymentMethod)
let tokenResult = await paymentMethod.tokenize();
console.log(tokenResult)
if (tokenResult.status === 'OK') {
return tokenResult.token;
} else {
let errorMessage = `Tokenization failed-status: ${tokenResult.status}`;
if (tokenResult.errors) {
errorMessage += ` and errors: ${JSON.stringify(
tokenResult.errors
)}`;
}
throw new Error(errorMessage);
}
}
// Helper method for displaying the Payment Status on the screen.
// status is either SUCCESS or FAILURE;
function displayPaymentResults(status) {
const statusContainer = document.getElementById(
'payment-status-container'
);
if (status === 'SUCCESS') {
statusContainer.classList.remove('is-failure');
statusContainer.classList.add('is-success');
} else {
statusContainer.classList.remove('is-success');
statusContainer.classList.add('is-failure');
}
statusContainer.style.visibility = 'visible';
}
document.addEventListener('DOMContentLoaded', async function () {
if (!window['Square']) {
throw new Error('Square.js failed to load properly');
}
const payments = window['Square'].payments(appId, locationId);
let card;
try {
card = await initializeCard(payments);
} catch (e) {
console.error('Initializing Card failed', e);
return;
}
// Checkpoint 2.
async function handlePaymentMethodSubmission(event, paymentMethod) {
event.preventDefault();
try {
// disable the submit button as we await tokenization and make a
// payment request.
cardButton['disabled'] = true;
const token = await tokenize(paymentMethod);
console.log(token)
//const paymentResults = await createPayment(token);
//displayPaymentResults('SUCCESS');
//console.debug('Payment Success', paymentResults);
} catch (e) {
//cardButton['disabled'] = false;
//displayPaymentResults('FAILURE');
console.error(e.message);
}
}
const cardButton = document.getElementById(
'card-button'
);
cardButton.addEventListener('click', async function (event) {
await handlePaymentMethodSubmission(event, card);
});
});
I wanted to make sure the token was getting created properly first so I commented out everything after that (the create payment part). I entered and submitted card details into the form but instead the token getting logged in the handlePaymentMethodSubmission function, the process hangs in the tokenize function at:
const token = await tokenize(paymentMethod);
This will hang up at the await
which you are experiencing. An easier way to confirm the token creation is to change:
const paymentResponse = await fetch('/payment', {
If you change /payment
to anything else like /payments
you’ll get the token that passed to the payment request.