FCHubFCHub.co

Developer Reference

REST API endpoints, WP-CLI commands, action hooks, webhooks, adapter system, database schema, CSV import, and cron jobs.

This is the comprehensive developer reference for FCHub Memberships. It covers everything you need to extend, integrate with, or debug the plugin.

Action Hooks

The plugin fires these WordPress action hooks during the membership lifecycle. All hooks are prefixed with fchub_memberships/.

HookArgumentsWhen
grant_createdint $userId, int $planId, array $contextNew membership access granted
grant_revokedarray $grants, int $planId, int $userId, string $reasonAccess revoked
grant_expiredarray $grantAccess expired naturally
grant_term_expiredarray $grantAccess expired because membership term reached v1.3.0
grant_pausedarray $grant, string $reasonMembership paused
grant_resumedarray $grantPaused membership resumed
grant_renewedarray $grantSubscription renewed
trial_convertedarray $grant, int $planId, int $userIdTrial converted to paid
trial_expiredarray $grantTrial expired without payment
trial_expiring_soonarray $grant, int $daysLeftTrial approaching end
drip_unlockedarray $notification, array $grant, int $userIdDrip content unlocked
drip_milestone_reachedarray $grant, int $milestone, int $userIdDrip completion milestone (25/50/75/100%)
access_expiringarray $grantAccess approaching expiration
grant_anniversaryarray $grantAnnual anniversary of grant date
payment_failedarray $grantSubscription payment failed

Filter Hooks

FilterArgumentsPurpose
fchub_memberships/resource_typesResourceTypeRegistry $registryRegister custom resource types

Listening to Hooks

add_action('fchub_memberships/grant_created', function (int $userId, int $planId, array $context) {
    // Your custom logic when a membership is granted
    $sourceType = $context['source_type'] ?? 'manual';
    error_log("User {$userId} granted plan {$planId} via {$sourceType}");
}, 10, 3);

REST API

All endpoints are under the fchub-memberships/v1 namespace. Unless noted, endpoints require manage_options capability (administrator).

MethodEndpointDescription
GET/plansList all plans with optional filtering
POST/plansCreate a new plan
GET/plans/{id}Get a single plan with rules
PUT/plans/{id}Update a plan
DELETE/plans/{id}Delete a plan (cascades to rules)
POST/plans/{id}/duplicateDuplicate a plan

Plan fields: title, slug, description, status, level, includes_plan_ids, restriction_message, redirect_url, duration_type, duration_days, trial_days, grace_period_days, settings, meta, scheduled_status, scheduled_at

Frontend API

These endpoints are available to authenticated users (no admin requirement):

MethodEndpointDescription
GET/access/checkCheck if current user can access a resource
GET/account/dataGet current user's membership data for the account page

Dynamic Options

MethodEndpointDescription
GET/options/resource-typesGet available resource types for dropdowns
GET/options/search/{resource_type}Search resources by type and query string

WP-CLI Commands

All commands are under the wp fchub-membership namespace.

Webhooks

Webhooks send membership events to external services as HTTP POST requests with JSON payloads.

Configuration

In Memberships > Settings:

  • Webhook Enabled (webhook_enabled) — master switch for webhooks
  • Webhook URLs (webhook_urls) — newline-separated list of endpoint URLs. Multiple URLs are supported
  • Webhook Secret (webhook_secret) — shared secret for HMAC-SHA256 signature verification

Events

EventWhen
grant_createdNew membership access granted
grant_revokedAccess revoked
grant_expiredAccess expired
grant_pausedMembership paused
grant_resumedMembership resumed

Payload Format

{
  "event_type": "grant_created",
  "timestamp": "2025-01-15T10:30:00+00:00",
  "site_url": "https://example.com",
  "data": {
    "user": {
      "id": 42,
      "email": "member@example.com",
      "display_name": "Jane Doe"
    },
    "plan": {
      "id": 1,
      "title": "Pro Membership",
      "slug": "pro"
    },
    "context": {
      "source_type": "order",
      "source_id": 156
    }
  }
}

Signature Verification

Every webhook includes an X-FCHub-Signature header containing the HMAC-SHA256 signature of the request body:

signature = HMAC-SHA256(request_body, webhook_secret)

Verify the signature on your receiving end:

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_FCHUB_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $payload, $your_shared_secret);

if (!hash_equals($expected, $signature)) {
    http_response_code(403);
    exit('Invalid signature');
}

The X-FCHub-Event header contains the event type string.

Delivery

Webhooks are delivered asynchronously via Action Scheduler when available. The fchub_memberships_dispatch_webhook hook fires with the URL, body, and headers. If Action Scheduler is not available, delivery falls back to synchronous wp_remote_post() with a 15-second timeout.

Failed deliveries are logged via the Logger class.

Test Webhook

Send a test event from Memberships > Settings or via the REST API:

curl -X POST https://example.com/wp-json/fchub-memberships/v1/settings/webhook-test \
  -H "X-WP-Nonce: <nonce>"

Adapter System

The adapter system provides a uniform interface for granting and revoking access across different content providers.

AccessAdapterInterface

interface AccessAdapterInterface
{
    public function supports(string $resourceType): bool;
    public function grant(int $userId, string $resourceType, string $resourceId, array $context = []): array;
    public function revoke(int $userId, string $resourceType, string $resourceId, array $context = []): array;
    public function check(int $userId, string $resourceType, string $resourceId): bool;
    public function getResourceLabel(string $resourceType, string $resourceId): string;
}

Built-in Adapters

AdapterProviderResource Types
WordPressContentAdapterwordpress_corePosts, pages, custom post types, taxonomies, menus, URLs, comments, special pages
FluentCommunityAdapterfluent_communityfc_space, fc_group
FluentCrmAdapterN/AContact tags and lists
LearnDashAdapterlearndashsfwd-courses, sfwd-lessons

Registering Custom Adapters

Adapters are resolved by provider string. You can register custom resource types through the fchub_memberships/resource_types action:

add_action('fchub_memberships/resource_types', function ($registry) {
    $registry->register('my_resource', [
        'label'     => 'My Custom Resource',
        'group'     => 'content',
        'provider'  => 'my_plugin',
        'searchable' => true,
    ]);
});

Database Tables

All tables are prefixed with {wp_prefix}fchub_membership_.

CSV Import

The import system supports multiple CSV formats through parser classes implementing CsvParserInterface.

Built-in Parsers

ParserDescription
GenericCsvParserStandard CSV with columns: email, plan_slug, status, starts_at, expires_at
PmproCsvParserCompatible with Paid Memberships Pro exports. Maps PMPro fields to membership fields

Import Flow

  1. Upload — CSV file is uploaded and validated
  2. Preview — The parser processes the CSV and returns a preview of what will be imported (users matched, plans matched, conflicts detected)
  3. Execute — Grants are created for each valid row. Existing grants are updated if found

Custom Parsers

Implement CsvParserInterface and register your parser via a hook to support additional CSV formats from other membership plugins.

Cron Jobs

WP-Cron Events

EventIntervalHandler
fchub_memberships_validity_check5 minutesSubscriptionValidityWatcher::check()
fchub_memberships_drip_processHourlyDripScheduleService::processNotifications()
fchub_memberships_expiry_notifyDailyAccessExpiringEmail::sendPendingNotifications()
fchub_memberships_daily_statsDailyMemberStatsReport::aggregateDaily() + anniversary check
fchub_memberships_trial_checkDailyTrialLifecycleService::sendTrialExpiringNotifications() + checkTrialExpirations()
fchub_memberships_plan_scheduleHourlyPlanService::processScheduledStatuses()
fchub_memberships_audit_cleanupWeeklyAuditLogRepository::cleanup(90)

Action Scheduler Hooks

HookHandler
fchub_memberships_send_emailwp_mail($to, $subject, $body, $headers)
fchub_memberships_dispatch_webhookwp_remote_post($url, ...) with error logging

All cron handlers check for FLUENTCART_VERSION before executing to avoid errors when FluentCart is temporarily deactivated.

On this page