benecaster_manual_subscriber_created
Fires when an admin manually enrolls a subscriber, once the grant is recorded. By this point the subscriber’s token is active and their welcome email has gone out.
Use it to tag the new subscriber in a CRM, post a Slack notification, write an audit record, or anything else that should happen when access is granted by hand rather than bought.
$expiry_at is a UTC datetime string, or null when the grant never expires. Guard against null — a manual grant with no end date is the common case, not the exception.
This fires only for the admin “Add subscriber manually” flow, not for paid signups or bulk enrollment. For every activation regardless of source, use benecaster_subscription_activated instead.
The hook passes five arguments, so register with an accepted-args count of 5 to reach $joined_at.
$joined_at and $expiry_at are different FORMATS on the SAME clock. $joined_at is usually a bare Y-m-d, because it is whatever the operator typed into a date field; $expiry_at is a full Y-m-d H:i:s. Both are UTC. Do not pass one where the other is expected, and do not convert either by the site’s gmt_offset — a listener that shifts $joined_at to local time moves every imported join date by the offset, which is the corruption this note exists to prevent.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
$user_id |
int |
— | WordPress user ID of the newly enrolled subscriber |
$show_id |
int |
— | WordPress post ID of the show the subscriber was enrolled into |
$tier_slug |
string |
— | Slug of the tier the subscriber was granted access to |
$expiry_at |
string|null |
— | MySQL UTC DATETIME string (e.g. '2027-01-01 00:00:00') representing when access will be automatically revoked, or null if the grant has no expiry |
$joined_at |
string|null |
— | The backdated join date the operator entered in the "Supporter since" field, verbatim and **UTC** — a bare `Y-m-d` from the form, or a full `Y-m-d H:i:s` from an API caller. Null when they left it blank, which is the common case. By the time this fires the value has already been written to the token row's `created_at`, so the subscriber's tenure badge already reflects it. |
Examples
Notify a Slack channel when a subscriber is manually added
add_action( 'benecaster_manual_subscriber_created', function(
int $user_id,
int $show_id,
string $tier_slug,
?string $expiry_at
): void {
$user = get_userdata( $user_id );
$show = get_the_title( $show_id );
$expiry = $expiry_at ? " (expires {$expiry_at} UTC)" : '';
my_slack_notify( "#memberships", "Admin manually added {$user->user_email} to {$show} on tier {$tier_slug}{$expiry}." );
}, 10, 4 );
Tag the subscriber in an external CRM
add_action( 'benecaster_manual_subscriber_created', function(
int $user_id,
int $show_id,
string $tier_slug,
?string $expiry_at
): void {
$user = get_userdata( $user_id );
my_crm()->tag_contact( $user->user_email, [ 'manual-grant', "tier:{$tier_slug}" ] );
}, 10, 4 );
Need this built rather than just documented? See our services →