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.
| Fact | Value |
|---|---|
| Tool | 3dcart (now Shift4Shop) |
| Category | E-commerce |
| Method | FlutterFlow API Call |
| Difficulty | Intermediate |
| Time required | 60 minutes |
| Last updated | July 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 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
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.
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.
1const functions = require('firebase-functions');2const axios = require('axios');34const SECURE_URL = process.env.SHIFT4SHOP_SECURE_URL; // e.g. https://www.yourstore.com5const 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/v38 || 'https://api.shift4shop.com/v3';910exports.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; }1516 if (!PRIVATE_KEY || !TOKEN || !SECURE_URL) {17 res.status(500).json({ error: 'Shift4Shop credentials not configured' });18 return;19 }2021 // 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}`;2526 // Forward query params except our own routing params27 const forwardParams = { ...req.query };28 delete forwardParams.resource;29 delete forwardParams.id;3031 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});51Pro 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.
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.
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}38Pro 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.
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.
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.
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.
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.
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.
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
WooCommerce's REST API uses simpler two-part consumer key/secret authentication rather than Shift4Shop's three-part credential system, and has much more extensive community documentation and FlutterFlow integration examples.
Ecwid offers a WebView embed path for instant working storefronts in FlutterFlow — ideal if you want a complete checkout experience without building custom UI, which Shift4Shop's pure REST API requires.
Magento's REST API provides more advanced product catalog features and multi-store management for larger-scale retail operations that have outgrown Shift4Shop's capabilities.
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.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation