Uses: Payments API | Orders API | Web Payments SDK
Learn how to authorize partial payments with the Square APIs and SDKs.
A partial payment is a payment applied to an order that is less than the total amount due. For example, a customer might apply a $10 external payment (such as a check or a third-party gift card) to a $50 order. The order cannot be completed until the customer presents an additional payment method to cover the outstanding balance.
Important
Some card networks might not support partial payments. Applications should handle errors accordingly.
You can use the Payments API and Orders API with the Square SDKs to authorize partial payments. The following sections explain how to
- Record an external non-Square payment as a partial payment for an order.
- Handle errors for partial payments.
This topic applies to any seller that handles partial payments, including coffee shops, hair salons, boutiques, and more.
Note
This guide does NOT discuss Square gift cards. To learn how to accept Square gift cards for a partial payment, see Take Partial Payments with Square Gift Cards.
- You've created a Square account and application.
- You've installed the client-side SDK of your choice (Web Payments SDK, In-App Payments SDK - iOS, or In-App Payments SDK - Android).
- There is at least one item in the seller's catalog.
- To test the example code, you can find your production personal access token, application ID, and location ID in the Developer Console.
Important
Testing partial payments is not supported in Sandbox, so the example code in this guide calls production endpoints.
Warning
Don't deploy an application into production that contains your personal access token. For a secure authorization implementation in production, implement OAuth instead of using a personal access token.
To handle partial payments, your application needs PAYMENTS_WRITE
, ORDERS_WRITE
, and ORDERS_READ
permissions. For more information about using OAuth with Square, see OAuth API.
An external payment is a form of tender issued by an entity outside of Square. Checks and third-party gift cards are some common types of external payments.
Square assumes that any external payments are deposited directly to a seller's external bank account. External payments aren't credited to a seller's Square balance. However, you can indicate when an external payment is applied to part of an order.
For example, to pay for a $20.00 lunch takeout order at a Square seller, a customer presents a $10.00 gift card issued by a parent restaurant group. The parent restaurant group owns the restaurant, but doesn't have a Square account associated with this establishment. In this case, you create two payments to attach to the Square order, noting that one of them is EXTERNAL
.
The following steps detail how to authorize an external payment as a partial payment for a Square order. The example code was written to complement the Web Payments Quickstart, so you might find it useful to consult the example repository.
When a customer finishes adding items to their cart and proceeds to check out on the client, pass their selections to the server so that you can send a CreateOrder request. In addition to authentication credentials and an idempotency_key
, you need the following information for the request:
location_id
- A unique identifier for the physical place of business that fulfills the order.customer_id
- A unique identifier for the customer that was returned in a request to CreateCustomer.line_items
- An array of information about the products that the customer is purchasing, as they relate to your catalog. For more information about how to create more complex orders, see Create Orders.
The following example CreateOrder
request creates an Order for a deluxe sandwich. In the corresponding example catalog, a deluxe sandwich has the catalog_object_id
of U2LA7CNNKPXMMSBVDY4JCZOO
, and costs $20.
Create order
Store the returned ID for the Order
. You need it to create a Payment
in the next step.
In this example, a customer presents a $10.00 non-Square gift card for a parent restaurant company. In addition to authentication credentials and an idempotency_key
, you need to set the following fields in the CreatePayment request body:
order_id
- The ID for theOrder
object that you created in step 1.source_id
- Always set toEXTERNAL
for non-Square gift cards.external_details
- An object that details information about the non-Square gift card, including thetype
andsource
.type
is alwaysOTHER_GIFT_CARD
for non-Square gift cards.autocomplete
- Must befalse
. If there's an outstanding balance, additional payments need to be created and added to the order.amount_money
- The payment amount.
In the following example, the order_id
corresponds to an Order
for one deluxe sandwich, with a total_money
value of 2000
. The source_id
is EXTERNAL
, representing the non-Square gift card. The amount_money
records the $10.00 on the external card (1000
).
Create payment
Keep track of the ID for the Payment
. You need to pass it in a future request to complete the order.
Before you can complete the order, you need to prompt the customer to provide an additional payment method to cover the outstanding balance. To accept a credit card payment, use the Web Payments SDK, as detailed in the following steps.
Store your developer access token, located in the Developer Console, according to your application logic (which could be something like a .env
).
Add the following script to the <head>
of your .html
to initialize the Web Payments SDK:
<head>
<script
type="text/javascript"
src="https://web.squarecdn.com/v1/square.js"
></script>
</head>
To initialize the Square Payments
object, pass your application ID and location ID, also found in the Developer Console, to Square.payments
.
const payments = Square.payments(APPLICATION_ID, LOCATION_ID);
Warning
Never share any developer credentials in your client-side code.
Write an initializeCard
function to call payments.card()
to create a Card
object and attach the Card
to a DOM element.
async function initializeCard(payments) {
const card = await payments.card();
await card.attach('#card-container');
return card;
}
Add an event listener to execute initializeCard
when the DOM loads.
document.addEventListener('DOMContentLoaded', async function () {
let card;
try {
card = await initializeCard(payments);
} catch (e) {
console.error('Initializing card failed', e);
return;
}
// Placeholder for handlePaymentMethodSubmission
});
This displays a card payment input field to the customer. The following example demonstrates how the field looks embedded in the Web Payments SDK Quickstart:
To generate a corresponding token from the customer's input, you need to call the SDK tokenize()
method. The following example calls the method within a helper tokenize
function:
async function tokenize(paymentMethod) {
const tokenResult = await paymentMethod.tokenize();
if (tokenResult.status === 'OK') {
return tokenResult.token;
} else {
let errorMessage = `Tokenization failed with status: ${tokenResult.status}`;
if (tokenResult.errors) {
errorMessage += ` and errors: ${JSON.stringify(
tokenResult.errors,
)}`;
}
throw new Error(errorMessage);
}
}
Add the helper tokenize
function to a parent handler function that's called when a customer submits a payment.
Listen for when the customer submits the payment. In the following example, an event listener triggers the handlePaymentMethodSubmission
parent handler function when a customer clicks the Pay button:
const payButton = document.getElementById('pay-button');
payButton.addEventListener('click', async function (event) {
await handlePaymentMethodSubmission(event, card);
});
handlePaymentMethodSubmission
calls tokenize
and passes the token result to a createPayment
helper function.
async function handlePaymentMethodSubmission(event, paymentMethod) {
try {
const token = await tokenize(paymentMethod);
const paymentResults = await createPayment(token);
} catch (e) {
console.error(e.message);
}
}
createPayment
is a helper function that you write to pass the token and other data from the client to your server, so that you can make the backend call to CreatePayment
. You need to pass the following information:
source_id
- The token generated for the card payment method when you called the Squaretokenize
method.order_id
- The ID for theOrder
object that you created in step 1.
In addition to the source_id
, the order_id
, and an idempotency_key
, you need to set the following fields in the CreatePayment request body:
autocomplete
- Must befalse
because this payment is one of several attached to theOrder
.amount_money
- The payment amount, calculated by subtracting the external non-Square gift card amount fromOrder.total_money
.
In the following example, the order_id
corresponds to an order for one deluxe sandwich that costs $20.00, with a total_money
value of 2000
. After the external non-Square gift card is applied to the Order, the total amount due is 1000
. The amount_money
charges the entire 1000
outstanding balance to the secondary payment method.
Create payment
Keep track of the Payment
ID. You need to pass it in the next step to complete the Order
.
Call PayOrder from your server to complete the customer's purchase. Trigger this call according to your application interface and logic. For example, you can send the request after a customer selects "Submit Order".
The endpoint takes the order_id
as a path parameter: /orders/order_id/pay
. In the request body, pass the payment_ids
associated with the Order
in addition to authentication credentials and an idempotency_key
, as shown in the following example.
Pay order
At this point, the customer has paid for the purchase. Display a success message according to your application interface and logic.
For help troubleshooting errors, see the following API Reference: