Overview
The Fanbasis integration provides payment-gated access to AdRecon. It consists of two endpoint groups:- Admin endpoints (
/api/admin/fanbasis) — Manage products, webhook registration, and view logs - Webhook endpoint (
/api/fanbasis/webhook) — Public webhook receiver for payment events
Fanbasis is a payment platform for digital products. This integration automatically provisions Supabase auth accounts when users purchase enabled offers.
Configuration
Set these environment variables:| Variable | Purpose | Required |
|---|---|---|
FANBASIS_API_KEY | Fanbasis API key for admin actions | Yes (admin features) |
SUPABASE_URL | Supabase project URL | Yes |
SUPABASE_SERVICE_ROLE_KEY | Server-side auth key | Yes |
FANBASIS_MAGIC_LINK_REDIRECT_URL | Post-login redirect URL | No (falls back to request host) |
integration_secrets table) after registration.
Admin Endpoints
All admin endpoints require:GET /api/admin/fanbasis
Query Fanbasis integration status, offers, and webhook logs.Query Parameters
Action to perform.Options:
status— Check API key and webhook secret configurationoffers— List enabled offers from databasewebhook-log— Paginated webhook event log
Page number for
webhook-log action (default: 1)Items per page for
webhook-log action (default: 25, max: 100)Response Examples
POST /api/admin/fanbasis
Perform admin actions.Request Body
Action to perform.Options:
test_connection— Verify Fanbasis API keysync_products— Fetch and sync all products from Fanbasistoggle_offer— Enable/disable an offerregister_webhook— Register webhook subscription with Fanbasissend_test_webhook— Trigger test event from Fanbasissend_direct_test— Send synthetic test payload directly to webhookmanual_provision— Manually provision access for an email
Action: test_connection
Verify API key by making a test request to Fanbasis.Request
Response (Success)
Response (Failure)
Action: sync_products
Fetch all products from Fanbasis and upsert intofanbasis_enabled_offers table.
Syncing preserves the
enabled flag for existing offers — only updates title/price.Request
Response
- Fetch all products via paginated
/productsendpoint (max 50 pages) - For each product:
- Use product ID as canonical
service_id - Extract checkout session ID from
payment_linkURL - If checkout session ID differs from product ID, migrate old row to prevent duplicates
- Use product ID as canonical
- Upsert with conflict resolution on
service_id - Newly synced offers default to
enabled: false
Action: toggle_offer
Enable or disable an offer for webhook provisioning.Product/service ID to toggle
Enable (true) or disable (false) the offer
Request
Response
Action: register_webhook
Register a webhook subscription with Fanbasis.Request
Response
- Core events:
payment.succeeded,payment.failed,payment.expired,payment.canceled,product.purchased,subscription.created,subscription.renewed,subscription.completed,subscription.canceled - Optional events:
payment.refunded,payment.dispute.opened
Action: send_test_webhook
Trigger a test event from Fanbasis to your webhook.Event type to test (default:
payment.succeeded)Request
Response
Action: send_direct_test
Send a synthetic test payload directly to your webhook endpoint (bypasses Fanbasis).Event type to simulate (default:
payment.succeeded)Test email address (default:
[email protected])Request
Response
Action: manual_provision
Manually grant access to a user (e.g., for comped accounts or failed webhook recovery).Email address to provision
Service ID to associate (optional)
Original webhook log entry ID (optional, for audit trail)
Request
Response
- Search for existing user by email (scans up to 100 pages of 200 users each)
- If not found: create user with
email_confirm: true - If found and revoked: update metadata to restore access and remove ban
- If found and active: update metadata with new purchase timestamp
- Send magic link (OTP) for immediate login
- Log manual provision event to
fanbasis_webhook_log
user_created— New account createduser_exists— Existing active user updateduser_reactivated— Previously revoked user restored
Webhook Endpoint
POST /api/fanbasis/webhook
Public endpoint that receives payment events from Fanbasis.This endpoint is unauthenticated (no Bearer token required). Webhook payloads are validated via secret signature (when configured).
Request Body
Fanbasis sends webhook payloads in various formats. The endpoint normalizes these fields:Event type (also checks
type, event.type, data.event_type)Event payload (structure varies by event type)
Webhook Validation
Event Handling
Purchase Events
These events create or update user accounts:payment.succeededproduct.purchasedsubscription.createdsubscription.renewed
- Extract buyer email and service ID from payload
- Validate offer is enabled (checks
fanbasis_enabled_offerstable) - If offer disabled, check if product title contains “adrecon” (case-insensitive override)
- Find existing user by email or create new account
- Update
user_metadata: - Send magic link (OTP) for immediate login
- Log event to
fanbasis_webhook_logwith result
Offer Validation
Revocation Events
These events revoke access:payment.refundedpayment.dispute.openedsubscription.canceledsubscription.completed
- Find user by email
- If not found, log
skipped_user_missingand return - Update
user_metadata: - Apply auth ban:
ban_duration: "876000h"(100 years) - Log event with result
Other Events
All other events are logged but do not modify user accounts.Response
The webhook always returns200 OK with a result code:
Always
true (prevents Fanbasis retries)Processing result.Values:
user_created— New account createduser_exists— Existing account updateduser_reactivated— Previously revoked account restoredaccess_revoked— Access removedskipped_no_email— No email in payloadskipped_offer_not_enabled— Offer not enabledskipped_user_missing— User not found (revocation events only)logged— Event logged without actionerror— Processing failed
Example Webhook Payloads
Database Schema
fanbasis_enabled_offers
Stores synced products and their enabled state.Schema
fanbasis_webhook_log
Audit log for all webhook events.Schema
integration_secrets
Secure storage for webhook secrets.Schema
key = 'fanbasis_webhook_secret'.
Complete Admin Integration Example
Fanbasis Admin Dashboard
Best Practices
Sync before enabling
Always run “Sync Products” before enabling offers to ensure latest data
Test webhooks
Use “Send Test Event” to verify provisioning before going live
Monitor webhook log
Regularly check webhook log for failed provisions or errors
Manual provision recovery
Use manual provision to grant access if webhook fails
Troubleshooting
Webhook Not Receiving Events
- Check webhook registration:
GET /api/admin/fanbasis?action=status - Verify
webhookSecretSet: true - Check Fanbasis dashboard for webhook subscription status
- Send test event:
POST /api/admin/fanbasiswithaction: send_test_webhook - Check webhook log:
GET /api/admin/fanbasis?action=webhook-log
User Not Provisioned After Purchase
- Check webhook log for event with buyer email
- Look for
skipped_offer_not_enabledresult — enable offer if needed - Check for
errorresult — fix underlying issue - Use manual provision as recovery:
POST /api/admin/fanbasiswithaction: manual_provision
Duplicate Offers After Sync
This occurs when Fanbasis changes checkout session IDs. The sync logic automatically:- Detects old checkout-session-ID rows
- Transfers
enabledstate to product-ID row - Deletes old row to prevent duplicates (source:api/admin/fanbasis.js:213-248)
Related Endpoints
- Overview — API authentication and error handling
- Admin Users — User account management