Partial Payment Authorizations

Uses: Payments API | Orders API | Web Payments SDK

Learn how to authorize partial payments with the Square APIs and SDKs.

Link to section

Overview

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.

Link to section

Requirements

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.

Link to section

Record an external non-Square payment as a partial payment for an order

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.

Link to section

1. Send a CreateOrder request from the server.

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.

Link to section

2. From the server, create a Payment with source_id set to EXTERNAL for the Order.

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 the Order object that you created in step 1.
  • source_id - Always set to EXTERNAL for non-Square gift cards.
  • external_details - An object that details information about the non-Square gift card, including the type and source. type is always OTHER_GIFT_CARD for non-Square gift cards.
  • autocomplete - Must be false. 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.

Link to section

3. From the frontend, initialize the Web Payments SDK and Square Payments object.

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.

Link to section

4. Add payments to your frontend UI.

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:

A graphic showing the Quickstart web page after all walkthrough steps are completed and a Pay $1.00 button.

Link to section

5. On the frontend, get the customer's input and generate a token.

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 Square tokenize method.
  • order_id - The ID for the Order object that you created in step 1.
Link to section

6. Call the CreatePayment endpoint from your server.

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 be false because this payment is one of several attached to the Order.
  • amount_money - The payment amount, calculated by subtracting the external non-Square gift card amount from Order.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.

Link to section

7. Call PayOrder to complete the order from your server.

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.

Link to section

Handle errors for partial payments

For help troubleshooting errors, see the following API Reference: