Skip to main content
RapidDev - Software Development Agency
flutterflow-integrationsFlutterFlow API Call

3dcart (now Shift4Shop)

Connect FlutterFlow to 3dcart (now Shift4Shop) by routing API calls through a Firebase Cloud Function that securely holds the three-part Shift4Shop credential set — SecureURL, PrivateKey, and Token. FlutterFlow's API Calls panel then queries the function to fetch products, orders, and customers for a mobile store management app. The PrivateKey must never appear in a FlutterFlow header literal or it ships to every user's device.

What you'll learn

  • How Shift4Shop's unique three-part credential system (SecureURL, PrivateKey, Token) works and why all three must be proxied
  • How to deploy a Firebase Cloud Function that holds and injects the three Shift4Shop headers on every forwarded request
  • How to create a FlutterFlow API Group targeting the proxy and add product, order, and customer GET calls
  • How to map Shift4Shop JSON responses to FlutterFlow Data Types and bind them to ListViews
  • How to add order-update write operations behind your own app authentication so only authorized users can modify orders
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate17 min read60 minutesE-commerceLast updated July 2026RapidDev Engineering Team
TL;DR

Connect FlutterFlow to 3dcart (now Shift4Shop) by routing API calls through a Firebase Cloud Function that securely holds the three-part Shift4Shop credential set — SecureURL, PrivateKey, and Token. FlutterFlow's API Calls panel then queries the function to fetch products, orders, and customers for a mobile store management app. The PrivateKey must never appear in a FlutterFlow header literal or it ships to every user's device.

Quick facts about this guide
FactValue
Tool3dcart (now Shift4Shop)
CategoryE-commerce
MethodFlutterFlow API Call
DifficultyIntermediate
Time required60 minutes
Last updatedJuly 2026

Build a Mobile Store Management App for Your 3dcart / Shift4Shop Store

3dcart rebranded to Shift4Shop in 2021 after being acquired by Shift4 Payments. The platform's REST API — available at https://api.shift4shop.com/v3/ (also legacy https://apirest.3dcart.com) — gives developers access to the full store: products, orders, customers, categories, and inventory. In FlutterFlow, you can build a compelling mobile admin app that lets a store owner check orders, update product availability, and look up customer history from their phone.

What makes Shift4Shop unusual among e-commerce APIs is its three-part credential system. Every API request requires three headers simultaneously: SecureURL (the store's own domain URL used as an identifier), PrivateKey (a private API key scoped to your store), and Token (a separate public token for request authentication). Missing any one of these three headers — even if the other two are correct — returns a 401 error. The PrivateKey is a sensitive credential that must never appear in a FlutterFlow API Call header literal, because FlutterFlow compiles API Call configurations directly into the Flutter app binary, making them extractable. The solution is a Firebase Cloud Function proxy that stores all three credentials securely and forwards them to Shift4Shop on every request.

Shift4Shop offers an appealing pricing model: US merchants using Shift4 Payments as their processor can access the platform for free (End-to-End plan) — verify current pricing and plan availability at shift4shop.com. API access is available on paid plans. Before starting, generate your API credentials in your Shift4Shop store's Admin Panel under Settings → API and confirm which base URL your store uses: newer stores typically use https://api.shift4shop.com/v3/, while older 3dcart stores may still use https://apirest.3dcart.com — the two are functionally equivalent but you must use the correct one for your store.

Integration method

FlutterFlow API Call

FlutterFlow connects to the Shift4Shop REST v3 API through a Firebase Cloud Function proxy that securely stores all three required credentials: SecureURL, PrivateKey, and the public Token. FlutterFlow's API Calls target the function URL and receive product, order, and customer data. The Cloud Function injects all three headers so none of the sensitive credentials reach the compiled Flutter app.

Prerequisites

  • A Shift4Shop store with API access enabled — check your plan includes API access at shift4shop.com
  • Your three API credentials from Shift4Shop Admin → Settings → API: SecureURL (your store domain), PrivateKey, and Token (public token)
  • The correct base URL for your store: https://api.shift4shop.com/v3/ for newer stores, or https://apirest.3dcart.com for legacy 3dcart stores
  • A Firebase project on the Blaze plan with Cloud Functions enabled for outbound HTTP calls
  • A FlutterFlow project (any tier) with Firebase connected via Settings & Integrations → Firebase

Step-by-step guide

1

Generate your Shift4Shop API credentials

Log into your Shift4Shop store's Admin Panel. Navigate to Settings → API (the exact path may vary slightly by Shift4Shop version — look for API, REST API, or Developer Tools in the Settings menu). You will find three credentials that are ALL required for every API call: 1. SecureURL — this is your store's primary domain URL (e.g. https://www.yourstore.com). It acts as a store identifier in the API, not a password, but it is still required in every request header. 2. PrivateKey — this is a long alphanumeric string that authenticates API access to your specific store. It is a sensitive credential — treat it like a password. Do not share it, do not paste it into FlutterFlow, and do not commit it to source control. 3. Token — this is a separate public token used alongside the PrivateKey. Both are required simultaneously; submitting only one returns a 401 error. Note down all three credentials and keep them in a secure location like 1Password or your Firebase Functions environment configuration. Also confirm your store's API base URL: if your store was created after the Shift4Shop rebrand, use https://api.shift4shop.com/v3/; if your store predates the rebrand or was originally a 3dcart store, test both URLs — the legacy https://apirest.3dcart.com may still be what your store responds to. When in doubt, check your store's API documentation page or contact Shift4Shop support to confirm the correct base URL for your account.

Pro tip: If your store is on the free End-to-End plan (US merchants using Shift4 Payments), verify that API access is included in your plan — some store management features may require an upgraded plan.

Expected result: You have all three Shift4Shop API credentials (SecureURL, PrivateKey, Token) noted and your store's base URL confirmed.

2

Deploy a Firebase Cloud Function proxy for Shift4Shop

The Shift4Shop PrivateKey cannot appear in a FlutterFlow API Call — it would be compiled into your app binary and extractable by anyone who downloads your app. Create a Firebase Cloud Function that receives requests from FlutterFlow, adds all three required Shift4Shop headers from environment variables, and forwards the request to the Shift4Shop API. In the Firebase Console, navigate to your project → Cloud Functions. Ensure your project is on the Blaze billing plan (required for outbound HTTP calls from Cloud Functions). Click + Add Function or use the Functions dashboard to deploy. Store your three credentials as environment variables: SHIFT4SHOP_SECURE_URL, SHIFT4SHOP_PRIVATE_KEY, SHIFT4SHOP_TOKEN, and SHIFT4SHOP_BASE_URL. Deploy the proxy function below. It accepts three query parameters from FlutterFlow: resource (e.g. Products, Orders, Customers), id (optional, for single-resource endpoints), and an optional action for write operations. The function constructs the full Shift4Shop API URL, adds all three required headers, and returns the response to FlutterFlow. After deploying, copy the Cloud Function trigger URL (something like https://us-central1-your-project.cloudfunctions.net/shift4shopProxy) and test it immediately: call it with ?resource=Products in your browser — if configured correctly, you should receive a JSON array of your store's products. This confirms all three Shift4Shop credentials are working before you touch FlutterFlow at all.

index.js
1const functions = require('firebase-functions');
2const axios = require('axios');
3
4const SECURE_URL = process.env.SHIFT4SHOP_SECURE_URL; // e.g. https://www.yourstore.com
5const PRIVATE_KEY = process.env.SHIFT4SHOP_PRIVATE_KEY;
6const TOKEN = process.env.SHIFT4SHOP_TOKEN;
7const BASE_URL = process.env.SHIFT4SHOP_BASE_URL // e.g. https://api.shift4shop.com/v3
8 || 'https://api.shift4shop.com/v3';
9
10exports.shift4shopProxy = functions.https.onRequest(async (req, res) => {
11 res.set('Access-Control-Allow-Origin', '*');
12 res.set('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS');
13 res.set('Access-Control-Allow-Headers', 'Content-Type');
14 if (req.method === 'OPTIONS') { res.status(204).send(''); return; }
15
16 if (!PRIVATE_KEY || !TOKEN || !SECURE_URL) {
17 res.status(500).json({ error: 'Shift4Shop credentials not configured' });
18 return;
19 }
20
21 // e.g. resource=Products, id=123 (optional)
22 const resource = req.query.resource || 'Products';
23 const id = req.query.id ? `/${req.query.id}` : '';
24 const endpoint = `${BASE_URL}/${resource}${id}`;
25
26 // Forward query params except our own routing params
27 const forwardParams = { ...req.query };
28 delete forwardParams.resource;
29 delete forwardParams.id;
30
31 try {
32 const response = await axios({
33 method: req.method === 'GET' ? 'GET' : req.method,
34 url: endpoint,
35 headers: {
36 'SecureUrl': SECURE_URL,
37 'PrivateKey': PRIVATE_KEY,
38 'Token': TOKEN,
39 'Content-Type': 'application/json',
40 'Accept': 'application/json',
41 },
42 params: forwardParams,
43 data: req.method !== 'GET' ? req.body : undefined,
44 });
45 res.status(200).json(response.data);
46 } catch (error) {
47 const status = error.response?.status || 500;
48 res.status(status).json({ error: error.message, detail: error.response?.data });
49 }
50});
51

Pro tip: If your store returns 401 even when all three credentials look correct, double-check the header names: Shift4Shop uses SecureUrl (capital U, lowercase l), PrivateKey (capital P and K), and Token (capital T). Incorrect casing in header names is a common cause of authentication failures.

Expected result: The Cloud Function deploys and returns a JSON array of Shift4Shop products when called with ?resource=Products from your browser.

3

Create a FlutterFlow API Group for the Shift4Shop proxy

Open your FlutterFlow project and click API Calls in the left nav → + Add → Create API Group. Name it Shift4Shop. In the Base URL field, paste your Cloud Function trigger URL: https://us-central1-your-project.cloudfunctions.net/shift4shopProxy. Leave the Authentication section empty — authentication is handled inside the Cloud Function, not in FlutterFlow. Inside the Shift4Shop API Group, click + Add API Call to add your first endpoint. Name it GetProducts, set Method to GET. Add a Query Parameter named resource with a default value of Products. Add additional optional query parameters: limit (default 20), offset (default 0), categoryid (optional, for filtering by category). These parameters are passed through the proxy to Shift4Shop's native pagination and filter parameters. Add a second API Call named GetOrders: same method GET, resource parameter defaulting to Orders. Add query parameters: limit (20), offset (0), and status (optional string, for filtering by order status like New, Processing, Shipped). Add a third API Call named GetCustomers: resource=Customers, limit=20, offset=0, searchby (String, optional for search-by-email or search-by-name functionality). For each API Call, open the Response & Test tab, fill in the resource parameter, and click Test API Call. If the proxy is working, you'll see JSON from your Shift4Shop store. Click Generate JSON Paths to detect the response structure. Shift4Shop wraps resources in arrays at the root level — products come as [{...}, {...}], not nested inside a wrapper object.

api_group_config.json
1{
2 "API Group": "Shift4Shop",
3 "Base URL": "https://us-central1-YOUR_PROJECT.cloudfunctions.net/shift4shopProxy",
4 "Authentication": "None (handled by Cloud Function)",
5 "API Calls": [
6 {
7 "Name": "GetProducts",
8 "Method": "GET",
9 "Query Parameters": [
10 { "name": "resource", "default": "Products" },
11 { "name": "limit", "default": "20" },
12 { "name": "offset", "default": "0" },
13 { "name": "categoryid", "type": "String" }
14 ]
15 },
16 {
17 "Name": "GetOrders",
18 "Method": "GET",
19 "Query Parameters": [
20 { "name": "resource", "default": "Orders" },
21 { "name": "limit", "default": "20" },
22 { "name": "offset", "default": "0" },
23 { "name": "status", "type": "String" }
24 ]
25 },
26 {
27 "Name": "GetCustomers",
28 "Method": "GET",
29 "Query Parameters": [
30 { "name": "resource", "default": "Customers" },
31 { "name": "limit", "default": "20" },
32 { "name": "offset", "default": "0" },
33 { "name": "searchby", "type": "String" }
34 ]
35 }
36 ]
37}
38

Pro tip: If you see 'legacy' 3dcart endpoints referenced in older documentation (e.g. /3dCartWebAPI/v3/), those are for the pre-rebrand API. The current Shift4Shop REST v3 uses clean resource names like /Products, /Orders, /Customers — no path prefix needed.

Expected result: The Shift4Shop API Group appears in the FlutterFlow API Calls panel with GetProducts, GetOrders, and GetCustomers calls that all return data from your store when tested.

4

Create Data Types and bind responses to ListViews

With working API Calls confirmed, create FlutterFlow Data Types to represent the Shift4Shop response shapes. Go to Data Types in the left nav → + Add Data Type. Create a Shift4Product type with fields: catalogid (String), name (String), price (Double), stock (Integer), thumbnailUrl (String), categoryId (String). Create a Shift4Order type with fields: orderid (String), customeremail (String), ordertotal (Double), orderstatus (String), orderdate (String), firstname (String), lastname (String). Create a Shift4Customer type with fields: customerid (String), firstname (String), lastname (String), email (String), orders (Integer). Link these to your API Calls: open GetProducts → Response & Test, use the generated JSON Paths (Shift4Shop products come as an array — JSON Paths will look like $[0].catalogid, $[0].name, $[0].price, $[0].thumbnailurl). Do the same for GetOrders and GetCustomers. Build your first page — an Orders page: add a ListView, bind it via Backend Query to Shift4Shop → GetOrders. Inside the ListView, add a Card with Text widgets for orderid, customeremail, ordertotal (formatted as currency), and a Container for orderstatus with conditional background color (New = blue, Processing = orange, Shipped = green, Completed = grey). Build a Products page with a similar ListView bound to GetProducts, showing product name, price, and a stock count with a warning color when stock is zero. Build a Customers page with GetCustomers data, a search field bound to the searchby parameter, and a customer detail screen that deep-links to order history. Add a bottom navigation bar with tabs for Orders, Products, and Customers to complete the mobile admin app structure.

Pro tip: Shift4Shop field names in JSON responses use lowercase with no separators (e.g. catalogid, thumbnailurl, customeremail, orderdate) — map these carefully in your Data Type JSON Paths. Do not assume camelCase or snake_case formatting.

Expected result: The Orders, Products, and Customers screens each display live data from your Shift4Shop store fetched through the proxy, with appropriate visual formatting and color-coded status badges.

5

Add order-update write operations with app authentication

Read operations (GET) are sufficient for a basic store overview app, but a full store management tool also needs to update order statuses — marking orders as shipped, processing, or completed. Write operations require additional security care: not only must the PrivateKey stay in the Cloud Function proxy, but you also need to ensure that only authorized users (you and your team) can trigger write calls. First, add a write endpoint to your Cloud Function proxy. The current proxy already supports non-GET methods — update the Cloud Function to handle the PUT method for updating a specific resource by ID. Shift4Shop uses PUT /Orders/{orderId} with a JSON body containing the new status field to update an order. In FlutterFlow, add a new API Call in the Shift4Shop API Group: name it UpdateOrderStatus, set Method to PUT. Add two variables: resourceId (the order ID to update) and status (the new status string). Update the proxy call so the resource parameter is Orders and the id parameter carries the resourceId. Before wiring this action to a button, add your own app-level authentication. Enable Firebase Authentication in your FlutterFlow project (Settings & Integrations → Firebase → Firebase Authentication → Email/Password). Create a simple login screen with an email/password form. Gate the entire admin app behind a logged-in state check on every page — use the conditional widget visibility or an initial action flow on each page to redirect unauthenticated users to the login screen. Only after confirming the user is logged in (and ideally checking their Firebase custom claims or a Firestore role document to verify they're an admin) should the UpdateOrderStatus action be available. Connect the status update to a dropdown widget on the order detail screen and confirm the update through a Dialog confirmation before firing the PUT call.

Pro tip: If you'd rather skip building and maintaining the Cloud Function proxy yourself, RapidDev's team builds FlutterFlow store management integrations like this Shift4Shop connection regularly — request a free scoping call at rapidevelopers.com/contact.

Expected result: Authenticated admin users can update order statuses from the order detail screen, with changes reflected in the Shift4Shop admin panel within seconds.

Common use cases

Mobile order management dashboard for store owners

A Shift4Shop merchant builds a FlutterFlow mobile app to manage orders on the go. The app queries /Orders through the proxy, displays them in a ListView sorted by date with status badges, lets the owner tap to view order details including line items and customer info, and updates order status (processing, shipped, completed) via proxied PATCH calls.

FlutterFlow Prompt

An order management screen with a top filter row (All / Processing / Shipped / Completed status buttons), a scrollable order list below with order number, customer name, total, and status badge, and a detail screen with itemized products, shipping address, and a status update dropdown.

Copy this prompt to try it in FlutterFlow

Product inventory manager

A store operator uses a FlutterFlow app to quickly check and update product stock levels without logging into the Shift4Shop admin panel. The app fetches /Products with stock quantities, highlights low-stock items with a warning badge, and lets the operator update inventory counts directly via the proxy write endpoint.

FlutterFlow Prompt

A product inventory screen with a search bar, a sorted list of products by stock level (lowest first), color-coded stock badges (red = out of stock, yellow = low, green = in stock), and a tap-to-edit stock count field that saves via an API call.

Copy this prompt to try it in FlutterFlow

Customer lookup and order history viewer

A customer service team uses a FlutterFlow app to quickly look up Shift4Shop customers by name or email, view their order history, and access order details for support calls — without needing access to the full Shift4Shop admin panel.

FlutterFlow Prompt

A customer search screen with a name/email search field, a results list showing customer name, email, and order count, and a customer detail screen showing all past orders with amounts, dates, and statuses.

Copy this prompt to try it in FlutterFlow

Troubleshooting

Every API call returns 401 even though all three credentials are set in the Cloud Function

Cause: The three required Shift4Shop headers have specific capitalization: SecureUrl (capital S and U), PrivateKey (capital P and K), Token (capital T). Incorrect casing causes 401 even when the credential values are correct.

Solution: In your Cloud Function code, verify the header names match exactly: 'SecureUrl', 'PrivateKey', 'Token' — these are case-sensitive. Also verify that the SHIFT4SHOP_BASE_URL environment variable points to the correct base URL for your store (shift4shop.com or apirest.3dcart.com). Test the Cloud Function directly with a REST client to isolate whether the issue is in the function or in FlutterFlow's API Call configuration.

typescript
1// Correct header casing for Shift4Shop:
2headers: {
3 'SecureUrl': SECURE_URL,
4 'PrivateKey': PRIVATE_KEY,
5 'Token': TOKEN,
6}

401 returned even though the Token header is correct, but the PrivateKey is also set

Cause: Shift4Shop requires ALL THREE headers on every request — SecureUrl, PrivateKey, AND Token. Missing any one of the three, even if the other two are valid, returns a 401.

Solution: Log the outgoing headers from your Cloud Function to confirm all three are being sent. Add a console.log statement before the axios call: console.log('Headers:', {SecureUrl: SECURE_URL ? 'set' : 'missing', PrivateKey: PRIVATE_KEY ? 'set' : 'missing', Token: TOKEN ? 'set' : 'missing'}). Check the Cloud Function logs in the Firebase Console to see which headers are missing from the environment configuration.

XMLHttpRequest error when testing Shift4Shop API Calls in FlutterFlow's web Preview

Cause: FlutterFlow's web Preview mode makes requests from a browser, which enforces CORS. Shift4Shop's API does not support browser-origin CORS requests directly.

Solution: This is expected when calling the proxy directly with a browser CORS issue. Ensure your Cloud Function includes the Access-Control-Allow-Origin: * response header and handles OPTIONS preflight requests — the proxy code in Step 2 includes this. If the error persists, confirm you're calling your Cloud Function URL in the API Group Base URL, not the Shift4Shop API URL directly.

The store's products and orders load on the older 3dcart domain but not the Shift4Shop base URL

Cause: Legacy 3dcart stores that predate the Shift4Shop rebrand may still route API requests through apirest.3dcart.com rather than the new api.shift4shop.com domain.

Solution: In your Cloud Function environment configuration, update SHIFT4SHOP_BASE_URL to https://apirest.3dcart.com and redeploy. Test with ?resource=Products from your browser to confirm which base URL your store responds to. If neither works, contact Shift4Shop support to confirm the API endpoint for your account.

Best practices

  • Never place any of the three Shift4Shop credentials (SecureURL, PrivateKey, Token) in a FlutterFlow API Call header — all three must live in the Cloud Function environment variables and be injected server-side.
  • Always verify all three header names use exact capitalization (SecureUrl, PrivateKey, Token) — Shift4Shop headers are case-sensitive and a single wrong-case character causes 401 errors that look like credential failures.
  • Confirm your store's correct base URL before starting development: newer stores use https://api.shift4shop.com/v3/, while legacy 3dcart stores may use https://apirest.3dcart.com — test both in a REST client against your credentials.
  • Gate all write operations (order status updates, product edits) behind your own app authentication layer — even with the Cloud Function proxy, any user with your app installed can trigger API calls if there's no login gate.
  • Reference both '3dcart' and 'Shift4Shop' in your app documentation and onboarding, since many long-running stores still know the platform by its original name.
  • Add pagination support from the start — a store with hundreds of products or thousands of orders will need the limit and offset parameters to avoid slow loads and incomplete data.
  • Cache order and product data in Firestore between sessions so the app loads immediately with stale data while fresh data loads in the background.
  • Test write operations (order updates) in a separate development or test store before connecting to your live production store — Shift4Shop does not have a sandbox mode, so write calls affect your real store immediately.

Alternatives

Frequently asked questions

Does the integration work with the old 3dcart brand or only with Shift4Shop?

The API is the same regardless of which brand name you know the platform by — 3dcart and Shift4Shop are the same platform after the 2021 rebrand. The REST API v3 endpoints and credentials work identically. The only difference you may encounter is the base URL: newer stores created after the rebrand use api.shift4shop.com, while some legacy 3dcart stores still use apirest.3dcart.com. Both are supported — just configure your Cloud Function with the correct base URL for your specific store.

Can I use the Shift4Shop integration for a customer-facing shopping app rather than an admin tool?

Technically yes — the Shift4Shop API provides product catalog data that you could display to shoppers. However, Shift4Shop's checkout flow is hosted on the Shift4Shop storefront (similar to how Ecwid manages checkout), and there is no native FlutterFlow cart or payment integration. You would need to deep-link to the Shift4Shop-hosted checkout for payment processing. For a pure customer shopping app, consider a platform with a more complete headless commerce API like WooCommerce or Shopify.

Is Shift4Shop free to use?

Shift4Shop offers a free End-to-End plan for US merchants who process payments through Shift4 Payments — this plan includes API access. Merchants who want to use a different payment processor pay a monthly subscription fee. Verify current plan pricing and API access details at shift4shop.com, as plan offerings change over time.

Why do I need all three credentials? Can't I use just the PrivateKey?

Shift4Shop's authentication design requires all three headers to work together: SecureUrl identifies which store the request is for, PrivateKey authenticates access to that store, and Token is an additional validation layer. This three-part system is unique among e-commerce APIs — most platforms use one or two credential types. If any one of the three is missing or incorrect, the API returns 401 regardless of whether the others are valid.

Can I see live order updates in my FlutterFlow app without polling?

Shift4Shop's REST API is request/response only — it doesn't support WebSockets or real-time push notifications natively. To show near-real-time order updates, implement a periodic refresh: use a Timer action in FlutterFlow (on the order list page) to re-fire the GetOrders API Call every 60 seconds. For true real-time notifications, Shift4Shop supports webhooks that can fire to a Firebase Cloud Function, which can then push a notification to your FlutterFlow app via Firebase Cloud Messaging.

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 FlutterFlow 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.