Skip to main content
RapidDev - Software Development Agency
retool-integrationsREST API Resource

How to Integrate Retool with Shift4Shop (formerly 3dcart)

Connect Retool to Shift4Shop (formerly 3dcart) using a REST API Resource configured with OAuth token authentication. Set the base URL and access token in the Resources tab, then build visual queries to manage products, orders, and customers. The setup takes about 20 minutes and lets your operations team run bulk actions faster than Shift4Shop's native admin.

What you'll learn

  • How to create a Shift4Shop REST API Resource in the Retool Resources tab with OAuth token authentication
  • How to query Shift4Shop orders, products, and customers using GET requests in the visual query editor
  • How to build an order management panel with filters, search, and status update actions
  • How to use JavaScript transformers to reshape Shift4Shop API responses for Retool Table components
  • How to create a product inventory panel with bulk update capabilities
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate17 min read20 minutesE-commerceLast updated April 2026RapidDev Engineering Team
TL;DR

Connect Retool to Shift4Shop (formerly 3dcart) using a REST API Resource configured with OAuth token authentication. Set the base URL and access token in the Resources tab, then build visual queries to manage products, orders, and customers. The setup takes about 20 minutes and lets your operations team run bulk actions faster than Shift4Shop's native admin.

Quick facts about this guide
FactValue
ToolShift4Shop (formerly 3dcart)
CategoryE-commerce
MethodREST API Resource
DifficultyIntermediate
Time required20 minutes
Last updatedApril 2026

Why Connect Retool to Shift4Shop?

Shift4Shop's built-in admin panel is designed for individual order and product management, but teams running high-volume e-commerce operations frequently outgrow its interface for bulk tasks. Operations teams need to filter orders across multiple criteria, update product stock in bulk, and view customer order histories without clicking through dozens of individual records. Connecting Retool to Shift4Shop's REST API lets you build a faster, more flexible admin panel that fits your team's workflow rather than the platform's default navigation.

Shift4Shop has undergone a significant rebrand from 3dcart to Shift4Shop, and many businesses using the platform are in a transitional state — maintaining legacy configurations while adapting to the new Shift4 payment integration requirements. A Retool panel built over the API provides a consistent operational interface regardless of which era of the platform your store is on, and can surface data from both the e-commerce layer and your internal databases in a single view.

The REST API Resource pattern in Retool is particularly well-suited for Shift4Shop because all requests are proxied server-side, which means your API credentials stay secure and you avoid the CORS issues that would arise from making API calls directly from a browser-based dashboard. This makes it straightforward to build tools that your warehouse staff, customer service agents, and merchandising teams can all use with appropriate Retool permission groups controlling who can read vs. write data.

Integration method

REST API Resource

Retool connects to Shift4Shop through a REST API Resource configured in the Resources tab. You set the store API URL and OAuth Private Token once, and all subsequent queries are built visually using method, path, and body fields. Retool proxies all requests server-side, eliminating CORS issues and keeping your access token off the browser. JavaScript transformers reshape the Shift4Shop JSON responses into the format your Table and Chart components expect.

Prerequisites

  • A Retool account (Cloud or self-hosted) with permission to add Resources
  • A Shift4Shop store with API access enabled (requires a paid plan; free plan does not include API access)
  • Your Shift4Shop store's Private API Token (found in Dashboard → API → Private Key in the store control panel)
  • Your store's API URL (format: https://apirest.3dcart.com — note that Shift4Shop still uses the 3dcart API domain)
  • Basic familiarity with the Retool app builder, query editor, and JavaScript transformer functions

Step-by-step guide

1

Add a Shift4Shop REST API Resource

Go to the Resources tab in Retool — click Resources in the left sidebar from the home page or use the top navigation menu. Click the blue Add Resource button in the upper right. In the resource type selector, search for 'REST' and select REST API to open the configuration form. Fill in the resource configuration: - Name: Enter 'Shift4Shop API' or 'Shift4Shop Production' to identify this resource clearly. - Base URL: Enter the Shift4Shop API base URL. Despite the rebrand, the API endpoint domain is still https://apirest.3dcart.com. The path for the REST API v2 endpoints is /3dCartWebAPI/v2 — you can include this in the base URL so your queries only need to specify the resource path (e.g., /Orders). For authentication, Shift4Shop uses two header-based credentials for all requests: 1. A store-specific Private Token passed as the SecureURL header 2. A public API key (available from Shift4Shop's developer program) passed as the PrivateKey header In the Headers section of the resource configuration, add two default headers: - Key: PrivateKey | Value: {{ retoolContext.configVars.SHIFT4SHOP_PRIVATE_KEY }} - Key: SecureURL | Value: your store's base URL (e.g., https://yourstore.3dcart.com) - Key: Content-Type | Value: application/json - Key: Accept | Value: application/json Before saving, go to Settings → Configuration Variables in Retool, click Add Variable, and create SHIFT4SHOP_PRIVATE_KEY as a secret variable containing your Private Token. Click Save to create the resource.

Pro tip: The Shift4Shop API still uses 3dcart domains for legacy API compatibility. If you see SSL or hostname errors, verify you are using https://apirest.3dcart.com as the base URL rather than any shift4shop.com domain.

Expected result: A Shift4Shop REST API resource appears in your Resources list. The private key is stored as a secret configuration variable and referenced securely in the resource headers.

2

Query Shift4Shop orders and display in a Table

Create your first data query to retrieve orders from Shift4Shop. In your Retool app, click + New in the query panel at the bottom of the screen. Select your Shift4Shop API resource. Set the HTTP Method to GET and the URL path to /Orders. In the URL Parameters section, add pagination and filtering parameters that reference components in your app: - limit: {{ select_pageSize.value || 100 }} — how many orders to return - offset: {{ (table_orders.pageIndex || 0) * 100 }} — for pagination - datestart: {{ dateRange.start ? new Date(dateRange.start).toISOString().split('T')[0] : '' }} - dateend: {{ dateRange.end ? new Date(dateRange.end).toISOString().split('T')[0] : '' }} - status: {{ statusSelect.value || '' }} Set the query to Run this query automatically when inputs change and trigger On page load. Add a JavaScript transformer to the query to reshape the response data — Shift4Shop returns an array of order objects directly: Drag a Table component onto the canvas and set its data source to {{ ordersQuery.data }}. Map columns to: order_id, customer_email, status, total, and order_date. Add a DateRange picker component and a Select component for order status above the Table. The query will re-run automatically when filters change. To make the order status filter options accurate, set the Select component's values to Shift4Shop's order status codes: New, Pending, Processing, Shipped, Partially Shipped, Cancelled, Hold.

ordersTransformer.js
1// JavaScript transformer to reshape Shift4Shop orders response
2const orders = Array.isArray(data) ? data : [];
3return orders.map(order => ({
4 order_id: order.OrderID,
5 invoice_no: order.InvoiceNumber || '',
6 customer_name: `${order.BillingFirstName || ''} ${order.BillingLastName || ''}`.trim(),
7 customer_email: order.BillingEmail || '',
8 status: order.OrderStatus,
9 total: parseFloat(order.OrderAmount || 0).toFixed(2),
10 order_date: order.OrderDate ? order.OrderDate.split('T')[0] : '',
11 ship_date: order.ShipDate ? order.ShipDate.split('T')[0] : 'Not shipped',
12 payment_method: order.PaymentMethod || ''
13}));

Pro tip: Shift4Shop returns order dates in ISO 8601 format. Split on 'T' to extract just the date portion for cleaner display in the Table, or use a full date formatter if your team needs to see the time component.

Expected result: The Table displays a paginated list of Shift4Shop orders with customer names, order totals, statuses, and order dates. The date range and status filters control which orders are shown.

3

Query products and build an inventory panel

Create a second query for product and inventory management. Click + New in the query panel and select your Shift4Shop API resource. Set the method to GET and the path to /Products. Add URL parameters for filtering and pagination: - limit: 200 (Shift4Shop allows up to 200 per request) - offset: {{ (productsTable.pageIndex || 0) * 200 }} - categoryid: {{ categorySelect.value || '' }} — filter by product category - stockstatus: {{ stockFilter.value || '' }} — filter by in-stock / out-of-stock Add a JavaScript transformer to flatten the response and calculate a low-stock flag. Drag a Table component into a second tab or section of your app, named 'Inventory'. Set the data source to {{ productsQuery.data }}. Enable inline editing on the Table for the price and stock_quantity columns. In the Table's Inspector, toggle Allow users to edit this table and set the Save Action to run a PUT query. Create the PUT query: - Method: PUT - Path: /Products/{{ productsTable.selectedRow.product_id }} - Body: { 'Price': {{ productsTable.changesetArray[0]?.price }}, 'Stock': {{ productsTable.changesetArray[0]?.stock_quantity }} } In the Table's Inspector, set the Save action to trigger this PUT query. Add an On success event handler that refreshes the products query and shows a 'Inventory updated' notification. This lets your merchandising team make stock and price changes directly in the Retool table without touching the Shift4Shop admin interface.

productsTransformer.js
1// JavaScript transformer for Shift4Shop products
2const products = Array.isArray(data) ? data : [];
3return products.map(p => ({
4 product_id: p.CatalogID,
5 sku: p.SKUInfo?.SKU || p.CatalogID,
6 name: p.Name,
7 price: parseFloat(p.Price || 0).toFixed(2),
8 stock_quantity: p.Stock || 0,
9 category: p.CategoryID || '',
10 status: p.Hide === 'Y' ? 'Hidden' : 'Active',
11 low_stock: (p.Stock || 0) < 10
12}));

Pro tip: Add a conditional row color to the products Table: set the Row color expression to {{ currentRow.low_stock ? '#FEF2F2' : '' }} in the Table's Inspector to highlight low-stock products in light red — making it immediately obvious which products need restocking.

Expected result: The Inventory tab shows all Shift4Shop products with stock levels, prices, and SKUs. Inline editing is enabled for price and quantity columns, and changes save back to Shift4Shop on click of the Save button.

4

Build an order status update workflow

Add the ability to update order statuses directly from your Retool order management panel. This is one of the most common operational tasks for Shift4Shop teams — moving orders from 'Processing' to 'Shipped' or 'Cancelled' in bulk. First, add a Select component above the orders Table labeled 'Update status to'. Set its values to the Shift4Shop order statuses: Processing, Shipped, Partially Shipped, Cancelled, On Hold. Add a Button labeled 'Apply to Selected Rows'. Create a JavaScript query that iterates over the Table's selected rows and sends a PUT request for each one: - In the query editor, select JavaScript as the query type - Write a loop that triggers a resource query for each selected order row Because Shift4Shop does not have a bulk update endpoint, you will call the update endpoint individually for each selected order. Use Promise.all() to parallelize the requests for speed. The update endpoint is PUT /Orders/{OrderID} with a body containing the new OrderStatus value. Create the underlying PUT resource query first: method PUT, path /Orders/{{ currentOrderId }}, body { 'OrderStatus': '{{ newStatus }}' }. Reference this in your JavaScript loop. In the Apply button's event handler, chain: first run the status update JavaScript query, then on success run the orders query to refresh the table, then show a notification: '{{ selectedRows.length }} orders updated to {{ statusSelect.value }}'. For compliance tracking, add an On success handler that also inserts a row into your internal PostgreSQL audit table with the Retool user's email, timestamp, affected order IDs, and the new status. This creates an audit trail outside of Shift4Shop.

bulkStatusUpdate.js
1// JavaScript query: bulk update Shift4Shop order statuses
2const selectedOrders = ordersTable.selectedRows;
3const newStatus = newStatusSelect.value;
4
5if (!selectedOrders || selectedOrders.length === 0) {
6 return { error: 'No orders selected' };
7}
8
9if (!newStatus) {
10 return { error: 'No status selected' };
11}
12
13// Trigger update for each selected order in parallel
14const updatePromises = selectedOrders.map(order =>
15 updateOrderStatusQuery.trigger({
16 additionalScope: {
17 currentOrderId: order.order_id,
18 newStatus: newStatus
19 }
20 })
21);
22
23const results = await Promise.all(updatePromises);
24return { updated: results.length, orderIds: selectedOrders.map(o => o.order_id) };

Pro tip: Shift4Shop rate-limits API requests. If you are updating more than 20 orders at once, add a delay between batches using Promise-based setTimeout wrappers to avoid hitting the rate limit and getting 429 errors on some requests.

Expected result: Selecting multiple orders in the Table and clicking 'Apply to Selected Rows' updates all selected orders to the new status in Shift4Shop. The table refreshes automatically, and a notification confirms how many orders were updated.

5

Add customer lookup and order history drill-down

Build a customer service view that lets support agents quickly look up a customer's account and see their complete order history from Shift4Shop. This eliminates the need for agents to use the Shift4Shop admin for routine customer inquiries. Drag a TextInput component onto the canvas labeled 'Search customer by email or name'. Create a query using your Shift4Shop API resource, method GET, path /Customers, URL parameter email: {{ customerSearch.value }} (Shift4Shop supports filtering customers by email). Set this query to Run when inputs change with a 500ms debounce to avoid firing on every keystroke. Drag a Table component below the search input and bind it to {{ customersQuery.data }}. Display customer ID, name, email, phone, and total lifetime orders. In the Table's event handlers, add an On Row Click handler that triggers a second query to fetch that customer's orders: GET /Orders with the customerid URL parameter set to {{ customersTable.selectedRow.customer_id }}. Add a second Table below the first (or in a right-side panel using a Container component with a horizontal layout) to display the orders for the selected customer. Bind this to {{ customerOrdersQuery.data }}. Finally, add a TextArea component below the customer orders table labeled 'Support notes'. Add a Button labeled 'Save Note'. Create a PostgreSQL query (if you have a PostgreSQL resource) that inserts a note with the Retool user's email, timestamp, Shift4Shop customer ID, and the note text. This creates a lightweight CRM layer on top of Shift4Shop data that is stored in your own database and visible to all agents in the Retool app.

customersTransformer.js
1// JavaScript transformer for customer search results
2const customers = Array.isArray(data) ? data : [];
3return customers.map(c => ({
4 customer_id: c.CustomerID,
5 name: `${c.BillingFirstName || ''} ${c.BillingLastName || ''}`.trim(),
6 email: c.Email || '',
7 phone: c.Phone || '',
8 company: c.BillingCompany || '',
9 total_orders: c.OrderCount || 0,
10 date_joined: c.CustomerSince ? c.CustomerSince.split('T')[0] : ''
11}));

Pro tip: The Shift4Shop customers endpoint returns up to 100 results per request. If your store has many customers with similar names, prompt agents to search by email address rather than name for more precise results and to avoid loading large result sets.

Expected result: Typing in the customer search field triggers the customers query and populates the customer table. Clicking a customer row loads their order history in the adjacent table. Agents can save notes that are stored in the internal database and visible to all team members in the app.

Common use cases

Build a bulk order management panel

Create a Retool dashboard that lists all Shift4Shop orders with filters for date range, order status, payment status, and shipping status. Operations teams can select multiple orders and bulk-update their status, print packing slips, or flag orders for review. A detail panel on the right side shows full order information, customer history, and shipment tracking when an order row is selected.

Retool Prompt

Build an order management panel that fetches Shift4Shop orders with filters for date range and status (new, processing, shipped, completed, cancelled). Show order ID, customer name, total, payment status, and ship date in a Table. Add a status update dropdown and Apply button for bulk status changes on selected rows.

Copy this prompt to try it in Retool

Create a product inventory management dashboard

Build a Retool panel that shows all Shift4Shop products with current stock levels, SKU, price, and category. Merchandising teams can filter by low stock (quantity below a threshold), search by SKU or product name, and update quantities or prices directly in the table using Retool's inline editing feature. Changes are written back to Shift4Shop via PUT requests triggered by a Save button.

Retool Prompt

Create a product inventory panel that displays all Shift4Shop products with SKU, name, price, and stock quantity. Add a filter for products with quantity less than 10. Enable inline editing for the price and quantity columns, and add a Save Changes button that sends PUT requests to update each modified product in Shift4Shop.

Copy this prompt to try it in Retool

Build a customer lookup and order history tool

Build a customer service tool that lets support agents search for Shift4Shop customers by email or name, view their profile, and see their complete order history in a side-by-side layout. Agents can see order totals, statuses, and item details without switching between the Shift4Shop admin and other tools. Add a notes field that saves agent comments to your internal PostgreSQL database alongside the Shift4Shop customer ID.

Retool Prompt

Build a customer lookup tool with a search input for email or customer name that queries the Shift4Shop customers endpoint. Show customer details (name, email, total orders, lifetime value) on the left and their full order history in a Table on the right. Add a text area for agent notes that saves to a PostgreSQL notes table keyed on the Shift4Shop customer ID.

Copy this prompt to try it in Retool

Troubleshooting

API returns 401 Unauthorized or 'Invalid API key' error on all requests

Cause: The Shift4Shop API requires both a Private Token (store-specific) and a Public API key (from Shift4Shop's developer program) sent as separate headers. If either header is missing or incorrect, all requests will fail with a 401. The header names are case-sensitive: PrivateKey and SecureURL.

Solution: In the Retool Resources tab, click your Shift4Shop resource and verify that both headers are configured: PrivateKey (your store's private token from Dashboard → API → Private Key) and SecureURL (your store's storefront URL). Confirm the values match exactly what you see in the Shift4Shop control panel. If you recently regenerated your API key, update the configuration variable in Retool Settings → Configuration Variables.

Orders query returns an empty array even though orders exist in the store

Cause: Shift4Shop's /Orders endpoint defaults to returning only 'New' status orders if no status filter is provided in some API versions. Additionally, the date range filters must be in the correct format (YYYY-MM-DD) or they are silently ignored.

Solution: Remove all filters from the query temporarily and run it to confirm the endpoint is working. Then add filters back one at a time. For the date parameters, ensure you are using datestart and dateend (not startdate/enddate) and that the format is YYYY-MM-DD. To return all statuses, omit the status parameter entirely rather than passing an empty string.

typescript
1// Correct URL parameter format for Shift4Shop dates
2// In URL Parameters section:
3// datestart: {{ dateRange.start ? new Date(dateRange.start).toISOString().split('T')[0] : '' }}

PUT request to update an order fails with 'Order not found' or 404 error

Cause: The order ID format expected in the URL path differs from the OrderID field returned in the GET response. Shift4Shop uses numeric order IDs in the API path, but the response may include both OrderID (numeric) and InvoiceNumber (alphanumeric) fields, and using the wrong one in the PUT path causes a 404.

Solution: Ensure the PUT request path uses the numeric OrderID field from the GET response (e.g., /Orders/12345), not the InvoiceNumber. In your JavaScript transformer, map the numeric field explicitly as order_id: order.OrderID and reference {{ ordersTable.selectedRow.order_id }} in the PUT query path.

Product stock updates via PUT request return 200 OK but the stock level does not change in Shift4Shop

Cause: Shift4Shop's product update endpoint uses different field names for different product types. Simple products use the Stock field, but products with variants (options) require updating the variant-level stock via a separate /Products/{CatalogID}/OptionSets endpoint, and the top-level PUT ignores the Stock field for these products.

Solution: Check whether the product has variants by examining the OptionSets array in the product GET response. For products with options/variants, query the /Products/{CatalogID}/OptionSets endpoint to get variant IDs, then update each variant's stock individually via PUT /Products/{CatalogID}/OptionSets/{OptionSetID}. In your Retool inventory panel, add a flag column in the transformer that marks products with variants so agents know which ones require the variant-level update flow.

Best practices

  • Store your Shift4Shop Private Token as a secret configuration variable in Retool Settings — never include it directly in query headers or JavaScript code where it could appear in browser network requests.
  • Create separate Retool resources for your Shift4Shop sandbox and production environments, and use Retool resource environments to switch between them without modifying app queries.
  • Add confirmation modals to all order status update and cancellation actions — these changes affect customer-facing records and should require explicit confirmation with the order details displayed.
  • Use JavaScript transformers to normalize Shift4Shop's API response fields before binding to Table components — the API returns inconsistent field names between endpoints and some fields may be null rather than empty strings.
  • Implement pagination for all list queries (orders, products, customers) — Shift4Shop limits responses to 200 records per request and returns more data than a Table can display without pagination controls.
  • Restrict write access (order status updates, product edits) to specific Retool user groups using Retool's permission groups feature, so warehouse staff can view but not modify order records.
  • Log all write operations (status changes, inventory updates) to an internal audit table with the Retool username, timestamp, and changed values for compliance and debugging purposes.
  • Use the Shift4Shop API's limit and offset parameters with Retool's Table pagination controls to avoid loading all orders into memory — large stores can have tens of thousands of orders that would cause slow query responses.

Alternatives

Frequently asked questions

Does Shift4Shop have a native Retool connector or must I use a REST API Resource?

Shift4Shop does not have a native Retool connector with pre-built action dropdowns. You connect using a generic REST API Resource in the Resources tab. This requires manually configuring the base URL, authentication headers (PrivateKey and SecureURL), and building queries with the HTTP method, path, and body fields. Despite requiring more initial setup than native connectors, this approach provides full access to all Shift4Shop API endpoints.

Why does the Shift4Shop API still use 3dcart.com domains after the rebrand?

Shift4Shop maintained backward compatibility with existing integrations when it rebranded from 3dcart. The API base URL (https://apirest.3dcart.com) and some developer portal URLs still use the 3dcart domain. This is intentional and will continue to work for existing and new integrations. Use this URL in your Retool REST API Resource configuration rather than any shift4shop.com domain for API calls.

Can Retool update Shift4Shop product inventory in bulk?

Yes, but Shift4Shop does not provide a bulk update endpoint — each product must be updated individually via a PUT request to /Products/{CatalogID}. In Retool, you can use a JavaScript query with Promise.all() to send multiple PUT requests in parallel, which is much faster than sequential updates. For very large catalogs (hundreds of products at once), consider batching requests and adding delays to avoid hitting the API rate limit.

How do I handle Shift4Shop products with variants (options) in Retool?

Products with color, size, or other variants in Shift4Shop have their inventory managed at the option set level, not the top-level product level. When building an inventory management panel, query /Products/{CatalogID}/OptionSets for products that have the OptionSets array populated in the product GET response. Update variant stock via PUT requests to /Products/{CatalogID}/OptionSets/{OptionSetID}. In your Retool transformer, add a has_variants flag to help agents identify which products require the variant update flow.

Can Retool receive Shift4Shop webhook notifications for new orders?

Yes. Create a Retool Workflow with a Webhook trigger to receive Shift4Shop notifications. The Workflow editor provides a unique HTTPS endpoint URL that you configure in Shift4Shop's control panel under Settings → General → Real-time Notifications or the equivalent webhook settings. When a new order arrives, Shift4Shop POSTs the order data to the Retool Workflow, which can then update your internal database, send a Slack notification, or trigger other downstream actions.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Integrations are where projects stall

We wire Retool integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.