Reviews & social proof
Google Reviews & Social Proof Display
Indicative price, not an offer: $9-15/mo, covers Google API credentials and review sync automation
Generated from docs/plan/paid/google-reviews-social-proof-display/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
Paid module that syncs Google Business Profile reviews to the storefront and displays them alongside in-store reviews. Requires Google OAuth setup; merchants get a credible third-party trust signal without manual import work.
The problem
My Google Business Profile has hundreds of 4.8-star reviews, but they’re not on my storefront, so customers don’t see them. I lose credibility because the reviews they find are only on Google. Setting up the OAuth and API is too technical for me to do alone.
What it does
- OAuth 2.0 flow: redirect to Google login, request My Business API scope, exchange code for access token
- Store encrypted access and refresh tokens in google_credentials table
- Sync Google reviews via Google My Business API v4 endpoint
- Cache synced reviews in google_reviews table (never store raw credentials in cache)
- Display Google reviews on storefront with ‘Verified by Google’ badge
- Show Google aggregate rating (e.g., ‘4.8★ 312 reviews from Google’) on product or store page
- Refresh sync manually (admin button) or automatically on schedule (e.g., daily)
- Detect and handle review updates (if reviewer edited review on Google, sync the new version)
- Handle review deletions (if deleted on Google, remove from cache)
- Disconnect flow: admin clicks Disconnect, revokes token in Google, deletes local credentials and cache
- Admin dashboard: last sync time, next scheduled sync, review count, sync errors and retry log
- Error handling: log API rate limits, auth failures, quota exceeded; email shop admin on failure
- Webhook: emit on_google_reviews_synced when sync completes successfully
- Per-shop multi-account support (one merchant may own multiple Google profiles)
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- Manually importing Google reviews (that’s a data import tool; separate from API integration)
- Two-way sync (editing storefront review updates Google) — Google API is read-only
- Responding to Google reviews from storefront (that’s a separate management integration)
- Aggregating Google + in-store reviews into a single unified feed (that’s review aggregation, separate feature)
- Google Post embedding or media (different Google APIs; out of scope)
- Translating Google reviews into customer’s language (handled by i18n layer if added)
- Review attribution to specific products (sync reviews at store level only; product attribution is a future enhancement)
Data model
New google_credentials table: { shopId, googleAccessToken (encrypted), googleRefreshToken (encrypted), googleAccountId, scope (string), lastSyncedAt: DateTime|null, nextSyncScheduledAt: DateTime, expiresAt: DateTime }. New google_reviews cache table: { id, googleReviewId (unique from Google), shopId, rating: int, reviewText: string, reviewerName: string, reviewDate: DateTime, syncedAt: DateTime, attributedToProduct: productId|null, isDeleted: boolean }. New google_sync_logs audit table: { shopId, syncStartedAt, syncCompletedAt, reviewsAdded: int, reviewsUpdated: int, reviewsDeleted: int, error: string|null }. No migration; new tables.
API
- GET /admin/integrations/google/auth-url — returns OAuth authorization URL to redirect user
- GET /admin/integrations/google/callback?code=AUTH_CODE — OAuth callback handler; stores token and initiates first sync
- POST /admin/integrations/google/sync — manual trigger for sync; returns { syncId, status: ‘queued’ }
- GET /admin/integrations/google/sync-status/:syncId — poll sync progress; returns { status, reviewsProcessed, errors }
- GET /admin/integrations/google/status — current connection status: { connected: bool, accountId, lastSync, nextSync, reviewCount, errors }
- GET /storefront/reviews/google-summary — { avgRating: 4.8, count: 312, excerpt: ‘312 verified reviews from Google’ }
- GET /storefront/reviews?source=google — list synced Google reviews
- DELETE /admin/integrations/google — disconnect (revoke token, clear credentials and cache)
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
Integration card in admin > Settings > Integrations: ‘Google Business Profile’. If disconnected, shows ‘Connect Google’ button. If connected, shows: Account name, last sync time (e.g., ‘2 hours ago’), manual Sync button, next scheduled sync (e.g., ‘Tomorrow at 2 AM’), and Disconnect button. Error log panel: recent sync failures, API errors, rate limit hits with retry status. Review count badge showing number of cached Google reviews. Admin can view synced reviews in a read-only list with Google attribution.
The seam — why this is paid
Paid module owns: Google OAuth integration, API key/credential management, encrypted token storage, sync automation, and rate-limit handling. Core owns: the cache table schema, storefront display (handled by existing review components), webhook emission, and admin UI framework. Reason: Google OAuth is an external credential and an ongoing managed relationship with Google’s API; merchants cannot use this feature without a Google Business Profile and API setup from Google. Core does not manage external review sources.
Paid module owns Google OAuth credential and API call management; core does not manage external review sources
Dependencies
- Assumption: merchant has a Google Business Profile and can create OAuth credentials in Google Cloud Console
- Google My Business API v4.9+ enabled in Google Cloud Project
- OAuth redirect URI registered in Google Cloud Console (docs must explain this setup)
- Background job/task scheduler (for automated daily sync)
- Token encryption layer (AES-256 or equivalent)
- Cache invalidation and refresh logic (on successful sync, clear old reviews and insert new ones)
- Webhook system (emit on_google_reviews_synced event)
- Paid plugin activation/deactivation framework (plugin can be toggled off)
- Email system (send admin alerts on sync failures)
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- OAuth flow redirects to Google login; user approves ‘My Business API’ scope; authorization code is exchanged for accessToken and refreshToken
- Callback handler stores tokens encrypted in google_credentials; tokens are never logged or exposed in responses
- refreshToken is used to obtain a new accessToken when current one expires; refresh happens transparently without user re-auth
- Manual sync fetches reviews from Google My Business API and stores in google_reviews table within 30 seconds for <1000 reviews
- Synced reviews include: rating (1-5), text, reviewer name, review date; DO NOT include merchant’s own replies
- avgRating computed from synced reviews is between 1 and 5, and is exactly: sum of all review ratings / count of reviews
- If Google API returns 403 Unauthorized (auth expired), email sent to shop admin with ‘Please reconnect Google’ message
- If Google API rate limit is hit (429), sync retries after 1 hour; subsequent manual syncs are blocked until rate limit resets
- Disconnecting revokes token via Google API, deletes all entries in google_credentials and google_reviews for that shop
- GET /storefront/reviews/google-summary only returns reviews with rating >= 1 and isDeleted=false
- Storefront displays reviews with ‘Verified by Google’ badge and includes Google star icon
Risks
Token rotation fails (refreshToken expired) = sync stops working; merchant must re-authenticate but gets no notification. Encrypted token corrupted (bad password, DB corruption) = cannot decrypt, entire integration dead. Old deleted reviews in cache displayed as current even though Google deleted them. API rate limit hit = syncs stop for 24 hours with no automatic retry; shop admin sees zero reviews on display. Merchant revokes Google app access in Google console = token not in our cache to detect it, sync silently fails next run without alerting admin. Google reviews displayed with wrong (or any) product attribution when shop has multiple products. Stored reviews very stale (last sync 6 months ago due to cron failure) but displayed as if current, no warning to customer.
Commercial context
| Suggested price | $9-15/mo, covers Google API credentials and review sync automation |
| Rival anchor | Google Reviews by Reputon (free app, but requires Google OAuth credential) |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and ../../AI-GUIDE.md for how to work on this repository.