Hooks, REST and WP-CLI

Actions

  • redeemid_signed_in, redeemid_linked, redeemid_disconnected and redeemid_before_logout
  • redeemid_log, which receives redacted log events
  • redeemid_levels_changed (int $user_id, string[] $added, string[] $removed), with level slugs, after a sync
  • redeemid_access_changed (int[] $post_ids), redeemid_access_levels_changed and redeemid_access_locked_changed (int $post_id, bool $locked)
  • redeemid_features_changed (int $user_id, string[] $added, string[] $removed) and redeemid_features_mapping_changed (string[] $slugs)

For example, purge a page cache when an item’s rule changes. An empty list means any item may have changed:

add_action( 'redeemid_access_changed', function ( array $post_ids ) {
	if ( ! $post_ids ) {
		my_cache_purge_all();
		return;
	}
	foreach ( $post_ids as $post_id ) {
		my_cache_purge_url( get_permalink( $post_id ) );
	}
} );

Filters

  • Sign-in: redeemid_auth_callback_slug, redeemid_default_redirect, redeemid_customer_admin_redirect, redeemid_sign_in_redirect and redeemid_offer_existing_account
  • Settings: redeemid_setting_{key}
  • Access: redeemid_access_levels and redeemid_access_rules (set levels and content rules from code; the admin screens then show them read-only), redeemid_gated_post_types, redeemid_access_context, redeemid_effective_rule, redeemid_teaser_settings, redeemid_paywall_schema and redeemid_drip_days
  • Features: redeemid_features, redeemid_feature_tests and redeemid_feature_decision (see Features)
  • Commerce: redeemid_context_country, redeemid_buyer_ip and redeemid_checkout_banner
  • Display: redeemid_locked_panel and redeemid_health_checks
  • Other: redeemid_official_state, redeemid_reassign_user and redeemid_pre_sync_now

For example, send Shopify the visitor’s real IP from a header your CDN sets. Forwarded headers aren’t read by default, because visitors can forge them:

add_filter( 'redeemid_buyer_ip', function ( string $ip ) {
	if ( empty( $_SERVER['HTTP_CF_CONNECTING_IP'] ) ) {
		return $ip;
	}
	return sanitize_text_field( wp_unslash( $_SERVER['HTTP_CF_CONNECTING_IP'] ) );
} );

REST routes

The namespace is redeemid/v1. Every write route needs the wp_rest nonce.

Route Purpose
GET /auth/status The caller’s own display-safe state
GET /auth/login Redirects to Shopify
POST /auth/logout Returns {redirect}, the Shopify end-session URL
POST /auth/refresh Refreshes the Shopify session; returns status, never tokens
POST /auth/disconnect Unlinks the Shopify customer from the current user
POST /account/sync Re-syncs the current user’s record (rate-limited)
POST /cart/identity Attaches the signed-in customer to Shopify’s plugin cart (rate-limited)
POST /webhooks/events Shopify webhooks (HMAC-verified)
GET /features The caller’s own granted feature slugs
GET /editor/products?search= The Plan Card product picker (editors only)

For example, refresh the signed-in member’s record from a script, with a nonce from wp_create_nonce( 'wp_rest' ):

await fetch( '/wp-json/redeemid/v1/account/sync', {
	method: 'POST',
	headers: { 'X-WP-Nonce': restNonce },
} );

Forms that work without JavaScript post to admin-post.php handlers instead (redeemid_login, _logout, _connect, _link_confirm, _sync and _disconnect), which redirect back to a page.

WP-CLI

wp redeemid resync user <id>...
wp redeemid resync all [--foreground]
wp redeemid resync status|pause|resume|cancel
wp redeemid access explain <post> --as=<guest|signed-in|level|tags|user> [--tags=a,b] [--user=<id>] [--format=json]
wp redeemid access recompute

For example, see why a guest can’t read post 42:

wp redeemid access explain 42 --as=guest

RedeemID is still being built

RedeemID is a WordPress plugin that lets customers sign in with their Shopify account and opens your site to what that account holds. It is in early development, so parts of this site are unfinished and details will change.

It is coming soon. We are looking for sponsors and for the first stores and publishers to use it.

For more information, email vinny@vinnysgreen.com.

Get in touch