For SwiftSoftware and ZaarHub administrators managing the Program backend.
From sign-in to a claim approved and the public pages matching your settings.
Sign in. Open https://zaarhub.com/admin-panel.html and sign in with your administrator credentials. This is the only admin console β older links such as /admin-dashboard.html or /admin-login.html now redirect straight back here.
Read the numbers first. Open the Admin Dashboard and look at the platform totals before touching anything β it tells you whether today is normal.
Clear the claim queue. Open the Business Claim & Verification Flow, check the claimant's evidence, then approve or reject. Approval is what gives a business its portal.
Manage a tenant. Use Tenant Management to inspect or adjust a directory/tenant.
Watch the network. Review Fraud Monitoring for suspicious earn and redeem patterns, and Audit & Logging for who changed what.
Configure the public face. Set the Notifications Ticker, Editor's Picks, Verification Badges and Category Management β these decide what every visitor sees.
Own the loyalty numbers. The earn rate, the redemption cap (10% of a bill), the minimum balance (100 ZaarCash) and free-item treatment are programme settings you control. Every user-facing guide quotes these numbers, so change them here and keep the guides in step.
See the result. Claims move, the ticker reflects real activity, and every public page matches the settings you just made.
When a business owner claims a listing on ZaarHub, the system follows this flow:
The system checks two things for automatic approval:
@mybusiness.com) is checked against the submitted website domain (e.g. mybusiness.com). If they match β auto-approvedemail field in the directory β auto-approvedWhen auto-approved:
business_type = 'merchant' and a random temp passwordmethod = 'auto_domain'company_admin β they see the business dashboardjohn@bobsauto.com claims a business and submits website https://bobsauto.com. The domain bobsauto.com matches β instant approval.
If auto-approval fails (email domain doesn't match the website), the claim goes to the admin panel for manual review:
When manually approved via admin panel:
visitor_accounts row with business_type = 'merchant'The admin panel is your central hub for monitoring and managing the entire ZaarHub Loyalty Program.
As an admin, you have oversight of all tenant accounts. Your responsibilities include:
Fraud detection is one of the most critical admin functions. The system flags suspicious transactions automatically, but you need to investigate.
What to look for:
Review process: Open the flagged transaction β review the customer history and business history β check for matching IPs or account creation dates β make a determination: dismiss flag, warn the party, or escalate for suspension.
Admins handle a variety of support requests from tenants. Common scenarios:
The ZaarHub Platform maintains a comprehensive audit trail. All admin actions are logged and subject to review.
Admin accounts have elevated privileges. Follow these practices to keep the platform secure:
Visitors can request cities that aren't listed yet:
Create one-question polls for your directory:
Business owners manage service bookings from their dashboard:
Admins verify and manage referrals:
The ZaarHub Loyalty Program is native to the Multi-Directory platform. Loyalty capability is built into every directory β there is no separate IncentiveSwift engine. Each directory admin creates and configures their own loyalty programmes, and members are visitor_accounts of the directory. The native clearinghouse handles ZaarCash billing, reimbursement, and expiry.
The programme rules the guides state as fact (ZaarHub's current settings):
The settings above are more than configuration: because the programme is customer-facing, the numbers you choose are the promises customers see. Publish your terms β earning rates, cap, minimum and expiry β and keep them accurate here, in the loyalty guide, and in the panel. Promotional and gift-card style rules vary by state and country; confirm what applies to you before launch, including whether unredeemed balances must be honoured or may expire.
Read the full ZaarCash programme guide for administrators β
You are configuring a customer-facing rewards scheme, so the settings you choose are the promises customers see. Publish your terms (earning rates, cap, minimum, expiry) and keep them accurate in this guide and in the panel.
Promotional and gift-card style rules vary by state and country β confirm what applies to you before launch, including whether unredeemed balances must be honoured or may expire.
The platform stores and applies your settings; it does not decide them, does not reimburse redeemed value, and gives no warranty that a particular configuration is lawful or profitable in your jurisdiction.
Loyalty Programs (per-directory):
GET /api/v1/directories/:slug/loyalty/programs β list programsPOST /api/v1/directories/:slug/loyalty/programs β create a program (name, points_per_checkin, max_checkins_per_day=1, points_expire_days=365, currency name/icon/color, tier/milestone/streak/referral/birthday/social bonuses, is_active)GET /api/v1/directories/:slug/loyalty/programs/:program_id β program detailPUT /api/v1/directories/:slug/loyalty/programs/:program_id β update programDELETE /api/v1/directories/:slug/loyalty/programs/:program_id β delete programPOST /api/v1/directories/:slug/loyalty/programs/:program_id/enroll β enroll a member (visitor)POST /api/v1/directories/:slug/loyalty/programs/:program_id/checkin β daily check-in (awards points_per_checkin; daily cap enforced)GET /api/v1/directories/:slug/loyalty/members/:visitor_account_id β member profileTiers (membership levels):
GET/POST /api/v1/directories/:slug/loyalty/programs/:program_id/tiers β list / create a tier (name, min_points, color, perks, multiplier)PUT/DELETE /api/v1/directories/:slug/loyalty/programs/:program_id/tiers/:tier_id β edit a tier (name, min_points, color, perks, multiplier; omitted fields keep their value) / delete a tierRewards (catalog + earn + approval):
GET/POST /api/v1/directories/:slug/loyalty/programs/:program_id/rewards β list / create a reward (points_required, requires_approval, reward_tag, sort_order)DELETE /api/v1/directories/:slug/loyalty/programs/:program_id/rewards/:reward_id β delete a rewardPOST /api/v1/directories/:slug/loyalty/programs/:program_id/rewards/earn β member redeems a reward (deducts ZaarCash, creates an earned record)GET /api/v1/directories/:slug/loyalty/members/:member_id/rewards β member's earned rewardsPOST /api/v1/directories/:slug/loyalty/rewards/earned/:earned_id/approve β admin approves a pending earned rewardMilestones (trigger-based bonuses):
GET/POST /api/v1/directories/:slug/loyalty/programs/:program_id/milestones β list / create a milestone (trigger_type, trigger_value, bonus_points, once_per_member)Clearinghouse (ZaarCash billing, /networks/:slug/clear):
POST /networks/:slug/clear/scan β process a scan (check-in/purchase/redeem) through the clearinghouseGET /networks/:slug/clear/treasury β treasury summaryGET /networks/:slug/clear/ledgers β business ledgersGET /networks/:slug/clear/caps, PUT /networks/:slug/clear/caps β redemption caps (max % of a bill payable with ZaarCash; 10% default)POST /networks/:slug/clear/expire β run ZaarCash expiry (365-day rolling)GET /networks/:slug/clear/logs β clearing logsScanner PWA (/scanner):
points_per_checkin), Purchase (earn rate Γ amount), Redeem (deduction with caps)/scanner, /scanner-manifest.json, /sw-scanner.jsBusiness Profile Loyalty Section: Every business detail page (/biz/:slug/:id) fetches program & tier data and, if the visitor is logged in, displays their personal tier badge, ZaarCash balance, and scannable QR code. Non-enrolled visitors see a Join button that calls POST .../loyalty/programs/:program_id/enroll.
Per-Directory Feature Toggle: The feature_config JSONB column on directories controls whether loyalty features render. Set {"loyalty_enabled": true} to enable the loyalty section on business profiles for a given directory.
POST /auth/login using the Authorization: Bearer <token> header. Bad tokens return 401. Loyalty program defaults: max_checkins_per_day=1, points_per_checkin=10, points_expire_days=365.
Business owners configure CTA buttons on their listing from the Integrations tab:
Businesses in the directory can earn verification badges that display on their listings. These badges help visitors identify trusted businesses at a glance:
Badge display: Badges appear as icons next to the business name on listing cards, search results, and the business detail page. They are controlled by the ZaarHub system and cannot be manually toggled by business owners (except Editor's Pick, which is admin-controlled).
Editor's Picks are featured businesses hand-selected by admins to appear in a special "Editor's Picks" section on the directory and ZaarHub frontend. They're part of the ZaarHub curation system.
Three server-rendered B2B pages are available for your directory network. As an admin, you should monitor their usage and content:
/rfq-marketplace) β Businesses post Request-for-Quote listings. Review RFQ volume and supplier response rates periodically to gauge marketplace health./coop-hub) β Cooperative purchasing and partnership hub. Monitor which directories are participating and flag any inappropriate partnership listings./lead-exchange) β Business lead marketplace. Watch for lead quality and ensure all participants follow directory terms of service.Business listings enriched from third-party sources (Google Places, Yelp, etc.) display a Data Freshness Timestamp to visitors. For example: "Data last updated: June 2025 from Google Places."
The Notifications Ticker is a scrolling bar that automatically displays recent platform activity on the directory frontend. Unlike admin-created announcements, this ticker populates automatically from real platform events β new businesses added, deals posted, reviews written, and claims verified.
--ticker-bg, --ticker-text, --ticker-accent, --ticker-font-size, --ticker-speed.Categories are organized with categories that contain subcategories (e.g., Fine Dining & Cuisine contains Italian, Chinese; Food & Drink contains Coffee Shop, Pizza). A business can belong to multiple subcategories (up to 3 by default, 5 with admin override).
Before populating a directory with businesses, create your categories from the Category Manager (Admin Panel β Categories). Categories are organized as categories β subcategories (not "groups"): e.g., Fine Dining contains Italian, Chinese; Food & Drink contains Coffee Shop, Pizza. A business can belong to multiple subcategories (up to 3 by default, 5 with admin override).
Go to Admin Panel β Populate Businesses. This is a manual, admin-driven flow (not an auto-scraper):
api_config β provider_keys table β GOOGLE_PLACES_API_KEY env var. To change it, update either the provider_keys row for google_places or the env var, then restart.When you publish a business, the system auto-flags likely franchises / big chains using a known-chain name list (~120 national brands) plus Google Places types heuristics. You'll see a manual override before publishing: confirm Local (small/local business) or mark Franchise. The community directory is focused on small, local businesses β franchises/chains (and suppliers) are excluded from the public front end and only appear in the back office where relevant.
Go to Admin Panel β Search & Import. The search engine includes a Category Filter dropdown that shows all existing categories. Select a category (or group) to narrow your search. The filter makes results highly targeted from the start β example: select "Coffee Shop" and the search returns coffee shops in the target city.
After search results load, you have two ways to assign categories:
Individual assignment:
Bulk assignment:
After claiming their business, owners can manage categories through the Business Portal:
Go to Pending Category Requests in the admin sidebar. Each request shows business name, current categories, requested category, and optional rationale. One-click Approve or Deny with optional denial reason.
Chinese, French, Indian, Italian, Japanese, Mediterranean, Steakhouse
Bars & Breweries, Breakfast, Catering, Coffee Shop, Food Trucks, Pizza, Seafood
Artisan & Handmade Goods, Bakeries & Dessert Shops, Books/Music/Hobby, Boutiques & Vintage Thrift, Electronics Repair & Resale, Farmers Market, Florists & Garden Shops, Gifts & Stationery, Home & Decor, Specialty Grocery & Gourmet
Cleaning Services, Electrician, HVAC, Landscaping, Maintenance & Handyman, Plumber, Pool Service, Roofing, Screen Enclosures, Tree Service
Chiropractor, Dentist, Medical & Health Services, Medical Spa, Pet Groomer, Physical Therapy, Veterinarian
Accountant, Business & Professional Services, Personal Injury Lawyer, Property Management, Real Estate Agent
Family Entertainment, Live Music & Bars, Local Attractions & Tours, Special Events & Party Planning
Boat Charter, Day Spa, Fitness Studio, Hair Salon, Tattoo Parlor
Auto Repair, Car Detailing & Wash, Tire Shops & Oil Change
Dog Daycare & Boarding
Child Care & Education
Other
Google does not give you one key. It gives you a key per API, and the mistake we see most often is using the wrong one β which is what breaks business discovery. There are two, and they are not interchangeable.
*.zaarhub.com plus any custom domains). It cannot do the server-side search job β a Maps JavaScript key sitting in the Places field is the single most common cause of "The provided API key is invalid".
A key is scoped: platform-wide, to one network, or to one directory. A key saved at network level is inherited by every city in that network, so the ZaarHub Google Places key is pasted once and all cities use it β do not paste the same key into every city. A standalone directory that is not inside a network keeps its own key. Pick the scope in the Scope dropdown in the row (platform-wide / a network / one directory) before pressing οΌ Add key; the π Which key is in force for a directory panel below it then shows, per provider, whether the winning key is the directory's own, inherited from its network, or the platform key β always masked.
Keys are entered in the panel, full stop. If a key has ever been shared anywhere β a chat, an email, a doc, a screenshot, in source code β treat it as leaked and rotate it: create a new key in Google Cloud, save it in the panel, then delete the old one in Google Cloud.
*.zaarhub.com plus each custom domain.Everything below needs something a machine can't supply: a key from a provider console, a business decision (which gateway, which CRM account), or a DNS record. None of it is done yet, and none of it can be done from code. Tick each line as it's finished β every line names the exact panel screen, so a VA can work straight down the list.
The panel lives at https://zaarhub.com/admin-panel.html. Each
screen below is a section on that page, in the order the links appear at the top.
Why: the keys were shared in a chat/message, so treat them as seen and replace them.
How: Google Cloud console β Credentials β create a new key β restrict it
(Places API (New) by server IP address; Maps JavaScript by
website / HTTP referrer) β paste it into the matching labelled field below β then
delete the old key in Google Cloud. Which key is which is section 19 above.
Where: the server key goes in Admin Panel β π Provider API Keys β the "Google Places"
row β "Paste API key" β οΌ Add key; the browser key goes in the directory's
SEO settings β "Google Maps API Key".
Rule: keys are entered in the panel β never in a chat, ticket, document or code
file. The panel only ever shows a masked preview (first 4 + last 4 characters), and an
empty box never means "no key"; the row itself says when a key is stored and when it last changed.
Why: no gateway is set, so checkout refuses and payouts stay pending.
Where: Admin Panel β π³ Payment Gateways β connect Stripe and/or PayPal.
A gateway cannot be switched on without its webhook verification value, and the receiver
refuses any event it can't verify, so enter that too.
Why: with none set, statement emails and reminders are skipped β the panel
reports the service as "not configured".
Where: Admin Panel β βοΈ Email / SMTP β choose the directory, fill
From name, From email, Reply-to and the transport
credentials, then press Send test email and confirm it arrives.
Why: the ZaarCash-per-redemption rate is still 0, so customers earn
nothing when they redeem.
Where: Admin Panel β β Loyalty Programmes β set the units per
redemption (and per check-in and visit if you use them).
A rate of 0 switches that source off, so a 0 here is a deliberate "no earning", not a default.
Where: Admin Panel β π¦ Clearinghouse Settlement β set
Settlement enabled, Cycle day (1β28), the issue/redeem rates, minimum
payout and ZaarCash expiry (days), then Save settlement settings.
Note: with no payment provider configured (item 2) a settlement run cannot pay out β it
stays pending, by design.
Where: Admin Panel β βοΈ Onboarding Questionnaires β write the questions
for each audience (customer, supplier, business), then Publish it: a
draft never reaches the public. Finally walk each onboarding flow end to end yourself.
What it does: completing a questionnaire credits the network currency
(100 units = US$1) through the native loyalty programme and pushes the answers to
CoreSwift; if the CRM is unreachable the answers and the currency still land, and the reason is recorded
on the response.
Decision (do this now): from the candidates in the audit, choose the one
CoreSwift account the ZaarHub network should own its leads in.
Connect (wait for the screen): the server already exposes the connection endpoints
(/api/v1/integrations/coreswift/connection, β¦/connection/targets,
β¦/connection/test) but there is no admin screen for them yet β the
"Integration settings β" button on the panel leads to a section that does not exist. Until that screen
ships, the connection cannot be made from the panel. This is written down here as
pending rather than sending you to a screen that is not there; an endpoint with no UI
control is a defect to close, and this line is the reminder.
Where: Admin Panel β π Domains, Subdomains & Subfolders β choose
a subdomain of the network (e.g. palm-bay.zaarhub.com), its own
custom domain, or a subfolder of a host (e.g. zaarhub.com/palm-bay),
then οΌ Add mapping.
Why it needs you: the code side can be done from the panel, but a mapping only goes live
once DNS resolves. After creating the record, press Check live β a host
whose DNS still resolves elsewhere is reported not live, never as working.