Smart NFC/QR pet identification — reuniting lost pets with their owners.
Live at pawtag.co.uk
PawTag is a WordPress-based SaaS platform with a companion iOS/Android app. Physical tags embed a unique UUID via NFC chip and QR code. When a finder taps or scans a tag, they land on the pet's profile and can contact the owner instantly — no app required on the finder's end.
Owner registers → adds pet profile → orders physical tag
Finder taps NFC / scans QR → views pet profile → contacts owner
The platform supports audio calls via WebRTC, push notifications, lost-mode alerts, community alert broadcasts, in-app NFC chip programming, and full subscription billing through Stripe.
- Register pets with name, species, breed, photo, medical notes, and contact preferences
- NFC + QR tag linking — each tag carries a unique UUID routed to the correct pet profile
- Lost mode — one tap marks a pet lost, triggering push notifications and broadcasting to community subscribers
- Community alerts — lost pets appear on a public map; nearby users receive push + email alerts
- Scan analytics — track when and how often tags are scanned (NFC vs QR vs direct)
- Lost poster generator — print-ready A4 poster with tear-off contact strips
- Pet passport — health record for vet visits: microchip number, vaccinations, behaviour notes, insurance
- Physical tag purchase — buy a standalone physical tag for £2.99 via Stripe; scan to claim to any pet
- Subscription billing via Stripe — Pro tier unlocks additional pets, analytics, Pet Passport, scan notifications
- Email verification — account verification flow with in-app resend prompt
- Push notifications — Expo push tokens + native FCM/APNs; in-app call routing via WebRTC
- In-app NFC writing — programme blank NFC chips directly from the app (admin-gated); accessible from the Scan tab and pet detail screen
- Email preference management — in-app toggles for scan alert and marketing emails
- Community alert subscriptions — manage area, radius, and subscription status from the Settings screen
- No account or app needed — tap/scan takes them directly to the pet's profile
- Private audio call — WebRTC call to the owner's phone without revealing either party's number
- WhatsApp / phone contact — owner-controlled visibility
- Contact form — sends a message directly to the owner
- Orders management with shipping and delivery tracking
- Production sheet — allocates pre-made stock tags to orders
- Stock tag system — batch-generate pre-made tags, export CSV for manufacturer, low-stock email alerts
- 3MF tag file generator — injects the pet's QR code into a printable 3D model for the physical tag
- Marketing emails — compose and broadcast to all users, Pro subscribers, or free-tier users
- Community alert subscriber list management and manual alert broadcast
- Push notifications panel — send admin messages to all users or specific users; messages route to the app's Alerts screen
- Per-user subscription overrides and audit log
- App Elements — live control of the mobile app UI (dashboard banner, announcement card, maintenance overlay, animated background)
- App Settings — NFC write enable/disable toggle, platform version control, force-update flags, store URLs
| Requirement | Version |
|---|---|
| WordPress | 6.0+ |
| PHP | 8.3+ |
| MySQL | 5.7+ / MariaDB 10.3+ |
| Stripe account | For subscription billing |
| HTTPS | Required (NFC redirects and Stripe) |
- Upload
wp-content/plugins/pawtag-manager/to your WordPress plugins directory. - Upload
wp-content/themes/pawtag-theme/to your themes directory. - Activate the PawTag Manager plugin in WP Admin → Plugins.
- Activate the PawTag theme in WP Admin → Appearance → Themes.
- Navigate to WP Admin → PawTags → Settings and configure:
- Stripe publishable and secret keys
- Stripe webhook secret (from your Stripe dashboard)
- SMTP settings for transactional email
- The plugin automatically creates all required pages and database tables on activation.
The companion app requires a second plugin for authentication, push notifications, and all mobile API routes:
- Upload
PawTag-App/wordpress/pawtag-mobile-api.phptowp-content/plugins/pawtag-mobile-api/pawtag-mobile-api.php(inside a subfolder — do not place it directly inwp-content/plugins/). - Activate PawTag Mobile API in WP Admin → Plugins.
| Table | Purpose |
|---|---|
wp_pawtag_scans |
Tag scan events (NFC / QR / direct). IP addresses stored as SHA-256 hashes. |
wp_pawtag_subscriptions |
Stripe subscription state per user (tier, status, expiry, Stripe IDs) |
wp_pawtag_audit_log |
Full change history for pet profiles |
wp_pawtag_alert_subscribers |
Email addresses subscribed to community lost/found alerts |
wp_pawtag_notifications |
In-app notification feed per owner |
All endpoints are under /wp-json/pawtag/v1/.
All authenticated endpoints require an X-PawTag-Token header. Tokens are issued by POST /auth/login. Standard Authorization: Bearer is intentionally not used — shared hosting JWT plugins intercept Bearer tokens.
Note: Photo uploads use base64-encoded JSON body — NOT multipart/form-data (WAF blocks multipart on REST paths).
| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/auth/login |
— | Issue a session token |
POST |
/auth/register |
— | Create a new owner account |
GET |
/auth/test |
— | Verify token is recognised |
POST |
/auth/resend-verification |
✓ | Resend email verification link |
GET |
/config |
— | App config: feature flags, version control, app elements |
GET |
/dashboard |
✓ | Owner's pets, subscription status, email_verified flag |
GET |
/pet/{id} |
✓ | Single pet detail |
POST |
/pet |
✓ | Create a pet |
PUT |
/pet/{id} |
✓ | Update a pet |
POST |
/pet/{id}/photo |
✓ | Upload pet photo (base64 JSON body) |
GET |
/pet/{id}/passport |
✓ | Get pet passport |
PUT |
/pet/{id}/passport |
✓ | Update pet passport |
GET |
/tag/{uuid} |
— | Public pet profile by tag UUID |
POST |
/pet/{uuid}/lost |
— | Toggle lost/found status |
GET |
/scans/{uuid} |
✓ | Scan history for a pet |
POST |
/push/register |
✓ | Register Expo push token |
POST |
/push/disable |
✓ | Unregister push token |
GET |
/notifications |
✓ | In-app notification feed |
POST |
/notifications/read |
✓ | Mark notifications read |
POST |
/notifications/delete |
✓ | Delete a notification |
POST |
/account/delete |
✓ | Delete account and all data |
GET |
/webrtc/config |
— | ICE/TURN server configuration |
POST |
/webrtc/room |
— | Create a WebRTC signalling room |
POST |
/webrtc/room/{id}/notify |
— | Push call notification to owner |
GET |
/webrtc/room/{id}/answer |
✓ | Poll for WebRTC answer SDP |
POST |
/webrtc/room/{id}/answer |
— | Post WebRTC answer SDP |
GET |
/autologin |
✓ | Issue a one-time auto-login token for in-app browser |
GET |
/community-alerts |
— | List active lost pet alerts |
POST |
/community-alerts/subscribe |
— | Subscribe to lost pet alerts (email, area, radius) |
GET |
/community-alerts/subscription |
✓ | Get subscription status |
POST |
/community-alerts/unsubscribe |
✓ | Unsubscribe from community alerts |
GET |
/notification-preferences |
✓ | Get email preferences (scan alerts, marketing) |
POST |
/notification-preferences |
✓ | Save email preferences |
GET |
/claim/{short_id} |
— | Look up a tag by short ID (PAW-XXXXX) |
POST |
/claim/{uuid} |
✓ | Claim an unclaimed tag to the authenticated user's account |
The iOS and Android app lives in PawTag-App/. Built with Expo SDK 54 / React Native using file-based routing via expo-router.
Current version: v1.2.9 (Android versionCode 33, iOS build 27)
| Platform | Store | Status |
|---|---|---|
| iOS | TestFlight | v1.2.9 (build 27) — pending Apple review |
| Android | Google Play closed alpha | v1.2.9 (versionCode 33) ✓ |
cd PawTag-App
npm install
npx expo start # Start dev server (requires a development build on device)Set EXPO_PUBLIC_WP_BASE_URL=https://your-domain.com in a .env file in PawTag-App/.
| Screen | Path | Notes |
|---|---|---|
| Dashboard | /(tabs)/ |
Pet cards, lost count, community alert card |
| Scan | /(tabs)/scan |
NFC scan, QR camera, short ID entry, NFC write entry point |
| Alerts | /(tabs)/alerts |
In-app notification feed (cache-first) |
| Settings | /(tabs)/settings |
Profile, push, email prefs, community alert sub |
| Pet detail | /pet/[id] |
Edit pet, lost mode, scan chart, NFC write |
| Pet passport | /pet/passport/[id] |
Vaccinations, behaviour, insurance |
| Replace tag | /pet/replace/[id] |
Claim a new physical tag |
| Tag profile | /tag/[uuid] |
Public finder view — contact owner, found button |
| Short ID lookup | /t/[short_id] |
Redirect from printed short IDs |
| Community alerts | /community-alerts |
Lost pet list + email subscription |
| NFC write | /nfc-write |
Programme blank NFC chips (admin-gated) |
| Claim tag | /claim/[uuid] |
Claim a new unclaimed physical tag |
| WebRTC call | /call/[roomId] |
Live audio call screen |
| Onboarding | /onboarding |
First-run walkthrough |
cd PawTag-App
npx eas-cli build --platform ios --profile production --auto-submit --non-interactive
# Builds on EAS cloud (macOS worker), auto-submits to TestFlight on completionBuild iOS first, always. EAS uploads the full project directory. If Android Gradle runs concurrently it locks android/.gradle/ causing an EBUSY error.
$env:JAVA_HOME = "C:\Program Files\Android\Android Studio\jbr"
$env:ANDROID_HOME = "C:\Users\{username}\AppData\Local\Android\Sdk"
cd PawTag-App\android
.\gradlew bundleRelease --no-configuration-cache
# Output: app\build\outputs\bundle\release\app-release.aab
# Submit to Google Play — run AFTER iOS EAS upload has completed
cd ..\
npx eas-cli submit --platform android --profile production --path android/app/build/outputs/bundle/release/app-release.aab --non-interactivePawTag-App/app.json→version,ios.buildNumber,android.versionCodePawTag-App/android/app/build.gradle→versionName,versionCode
A deploy.py script (Python + paramiko) uploads changed files to the live server over SFTP.
python deploy.py # Full deploy — uploads plugin + theme + mobile API + .htaccess
python deploy.py --zip-only # Build plugin zips locally only (does NOT update live server)Important: --zip-only never touches the live server. Always run the full deploy.py after PHP changes.
After deploying, flush the LiteSpeed cache: StackCP → LiteSpeed Cache → Flush All.
deploy.py uploads:
pawtag-mobile-apiplugin (fromPawTag-App/wordpress/pawtag-mobile-api.php)pawtag-theme(all theme files).htaccess,.user.ini, logo
Note: pawtag-manager plugin changes must be deployed via WP Admin → Plugins → Upload Plugin (zip from plugin-zips/pawtag-manager.zip).
https://your-domain.com/wp-json/pawtag/v1/stripe/webhook
Events handled: checkout.session.completed, customer.subscription.updated, customer.subscription.deleted, invoice.payment_succeeded, invoice.payment_failed.
wp-content/
plugins/
pawtag-manager/
pawtag-manager.php — Plugin bootstrap
includes/ — Core classes (DB, post types, emailer, audit log)
api/ — REST API route handlers
admin/ — Admin pages (orders, production, marketing, 3MF, stock, push, settings)
stripe/ — Stripe checkout, subscriptions, webhook handler
frontend/
views/ — Owner dashboard, onboarding
assets/
3mf/ — Base 3MF model for tag generation
images/pets/ — Default pet avatar illustrations
themes/
pawtag-theme/
page-templates/ — All frontend page templates
template-parts/ — Homepage sections (hero, pricing, how-it-works)
assets/ — CSS, JS, fonts
PawTag-App/ — Expo / React Native companion app
app/
(tabs)/ — Tab navigator screens (dashboard, scan, alerts, settings)
pet/ — Pet detail, passport, replace tag
tag/ — Public tag profile (finder view)
community-alerts.tsx — Community lost pet alerts
nfc-write.tsx — In-app NFC chip programmer
claim/ — Tag claim flow
call/ — WebRTC call screens
onboarding.tsx — First-run onboarding
hooks/ — Custom React hooks (auth, pets, NFC, push, config, app elements)
lib/ — API client, auth helpers, theme tokens
components/ — Shared UI components
wordpress/
pawtag-mobile-api.php — ⚠ SOURCE OF TRUTH for mobile API plugin (deploy.py uploads this)
rebrand/
rebrand.py — Full rebrand automation script
plugin-zips/
pawtag-manager.zip — Latest built zip (upload via WP Admin to deploy)
deploy.py — SFTP deploy script
Proprietary — © PawTag. All rights reserved.