Skip to main content

Shop Component API

Note

NOTE: This API is only available to select merchants and partners using 3rd party checkout solutions. For more information, contact our enterprise sales team.


The Shop Component JS API enables your existing ecommerce site to use Shop Pay for checkout. Customers who select a Pay with Shop button or are recognized by email are shown all relevant cart information and can complete the transaction in an experience consistent with other usages of Shop Pay using a popup on your site.

TermDefinition
Shop Pay loginLogging in to a Shop Pay account. This occurs directly between a customer and Shopify.
Payment requestA payment request includes line items, applied discounts, tax calculations and available shipping methods.
Authentication modalWhen a Shop Pay user's email is recognized, the customer will see an interface to enter a One Time Password (OTP) for authentication.
Shop Pay popupMost of the interactions in Shop Pay Checkout happen within the context of a Shopify-hosted popup window.

Anchor to Technical requirementsTechnical requirements

  • A Shopify account with Shopify Payments enabled
  • The public domain(s) for the site you will be integrating Shop Component into
  • A non-Shopify-hosted ecommerce environment to implement against (frontend + backend)
  • The content security policy on the frontend must be configured to allow cdn.shopifycloud.com, cdn.shopify.com, shop.app, pay.shopify.com, *.shopifysvc.com, *.stripe.com
  • The backend needs to be able to functionally access all applicable resources required to assess and update the state of the payment request, including cart details, tax calculations, shipping methods / pricing, local pickup locations, discounts, inventory availability, etc.
  • An understanding of the work necessary to integrate with the Order Management System and other backend systems to perform post-order actions in Shopify such as captures, refunds, and updating fulfillment information.

Anchor to Your system is the main source of truthYour system is the main source of truth

This API extends your existing systems, so it treats those systems as canonical for everything that they already handle. This includes:

  • Cart contents

  • Shipping methods

  • Pickup locations

  • Tax calculation

  • Discounts

  • Inventory reservations

    Shopify is the source of truth for the payment transaction and for Shop Pay related fields, including vaulted customer addresses and payment methods.

    Consequently, while this API receives detailed information about the cart in the form of a payment request, any changes to the payment request related to your system's canonical topics must be validated. Whenever the payment request is returned to Shopify, it's used as a replacement for prior data received.

Upon payment completion, the order ID is returned from Shopify via a webhook for use in post-order actions such as capturing payments, issuing refunds, and adding order tracking information.

Your system is responsible for providing a source identifier that uniquely identifies the order, and is often either an existing cart or order identifier from your system. This value is persisted onto the Shopify order record.

You will need to create a custom app in Shopify, granting a shared key and Shopify API access tokens.

Anchor to Shop Pay popup interactionsShop Pay popup interactions

Shop Pay customers will authenticate with a Shop Pay login, either through an authentication modal or directly within the Shop Pay popup.

In order for Shopify to receive your system's canonical information during the checkout process, Shopify will dispatch events to your frontend integration when there are relevant customer actions in the Shop Pay popup. Following this, your system will then determine if there are any subsequent updates required to be made to the payment request. Based on its new state, calculate and rebuild an updated payment request to provide in the required response to the event.

Once accepted by a customer through the action of clicking the Pay now button, your backend should submit the final payment request mutation, including the paymentMethod token provided by Shopify, resulting in processing the payment and order creation.

While the Shop Pay popup is open, an overlay will darken the background, however the cart on your shop may remain visible. It's important that a customer does not see a different total in the cart because it hasn't updated based on selected shipping methods or discounts applied in Shop Pay. To handle this, we recommend updating any cart totals while the user interacts with the Shop Pay Checkout so that values match. A potential fallback is displaying the totals in a pending state through microcopy like Calculating... or through skeletons, spinners, or other pending UI elements.

A payment request must first be validated in your system including verifying that the payment request hasn't been modified unexpectedly, confirming inventory reservation, discount and pricing validation before submitting the final Shop Pay payment request, which will then create the order in Shopify.

Although rare, there can be a delay before an order becomes available via the Shopify API. It's important to ensure that synchronous order creation is not required for functionality of your checkout. Instead, webhooks can be relied upon for order creation confirmation.


This diagram reflects a "happy path" checkout. For simplicity, it bypasses the Shop Pay login flow, assuming a customer is already logged into Shop Pay.

Shop Component flow

Anchor to JavaScript SDK for buttons and email recognitionJavaScript SDK for buttons and email recognition

Shopify provides Shop Pay button and Shop Pay Login Web Components that you can add to your store.

Use the following code to load the script into your webpage from the CDN and embed the components.

// This script must be placed in the <head> of your site on any pages where Shop Pay components exist.
// In most cases this will be in your checkout, however it may also be included on product and/or cart pages where necessary.
<script src="https://cdn.shopify.com/shopifycloud/shop-js/shop-pay-payment-request.js"></script>

<div id="shop-pay-button-container"></div>
<div id="shop-pay-login-container">
<input type="email" id="email-input"/>
</div>

<script>
window.ShopPay.PaymentRequest.configure({
shopId: 1,
clientId: "[REPLACE-ME]",
debug: true, // Optional parameter. When set to true, it enables debug mode, which can be useful for development and troubleshooting.
})

window.ShopPay.PaymentRequest
.createButton().render('#shop-pay-button-container');

window.ShopPay.PaymentRequest
.createLogin({emailInputId: 'email-input'}).render('#shop-pay-login-container');
</script>

ParameterTypeDescription
shopIdNumberA required parameter. This is the ID for the shop. The shopId (integer) can be retrieved from the shop object in the Admin API.
clientIdStringA required parameter. This is the unique identifier for the client. The clientId is provided by Shopify.
debugBooleanAn optional parameter. When set to true, it enables debug mode, which will console log additional information that can be useful for development and troubleshooting. This should be omitted in production environments.
onAnalyticsEventFunctionAn optional parameter. This is a callback function that will be invoked with specific Event objects. This can be useful for monitoring user interactions and gathering data. See below for supported events.
localeShopPayLocaleAn optional parameter. Specifies the desired locale for the checkout experience. Expects a valid ISO language code, optionally followed by an ISO country code. Defaults to English (en). For a list of supported locales, see the Supported Locales List section.

The following events are currently supported:

  • loginpromptdisplayed: This event is triggered when the Shop Pay login modal prompt is displayed.

  • windowopened: This event is triggered when the Shop Pay popup checkout window is opened.

  • windowclosed: This event is triggered when the Shop Pay popup checkout window is closed.

    Here's an example of how you might handle these events in your onAnalyticsEvent callback:

<script>
window.ShopPay.PaymentRequest.configure({
shopId: 1,
clientId: "[REPLACE-ME]",
onAnalyticsEvent: (event) => {
switch (event.type) {
case 'loginpromptdisplayed':
console.log('Login prompt was displayed.');
break;
case 'windowopened':
console.log('Window was opened.');
break;
case 'windowclosed':
console.log('Window was closed.');
break;
default:
console.log('Unknown event:', event);
}
}
})
</script>

ParameterTypeDescription
emailInputIdStringA required parameter. The unique identifier of the email input element to listen to. This is also used to anchor the login modal to an element.

ParameterTypeDescription
buyWithBooleanAn optional parameter. If true, displays the "Buy with" variant of the button. Defaults to false.

NameDescriptionConstraints
--shop-pay-button-widthThe width of the button.Default: 262px

Minimum: 120px

Minimum (buy-with): 193px
--shop-pay-button-heightThe height of the button.Default: 42px

Minimum: 40px
--shop-pay-button-border-radiusThe border radius of the button.Default: 4px

The following example styles the button with the default height of 42 pixels, a width of 200 pixels, and a border radius of 0 pixels:

<style>
shop-pay-payment-request-button {
--shop-pay-button-width: 200px;
--shop-pay-button-border-radius: 0px;
}
</style>
Note

Upon invoking the .render method, the button is optimistically rendered while an HTTP request is dispatched to Shopify to check the availability of Shop Pay in the configured shop. If the Shopify Payments setup is incomplete or Shop Pay is deactivated in the payment settings, the button element is removed from the DOM.

Anchor to Enabling and disabling the Shop Pay buttonEnabling and disabling the Shop Pay button

If you need to disable and re-enable the Shop Pay button for specific user interactions or other conditions in your application, you can use the following methods.

// Disable the Shop Pay button
window.ShopPay.PaymentRequest.Buttons.disable();

// Re-enable the Shop Pay button
window.ShopPay.PaymentRequest.Buttons.enable();

Example: Disable the Shop Pay button until a valid variant is selected

// Disable the payment request button to prevent a customer from opening Shop Pay before a variant is selected
window.ShopPay.PaymentRequest.Buttons.disable();

const addProductToCartButton = document.getElementById('addProductToCartButton');
addProductToCartButton.addEventListener('click', function() {
// Once the selected valid variant has been successfully processed, re-enable the button
window.ShopPay.PaymentRequest.Buttons.enable();
});

The example code below provides guidance on how to use Shop Component.

Use the .myshopify.com hostname from your onboarding email to configure the API.

window.ShopPay.PaymentRequest.configure({
shopId: 1,
clientId: "[REPLACE-ME.myshopify.com]",
})

Create a session to make a payment request. shop_id (integer) can be retrieved from the shop object in the Admin API.

PaymentRequest fields are defined below.

const initialPaymentRequest = window.ShopPay.PaymentRequest.build({
lineItems: [
{
label: "T-Shirt",
originalItemPrice: {
amount: 10.00,
currencyCode: "USD"
},
itemDiscounts: [
{
label: "10% off",
amount: {
amount: 1.00,
currencyCode: "USD"
}
}
],
finalItemPrice: {
amount: 9.00,
currencyCode: "USD"
},
quantity: 2,
sku: "t-shirt",
requiresShipping: true,
originalLinePrice: {
amount: 20.00,
currencyCode: "USD"
},
lineDiscounts: [
{
label: "10% off",
amount: {
amount: 2.00,
currencyCode: "USD"
}
}
],
finalLinePrice: {
amount: 18.00,
currencyCode: "USD"
},
}
],
discountCodes: [],
deliveryMethods: [],
subtotal: {
amount: 18.00,
currencyCode: "USD"
},
totalTax: {
amount: 1.25,
currencyCode: "USD"
},
total: {
amount: 19.25,
currencyCode: "USD"
},
presentmentCurrency: "USD",
locale: 'en',
});

const session = window.ShopPay.PaymentRequest.createSession({
paymentRequest: initialPaymentRequest
});

Anchor to Attach event listenersAttach event listeners

Use ShopPayPaymentRequestSessionCreate on your server to create a session.

session.addEventListener("sessionrequested", (ev) => {
// Shop Pay Payment Request Session on your server
const response = fetch('/replace_with_your_endpoint', {
method: 'POST',
body: JSON.stringify({
payment_request: initialPaymentRequest
}),
headers: {
'Content-Type': 'application/json',
},
}).then(response => response.json()).then(data => {
const {token, checkoutUrl, sourceIdentifier} = data;
// optionally update the payment request if it has changed since it was created
const updatedPaymentRequest = window.ShopPay.PaymentRequest.build({YOUR_UPDATED_PAYMENT_REQUEST});
session.completeSessionRequest({token, checkoutUrl, sourceIdentifier, updatedPaymentRequest});
});
});

Listen to events that may change calculations such as when a delivery method type, shipping address, delivery method, pickup location, pickup location filter, or discount code changes. Recalculate the payment request and update the session.

session.addEventListener("deliverymethodtypechanged", async (ev) => {
const currentPaymentRequest = session.paymentRequest;
const deliveryMethodType = ev.deliveryMethodType;

let pickupLocations = [];
if (deliveryMethodType === 'PICKUP') {
pickupLocations = await fetchPickupLocations();
}

// Update the payment request based on the delivery method type change
const updatedPaymentRequest = window.ShopPay.PaymentRequest.build({
...currentPaymentRequest,
pickupLocations,
});

session.completeDeliveryMethodTypeChange({ updatedPaymentRequest: updatedPaymentRequest });
});
session.addEventListener("shippingaddresschanged", async (ev) => {
const currentPaymentRequest = session.paymentRequest;
const selectedAddress = ev.shippingAddress;

// Update the payment request based on the shipping address change
const updatedPaymentRequest = window.ShopPay.PaymentRequest.build({
...currentPaymentRequest,
deliveryMethods: [
{
label: "Standard",
amount: {
amount: 10.00,
currencyCode: "USD"
},
code: "STANDARD",
minDeliveryDate: '2024-01-01',
maxDeliveryDate: '2027-01-01',
},
{
label: "Express",
amount: {
amount: 20.00,
currencyCode: "USD"
},
code: "EXPRESS",
minDeliveryDate: '2024-01-01',
maxDeliveryDate: '2026-01-01',
}
]
});

session.completeShippingAddressChange({ updatedPaymentRequest: updatedPaymentRequest });
});
session.addEventListener("deliverymethodchanged", async (ev) => {
const currentPaymentRequest = session.paymentRequest;
const selectedDeliveryMethod = ev.deliveryMethod;

let updatedRequestValues;

if (selectedDeliveryMethod) {
updatedRequestValues = {shippingLines: [{
label: selectedDeliveryMethod.label,
amount: selectedDeliveryMethod.amount,
code: selectedDeliveryMethod.code
}],
totalShippingPrice: {
finalTotal: {
amount: selectedDeliveryMethod.amount.amount,
currencyCode: "USD",
},
},
total: {
amount: 20 + selectedDeliveryMethod.amount.amount,
currencyCode: "USD"
}}
} else {
updatedRequestValues= {total: {
amount: 20,
currencyCode: "USD"
}}
}

// Update the payment request based on the delivery method change
// and update the totals accordingly
const updatedPaymentRequest = window.ShopPay.PaymentRequest.build({
...currentPaymentRequest,
...updatedRequestValues,
});

session.completeDeliveryMethodChange({ updatedPaymentRequest: updatedPaymentRequest });
});
session.addEventListener("pickuplocationchanged", async (ev) => {
const currentPaymentRequest = session.paymentRequest;
const pickupLocation = ev.pickupLocation;

// Update the payment request based on the pickup location change
// and update the totals accordingly
const updatedPaymentRequest = window.ShopPay.PaymentRequest.build({
...currentPaymentRequest,
totalShippingPrice: {
finalTotal: {
amount: pickupLocation.amount.amount,
currencyCode: "USD",
},
},
total: {
amount: 20 + pickupLocation.amount,
currencyCode: "USD"
},
});

session.completePickupLocationChange({ updatedPaymentRequest: updatedPaymentRequest });
});
session.addEventListener("pickuplocationfilterchanged", async (ev) => {
const currentPaymentRequest = session.paymentRequest;
const buyerLocation = ev.buyerLocation;

// Update the payment request based on the pickup location filter change
// by filtering the available pickup locations based on a customer's location
const updatedPaymentRequest = window.ShopPay.PaymentRequest.build({
...currentPaymentRequest,
pickupLocations: [{
label: "620 King Street West",
code: "PICK_UP-KING-STREET-WEST",
detail: "620 King Street West, Toronto, ON",
amount: {
amount: 10.00,
currencyCode: "USD"
},
readyExpectationLabel: "Ready in 1 hour",
proximityLabel: "Less than 1 km away",
}]
});

session.completePickupLocationFilterChange({ updatedPaymentRequest: updatedPaymentRequest });
});
session.addEventListener("discountcodechanged", async (ev) => {
const currentPaymentRequest = session.paymentRequest;
const selectedDiscountCodes = ev.discountCodes; // Array of discount codes ["example-code-1"]

// Update the payment request based on the discount code change
// Let's assume the discount code is valid and the discount is 15% off
const updatedPaymentRequest = window.ShopPay.PaymentRequest.build({
...currentPaymentRequest,
discountCodes: selectedDiscountCodes,
lineItems: [
{
label: "T-Shirt",
finalItemPrice: {
amount: 10.00,
currencyCode: "USD"
},
quantity: 2,
sku: "t-shirt",
requiresShipping: true,
finalLinePrice: {
amount: 20.00,
currencyCode: "USD"
},
}
],
subtotal: {
amount: 20.00,
currencyCode: "USD"
},
discounts: [
{
label: "example-code-1",
amount: {
amount: 3.00 // Discounts must be passed to Shopify as a positive value
currencyCode: "USD"
}
}
],
totalTax: {
amount: 1.06,
currencyCode: "USD"
},
total: {
amount: 18.06,
currencyCode: "USD"
}
});

session.completeDiscountCodeChange({ updatedPaymentRequest: updatedPaymentRequest });
});

Confirm the payment once the user clicks the Pay now button in the Shop Pay popup.

The server confirmation must invoke the ShopPayPaymentRequestSessionSubmit mutation to confirm that the payment is to be processed. Use ShopPayPaymentRequestSessionSubmit on your server to submit the session.

session.addEventListener("paymentconfirmationrequested", async (ev) => {
// The customer's billing address contains relevant contact details such as email & phone number (if available)
const billingAddress = ev.billingAddress;
// Before submitting the payment request for processing, a final check should be done on your server
// to make sure the payment request (total price, inventory available, etc.) is still valid.
const response = fetch('/replace_with_your_endpoint', {
method: 'POST',
body: JSON.stringify({
token: session.token,
payment_request: session.paymentRequest
}),
headers: {
'Content-Type': 'application/json',
},
}).then(response => response.json()).then(data => {
if (data.errors) {
// Handle errors here.
// For example: if an item is no longer in stock, you can send a new paymentRequest without that lineItem by building a new payment request and including it in completePaymentConfirmationRequest along with the errors.
session.completePaymentConfirmationRequest({
errors: [
{
"type": "generalError",
"message": "Something went wrong. Please try again."
}
// Optionally build an updated paymentRequest and include it here
]
})
} else {
// confirm the payment request is processing
session.completePaymentConfirmationRequest();
}
});
});

This event is dispatched when the payment is complete. Close the Shop Pay popup and redirect the user to the order confirmation page.

session.addEventListener("paymentcomplete", async (ev) => {
console.log(ev.processingStatus.status);

session.close(); // close the Shop Pay popup
window.location.href = "/thank-you";
});

This event is dispatched when a payment attempt fails. The event contains information about why the payment failed.

session.addEventListener("paymentattemptfailed", async (ev) => {
const { reason, errorCode } = ev.error;
console.log(`Payment attempt failed: ${reason}`);
console.log(`Error code: ${errorCode}`);
});

This event is dispatched when the checkout window is closed.

session.addEventListener("windowclosed", async () => {
// handle window closed event
});
Warning

Only call the corresponding complete call once for each event.


Anchor to API Reference: FrontendAPI Reference: Frontend

Anchor to ShopPayPaymentRequestSessionShopPayPaymentRequestSession

These events are what Shopify will emit as the user interacts with Shop Pay which you must listen for and respond accordingly. See examples above.

interface ShopPayPaymentRequestSession {
// Requires a server call
sessionrequested: EventHandler<ShopPaySessionRequestedEvent>;
completeSessionRequest(sessionRequestResponse: {token, checkoutUrl, sourceIdentifier} & ShopPayPaymentRequestUpdate): void;

// Dispatched as the user changes various fields
deliverymethodtypechanged: EventHandler<DeliveryMethodTypeChangedEvent>;
completeDeliveryMethodTypeChange(update: ShopPayPaymentRequestUpdate): void;

pickuplocationchanged: EventHandler<PickupLocationChangedEvent>;
completePickupLocationChange(update: ShopPayPaymentRequestUpdate);

pickuplocationfilterchanged: EventHandler<PickupLocationFilterChangedEvent>;
completePickupLocationFilterChange(update: ShopPayPaymentRequestUpdate);

shippingaddresschanged: EventHandler<ShopPayShippingAddressChangedEvent>;
completeShippingAddressChange(update: ShopPayPaymentRequestUpdate): void;

deliverymethodchanged: EventHandler<ShopPayDeliveryMethodChangedEvent>;
completeDeliveryMethodChange(update: ShopPayPaymentRequestUpdate): void;

discountcodechanged: EventHandler<ShopPayDiscountCodeChangedEvent>;
completeDiscountCodeChange(update: ShopPayPaymentRequestUpdate): void;

// Dispatched once a customer clicks the Pay button in order to confirm
// the payment should be processed
paymentconfirmationrequested: EventHandler<ShopPayPaymentConfirmationRequestedEvent>;
completePaymentConfirmationRequest(update: ShopPayPaymentRequestUpdate): void;

// Dispatched after a payment processing attempt
paymentcomplete: EventHandler<ShopPayPaymentCompleteEvent>;

// Dispatched when a payment attempt has failed
paymentattemptfailed: EventHandler<ShopPayPaymentAttemptFailedEvent>;

// Dispatched after the checkout window is closed
windowclosed: EventHandler<WindowClosedEvent>;

// Cancels the session
close(): void;
}

interface ShopPayPaymentRequestUpdate {
updatedPaymentRequest?: ShopPayPaymentRequest;
errors?: ShopPayUserError[];
}
Field nameTypeDescription
sessionrequestedEvent HandlerThis event handler is triggered when a new Shop Pay session is requested. The listener must make a server-to-server call from your backend to Shop Pay's servers, and then call completeSessionRequest() from your frontend with the response.
completeSessionRequest(args: {token: string, checkoutUrl: string, sourceIdentifier: string} & ShopPayPaymentRequestUpdate) => voidThis function completes the session request. It must be invoked with the token, checkoutUrl, and sourceIdentifier from response of the ShopPayPaymentRequestSessionCreate mutation. You can optionally include an updated payment request.
deliverymethodtypechangedEvent HandlerThis event handler is triggered when a customer changes their preferred delivery method. When this event is triggered, completeDeliveryMethodTypeChange() must be called with the updated payment request.
completeDeliveryMethodTypeChange(args: ShopPayPaymentRequestUpdate) => voidThis function must be called when the delivery method type changes.
pickuplocationchangedEvent HandlerThis event handler is triggered when a customer changes the selected pickup location. completePickupLocationChange() must be called with the updated payment request.
completePickupLocationChange(args: ShopPayPaymentRequestUpdate) => void)This function must be called when the selected pickup location changes.
pickuplocationfilterchangedEvent HandlerThis event handler is triggered when the pickup location filter changes. completePickupLocationFilterChange() must be called with an updated payment request containing a filtered set of pickup locations.
completePickupLocationFilterChange(args: ShopPayPaymentRequestUpdate) => voidThis function must be called when the pickup location filter changes.
shippingaddresschangedEvent HandlerThis event handler is triggered when a customer changes their preferred shipping address. When this event is triggered, completeShippingAddressChange() must be called with the updated payment request.
completeShippingAddressChange(args: ShopPayPaymentRequestUpdate) => voidThis function must be called when the shipping address changes.
deliverymethodchangedEvent HandlerThis event handler is triggered when a customer changes their preferred delivery method. When this event is triggered, completeDeliveryMethodChange() must be called with the updated payment request.
completeDeliveryMethodChange(args: ShopPayPaymentRequestUpdate) => voidThis function must be called when the updated payment request.
discountcodechangedEvent HandlerThis event handler is triggered when the discount code changes. When this event is triggered, completeDiscountCodeChange() must be called with the updated payment request.
completeDiscountCodeChange(args: ShopPayPaymentRequestUpdate) => voidThis function updates the payment request after discount codes are changed by providing a updated payment request.
paymentconfirmationrequestedEvent HandlerThis event handler is triggered after a customer clicks the Pay button. The event includes the customer's billingAddress as a ShopPayContactField object. The ShopPayPaymentRequestSessionSubmit mutation must be invoked, then completePaymentConfirmationRequest() must be called afterwards.
completePaymentConfirmationRequest(args: ShopPayPaymentRequestUpdate) => voidThis function is used to confirm that Shopify must proceed with payment. If there are any errors, they must be provided in the errors field. If updatedPaymentRequest is given, errors must also be given.
paymentcompleteEvent HandlerThis event handler is triggered after Shopify successfully processes a payment. The event payload has a .processingStatus field of type ShopPayPaymentRequestReceiptCompleted.
paymentattemptfailedEvent HandlerThis event handler is triggered when a payment attempt has failed. The event payload has a .error field with details about why the payment attempt failed.
close() => voidThis function cancels the session and closes the popup.
windowclosedEventHandlerThis event handler is triggered after the checkout window is closed.

Anchor to ShopPayPaymentRequestShopPayPaymentRequest

A payment request is the primary means of communication between your system and Shop Pay.

Shop Component properties
Warning

The frontend ShopPayPaymentRequest, used to display the payment request in the Shop Pay popup, is different from the backend ShopPayPaymentRequestInput, used in mutations as part of payment processing.

interface ShopPayPaymentRequest {
supportedDeliveryMethodTypes?: ShopPayDeliveryMethodType[];
selectedDeliveryMethodType?: ShopPayDeliveryMethodType;
pickupLocations?: ShopPayPickupLocation[];
paymentMethod?: string;
discountCodes: string[];
lineItems: ShopPayLineItem[];
shippingLines: ShopPayShippingLine[];
deliveryMethods: ShopPayDeliveryMethod[]
locale: ShopPayLocale;
presentmentCurrency: ShopPayCurrencyCode;
subtotal: ShopPayMoney;
discounts?: ShopPayDiscountLine[];
totalShippingPrice?: ShopPayTotalShippingPrice;
totalTax?: ShopPayMoney;
total: ShopPayMoney;
}
Field nameTypeDescription
supportedDeliveryMethodTypesShopPayDeliveryMethodType[] (optional)The supported delivery method types for this checkout. Defaults to ["SHIPPING"].
selectedDeliveryMethodTypeShopPayDeliveryMethodType (optional)The selected delivery method type.
pickupLocationsShopPayPickupLocation (optional)The available pickup locations when the selected delivery method type is PICKUP.
paymentMethodstring (optional)The one time use payment token, included only in the paymentconfirmationrequested event.
discountCodesShopPayDiscountCode[]All applied discount codes, displayed under the discount code field as tags.
lineItemsShopPayLineItem[]The line items to display.
shippingLinesShopPayShippingLine[]The shipping line items to display.
deliveryMethodsShopPayDeliveryMethod[]The available delivery methods.
localeShopPayLocaleA locale iso code such as 'en' used to inform the display of instructions and amounts.
presentmentCurrencyShopPayCurrencyCodeThe three-letter currency code that represents the world currency for the transaction. These include standard ISO 4217 codes, legacy codes, and non-standard codes.
subtotalShopPayMoneyThe subtotal of the line items, calculated as the sum of the finalLinePrice from all lines.
discountsShopPayDiscountLine[] (optional)All discounts applied to the subtotal. These must be positive values.
totalShippingPriceShopPayTotalShippingPrice (optional)The total shipping price after all applicable discounts, not including tax.
totalTaxShopPayMoney (optional)The total tax from all line items and shipping charges.
totalShopPayMoneyThe grand total includes all applicable discounts, shipping charges, and taxes. The customer will be charged this amount.

Anchor to ShopPayDeliveryMethodTypeShopPayDeliveryMethodType

One of the following delivery method types:

  • PICKUP - The customer will buy online and pickup the order.
  • SHIPPING - The customer's order will be shipped.

Represents line items in a payment request including cart line items, order-level line items such as discounts and taxes, and the grand total.

Shop Component line item properties
interface ShopPayLineItem {
label: string;
quantity: number;
sku?: string;
requiresShipping?: boolean;
image?: ShopPayLineItemImage;
originalItemPrice?: ShopPayMoney;
itemDiscounts?: ShopPayDiscountLine[];
finalItemPrice: ShopPayMoney;
originalLinePrice?: ShopPayMoney;
lineDiscounts?: ShopPayDiscountLine[];
finalLinePrice: ShopPayMoney;
}
Field nameTypeDescription
labelstringThe label for the line item.
quantitynumberThe quantity of the line item.
skustring (optional)The merchandise SKU if needed for inventory tracking and reporting.
requiresShippingboolean (optional)Whether the line item requires shipping. Defaults to true.
imageShopPayLineItemImage (optional)The image associated with the line item.
originalItemPriceShopPayMoney (optional)The original price of the item. Used to show price before any applicable discounts are applied, and must be included for all non-free items.
itemDiscountsShopPayDiscountLine[] (optional)All discounts applied to the item. These must be positive values.
finalItemPriceShopPayMoneyThe final price of the item after all applicable discounts.
originalLinePriceShopPayMoney (optional)The original price of the line item. Used to show price before any applicable discounts are applied, and must be included for all non-free lineItems.
lineDiscountsShopPayDiscountLine[] (optional)All discounts applied to the line item.
finalLinePriceShopPayMoneyThe final price of the line item based on quantity * item price including all applicable discounts.

Anchor to ShopPayLineItemImageShopPayLineItemImage

The image associated with the line item.

interface ShopPayLineItemImage {
url: string;
alt?: string;
}
Field nameTypeDescription
urlstringThe URL of the image. Recommended: 128x128px, 1:1 ratio image.
altstring (optional)The alt text associated with the image.

Anchor to ShopPayTotalShippingPriceShopPayTotalShippingPrice

Represents the total shipping price in a payment request.

Shop Component total shipping price
interface ShopPayTotalShippingPrice {
discounts?: ShopPayDiscountLine[];
originalTotal?: ShopPayMoney;
finalTotal: ShopPayMoney;
}
Field nameTypeDescription
discountsShopPayDiscountLine[] (optional)All discounts applied to the shipping price. These must be positive values.
originalTotalShopPayMoney (optional)The original total shipping price. Used to show shipping price before any applicable discounts are applied, and must be included for all non-free shipping methods.
finalTotalShopPayMoneyThe final total shipping price. Price after all applicable discounts.

Represents discount lines in a payment request.

interface ShopPayDiscountLine {
label: string;
amount: ShopPayMoney;
}
Field nameTypeDescription
labelstringThe label for the discount line.
amountShopPayMoneyThe amount of the discount as a positive value.

Represents shipping line items in a payment request.

interface ShopPayShippingLine {
label: string;
amount: ShopPayMoney;
code: string;
}
Field nameTypeDescription
labelstringThe label for the shipping line item.
amountShopPayMoneyThe amount of the shipping line item.
codestringThe service code of the shipping rate. Corresponds to ShopPayDeliveryMethod#code.

Represents an amount and the associated currency.

Field nameTypeDescription
amountnumber
currencyCodeShopPayCurrencyCode

Represents contact information for shipping or billing addresses. This interface is used to capture customer shipping and contact details during the checkout process.

Field nameTypeDescription
countryCodestringThe country ISO-3166 code of the contact.
postalCodestring (optional)The postal code of the contact.
provinceCodestring (optional)The province (or state) ISO-3166 code of the contact.
citystringThe city of the contact.
firstNamestring (optional)The first name of the contact.
lastNamestringThe last name of the contact.
address1stringThe address of the contact.
address2string (optional)The address2 of the contact.
phonestring (optional)The phone number of the contact.
emailstring (optional)The email address of the contact.
companyNamestring (optional)The company name of the contact.

Anchor to ShopPayPickupLocationShopPayPickupLocation

Represents an available order pickup location. Pickup locations are displayed to a customer if they select PICKUP as the delivery method type.

interface ShopPayPickupLocation {
label: string;
detail: string;
code: string;
amount: ShopPayMoney;
readyExpectationLabel?: string;
proximityLabel?: string;
}
Field nameTypeDescription
labelstringThe label for the pickup location.
detailstringThe detail describing the pickup location.
codestringThe code for the pickup location used to uniquely identify it.
amountShopPayMoneyThe amount of the pickup.
readyExpectationLabelstring (optional)The description of when the order will be ready for pickup.
proximityLabelstring (optional)The description for the proximity of the pickup location relative to the customer.

Anchor to ShopPayDeliveryMethodShopPayDeliveryMethod

Shop Component delivery methods
interface ShopPayDeliveryMethod {
code: string;
label: string;
detail?: string;
amount: ShopPayMoney;
minDeliveryDate?: ISO8601Date;
maxDeliveryDate?: ISO8601Date;
deliveryExpectationLabel?: string;
}
Field nameTypeDescription
codestringThe service code of the shipping rate.
labelstringThe service name of the shipping rate.
detailstring (optional)The description of the shipping rate.
amountShopPayMoneyThe total price amount of the shipping rate.
minDeliveryDateISO8601Date (optional)The minimum delivery date. ISO 8601-encoded date string. Required unless deliveryExpectationLabel provided.
maxDeliveryDateISO8601Date (optional)The maximum delivery date. ISO 8601-encoded date string. Required unless deliveryExpectationLabel provided.
deliveryExpectationLabelString (optional)If provided, will be displayed as further detail for expected delivery, replacing the calculated delivery estimate.

Anchor to ShopPayPaymentRequestUpdateShopPayPaymentRequestUpdate

Represents an updated state of the checkout. At least one of an updated payment request and an array of errors should be provided.

Field nameTypeDescription
updatedPaymentRequestShopPayPaymentRequest (optional)The updated payment request. If not provided, the current payment request will continue to be used.
errorsShopPayUserError[] (optional)An array of errors.

Anchor to PickupLocationChangedEventPickupLocationChangedEvent

Dispatched when a customer changes their pickup location.

interface PickupLocationChangedEvent extends Event {
pickupLocation: ShopPayPickupLocation;
}
Field nameTypeDescription
pickupLocationShopPayPickupLocationThe customer's pick up location.

Anchor to PickupLocationFilterChangedEventPickupLocationFilterChangedEvent

Dispatched when a customer changes their pickup location filter.

interface PickupLocationFilterChangedEvent extends Event {
buyerLocation: ShopPayBuyerLocation;
}
Field nameTypeDescription
buyerLocationShopPayBuyerLocationThe customer's location used to filter pickup locations.

Anchor to DeliveryMethodTypeChangedEventDeliveryMethodTypeChangedEvent

Dispatched when a customer changes their delivery method type.

interface DeliveryMethodTypeChangedEvent extends Event {
deliveryMethodType: ShopPayDeliveryMethodType;
}
Field nameTypeDescription
deliveryMethodTypeShopPayDeliveryMethodTypeThe delivery method type selected by the user.

Anchor to ShopPayBuyerLocationShopPayBuyerLocation

Represents a customer's location. Use this to set the available pickup locations.

interface ShopPayBuyerLocation {
address1?: string;
address2?: string;
city?: string;
provinceCode?: string;
countryCode?: string;
postalCode?: string;
coordinates?: {
latitude: number;
longitude: number;
};
}
Field nameTypeDescription
address1stringThe address of the contact.
address2string (optional)The address2 of the contact.
citystringThe city of the contact.
provinceCodestring (optional)The province (or state) ISO-3166 code of the contact.
countryCodestringThe country ISO-3166 code of the contact.
postalCodestring (optional)The postal code of the contact.
coordinates.latitudenumber (optional)The latitude of the customer's location.
coordinates.longitudenumber (optional)The longitude of the customer's location.

Anchor to ShopPayPaymentConfirmationRequestedEventShopPayPaymentConfirmationRequestedEvent

Dispatched when a customer clicks the Pay now button to confirm their payment. This event includes the customer's billing address.

interface ShopPayPaymentConfirmationRequestedEvent extends Event {
billingAddress: ShopPayContactField;
}
Field nameTypeDescription
billingAddressShopPayContactFieldThe customer's billing address and contact info.

Anchor to ShopPayPaymentRequestReceiptCompletedShopPayPaymentRequestReceiptCompleted

A successful completed receipt. Note the status will be completed. This event only occurs if the payment is successfully processed.

interface ShopPayPaymentRequestReceiptCompleted {
completedAt: ISO8601Date;
billingAddress: {
countryCode: string;
postalCode?: string;
provinceCode?: string;
city?: string;
firstName?: string;
lastName?: string;
address1?: string;
phone?: string;
};
creditCardDetails?: {
brand?: string;
lastDigits?: string;
};
paymentType: "SHOP_PAY" | "SHOPIFY_INSTALLMENTS";
accountUrl?: string;
status: "completed";
}
Field nameTypeDescription
completedAtISO8601DateThe date the receipt was completed.
billingAddressShopPayContactFieldThe billing address of the customer.
creditCardDetails{brand?: string, lastDigits?: string}The credit card details of the customer.
paymentType"SHOP_PAY" or "SHOPIFY_INSTALLMENTS"The type of payment used.
accountUrlstring (optional)The URL to the customer's account.
status"completed"The status of the receipt.

Anchor to ShopPayPaymentAttemptFailedEventShopPayPaymentAttemptFailedEvent

Dispatched when a payment attempt has failed. This can happen due to various reasons such as insufficient funds, invalid payment details, or other payment processing errors.

Note

Buyers have the option to select a different payment method to retry their checkout after a failure. Do not call session.close() to allow users to retry with a new payment method without disrupting their session.

interface ShopPayPaymentAttemptFailedEvent extends Event {
error: {
errorCode: string;
reason: string;
};
}
Field nameTypeDescription
error{errorCode: string, reason: string}The reason why the payment attempt failed.

Represents an error that is surfaced to the user during checkout.

Shop Component general error
Shop Component discount code error
Shop Component shipping address error
Field nameTypeDescription
type'generalError' or 'discountCodeError' or 'shippingAddressError'The context of the error.
messagestring (optional)The localized message shown to the user.
  • generalError - These errors are shown at the top of the checkout. Although we recommend setting your own message, the error text will be defaulted to "Something went wrong. Please close Shop Pay and try again".
  • discountCodeError - These errors are shown near discount code entry. For example, to indicate that a discount code is expired. Although we recommend setting your own message, the error text will be defaulted to "Enter a valid discount code".
  • shippingAddressError - These errors are shown near shipping address selection. For example, in order to indicate that the selected shipping address is undeliverable to. Although we recommend setting your own message, the error text will be defaulted to "Shipping not available for selected address".
Note

A maximum of two errors can be displayed at any given time. If more than two errors are provided, only the first two will be shown. Each error message has a character limit of 500; any message exceeding this limit will be truncated. Only plain text is supported for error messages. Any HTML or other formatting will be removed.


Once a customer clicks Pay, the paymentconfirmationrequested event will be triggered on your frontend containing the paymentMethod token.

Execute the ShopPayPaymentRequestSessionSubmit mutation in order to confirm the payment. Once that is complete, call session.completePaymentConfirmationRequest on your frontend to continue. A payment complete event will be dispatched.

Based on payment capture configuration in Payments settings in the Shopify admin, the payment will be processed as a authorized or capture. If manual capture is configured, you must call the orderCapture mutation using the Shopify Admin API to finalize the payment. See orderCapture for more information.

When creating an order in Shopify, it may not be immediately available to query, and the orders/create webhook may not fire immediately. It's important to ensure that neither of these is required for real-time functionality of your app. See Recovering from errors for more information on making your app resilient to webhook delivery issues.


Anchor to API Reference: GraphQL Pre-paymentAPI Reference: GraphQL Pre-payment

These mutations are used with the Storefront API to affect the Shop Pay payment request session.

Anchor to Example: ShopPayPaymentRequestSessionCreateExample: ShopPayPaymentRequestSessionCreate

Details about the ShopPayPaymentRequestSessionCreate mutation can be found on the dedicated Storefront API ShopPayPaymentRequestSessionCreate page.

Mutation

mutation shopPayPaymentRequestSessionCreate($sourceIdentifier: String!, $paymentRequest: ShopPayPaymentRequestInput!) {
shopPayPaymentRequestSessionCreate(sourceIdentifier: $sourceIdentifier, paymentRequest: $paymentRequest) {
shopPayPaymentRequestSession {
token
sourceIdentifier
checkoutUrl
paymentRequest {
…
}
}
userErrors {
field
message
}
}
}

Input

{
"sourceIdentifier": "xyz123",
"paymentRequest": {
// …
}
}

Response

{
"shopPayPaymentRequestSessionCreate": {
"shopPayPaymentRequestSession": {
"sourceIdentfier": "xyz123",
"token": "db4eede13822684b13a607823b7ba40d",
"checkoutUrl": "https://shop.app/checkout/1/spe/db4eede13822684b13a607823b7ba40d/shoppay",
"paymentRequest": {
// …
}
},
"userErrors": []
}
}

Anchor to ShopPayPaymentRequestSessionCreate ArgumentsShopPayPaymentRequestSessionCreate Arguments

ArgumentTypeDescription
sourceIdentifierString!A unique identifier for the source of the order.
paymentRequestShopPayPaymentRequestInput!The payment request details.

Source Identifier

The sourceIdentifier must be unique across all orders to ensure accurate tracking and referencing. For instance, it could be a unique ID associated with an order or checkout on your platform.

Anchor to ShopPayPaymentRequestSessionShopPayPaymentRequestSession

FieldTypeDescription
tokenStringThe unique token for the payment request session.
sourceIdentifierStringA unique identifier for the source of the order.
checkoutUrlStringThe URL for the checkout associated with the payment request session.
paymentRequestShopPayPaymentRequestThe payment request associated with the session.

FieldTypeDescription
fieldStringThe field that caused the error.
messageStringThe error message.

Anchor to Example: ShopPayPaymentRequestSessionSubmitExample: ShopPayPaymentRequestSessionSubmit

Details about the ShopPayPaymentRequestSessionSubmit mutation can be found on the dedicated Storefront API ShopPayPaymentRequestSessionSubmit page.

Mutation

mutation shopPayPaymentRequestSessionSubmit($token: String!, $paymentRequest: ShopPayPaymentRequestInput!, $idempotencyKey: String!, $orderName: String) {
shopPayPaymentRequestSessionSubmit(token: $token, paymentRequest: $paymentRequest, idempotencyKey: $idempotencyKey, orderName: $orderName) {
paymentRequestReceipt {
token
processingStatusType
}
userErrors {
field
message
}
}
}

Input

{
"token": "db4eede13822684b13a607823b7ba40d",
"paymentRequest": {
…
},
"idempotencyKey": "REPLACE_ME_WITH_A_UNIQUE_KEY",
}

Response

{
"shopPayPaymentRequestSessionSubmit": {
"paymentRequestReceipt": {
"token": "a607823b7ba40ddb4eede13822684b13",
"processingStatusType": "ready"
},
"userErrors": []
}
}

FieldTypeDescription
tokenString!The unique token for the payment request session.
paymentRequestShopPayPaymentRequestInput!The payment request details.
idempotencyKeyString!A unique string (typically a UUID or similar identifier) that must be attached to the submit request to ensure that payment transactions occur only once. For more information, see idempotent requests.
orderNameStringThe name to be assigned to the order that is created from the payment request.

Anchor to PaymentRequestReceiptPaymentRequestReceipt

FieldTypeDescription
tokenStringThe unique token for the payment request receipt. This will be different than session token.
processingStatusTypeStringThe processing status of the payment request.
paymentRequestShopPayPaymentRequestThe details of the payment request.

FieldTypeDescription
fieldStringThe field that caused the error.
messageStringThe error message.

Anchor to API Reference: GraphQL Post-paymentAPI Reference: GraphQL Post-payment

The post-payment process may involve capturing payments, adding tracking fulfillments, and issuing refunds. This section provides examples of how to use the Shopify GraphQL Admin API for these tasks.

Captures payment for an authorized transaction on an order if the Payments setting has been configured to manual. Using the order ID, you can fetch an order and orderTransaction, then call Admin API orderCapture mutation to capture the authorized payment.

Here is an example of how to use the orderCapture mutation:

Mutation

mutation orderCapture($input: OrderCaptureInput!) {
orderCapture(input: $input) {
transaction {
id
amountSet {
shopMoney {
amount
currencyCode
}
presentmentMoney {
amount
currencyCode
}
}
kind
status
}
userErrors {
field
message
}
}
}

Input

{
"input": {
"amount": "10.00",
"currency": "USD",
"id": "gid://shopify/Order/1",
"parentTransactionId": "gid://shopify/OrderTransaction/2"
}
}

Response

{
"orderCapture": {
"transaction": {
"id": "gid://shopify/OrderTransaction/3",
"amountSet": {
"shopMoney": {
"amount": "10.00",
"currencyCode": "USD"
},
"presentmentMoney": {
"amount": "10.00",
"currencyCode": "USD"
}
},
"kind": "CAPTURE",
"status": "SUCCESS"
},
"userErrors": []
}
}

As a merchant using Shop Component, you have access to multi-capture, and are able to execute partial captures by providing any amount less than the currently un-captured amount.

For the first partial capture made against an authorization, you're also able to void the remaining authorization left after capturing an amount by including "finalCapture": true in your partial capture input. See details in the orderCapture documentation.

Note

Once an authorization has been partially captured, it can no longer be voided by any means. It must either be captured, or left to expire after the 7 to 30 day authorization period.

With Extended Authorizations, you may capture payments beyond 7 days on most card types for a small fee. For more information, see Credit card authorization periods.

You're also able to use the Order Authorization API to void an authorization and then replace it with a new authorization.

By combining partial captures using "finalCapture": true, with the Order Authorization API to create new authorizations, you're able to re-issue an authorization for the un-captured amount, while also minimizing times where authorized amounts are held on a customer's card for items they've cancelled before fulfillment.

While you may choose to re-issue authorizations immediately after void or expiration in order to maintain an active authorization, it isn't necessary. Authorizations can be re-issued on demand, as long as the total amount captured + total amount currently authorized is less than the order total.

Anchor to Fulfillment trackingFulfillment tracking

You can fetch an order and fulfillment order using the order ID.

If the order is shipped with a tracking number, then you must run the fulfillmentCreate mutation to update the tracking information and fulfill the order. You can make subsequent updates to the tracking information using the fulfillmentTrackingInfoUpdate mutation.

If the order is for store pickup, then you should instead run the fulfillmentOrderLineItemsPreparedForPickup mutation to update the status.

Here is an example of how to use the fulfillmentCreate mutation:

Mutation

mutation fulfillmentCreate($fulfillment: FulfillmentInput!) {
fulfillmentCreate(fulfillment: $fulfillment) {
fulfillment {
id
status
trackingInfo(first: 10) {
company
number
url
}
}
userErrors {
field
message
}
}
}

Input

{
"fulfillment": {
"lineItemsByFulfillmentOrder": {
"fulfillmentOrderId": "gid://shopify/FulfillmentOrder/1"
},
"trackingInfo": {
"company": "UPS",
"number": "1Z001985YW99744790"
}
}
}

Response

{
"fulfillmentCreate": {
"fulfillment": {
"id": "gid://shopify/Fulfillment/1",
"status": "SUCCESS",
"trackingInfo": [
{
"company": "UPS",
"number": "1Z001985YW99744790",
"url": "https://www.ups.com/WebTracking?loc=en_US&requester=ST&trackNums=1Z001985YW99744790"
}
]
},
"userErrors": []
}
}

The following example shows how to use the fulfillmentOrderLineItemsPreparedForPickup mutation:

Mutation

mutation fulfillmentOrderLineItemsPreparedForPickup($input: FulfillmentOrderLineItemsPreparedForPickupInput!) {
fulfillmentOrderLineItemsPreparedForPickup(input: $input) {
userErrors {
field
message
}
}
}

Input

{
"input": {
"lineItemsByFulfillmentOrder": [
{
"fulfillmentOrderId": "gid://shopify/FulfillmentOrder/1046000776"
}
]
}
}

Response

{
"fulfillmentOrderLineItemsPreparedForPickup": {
"userErrors": []
}
}

Using the order ID returned from a completed checkout, you can run the refundCreate mutation:

Mutation

mutation refundCreate($input: RefundInput!) {
refundCreate(input: $input) {
refund {
id
transactions(first: 10) {
nodes {
id
kind
status
}
}
}
userErrors {
field
message
}
}
}

Input

{
"input": {
"currency": "USD",
"note": "Customer returned item",
"orderId": "gid://shopify/Order/1",
"transactions": [
{
"amount": "10.00",
"gateway": "shopify_payments",
"kind": "REFUND",
"orderId": "gid://shopify/Order/1",
"parentId": "gid://shopify/OrderTransaction/2"
}
]
}
}

Response

{
"refundCreate": {
"refund": {
"id": "gid://shopify/Refund/1",
"transactions": {
"nodes": [
{
"id": "gid://shopify/OrderTransaction/3",
"kind": "REFUND",
"status": "SUCCESS"
}
]
}
},
"userErrors": []
}
}

Anchor to Cancelling and deleting ordersCancelling and deleting orders

You can cancel orders in Shopify using the asynchronous orderCancel mutation which effectively stops the order from being further processed in Shopify:

Mutation

mutation OrderCancel($orderId: ID!, $notifyCustomer: Boolean, $refund: Boolean!, $restock: Boolean!, $reason: OrderCancelReason!, $staffNote: String) {
orderCancel(orderId: $orderId, notifyCustomer: $notifyCustomer, refund: $refund, restock: $restock, reason: $reason, staffNote: $staffNote) {
job {
id
done
}
jobResult {
id
done
}
orderCancelUserErrors {
field
message
code
}
}
}

Input

{
"orderId": "gid://shopify/Order/148977776",
"notifyCustomer": true,
"refund": true,
"restock": true,
"reason": "CUSTOMER",
"staffNote": "Wrong size. Customer reached out saying they already re-purchased the correct size."
}

Response

{
"orderCancel": {
"job": {
"id": "gid://shopify/Job/070bcd56-de0e-4985-bae8-c05be6365748",
"done": false
},
"jobResult": {
"id": "gid://shopify/OrderCancelJobResult/884324524",
"done": false
},
"orderCancelUserErrors": []
}
}

Localization is a crucial aspect of providing a seamless shopping experience for customers around the globe. The Shop Component API supports localization to ensure that customers can interact with the checkout process in their preferred language.

To set the locale, include the locale parameter when configuring the Shop Pay Payment Request. The locale parameter expects a valid ISO language code, with some locales followed by an ISO country code. See the Supported Locales List section for the full list.

window.ShopPay.PaymentRequest.configure({
shopId: 1,
clientId: "[REPLACE-ME.myshopify.com]",
locale: 'fr' // Example: Set locale to French
});
Note

If no locale is provided or if the provided locale is invalid, the default locale will be set to English (en).

Anchor to Supported Locales ListSupported Locales List

The following locales are supported by the Shop Component API:

Locale CodeLanguage
csCzech
daDanish
deGerman
enEnglish (Default)
esSpanish
fiFinnish
frFrench
hiHindi
itItalian
jaJapanese
koKorean
msMalay
nbNorwegian Bokmål
nlDutch
plPolish
pt-BRPortuguese - Brazil
pt-PTPortuguese - Portugal
svSwedish
thThai
trTurkish
zh-CNChinese - Simplified
zh-TWChinese - Traditional

Anchor to Monitoring & ResiliencyMonitoring & Resiliency

It's highly recommended to instrument your integration with sufficient logging to gain insights into any errors thrown by your system. At a minimum, failure paths in your event handlers should all be considered, and notifications should alert your team of issues as needed.

Shopify provides webhook subscriptions and APIs enabling multiple ways for you to monitor activity in your shop. The below guidelines are applicable to Shop Component.

Anchor to Webhook ConfigurationWebhook Configuration

At a minimum, you should be to setting up the following webhooks:

Webhook TopicDescription
ORDERS_CREATEA webhook is sent every time an order is created.
ORDER_TRANSACTIONS_CREATEA webhook is sent every time an order transaction is created.
DISPUTES_CREATEA webhook is sent every time a dispute is created. This requires the read_shopify_payments_disputes scope on your custom app.
DISPUTES_UPDATEA webhook is sent every time a dispute is updated. This requires the read_shopify_payments_disputes scope on your custom app.

It's important to note that webhook delivery may be delayed, and must therefore never be depended on for real-time critical workflows such as completing a customer checkout.

To learn more, see the webhook best practices guide, and our webhook topic resources for GraphQL and REST APIs.

Anchor to Creating a Webhook SubscriptionCreating a Webhook Subscription

Example of creating new webhook subscription for the topic "ORDERS_CREATE" using the webhookSubscriptionCreate mutation:

Mutation

mutation webhookSubscriptionCreate($topic: WebhookSubscriptionTopic!, $webhookSubscription: WebhookSubscriptionInput!) {
webhookSubscriptionCreate(topic: $topic, webhookSubscription: $webhookSubscription) {
webhookSubscription {
id
topic
format
uri
}
userErrors {
field
message
}
}
}

Input

{
"topic": "ORDERS_CREATE",
"webhookSubscription": {
"uri": "https://yoursite.com/webhooks/orders_create",
"format": "JSON"
}
}

Response

{
"webhookSubscriptionCreate": {
"webhookSubscription": {
"id": "gid://shopify/WebhookSubscription/1",
"topic": "ORDERS_CREATE",
"format": "JSON",
"uri": "https://yoursite.com/webhooks/orders_create"
},
"userErrors": []
}
}

A dispute, also known as a chargeback or inquiry, occurs when a customer questions the legitimacy of a charge with their financial institution.

To effectively manage disputes, you must either subscribe to the appropriate webhook topics and use the Shopify Admin API as necessary, or manage the disputes through the Shopify admin.

When a dispute is filed, you're able to provide additional information to support the legitimacy of the charge before the time limit. In any case, Shopify will ensure that evidence is submitted on your behalf, whether you take action or not.

Orders may also be eligible for Shopify Protect, in which case Shopify will reimburse you for the disputed amount and chargeback fee if it is lost.

For more information on dispute management, see the Shopify Payments Disputes Documentation.

Orders in Shopify will undergo a risk assessment after order creation. You can either query the OrderRiskSummary, or you can subscribe to the ORDERS_RISK_ASSESSMENT_CHANGED webhook. Orders can trigger automation events using Shopify Flow – see the flow reference risk examples for details.

Anchor to Recovering from errorsRecovering from errors

Although an order created event will be fired client-side when an order is completed, it's possible that a customer may close the window before the event is dispatched. In order to reconcile in such cases it is recommend to have a reconciliation job running on a schedule.

While webhook deliveries are recommended as the primary method for Shopify to trigger actions in your system, reconciliation jobs should always be implemented as well, as they serve multiple purposes:

  • In case the Shop Pay window is closed before the paymentcomplete event is dispatched
  • As a backup to webhooks, since webhooks may fail to be processed
  • To retrieve data which may not otherwise be available via webhook subscription

Anchor to Retrieving order data using the source identifierRetrieving order data using the source identifier

You can find shopPayPaymentRequestReceipts by their source_identifier (provided on ShopPayRequestSessionCreate mutation), which should correspond to the order in your system. For example, if the source identifier provided by your system for a given order was your-source-id-1, then you could issue a GraphQL request like below:

{
shopPayPaymentRequestReceipts(first:10, query: "source_identifier:'your-source-id-1'") {
nodes {
token
sourceIdentifier
processingStatus {
state
message
errorCode
}
order {
id
sourceIdentifier
transactions(first: 10) {
id
kind
errorCode
}
fulfillmentOrders(first: 10) {
nodes {
id
}
}
}
paymentRequest {
total {
amount
currencyCode
}
}
}
}
}

Note that while the above example request could result in multiple matching receipts, there will only be one corresponding order for a successfully completed receipt. The order may have multiple transactions (including failed payment attempts), fulfillmentOrders and lineItems.

Because of this, your system must filter the results received. For example with transactions you would filter by kind: "authorization" and status: "success" to identify the transaction authorization ID needed when capturing payment.

It's recommended to modify this example query to only retrieve the data required by your system, and introduce pagination where necessary.

Anchor to Retrieving order data using the receipt tokenRetrieving order data using the receipt token

Alternatively, order data can be retrieved using the shopPayPaymentRequestReceipt query. The receipt token is returned from the ShopPayPaymentRequestSessionSubmit mutation. This query can be used to find the status of the payment request receipt. The status can be processing, completed, action_required (for example, if the customer needs to complete a 3DS authentication. This is automatically handled by Shop Pay popup), or failed. The processingStatus message and errorCode can be used to provide more information about the status for failed receipts.

query {
shopPayPaymentRequestReceipt(token: "<token>") {
token
sourceIdentifier
processingStatus {
state
message
errorCode
}
order {
id
sourceIdentifier
transactions(first: 10) {
id
kind
errorCode
}
fulfillmentOrders(first: 10) {
nodes {
id
}
}
}
paymentRequest {
total {
amount
currencyCode
}
}
}
}

Anchor to Additional resourcesAdditional resources


Was this page helpful?