Connect Bolt.new to Shift4Shop (formerly 3dcart) using its REST API with three credentials: your store's SecureURL, a Public Token, and a Private Key. All API calls must go through a Next.js API route to keep the private key server-side. Build custom storefronts, order dashboards, or product management UIs on top of Shift4Shop's hosted catalog. Outbound REST calls work in Bolt's WebContainer during development.
Build a Custom Shift4Shop Storefront or Admin Dashboard with Bolt.new
Shift4Shop stands out in the e-commerce platform market for a unique reason: it offers a completely free plan with no monthly fees, no transaction fees, and no limits on products or bandwidth — the only condition is using Shift4 Payments as your payment processor. This makes it an attractive backend for builders who want a fully hosted e-commerce engine without the $29/month Shopify Basic subscription.
The Shift4Shop REST API gives you programmatic access to everything in your store: products, categories, orders, customers, inventory, shipping options, and coupons. This enables two powerful use cases with Bolt.new. First, you can build a completely custom storefront — your own React UI pulling product and catalog data from Shift4Shop, with Shift4Shop handling the cart, checkout, and payment processing in the background. Second, you can build internal admin dashboards for order fulfillment, inventory management, or sales reporting that your team uses alongside or instead of the default Shift4Shop admin interface.
Authentication uses three values: the store's SecureURL (the base URL for API calls), a Public Token (can be used for read-only catalog calls in some contexts), and a Private Key (required for all order and customer data). The Private Key must never leave your server — store it in .env and access it only from Next.js API routes. During Bolt.new development, all outbound calls to Shift4Shop work in the WebContainer. If you need Shift4Shop to push order or inventory events to your app via webhooks, you must deploy to Netlify or Vercel first and register a public URL.
Integration method
Shift4Shop's REST API uses three-credential authentication: a SecureURL (your store's API endpoint), a Public Token (safe to use in some contexts), and a Private Key (server-side only). All requests to the Shift4Shop API must be made from a Next.js API route where the Private Key is kept in server-side environment variables. Bolt.new's WebContainer supports outbound HTTP calls to the Shift4Shop API during development. Webhook events from Shift4Shop require a deployed URL on Netlify or Vercel since they send incoming POST requests.
Prerequisites
- A Shift4Shop store — sign up free at shift4shop.com (free plan available with Shift4 Payments)
- API credentials from Shift4Shop admin: Settings → API → Generate API Access Token (gives you SecureURL, Public Token, and Private Key)
- A Bolt.new account with a new Next.js project open
- Products already added to your Shift4Shop store to test catalog and inventory API calls
- A Netlify account for deployment if you need Shift4Shop order notification webhooks
Step-by-step guide
Generate Shift4Shop API credentials and set up authentication
Generate Shift4Shop API credentials and set up authentication
Shift4Shop uses a three-part authentication system that you include as HTTP request headers on every API call. Understanding each credential's purpose helps you use them correctly and securely. To generate credentials: log into your Shift4Shop admin panel, go to Settings (gear icon) → API → REST API. If you haven't enabled the REST API, toggle it on. Click Generate to create a new API access token. Shift4Shop shows you three values: 1. SecureURL — This is the base URL for all your API calls. It looks like `https://api.shift4shop.com/v3/{your-store-id}`. Every API request goes to this URL plus the endpoint path (e.g., `/Products`, `/Orders`). 2. PublicToken — A token that can be used for read-only catalog operations. Some integrations use this in client-side code for public data like product listings. However, for consistency and security, this guide uses it server-side only in API routes. 3. PrivateKey — This is the sensitive credential that authenticates write operations and access to order/customer data. It must never appear in client-side code, NEXT_PUBLIC_ environment variables, or be committed to Git. All three headers are sent together on every request: `SecureURL`, `PublicToken`, and `PrivateKey` as HTTP headers. The Shift4Shop API is RESTful with standard HTTP verbs (GET for reads, POST for creates, PUT for updates, DELETE for deletions) and returns JSON. Add all three values to your .env file in Bolt. The Shift4Shop REST API accepts HTTPS requests, and these outbound calls work correctly in Bolt's WebContainer during development.
Set up Shift4Shop API authentication in my Next.js project. Create a .env file with SHIFT4SHOP_SECURE_URL=https://api.shift4shop.com/v3/your-store-id, SHIFT4SHOP_PUBLIC_TOKEN=your-public-token, and SHIFT4SHOP_PRIVATE_KEY=your-private-key. Create a lib/shift4shop.ts helper file that exports a shift4shopFetch function. This function accepts an endpoint string (like '/Products') and optional init RequestInit. It reads the three env vars, sends them as SecureURL, PublicToken, and PrivateKey headers, appends Content-Type application/json, and fetches from SHIFT4SHOP_SECURE_URL + endpoint. Throw a descriptive error if any env var is missing. Return the parsed JSON.
Paste this in Bolt.new chat
1// lib/shift4shop.ts2const getCredentials = () => {3 const secureUrl = process.env.SHIFT4SHOP_SECURE_URL;4 const publicToken = process.env.SHIFT4SHOP_PUBLIC_TOKEN;5 const privateKey = process.env.SHIFT4SHOP_PRIVATE_KEY;67 if (!secureUrl || !publicToken || !privateKey) {8 throw new Error(9 'Missing Shift4Shop credentials. Set SHIFT4SHOP_SECURE_URL, ' +10 'SHIFT4SHOP_PUBLIC_TOKEN, and SHIFT4SHOP_PRIVATE_KEY in .env'11 );12 }13 return { secureUrl, publicToken, privateKey };14};1516export async function shift4shopFetch<T = unknown>(17 endpoint: string,18 init: RequestInit = {}19): Promise<T> {20 const { secureUrl, publicToken, privateKey } = getCredentials();21 const url = `${secureUrl}${endpoint.startsWith('/') ? endpoint : '/' + endpoint}`;2223 const response = await fetch(url, {24 ...init,25 headers: {26 SecureURL: secureUrl,27 PublicToken: publicToken,28 PrivateKey: privateKey,29 'Content-Type': 'application/json',30 Accept: 'application/json',31 ...init.headers,32 },33 });3435 if (!response.ok) {36 const errorText = await response.text();37 throw new Error(`Shift4Shop API ${response.status}: ${errorText}`);38 }3940 return response.json() as Promise<T>;41}Pro tip: The Shift4Shop REST API documentation is at developers.shift4shop.com. Each resource (Products, Orders, Customers) has its own endpoint. The SecureURL already includes your store identifier, so endpoint paths are just the resource names — for example, GET /Products returns your full product catalog.
Expected result: A configured Shift4Shop API helper in lib/shift4shop.ts with all three credentials stored in .env, ready to use in API routes.
Fetch products and build a catalog API route
Fetch products and build a catalog API route
The Shift4Shop Products endpoint (`GET /Products`) returns your store's full product catalog with rich data including name, description, SKU, price, sale price, stock levels, categories, images, and custom fields. This is the foundation for any custom storefront or catalog integration. The Products endpoint supports several useful query parameters for pagination and filtering. `countonly=1` returns just the count of matching products — useful for determining how many pages to show. `offset` and `limit` control pagination (max 200 per request). `categoryid` filters by category. `hide=false` returns only active/visible products. For custom storefronts, you typically want `hide=false` to match what your live store shows. Product images are returned in the `Images` array — the first image is typically the primary product image. Each image object includes `Url` (the full CDN URL) and `AltText`. Shift4Shop hosts these images on their CDN, so you can use the URLs directly in your React components without any additional asset handling. Inventory data is included in the product response as `Stock`, `StockAlert` (the low stock threshold), and `InventoryControl` (whether stock tracking is enabled for this product). This makes it easy to build inventory-aware UIs — showing 'Out of Stock' badges, filtering to in-stock products only, or building the inventory alert dashboard described in the use cases. For large catalogs, implement pagination in your API route using `offset` and `limit` parameters. A catalog with 500+ products should never be fetched in one call — load the first page immediately and implement infinite scroll or 'load more' pagination in your React component.
Create a products API route at app/api/shift4shop/products/route.ts. Accept GET requests with optional query params: limit (default 20, max 200), offset (default 0), categoryId (optional), inStockOnly (optional boolean). Use shift4shopFetch from lib/shift4shop.ts to GET /Products with these params. Return the products array with id, name, sku, price, salePrice, stock, thumbnail (first image URL), and isInStock. Also create a React ProductGrid component at components/ProductGrid.tsx that fetches from this route, displays products in a responsive 3-column grid with product name, price (crossed out if there's a sale price), stock badge, and image.
Paste this in Bolt.new chat
1// app/api/shift4shop/products/route.ts2import { NextRequest, NextResponse } from 'next/server';3import { shift4shopFetch } from '@/lib/shift4shop';45interface Shift4ShopProduct {6 CatalogID: number;7 SKU: string;8 Name: string;9 Price: number;10 SalePrice: number;11 Stock: number;12 Hide: boolean;13 Images: Array<{ Url: string; AltText: string }>;14 CategoryID: number;15}1617export async function GET(request: NextRequest) {18 const { searchParams } = new URL(request.url);19 const limit = Math.min(Number(searchParams.get('limit') ?? 20), 200);20 const offset = Number(searchParams.get('offset') ?? 0);21 const categoryId = searchParams.get('categoryId');22 const inStockOnly = searchParams.get('inStockOnly') === 'true';2324 const params = new URLSearchParams({25 limit: limit.toString(),26 offset: offset.toString(),27 hide: 'false',28 });29 if (categoryId) params.set('categoryid', categoryId);3031 const products = await shift4shopFetch<Shift4ShopProduct[]>(32 `/Products?${params.toString()}`33 );3435 const normalized = products36 .filter(p => !inStockOnly || p.Stock > 0)37 .map(p => ({38 id: p.CatalogID,39 sku: p.SKU,40 name: p.Name,41 price: p.Price,42 salePrice: p.SalePrice > 0 && p.SalePrice < p.Price ? p.SalePrice : null,43 stock: p.Stock,44 isInStock: p.Stock > 0,45 thumbnail: p.Images?.[0]?.Url ?? null,46 }));4748 return NextResponse.json({ products: normalized, offset, limit });49}Pro tip: Shift4Shop product images are hosted on Shift4Shop's CDN. You can use these URLs directly in Next.js Image components — add 'cdn.3dcart.com' to your next.config.js images.domains array to avoid the 'unconfigured hostname' error.
Expected result: A products API route that returns normalized product data from Shift4Shop, and a React component displaying the catalog in a responsive grid.
Build an order management API route and dashboard
Build an order management API route and dashboard
The Shift4Shop Orders endpoint (`GET /Orders`) returns all orders with full details including customer information, line items, shipping method, order status, and payment status. This is the data your fulfillment team needs to process and ship orders. Shift4Shop uses numeric status codes for order status. The key ones are: 1 (New), 2 (Processing), 3 (Awaiting Fulfillment), 4 (Shipped), 5 (Cancelled), 6 (Declined), 7 (Awaiting Payment), 8 (Backordered), 9 (Awaiting Shipment), 12 (Refunded). For a fulfillment dashboard, you typically filter to status 1 (New), 2 (Processing), and 9 (Awaiting Shipment). Orders include the `OrderItems` array with each line item's product name, SKU, quantity, unit price, and the order subtotal, shipping cost, tax amount, and total. The `ShipmentList` array shows any shipments created for the order with tracking numbers. Customer data is embedded in the order: `BillingFirstName`, `BillingLastName`, `BillingEmail`, and the `ShipFirstName`, `ShipLastName`, `ShipAddress` fields for the delivery address. All the information your team needs to print a packing slip or verify an address is in one API call. For the dashboard, a well-organized order table dramatically speeds up fulfillment workflows. Show order number, customer name, destination city/state, item count, order total, and status badge. Make the order number clickable to expand a drawer showing full line items and customer details. Add a status filter dropdown so the team can focus on orders needing attention.
Create an orders API route at app/api/shift4shop/orders/route.ts. Accept GET with optional query params: status (numeric code, default empty = all), limit (default 50), offset (default 0). Use shift4shopFetch to GET /Orders with these params. Return normalized orders with id, orderDate, customerName, customerEmail, status, statusLabel, itemCount, total, and shippingAddress (city, state, country). Create a status label map for Shift4Shop status codes (1=New, 2=Processing, 4=Shipped, etc.). Build a React OrdersDashboard component with a status filter dropdown and a sortable table.
Paste this in Bolt.new chat
1// app/api/shift4shop/orders/route.ts2import { NextRequest, NextResponse } from 'next/server';3import { shift4shopFetch } from '@/lib/shift4shop';45const STATUS_LABELS: Record<number, string> = {6 1: 'New',7 2: 'Processing',8 3: 'Awaiting Fulfillment',9 4: 'Shipped',10 5: 'Cancelled',11 6: 'Declined',12 7: 'Awaiting Payment',13 8: 'Backordered',14 9: 'Awaiting Shipment',15 12: 'Refunded',16};1718interface Shift4ShopOrder {19 InvoiceNumber: number;20 InvoiceDate: string;21 BillingFirstName: string;22 BillingLastName: string;23 BillingEmail: string;24 OrderStatus: number;25 OrderItems: unknown[];26 OrderAmount: number;27 ShipCity: string;28 ShipState: string;29 ShipCountry: string;30}3132export async function GET(request: NextRequest) {33 const { searchParams } = new URL(request.url);34 const status = searchParams.get('status');35 const limit = searchParams.get('limit') ?? '50';36 const offset = searchParams.get('offset') ?? '0';3738 const params = new URLSearchParams({ limit, offset });39 if (status) params.set('StatusID', status);4041 const orders = await shift4shopFetch<Shift4ShopOrder[]>(42 `/Orders?${params.toString()}`43 );4445 const normalized = orders.map(o => ({46 id: o.InvoiceNumber,47 orderDate: o.InvoiceDate,48 customerName: `${o.BillingFirstName} ${o.BillingLastName}`.trim(),49 customerEmail: o.BillingEmail,50 status: o.OrderStatus,51 statusLabel: STATUS_LABELS[o.OrderStatus] ?? `Status ${o.OrderStatus}`,52 itemCount: o.OrderItems?.length ?? 0,53 total: o.OrderAmount,54 shippingAddress: {55 city: o.ShipCity,56 state: o.ShipState,57 country: o.ShipCountry,58 },59 }));6061 return NextResponse.json({ orders: normalized });62}Pro tip: Shift4Shop's order status codes are numeric and not immediately obvious. Keep the STATUS_LABELS map in a shared constants file so it is consistent across your dashboard components and any webhook handlers that process status change events.
Expected result: An orders API route returning normalized Shift4Shop order data with readable status labels, and a dashboard component for filtering and viewing orders.
Deploy to Netlify and configure Shift4Shop webhooks
Deploy to Netlify and configure Shift4Shop webhooks
Outbound Shift4Shop API calls work flawlessly during Bolt.new development in the WebContainer — fetching products, orders, and inventory all function correctly in the preview environment. The only functionality that requires deployment is Shift4Shop's real-time notification system, which uses webhooks to push order and shipment events to your app. Shift4Shop offers webhook notifications (called 'Callbacks' in their interface) for events including new orders, order status changes, and inventory updates. These are POST requests sent from Shift4Shop servers to your endpoint URL. Since Bolt.new's WebContainer has no persistent public URL and cannot receive incoming HTTP connections, these notifications cannot reach your app during development. To deploy and configure webhooks: click Deploy in Bolt.new and connect your Netlify account. After deployment succeeds, go to your Netlify dashboard → Site Configuration → Environment Variables and add all three Shift4Shop credentials: `SHIFT4SHOP_SECURE_URL`, `SHIFT4SHOP_PUBLIC_TOKEN`, and `SHIFT4SHOP_PRIVATE_KEY`. Trigger a redeploy to apply the variables. For Shift4Shop webhooks: log into your Shift4Shop admin, go to Settings → API → Webhooks (or Callbacks depending on your version). Add a new webhook pointing to `https://your-app.netlify.app/api/shift4shop/webhook` for Order events. Shift4Shop sends a POST with the order number when triggered — your handler then calls back to the Shift4Shop API using the order number to fetch full details. This two-step pattern (notification → fetch) is common in e-commerce platform webhooks. A practical use case for the webhook: send an order confirmation email via SendGrid when Shift4Shop posts a new order notification. The webhook receives the order ID, your handler fetches the full order details from Shift4Shop, and then sends a branded email to the customer.
Create a Shift4Shop webhook handler at app/api/shift4shop/webhook/route.ts. Accept POST requests. Parse the body which contains orderId or InvoiceNumber. Use shift4shopFetch to GET /Orders/{orderId} to fetch the full order details. Log the order number, customer name, and total. Always return 200. Add a clear comment that this webhook handler requires a deployed public URL — it cannot be triggered against Bolt.new's WebContainer preview. Also create netlify.toml with Next.js build configuration.
Paste this in Bolt.new chat
1// app/api/shift4shop/webhook/route.ts2import { NextRequest, NextResponse } from 'next/server';3import { shift4shopFetch } from '@/lib/shift4shop';45// IMPORTANT: Shift4Shop webhooks require a publicly deployed URL.6// During Bolt.new WebContainer development, incoming webhook callbacks7// cannot be received. Deploy to Netlify first, then configure your8// webhook URL in Shift4Shop Admin → Settings → API → Webhooks.9export async function POST(request: NextRequest) {10 try {11 const body = await request.json();12 const orderId = body.InvoiceNumber ?? body.orderId;1314 if (orderId) {15 // Fetch full order details using the order ID from the notification16 const orders = await shift4shopFetch<unknown[]>(17 `/Orders?InvoiceNumber=${orderId}`18 );19 const order = Array.isArray(orders) ? orders[0] : orders;2021 if (order) {22 const o = order as Record<string, unknown>;23 console.log(24 `New Shift4Shop order #${orderId}: ` +25 `${o.BillingFirstName} ${o.BillingLastName} — ` +26 `$${o.OrderAmount}`27 );28 // TODO: Send order confirmation email, update internal database, etc.29 }30 }31 } catch (error) {32 // Log but don't expose — always return 200 to acknowledge receipt33 console.error('Shift4Shop webhook error:', error);34 }3536 // Always return 200 to prevent Shift4Shop from retrying37 return NextResponse.json({ received: true });38}Pro tip: Shift4Shop refers to their webhook system as 'Callbacks' in some documentation versions and 'Webhooks' in others — both refer to the same outbound HTTP notification feature. Look for both terms when navigating the admin interface.
Expected result: A deployed Netlify app with a webhook handler ready to receive Shift4Shop order notifications, enabling real-time order processing workflows.
Common use cases
Custom Product Catalog Page
Build a visually rich product catalog using your own React components and Tailwind CSS, pulling live product data from Shift4Shop. Display products with custom filtering, sorting, and layout that matches your brand — not the default Shift4Shop theme.
Create a product catalog page for my Shift4Shop store. Build an API route at app/api/shift4shop/products/route.ts that fetches all products from the Shift4Shop REST API using SecureURL from SHIFT4SHOP_SECURE_URL, PublicToken from SHIFT4SHOP_PUBLIC_TOKEN, and PrivateKey from SHIFT4SHOP_PRIVATE_KEY as request headers. Return an array of products with id, name, price, thumbnail, and stock. Create a React ProductCatalog component that fetches from this route and displays products in a responsive grid with search and category filter.
Copy this prompt to try it in Bolt.new
Order Management Dashboard
Create an internal order management view that shows recent orders, their status, customer details, and line items. Allow your fulfillment team to filter by status, search by order number, and view shipping details without logging into the Shift4Shop admin panel.
Build an order management dashboard. Create an API route at app/api/shift4shop/orders/route.ts that fetches orders from Shift4Shop using the three auth headers (SecureURL, PublicToken, PrivateKey from process.env). Accept query params for status filter (new, processing, shipped, cancelled) and limit (default 50). Return order ID, customer name, order date, status, total, and item count. Build a React Orders component with a filterable table, showing each order's key details and a status badge with appropriate color coding.
Copy this prompt to try it in Bolt.new
Low Stock Inventory Alert Dashboard
Build a dashboard that surfaces products with low inventory levels so your team can reorder before stockouts. Poll Shift4Shop for products with stock below a configurable threshold and display them prioritized by urgency.
Create an inventory management page that shows low-stock products. Build an API route at app/api/shift4shop/inventory/route.ts that fetches all products from Shift4Shop and filters to those with stock below a threshold (default 10 units). Sort by stock ascending. Return product name, SKU, current stock, and price. Build a React InventoryAlerts component that shows these products in a table with stock count color-coded (red for 0-3, orange for 4-9), and a header showing the total count of low-stock items.
Copy this prompt to try it in Bolt.new
Troubleshooting
API returns 401 Unauthorized even with correct credentials in headers
Cause: Shift4Shop requires all three headers (SecureURL, PublicToken, PrivateKey) to be present on every request, not just the PrivateKey. A common mistake is sending only one or two headers. Another cause is using the REST API URL as the base URL but omitting it from the SecureURL header — both the URL and the header must be present.
Solution: Verify that all three headers are included in every request: SecureURL (the full API base URL), PublicToken, and PrivateKey. Check your lib/shift4shop.ts helper to confirm all three are being set. Also verify the header names are exactly as Shift4Shop expects — they are case-sensitive. Log the request headers in development to confirm they are being sent.
Products endpoint returns an empty array even though products exist in the store
Cause: Shift4Shop hides inactive products by default in some API configurations. If products are set to 'Hide' in the admin panel, or if the API call is not filtering correctly, you may receive an empty result. The free plan also requires Shift4 Payments to be active — stores that haven't completed payment setup may have API access restrictions.
Solution: Add hide=false to your query parameters to include all active products. Check in the Shift4Shop admin that your products are not set to 'Hidden'. If you are on the free plan, verify your Shift4 Payments account is fully set up and connected — incomplete payment setup can restrict API access.
1// Add hide=false to ensure active products are returned2const params = new URLSearchParams({ limit: '20', offset: '0', hide: 'false' });3const products = await shift4shopFetch(`/Products?${params.toString()}`);Shift4Shop webhook callbacks are not arriving in Bolt.new
Cause: Bolt.new's WebContainer does not have a persistent public URL that external services can reach. Shift4Shop's callback/webhook system sends POST requests to your registered URL, requiring a publicly accessible server. The Bolt.new preview URL is not a valid callback target.
Solution: Deploy your app to Netlify, then register the deployed URL in Shift4Shop admin Settings → API → Webhooks/Callbacks. Use your Netlify domain (e.g., https://your-app.netlify.app/api/shift4shop/webhook). This is a fundamental limitation of WebContainers — incoming HTTP connections always require a deployed environment.
Images from Shift4Shop products show 'unconfigured host' error in Next.js Image component
Cause: Next.js requires all external image domains to be explicitly listed in next.config.js before they can be used in the next/image component. Shift4Shop hosts images on 3dcart.com CDN domains.
Solution: Add the Shift4Shop CDN domain to your next.config.js images configuration. The primary CDN domain is cdn.3dcart.com — add it to the remotePatterns or domains array.
1// next.config.js2module.exports = {3 images: {4 remotePatterns: [5 { protocol: 'https', hostname: 'cdn.3dcart.com' },6 { protocol: 'https', hostname: '*.3dcart.com' },7 ],8 },9};Best practices
- Store all three Shift4Shop credentials (SecureURL, PublicToken, PrivateKey) as server-side environment variables — never expose any of them in NEXT_PUBLIC_ variables or client-side code
- Create a centralized lib/shift4shop.ts helper that handles authentication headers for all API calls, rather than repeating the auth logic in every API route
- Implement pagination for large catalogs — the Products endpoint allows up to 200 items per request, but stores with thousands of products should use offset-based pagination
- Add response caching for product catalog data since product listings change infrequently — cache for 60-300 seconds to reduce API calls and improve page load times
- Use Shift4Shop's status code constants in a shared mapping object rather than hardcoding numeric status values directly in components
- Always return HTTP 200 from webhook handlers even if processing fails — Shift4Shop retries failed callbacks which can cause duplicate order processing
- Test your API routes against the Shift4Shop API from Bolt's WebContainer preview before deploying — all outbound calls work in development and catching errors early saves time
- For headless storefront use cases, use the Public Token for read-only product/category queries and reserve the Private Key usage for order and customer data API routes
Alternatives
WooCommerce is self-hosted on WordPress with unlimited customization — choose it over Shift4Shop if you need maximum control over the platform, already use WordPress, or want access to thousands of plugins.
BigCommerce offers a more enterprise-grade hosted platform with stronger multi-channel selling features — choose it over Shift4Shop if you need advanced B2B features or higher-volume merchant capabilities.
Ecwid is a lightweight e-commerce widget that embeds into any website without replacing it — choose it over Shift4Shop if you want to add a store to an existing site rather than building a new one.
Magento (Adobe Commerce) is an enterprise e-commerce platform with the most extensive feature set — choose it over Shift4Shop for large-scale commerce operations with complex B2B requirements and dedicated development resources.
Frequently asked questions
Is Shift4Shop really free?
Yes, Shift4Shop's Free plan offers unlimited products, orders, bandwidth, and storage with no monthly subscription fees. The condition is using Shift4 Payments as your payment processor. Shift4 charges a payment processing fee (similar to Stripe or Square) but eliminates the platform subscription cost. This makes it among the most cost-effective hosted e-commerce platforms for high-volume sellers.
Can I use Shift4Shop's API from Bolt.new during development without deploying?
Yes. All outbound API calls to Shift4Shop's REST API work in Bolt.new's WebContainer during development. You can fetch products, orders, inventory, and customer data from the preview environment. The only feature requiring deployment is Shift4Shop's webhook/callback system, which sends incoming POST requests that WebContainers cannot receive.
What's the difference between Shift4Shop's Public Token and Private Key?
The Public Token is designed for read-only operations on public catalog data — some implementations use it client-side to fetch product listings. The Private Key provides full API access including order management, customer data, and write operations. For security, this guide treats both as server-side only credentials and never exposes either in client-side code or NEXT_PUBLIC_ environment variables.
Can Bolt.new handle Shift4Shop's webhook callbacks?
Yes, after deployment. Write your webhook handler in Bolt.new, deploy to Netlify, and register the Netlify URL in Shift4Shop's admin panel (Settings → API → Webhooks). The WebContainer cannot receive incoming HTTP connections during development — this is a fundamental limitation of the browser-based runtime, not a Bolt.new-specific issue.
How do I handle Shift4Shop's pagination for large product catalogs?
Use the offset and limit query parameters on the /Products endpoint. Limit is capped at 200 per request. First call /Products?countonly=1 to get the total product count, then calculate how many pages you need. Implement either traditional pagination (page number controls) or infinite scroll in your React component, loading additional pages as the user scrolls. For catalogs under 200 products, a single call with limit=200 fetches everything.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation