Applies to: Web Payments SDK | Payments API
Learn how to get the web client ready to accept a payment card and send the resulting token to the server component of the quickstart application.
You need your Sandbox credentials because the quickstart application is configured to send requests to the Square Sandbox instead of your production Square account.
- Open the Developer Console and click the plus symbol under Applications to create a new application.
- Open the application, and then choose Credentials in the left pane.
- At the top of the page, set the Developer Console mode to Sandbox to get a Sandbox application ID.
- Copy the Sandbox Application ID and Sandbox Access Token.
- In the left pane, choose Locations, and the copy the Sandbox location ID.
- Paste the application ID, location ID, and Sandbox access token into a temporary text file.
Important
The Sandbox access token is a secure secret. Don't share it with anyone or upload it to the cloud.
The quickstart server code calls the CreatePayment endpoint and needs to be updated to use your Sandbox access token.
In the project root folder, create a copy of the .env.example file and name it .env.sandbox.
The dotenv library is used to manage secrets that shouldn't be made public. The .env.sandbox file should never be committed.
Open the copied file to edit.
Define
SQUARE_ACCESS_TOKEN
with your Sandbox access token from the Developer Console.SQUARE_ACCESS_TOKEN={SANDBOX_ACCESS_TOKEN}Restart your server for the Sandbox test environment (
npm run dev
) to use this new value.
You need a Sandbox application ID and Sandbox location ID in the following steps. You should paste these values into a text file or leave the Developer Console open in another browser tab so that you can copy the values as needed.
Replace the body of public/index.html with this 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>This HTML adds an element (
div id="card-container"
) that the Web Payments SDK attaches the card element to and adds a button that starts the tokenization process.Did you know?
The SDK also enables the Apple Pay, Google Pay, ACH (bank transfer), Square gift card, and Cash App Pay payment methods.
The following JavaScript instantiates the SDK, provides the Card payment object, attaches it to the page, and generates the payment token:
Add an empty
<script>
tag to the<head>
of index.html after<script type="text/javascript" src="https://sandbox.web.squarecdn.com/v1/square.js"></script>
.<script> </script>Add the following global constants inside the
<script>
tag, substituting the IDs from the Developer Console for the placeholder ({YOUR_SANDBOX_APPLICATION_ID}
and{YOUR_SANDBOX_LOCATION_ID}
) values:const appId = '{YOUR_SANDBOX_APPLICATION_ID}'; const locationId = '{YOUR_SANDBOX_LOCATION_ID}';Add the following code inside the
<script>
tag:async function initializeCard(payments) { const card = await payments.card(); await card.attach('#card-container'); return card; } 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; } // Step 5.2: create card payment });
The code does the following:
- Initializes the Web Payments SDK by calling Square.payments(appId, locationId).
- Initializes the Card payment method by calling the Payments
.card()
method and attaching the payment method to the page DOM by calling the Card.attach()
method.
Note
The Card payment method of the Web Payments SDK automatically infers whether to display the ZIP code, postal code, or postcode based on the issuing country of the buyer's credit card. Depending on the card that's used, the SDK automatically removes the postal code if the card's issuing country doesn't require the postal code for the payment.
Test the application
Navigate to http://localhost:3000/ in your browser.
Success
You should see the payment card input rendered on your page.
If you need to clear the contents of the card entry fields for the buyer, call card.destroy()
to destroy the object and then call the initializeCard(payments)
function again to initialize and attach the card
to your application DOM.
Before you can take a payment, you need to configure your developer credentials, which can be found in the Developer Console.
This example uses the Square Sandbox to accept a payment. You should use the Card-not-present success state values. However, if you choose to use your own payment card, the Sandbox doesn't charge it.
Add the following code after the
initializeCard
function inside the<script>
tag:// 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, idempotencyKey: window.crypto.randomUUID(), }); 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's up to the // developer to handle the error and provide the buyer the chance to fix // their mistakes. async function tokenize(paymentMethod) { const tokenResult = await paymentMethod.tokenize(); 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'; }Add the following code to the
DOMContentLoaded
event listener in step 4.3 by replacing// Step 5.2: create card payment
with the following code: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); 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); });
The complete DOMContentLoaded Event Listener
should look like the following code:
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;
}
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);
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);
});
});
The code does the following:
- Binds the
Card
tokenization to the trigger event, which is clicking the Pay button in this case. - Submits the tokenized card information and payment token by calling the CreatePayment endpoint on the backend.
Navigate to http://localhost:3000/ in your browser.
Input the card number 5105 1051 0510 5100 from the Card-not-present success state values. Any CVV or postal code works.
Choose the Pay $1.00 button.
You should see a green check mark and Payment successful on the page. The payment is credited to your developer test account. The next section shows how to find the payment in the Sandbox Square Dashboard.
Look at the Developer Console for a debug log of the payment information.
Did you know?
You can use any value from Sandbox Payments.