ShopKit

Flutter WooCommerce App · WebKoding · version 2.0.0 · documentation measured from the code on 5 October 2026

What's inside

ShopKit is the source code of a shopping app for iOS and Android, written in Flutter, plus a free WordPress plugin that connects it to a WooCommerce store. Every app runs in two modes:

11runnable apps (Core Kit, 9 niche designs, a showcase)
192screens: 48 in Core Kit + 144 niche
3languages: English, Arabic (right to left), Turkish
5,158automated Flutter tests, all passing
1companion WordPress plugin, free (GPL)

The folders in your download

Folder or fileWhat it is
README.txtA one-page quick start in plain text.
documentation/This guide. Open documentation/index.html in a browser.
shopkit/templates/The 11 apps. Each folder is a complete Flutter app you can open, run and publish on its own.
shopkit/packages/Code the apps share: shopkit_core (screens, widgets, themes, fonts, translations), shopkit_domain (data models and interfaces), shopkit_data_mock (the sample store and its photos), shopkit_data_woo (the WooCommerce connection), shopkit_app (connecting a store in the app, optional push).
plugin/webkoding-shopkit-connect.zipThe Webkoding ShopKit Connect for WooCommerce plugin, ready to upload to WordPress.
shopkit/backends/wordpress/The same plugin as readable source, with the API contract (API.md). You do not need this folder to use the plugin.
shopkit/tools/extract_template.sh (copy one app out as a standalone project), apply_app_icon.sh (generate every icon size).
design-source/The original screen designs as web pages and the 1024 × 1024 app icon. See Design files.
Changelog.txt, LICENSE.txtVersion history and licence.

Screens per app (counted from the source files)

App folderDesignOwn screensScreen codes
core_kitCore Kit (general store, light + dark)48S01-S48
electroElectro (electronics)17E01-E17
auraAura (jewellery, luxury)16A01-A16
pawlyPawly (pet supplies)16P01-P16
freshoFresho (grocery delivery)15F01-F15
foldFold (editorial fashion)16FL01-FL16
glowGlow (beauty, skincare)16G01-G16
nestNest (furniture, home)16N01-N16
peakPeak (sport, fitness)15K01-K15
todsTods (toys, kids, gifts)17T01-T17
showcaseA gallery app that opens every screen above on its sample storeall-

Each niche app also uses the shared Core Kit screens it needs (password reset, addresses, orders, settings, reviews, filters...) drawn in its own colours and fonts, so every app is a complete shop.

Requirements

ForYou needWhere the number comes from
Running the appsFlutter 3.24 or newer (Dart 3.3 or newer). Built and tested with Flutter 3.44.7 / Dart 3.12.2.environment: in every pubspec.yaml
AndroidAndroid 7.0 or newer on the phone (minSdk = 24); Android Studio or the Android SDK with API 36 and Java 17 to build.android/app/build.gradle.kts: minSdk = 24, compileSdk = 36, targetSdk = 36
iOSiOS 15.0 or newer on the phone; a Mac with Xcode to build (tested with Xcode 27.0).IPHONEOS_DEPLOYMENT_TARGET = 15.0
Your store (live mode only)WordPress 6.5+, PHP 7.4+, WooCommerce 10.0+, HTTPS. Tested up to WordPress 7.1 and WooCommerce 11.1.Plugin header and readme.txt

Demo mode needs none of the store requirements and no paid account of any kind.

Prerequisites start here if you are new

ShopKit is source code, so you build it with the standard Flutter tools. If you have used a terminal before, skip to Run in demo mode. If not, this section covers what you need. It takes about fifteen minutes.

What to install

ToolWhy
Flutter SDK (includes Dart)Builds and runs the app. Follow the official installer for your operating system.
VS Code with the Flutter extension, or Android StudioYour editor. One of them is enough.
Android Studio / Android SDKTo build for Android and run an Android emulator.
Xcode (Mac only)To build for iPhone. iOS apps cannot be built on Windows or Linux.

Opening a terminal

The four commands you need

CommandWhat it does
pwd (Windows: cd alone)Shows the folder you are in.
ls (Windows: dir)Lists files. Inside an app folder you see pubspec.yaml and lib.
cd <folder>Moves into a folder. cd .. goes up one level.
clear (Windows: cls)Clears the screen.

Tip: type cd with a space, drag a folder from Finder or File Explorer onto the terminal and press Enter; the path is filled in for you. Tab completes a folder name, ↑ repeats the last command.

Check Flutter

flutter --version
flutter doctor

flutter doctor lists your setup with a tick or a cross per item. Fix the crosses for the platforms you want (a cross next to Xcode does not matter if you only build for Android).

"flutter: command not found" means Flutter is installed but not on your PATH. Redo the "Update your path" step of the install guide, then close and reopen the terminal.

Unzip to a simple path

Extract the download to a folder whose path has no spaces and no non-English characters, for example ~/dev/shopkit or C:\dev\shopkit. Some build tools still trip over unusual paths.

Somewhere to run the app

A phone with USB debugging on, an Android emulator (Android Studio → Device Manager) or the iOS Simulator (Xcode → Open Developer Tool → Simulator). Check what Flutter sees with flutter devices.

Run in demo mode

Every app opens on its bundled sample store when you start it without a connection code. Everything is inside the app: products, photos (license-safe, bundled), fonts and translations, so it works offline.

cd shopkit/templates/core_kit
flutter pub get
flutter run

Replace core_kit with any other app folder: electro, aura, pawly, fresho, fold, glow, nest, peak, tods, or showcase to browse every design in one app.

The android/ and ios/ folders are included in every app, so you do not need flutter create .. You only run it if you want to add another platform yourself.

What demo mode simulates: sign-in accepts the sample account, card payments are simulated, the push switch uses a demo token, and screens that need services WooCommerce does not have (courier map, chat, loyalty points, saved cards...) show sample content. In live mode those screens are hidden. See Choosing a template.

Video: "Live in 10 minutes" setup video (63 seconds, no sound, English captions), included at documentation/video/setup-walkthrough.mp4 and recorded with version 2.0. It follows Live in 10 minutes on a real local WooCommerce store: upload and activate the ShopKit Connect plugin, the Status tab, create an app key (QR code and connection JSON), open the Core Kit app, connect it under Settings → Store by pasting the JSON (the simulator has no camera; on a phone you scan the QR code), add a product variation to the cart, check out with cash on delivery, and see the order in WooCommerce → Orders. Waiting parts are sped up; the key's secret is blurred.

Live in 10 minutes connect your WooCommerce store

You need a WordPress site with WooCommerce on HTTPS and a WordPress administrator account. The plugin does not change your shop's pages; it only adds what the app needs.

  1. Install the plugin In WordPress go to Plugins → Add New → Upload Plugin, choose plugin/webkoding-shopkit-connect.zip from your download, click Install Now, then Activate.
  2. Check the Status tab Open WooCommerce → ShopKit Connect. The Status tab checks nine things: WooCommerce, permalinks, HTTPS, the checkout page, app keys, background jobs, push, customer registration and whether the site can reach its own Store API. Fix anything marked red before you continue.
    Status tab on a test store
    Status tab on a test store
  3. Create an app key On the App keys tab, give the key a name (for example "iOS app") and click Create key. The page shows a connection JSON and a QR code of the same JSON. Copy the JSON now: it is shown only once. If you lose it, create a new key and revoke the old one. It looks like this (the key below is an example, not a working key):
    {"type":"shopkit-connect","version":1,
     "site_url":"https://store.example/",
     "api_url":"https://store.example/wp-json/",
     "app_key":"ak_0123456789abcdef.AbCdEfGhIjKlMnOp"}
    The app key identifies your app build; it is not a password and it never gives access to your WooCommerce REST API. Customer data still needs the customer's own sign-in.
    App keys tab right after creating a key (a throw-away key on a local test site).
    App keys tab right after creating a key (a throw-away key on a local test site).
  4. Give the code to the app There are two ways. Use the first to try your store, the second for the app you publish.

    In the app: scan or paste (no rebuild)

    Run the app as it comes (flutter run, demo mode) and open Connect your store: on the Profile tab while signed out, or Profile → Settings → Store while signed in. Tap Scan QR code and point the camera at the QR code on the plugin page, or paste the connection JSON and tap Connect. The app checks the code (it must be a ShopKit Connect code with an https:// address; plain http:// is accepted only for a local test store in a debug build), asks your store whether the key is valid, keeps the code in the phone's secure storage (Keychain / Keystore) and restarts on your store. It stays connected after the app is closed. Disconnect and use the demo store on the same screen signs out, forgets the code and everything kept for that store, and goes back to the demo store.

    The camera is used only for this scan; the permission text is in English, Arabic and Turkish (ios/Runner/*.lproj/InfoPlist.strings; Android shows its own system text). Web builds have no scan button: paste the JSON instead.

    At build time (the app you publish)

    Pass the same JSON with a --dart-define. The store is then fixed, the app never reads a saved code, and Connect your store is hidden everywhere, so your customers never see it. In the app folder you chose:

    cd shopkit/templates/fresho
    flutter run --dart-define=SHOPKIT_CONNECTION='{"type":"shopkit-connect","version":1,"site_url":"https://store.example/","api_url":"https://store.example/wp-json/","app_key":"ak_..."}'

    Windows PowerShell and some shells mangle the quotes in JSON. If that happens, pass the base64 of the JSON instead; the app accepts both. macOS / Linux: printf '%s' '<the JSON>' | base64. PowerShell: [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes('<the JSON>')). Then flutter run --dart-define=SHOPKIT_CONNECTION=<the base64 text>.

    To avoid typing it every time, put it in a file and use --dart-define-from-file: create connection.json next to pubspec.yaml with {"SHOPKIT_CONNECTION": "<the base64 text>"} and run flutter run --dart-define-from-file=connection.json. Keep this file out of public repositories.

    A build that should only ever show the demo store (for example a public demo) can hide the in-app flow with --dart-define=SHOPKIT_HIDE_CONNECT=true.

  5. Run it The app opens on your store. Sign in with a customer account (store staff accounts are refused on purpose, see Troubleshooting), add a product to the cart and check out. Cash on delivery and bank transfer finish inside the app; card gateways open your own checkout page inside the app.

Optional: what you can set in the plugin

TabSettingUsed by the app?
App settingsFeature switches: wishlist, notification feed, push, registration, checkout on your checkout page, writing reviews, deleting the accountYes. A feature switched off is hidden in the app.
App settingsLogo, home screen banners, contact email, phone and address, support, terms and refund links, free-shipping thresholdYes. The store name and logo appear on the splash screen of every app (the logo replaces the design's own mark) and the store name in the settings footer and the app switcher title.
App settingsPrimary colourCore Kit only: used as its accent colour (buttons, links, selected states). The niche apps keep their own curated palette and ignore it. A colour too light for white text is ignored. To recolour a niche app, see Branding.
PushLog only or Firebase Cloud Messaging; which order statuses notify; test message; broadcastSee Push notifications
LogsPlugin log (no personal data)For you
App settings tab
App settings tab
Push tab
Push tab

Choosing a template

Pick the design closest to your shop; the data, cart, checkout and account behaviour are the same in all of them. Run any of them in demo mode first, or run showcase to flip through all designs.

AppBest forFonts (bundled)Demo-only parts, hidden in live mode
Core KitAny general store; light and darkPlus Jakarta SansOTP code sign-in, saved cards, courier card, support chat, map strip, returns, seller store, loyalty points, help centre FAQ, currency switch
ElectroElectronics, gadgetsSpace GroteskLive courier card and map, store credit, member level, warranties, price alerts, back-in-stock "Notify", trending searches
AuraJewellery, luxury fashionJost, Cormorant GaramondAtelier progress, concierge, store credit, saved sizes, member events, trust badges
PawlyPet suppliesNunitoPet profiles, subscriptions list, Paw Points, courier card
FreshoGrocery deliveryManrope"15 min" promise, rider map and card, Fresh Club, substitution approvals, OTP sign-in. Delivery slots are your shipping methods.
FoldEditorial fashionArchivo, Playfair DisplayLookbook, saved sizes, store credit, members preview, drop and back-in-size alerts, trending searches
GlowBeauty, skincareLora, KarlaRitual tracker, streaks, skin profile and quiz, fragrance-note chart, free samples, gift wrap, glow points
NestFurniture, homeDM Serif Display, Work Sans"View in your room" card (a static layout, no AR), delivery windows, assembly, room plans, warranties
PeakSport, fitness (dark)Barlow, Barlow CondensedTraining programme, store credit, training goal, trending searches, price alerts, free-gift threshold
TodsToys, kids, giftsBaloo 2Child profiles, gift box builder, gift wrap, wish-jar sharing, trending searches. Age chips use your store's "Age" attribute.

"Hidden in live mode" means WooCommerce has no data for it, so the app does not show sample content to your customers. Each app's README.md lists the same.

Using one app on its own

The apps use the shared packages through relative paths, so keep the folder layout, or copy one app out as a self-contained project:

cd shopkit/tools
./extract_template.sh fresho ~/dev/my-grocery-app

Branding Guide do this before you publish

You change values, not logic. After saving a Dart file, press r in the terminal running flutter run to reload; for icons, names and package ids stop the app and run it again.

1. Package name and bundle id (required)

Every app ships with our ids (com.webkoding.<app>). You must replace them with your own reverse-domain id, for example com.yourshop.app. Google Play and the App Store reject an id that is already taken, an id cannot be changed after the first upload, and com.example is refused by both stores.

PlatformFileChange
Androidandroid/app/build.gradle.ktsapplicationId = "com.webkoding.fresho" → your id. This is the id Google Play uses. Changing namespace as well is optional; if you do, move android/app/src/main/kotlin/com/webkoding/<app>/MainActivity.kt to the matching folders and update its package line.
iOSios/Runner.xcodeproj/project.pbxprojOpen ios/Runner.xcworkspace in Xcode → Runner target → Signing & Capabilities → Bundle Identifier. Or replace every PRODUCT_BUNDLE_IDENTIFIER = com.webkoding.fresho in the file (three for the app, three for RunnerTests).

2. App name

Where it showsFileChange
Under the icon on Androidandroid/app/src/main/AndroidManifest.xmlandroid:label="Fresho"
Under the icon on iOSios/Runner/Info.plistCFBundleDisplayName and CFBundleName
Task switcherlib/app.darttitle: 'Fresho'
Store name inside the app (live mode)WordPress → Settings → General → Site TitleThe app reads it from your store

3. Icon

Replace design-source/assets/app-icon.png (1024 × 1024 PNG) with your own square icon, then generate every Android and iOS size:

cd shopkit/tools
./apply_app_icon.sh fresho

The script copies the PNG into the app and runs flutter_launcher_icons. The PNG opens in any image editor.

4. Logo and splash

In live mode every app's splash screen shows the logo you set in the plugin (App settings → Logo, or the site logo of your WordPress theme) in place of the design's own mark, with your store name. The onboarding screens use the images in shopkit/packages/shopkit_core/assets/images/ (Fresho, Glow and Nest also have their own assets/images/ folder); replace the files and keep the names.

5. Colours

Colours live in two places, both plain lists of Color(0xFFRRGGBB) values (0xFF means "opaque", the last six characters are an ordinary hex colour):

WhatFile
Core Kit (light)shopkit/packages/shopkit_core/lib/theme/themes/core_theme.dart, dark: core_dark_theme.dart
Shared screens drawn in a niche theme (orders, addresses, settings...)shopkit/packages/shopkit_core/lib/theme/themes/all_themes.dart, one class per theme
A niche app's own screensshopkit/templates/<app>/lib/widgets/<app>_design.dart
// core_theme.dart
accent:      Color(0xFF4353E6),   // your brand colour: buttons, links, active tabs
accentTonal: Color(0xFFEDEFFD),   // a light tint of the accent: chips, badges
background:  Color(0xFFFBFBFD),
surface:     Color(0xFFFFFFFF),
text:        Color(0xFF16161D),

Core Kit can also take its accent from the plugin: set App settings → Primary colour and the live app uses it for buttons, links and selected states (the rest of the palette stays). The niche apps do not: their palettes are designed as a whole, so change them in code.

For a niche app, change accent in both its *_design.dart file and its class in all_themes.dart. Default accents:

ThemeAccentThemeAccent
Core Kit0xFF4353E6Fold0xFF111111
Electro0xFF22D3EEGlow0xFFC25B6B
Aura0xFFA5842ENest0xFFB4643C
Pawly0xFFE8701BPeak0xFFC8F131
Fresho0xFF3E9B4FTods0xFF4E9BF5 (plus several accents)

6. Fonts

The 15 font families are bundled as .ttf files (SIL Open Font License) in shopkit/packages/shopkit_core/lib/assets/fonts/; nothing is downloaded at run time. Each app lists the families it uses under fonts: in its pubspec.yaml. To use another font:

  1. Put its .ttf files in the app, for example assets/fonts/Inter/.
  2. Add it under flutter: fonts: in the app's pubspec.yaml with family: Inter.
  3. In the theme file, replace the SkFonts.plusJakartaSans( call with SkFonts.style('Inter', , keeping the arguments.

7. Product photos and sample content

In live mode every product photo, name and price comes from your WooCommerce store. The sample store's photos (shopkit/packages/shopkit_data_mock/assets/images/, credits in CREDITS.md next to them) are only used in demo mode and are licensed CC0 or generated; you may keep or replace them.

8. Link scheme (optional)

Sign-in links and the return from checkout use the shopkit:// scheme. Keep it unless two of your apps are on the same phone. To change it, edit the same word in four places: android/app/src/main/AndroidManifest.xml (android:scheme), ios/Runner/Info.plist (CFBundleURLSchemes), lib/router.dart (uri.scheme == 'shopkit') and the plugin's Deep link scheme setting.

Languages

Every app and the plugin come in English, Arabic and Turkish. Arabic is fully right to left. The app follows the phone's language and the customer can change it on the language screen; the choice is saved on the device. In live mode the app sends its language to your store, and the plugin answers its messages in that language.

Where the words live

WordsFilesKeys per language
Shared screens and widgets (all Core Kit screens, cart, checkout, orders, errors...)shopkit/packages/shopkit_core/lib/l10n/shopkit_en.arb, _ar.arb, _tr.arb482
Aura screensshopkit/templates/aura/lib/l10n/aura_en.arb, _ar, _tr101
Electro screensshopkit/templates/electro/lib/l10n/electro_en.arb, _ar, _tr87
Fold screensshopkit/templates/fold/lib/l10n/fold_en.arb, _ar, _tr78
Fresho screensshopkit/templates/fresho/lib/l10n/fresho_en.arb, _ar, _tr85
Glow screensshopkit/templates/glow/lib/l10n/glow_en.arb, _ar, _tr94
Nest screensshopkit/templates/nest/lib/l10n/nest_en.arb, _ar, _tr77
Pawly screensshopkit/templates/pawly/lib/l10n/pawly_en.arb, _ar, _tr81
Peak screensshopkit/templates/peak/lib/l10n/peak_en.arb, _ar, _tr68
Showcase screensshopkit/templates/showcase/lib/l10n/showcase_en.arb, _ar, _tr79
Tods screensshopkit/templates/tods/lib/l10n/tods_en.arb, _ar, _tr114
The plugin (admin pages and messages to the app)webkoding-shopkit-connect/languages/*.po224

Product names, descriptions, categories and reviews come from WooCommerce in your store's language and are not translated by the app. Prices use your store's currency and the app language's number format ($1,299.00 in English, $1.299,00 in Turkish).

Change a word

Edit the value in the .arb file, then regenerate the code in that folder:

cd shopkit/packages/shopkit_core     # or shopkit/templates/<app>
flutter gen-l10n

Add a language (example: French)

  1. Copy shopkit/packages/shopkit_core/lib/l10n/shopkit_en.arb to shopkit_fr.arb, set "@@locale": "fr" and translate every value. Keep {placeholders} and plural forms as they are; you can drop the "@key" description entries.
  2. Optional: add "languageFrench": "Français" to every shopkit_*.arb file and a 'fr' => t.languageFrench line in SkLocale.nativeName (shopkit_core/lib/l10n/sk_l10n.dart); otherwise the language screen shows the code "fr".
  3. Do the same for the app's own file, for example shopkit/templates/fresho/lib/l10n/fresho_en.arb → fresho_fr.arb.
  4. Run flutter gen-l10n in shopkit_core and in the app. French now appears on the language screen.
  5. Run flutter test in shopkit_core: the completeness test names any key you missed.
  6. Plugin: add webkoding-shopkit-connect-fr_FR.po and .mo to the plugin's languages/ folder (start from the .pot file there, with Poedit or any PO editor).

Tests that guard the translations

Payments

Payment method in WooCommerceWhat happens in the app
Cash on delivery (cod), direct bank transfer (bacs), cheque (cheque)Chosen and placed inside the app through the WooCommerce Store API. The order success screen shows next.
Every other gateway (Stripe, PayPal, Square, iyzico, Apple Pay / Google Pay through your gateway...)The app hands its cart to your own checkout page, opened in a secure in-app web view. The customer pays there exactly as on your website; then the app shows its order success screen.

The app never sees card numbers and needs no gateway code: any gateway that works on your WooCommerce checkout works in the app. Only methods enabled in WooCommerce → Settings → Payments are offered.

In demo mode card payment is simulated and no money moves.

Push notifications

The plugin sends a push message when an order changes status (by default: processing, on hold, completed, cancelled, refunded, failed), when you send a broadcast and when you send a test. Messages go out in the background through WooCommerce's Action Scheduler, so checkout never waits for them. Every message is also stored in the customer's in-app notification feed, which works without push.

Store side: the plugin

  1. Create a free project in the Firebase console.
  2. Project settings → Service accounts → Generate new private key. A .json file downloads.
  3. Upload it to your server outside the web root (for example one folder above public_html) so nobody can download it.
  4. In WooCommerce → ShopKit Connect → Push choose Firebase Cloud Messaging and enter the absolute path of that file. The Status tab confirms the project id.

Until then the default Log only driver writes each notification to the plugin log and sends nothing anywhere.

App side: add your Firebase project

Every app already includes firebase_core and firebase_messaging, but not a Firebase project: the project files (google-services.json, GoogleService-Info.plist) are yours and cannot ship in a template. Without them the app runs normally with push switched off: no crash, no error messages, and the push switch on the settings screen is hidden. The in-app notification feed works either way.

  1. Install the FlutterFire command line tool and connect the app to your Firebase project. It writes the platform files and lib/firebase_options.dart:
    dart pub global activate flutterfire_cli
    cd shopkit/templates/fresho
    flutterfire configure
  2. Android and iOS read the platform files on their own; nothing else is needed. If you prefer the generated options file (required for web), pass it in lib/main.dart:
    import 'firebase_options.dart';
    ...
    final push = await FirebasePushMessaging.start(options: DefaultFirebaseOptions.currentPlatform);
  3. iOS only: in the Apple Developer account create an APNs key and upload it in Firebase → Project settings → Cloud Messaging; in Xcode add the Push Notifications and Background Modes → Remote notifications capabilities. The iOS simulator has no push token: test on a phone.

What the app then does, connected to your store with push switched on in the plugin:

Switching Push notifications off in the plugin hides the switch and stops the registration. Web builds do not use push unless you pass the Firebase options and add Firebase's web service worker yourself.

Send a test from the plugin's Push tab with a device token from the plugin log.

Costs: sending messages with Firebase Cloud Messaging is free of charge at the time of writing; check Google's current pricing. iOS push needs the paid Apple Developer Program.

Building for Release

Before your first release: replace the package name and bundle id, the app name and the icon (Branding Guide), and build with your connection code. A build without SHOPKIT_CONNECTION is the demo app.

Android: APK and App Bundle

The release build is signed with the debug key so that flutter run --release works out of the box. Google Play does not accept that. Create your own upload key once and keep it safe:

keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload

Create android/key.properties (do not share it):

storePassword=...
keyPassword=...
keyAlias=upload
storeFile=/Users/you/upload-keystore.jks

In android/app/build.gradle.kts, add at the top and replace the release block:

import java.util.Properties
import java.io.FileInputStream

val keyProps = Properties().apply {
    val f = rootProject.file("key.properties")
    if (f.exists()) load(FileInputStream(f))
}

android {
    ...
    signingConfigs {
        create("release") {
            keyAlias = keyProps["keyAlias"] as String?
            keyPassword = keyProps["keyPassword"] as String?
            storeFile = (keyProps["storeFile"] as String?)?.let { file(it) }
            storePassword = keyProps["storePassword"] as String?
        }
    }
    buildTypes {
        release {
            signingConfig = signingConfigs.getByName("release")
        }
    }
}

Then build:

flutter build appbundle --release --dart-define-from-file=connection.json   # for Google Play (.aab)
flutter build apk --release --dart-define-from-file=connection.json         # to install directly (.apk)

Output: build/app/outputs/bundle/release/app-release.aab and build/app/outputs/flutter-apk/app-release.apk. compileSdk and targetSdk are set to 36 explicitly; raise both when Google Play's target-API deadline moves.

iOS

flutter build ipa --release --dart-define-from-file=connection.json

Open ios/Runner.xcworkspace in Xcode once, choose your team under Signing & Capabilities, then upload build/ios/ipa/*.ipa with Apple's Transporter app or from Xcode's Organizer. You need the paid Apple Developer Program.

iOS Simulator with Xcode 27

Xcode 27's lipo accepts one architecture per check, while Flutter asks for all simulator architectures at once, which stopped simulator builds. Every app's ios/Flutter/Debug.xcconfig and Release.xcconfig therefore contain:

ARCHS[sdk=iphonesimulator*] = arm64

Simulators on Apple silicon Macs need only arm64, and device builds are not affected. On an Intel Mac, remove that line to run the simulator.

Updating

The app

Download the new version from CodeCanyon and read Changelog.txt. ShopKit is source code you have changed, so an update is a merge, not an install:

  1. Keep your project in git (git init and commit before you start customising).
  2. Unzip the new version into a separate folder.
  3. Copy the changed packages over yours (shopkit/packages/ is where most fixes land), or compare the two folders with a diff tool and take the changes you want.
  4. Run flutter pub get, flutter analyze and flutter test in your app folder.

Keeping your changes to colours, names and ids (Branding) and leaving shared screens alone makes updates simple.

The plugin

Upload the new plugin/webkoding-shopkit-connect.zip through Plugins → Add New → Upload Plugin and choose Replace current with uploaded. App keys, settings and customer data are kept. Existing app builds keep working; the plugin's REST API is versioned (shopkit/v1).

Troubleshooting

Run flutter doctor -v first for build problems. For store problems, open the plugin's Status and Logs tabs.

What you seeWhyFix
App stops at start with api_url must use https://The app refuses to send passwords and tokens over plain HTTP.Put the store on HTTPS (most hosts include a free Let's Encrypt certificate). Plain http:// is accepted only for localhost, 127.0.0.1, 10.0.2.2 (Android emulator) and *.local test sites.
The connection code is not valid JSON / not a ShopKit Connect codeThe shell changed the quotes, or only part of the JSON was copied.Pass the base64 of the JSON or use --dart-define-from-file (see step 4).
"This app is not connected to the store. Check the app key."The key was revoked, mistyped, or belongs to another site.Create a new key on the App keys tab and rebuild with its JSON.
"Store staff accounts cannot sign in to the app"On purpose: administrator and shop manager accounts never get app tokens, so a phone can never become a back-office login.Test with a customer account.
"Too many attempts. We can email you a sign-in link instead."Login lock-out protection: 5 wrong passwords per account from one network, or 20 per account from all networks, in 15 minutes (and 20 per network address).Use the emailed sign-in link the app offers; the owner is never locked out. Or wait 15 minutes.
"This account uses two-step verification"A two-factor plugin protects the account; the app does not support two-step sign-in yet.Sign in on the website, or use an account without two-step verification.
Signed-in requests fail with "You are not signed in" right after a successful sign-inSome hosts (often Apache with PHP-CGI) strip the Authorization header.Nothing to change in the app: it also sends the token as X-ShopKit-Token. If that header is stripped too, ask your host or security plugin to allow it.
Status tab: "The site could not reach its own Store API"A security plugin, firewall or "disable REST API" setting blocks /wp-json/.Allow wc/store/v1 and shopkit/v1 in that plugin or firewall.
Cart empties or "add to cart" fails; cart differs between requestsA cache or CDN caches /wp-json/ responses or strips the Cart-Token header the WooCommerce Store API uses for the app's cart.Exclude /wp-json/ (and ?rest_route=) from page caching and pass the Cart-Token, X-ShopKit-Key and X-ShopKit-Token headers through.
Status tab: "Plain permalinks are in use"Settings → Permalinks is on "Plain".The app works anyway through ?rest_route=, but choose any other permalink setting (for example "Post name"): it is what WooCommerce and caches expect. The connection JSON's api_url follows the setting, so create the key after changing it.
Checkout page says "This checkout link has expired" or "has already been used"The hand-off link is valid for 5 minutes and once.Go back to the app and tap checkout again.
"This browser is signed in to the store with another account"The in-app browser still has another customer's website session.Sign out on the website in that browser, then check out again from the app.
Sign-up is missing in the appWooCommerce → Settings → Accounts & Privacy does not allow account creation, or the plugin's registration switch is off.Turn both on.
No push messages arriveThe driver is still Log only, the service account path is wrong, or the app has no Firebase yet.Check the Status tab ("Push (Firebase)") and the Logs tab; follow Push notifications for the app side.
CORS errors in a browser consoleBrowsers enforce CORS; phones do not. The apps are built for iOS and Android.Run on a phone, emulator or simulator. A web build of the app needs your server to send CORS headers for /wp-json/.
Release APK shows no products although debug worksA custom AndroidManifest.xml without the INTERNET permission.Keep <uses-permission android:name="android.permission.INTERNET"/> in android/app/src/main/AndroidManifest.xml (it is there in every shipped app).
iOS Simulator build stops in debug_unpack_ios or with a lipo -verify_arch errorXcode 27 and the simulator architecture setting.Keep the ARCHS[sdk=iphonesimulator*] = arm64 line (see Release builds); on an Intel Mac remove it.
Because fresho depends on shopkit_core from path which doesn't existThe app folder was moved away from shopkit/packages/.Keep the layout, or use shopkit/tools/extract_template.sh.
Command PhaseScriptExecution failed (iOS)Stale CocoaPods or Xcode build data.
cd ios && pod install --repo-update && cd ..
flutter clean && flutter pub get
Gradle build fails on the first Android runAndroid SDK licences, a missing API 36 platform or Java older than 17.
flutter doctor --android-licenses
flutter clean && flutter run
and install "Android API 36" in Android Studio's SDK Manager.
"Connect your store" says the store refused the app keyThe key was revoked, or the JSON was cut off while copying.Create a new key on the plugin's App keys tab and scan its QR code.
"Connect your store" says ShopKit Connect is not activeThe site answered but the plugin is off, or the address in the JSON is not the WordPress site.Activate the plugin; check the Status tab.
No "Connect your store" anywhereThe app was built with SHOPKIT_CONNECTION (a fixed store) or SHOPKIT_HIDE_CONNECT=true.Expected. Build without them to use the in-app flow.
Google Play rejects the upload: "signed in debug mode"The release build still uses the debug key.Set up your upload key (Building for Release).

Third-Party Services & Costs

Read this before you plan a project. ShopKit and the ShopKit Connect plugin have no running cost of their own. Publishing a shop app uses services from other companies. They are separate products, not included in the price of this item, they need your own account, and their prices are set by them and can change. Check each provider's current pricing.

ServiceNeeded forCost (at the time of writing, October 2026)
Web hosting for WordPress + WooCommerce, with HTTPSLive modeYour hosting plan. WordPress, WooCommerce and the plugin are free.
Google Play ConsolePublishing on AndroidOne-off registration fee (US$25 at the time of writing)
Apple Developer ProgramPublishing on iOS, iOS pushYearly fee (US$99 per year at the time of writing)
Payment gateways (Stripe, PayPal, iyzico...)Card paymentsPer-transaction fees set by the provider. Cash on delivery and bank transfer cost nothing extra.
Firebase Cloud Messaging (Google)Push notifications (optional)Free of charge to send at the time of writing; other Firebase products are billed by usage.

Not implemented

Maps, live courier tracking, support chat and augmented reality are not implemented. The screens that show them are sample layouts: they show sample content in demo mode and are hidden in live mode. Making any of them real needs a paid third-party service at your own extra cost.

The Nest theme's "view in your room" card is a static UI layout. It has no AR functionality, no camera access and no 3D rendering, and no AR package is bundled. Real AR needs a third-party AR SDK or a hosted 3D/AR commerce service (monthly or per-view fees), paid 3D models of each product, and model hosting, all at your own extra cost.

For developers

Architecture

shopkit/packages/
  shopkit_core      UI only: screens S01-S48, Sk* widgets, 10 themes, fonts, translations.
                    Never imports HTTP, the domain or the API; screens take data and callbacks.
  shopkit_domain    Models and repository interfaces (catalog, cart, checkout, orders,
                    auth, account, wishlist, notifications, config). Money is integer minor units.
  shopkit_data_mock The sample store implementing every interface, per theme.
  shopkit_data_woo  The same interfaces against the WooCommerce Store API (wc/store/v1)
                    and the plugin (shopkit/v1).
  shopkit_app       Shared app runtime: "Connect your store" (QR scan / paste, kept in the
                    keychain, switch without rebuild) and optional Firebase push.
shopkit/templates/<app>/lib/
  main.dart         demo store, the store connected in the app, or SHOPKIT_CONNECTION
  router.dart       go_router map and guards
  state/            ShopSession (config, user, cart, wishlist), Loader (loading / error / retry)
  pages/            one page per route: loads data, maps it to view models, renders a screen
  ui/mappers.dart   domain model → view model
  screens/          the niche screens (E01, A01...)

How the app talks to the store

Tests (run on 5 October 2026)

FolderTestsResult
shopkit/packages/shopkit_core34passed
shopkit/packages/shopkit_data_mock326passed
shopkit/packages/shopkit_data_woo96passed
shopkit/packages/shopkit_app28passed
shopkit/packages/shopkit_domain33passed
shopkit/templates/aura407passed
shopkit/templates/core_kit422passed
shopkit/templates/electro414passed
shopkit/templates/fold433passed
shopkit/templates/fresho418passed
shopkit/templates/glow418passed
shopkit/templates/nest422passed
shopkit/templates/pawly485passed
shopkit/templates/peak467passed
shopkit/templates/showcase244passed
shopkit/templates/tods511passed
Total5,158all passed

Run them with flutter test in any of these folders. Every app has a test that paints each of its screens and fails on any layout or rendering error. The plugin is tested separately with a PHPUnit suite on a real WordPress + WooCommerce (152 tests, all passing on 5 October 2026); that suite is our development tooling and is not part of the download.

Design files no design software needed

design-source/ holds the original design of every screen and the app icon. You do not need Photoshop, Sketch, Figma or XD: the designs are web pages that open in your browser, and the icon is a PNG.

File or folderWhat it isOpen it with
design-source/START-HERE.htmlIndex of every design file in plain languageA web browser
design-source/README.txtThe same index as plain textA text editor
design-source/screens/The design of all screens as web pages, 390 × 844 px, one page per theme plus components and typographyA web browser
design-source/assets/app-icon.pngThe app icon, 1024 × 1024 PNG. Replace it with yours (Branding, step 3).Any image viewer or editor

A screen's code in the designs is the name of its Dart file: S17 → shopkit/packages/shopkit_core/lib/screens/core/s17_product_detail.dart, E05 → shopkit/templates/electro/lib/screens/e05.dart. The designs are the reference; you change the app in the Dart theme files, not in the HTML. Some live-mode screens differ from the designs on purpose, where WooCommerce has different data (for example the filter sheet offers "On sale" and "In stock" instead of "Free shipping").

Changelog

2.0.0 (October 2026)

ShopKit becomes a mobile app for a real WooCommerce store. Every app still runs offline on its sample store.

1.0.0 (July 2026)

First release: 192 screens (48 Core Kit + 144 across 9 niche themes) on sample data, 10 themes, the showcase app.

Support

Please read Troubleshooting first. Then contact us through the Support tab on the item page on CodeCanyon, with your operating system, the output of flutter doctor -v, the app folder you use and, for store problems, a screenshot of the plugin's Status tab. Questions about setup, branding and the plugin are welcome; custom development is not included in the licence.