Spin Wheel

⌘K
  1. Home
  2. Spin Wheel
  3. Hooks & Filters (Deve...
  4. Before random selection algorithm (uspw_before_prize_selection)

Before random selection algorithm (uspw_before_prize_selection)

uspw_before_prize_selection

The uspw_before_prize_selection action fires on the server during a spin, immediately after the eligible prize pool has been built and just before the weighted random draw runs. It is designed for read-only work — analytics, logging, A/B-test bucketing, notifications, and external integrations — that needs to see the prize pool and the visitor’s submitted data before a winner is chosen.

  • Hook type: Action (do_action)
  • Since: 1.0.0
  • Fires in: includes/core/class-spin-wheel.php, inside the AJAX spin handler

Important: this hook requires Ultimate Spin Wheel Pro

(Pro) In the free plugin this action is wrapped in a Pro gate and never fires. The exact call in the code is:

if ( apply_filters( 'ultimate_spin_wheel_pro_init', false ) ) { do_action( 'uspw_before_prize_selection', $campaign_id, $weighted_prizes, $user_data ); }

Every uspw_* developer hook is gated the same way. Your callback will only run when the separate Ultimate Spin Wheel Pro plugin is active (which makes ultimate_spin_wheel_pro_init return true). If you register a callback on the free plugin alone, it stays dormant.

Parameters

  • $campaign_id (int) — The ID of the spin wheel campaign being spun.
  • $weighted_prizes (array) — The eligible prize pool. Each item is an array with three keys: index (the slice’s position in the saved coupon list), weight (the slice’s probability as a float), and data (the full slice array — label, code, probability, coupon_type, and so on).
  • $user_data (array) — The visitor’s submitted lead data, typically name and email (phone is a Pro field). Keys are only present when the campaign collects them.

Because this is an action (not a filter), any value your callback returns is ignored. The pool passed in $weighted_prizes is a copy — modifying it does not change which slice the draw selects. Use it to observe the pool, not to rewrite it.

What is already in the pool

By the time this hook fires, the server has already filtered the slices down to only those that can actually win:

  • Slices with a probability of 0 (or blank) are excluded.
  • Unique-pool slices whose codes have run out are excluded.
  • WooCommerce Dynamic and Auto Generate slices (Pro) are excluded when Pro is not active.

So $weighted_prizes already reflects the real draw. A slice’s true chance is its weight divided by the sum of all weights in the pool.

Basic usage

Register the callback with three arguments:

add_action( 'uspw_before_prize_selection', 'my_prize_tracking', 10, 3 );
function my_prize_tracking( $campaign_id, $weighted_prizes, $user_data ) {
    // Your custom logic here.
}

Example 1: Log prize-pool analytics

Record how many prizes were eligible and the total weight, so you can audit the draw later.

add_action( 'uspw_before_prize_selection', 'track_prize_analytics', 10, 3 );
function track_prize_analytics( $campaign_id, $weighted_prizes, $user_data ) {
    $analytics_data = [
        'campaign_id' => $campaign_id,
        'timestamp' => current_time( 'mysql' ),
        'user_email' => $user_data['email'] ?? 'anonymous',
        'available_prizes' => count( $weighted_prizes ),
        'total_weight' => array_sum( wp_list_pluck( $weighted_prizes, 'weight' ) ),
    ];
    error_log( 'Prize Selection Analytics: ' . wp_json_encode( $analytics_data ) );
}

Example 2: A/B-test bucketing by email domain

Assign each visitor to a variant for reporting, without touching the draw.

add_action( 'uspw_before_prize_selection', 'ab_test_bucket', 10, 3 );
function ab_test_bucket( $campaign_id, $weighted_prizes, $user_data ) {
    if ( $campaign_id !== 555 || empty( $user_data['email'] ) ) {
        return;
    }
    $domain = substr( strrchr( $user_data['email'], '@' ), 1 );
    $variant = in_array( $domain, [ 'company.com', 'business.org' ], true ) ? 'B2B' : 'B2C';
    update_option( 'ab_test_spin_' . md5( $user_data['email'] ), [
        'variant' => $variant,
        'timestamp' => time(),
        'campaign_id' => $campaign_id,
    ] );
}

Example 3: Sync the spin attempt to a CRM

Push the visitor to an external system before the result is known.

add_action( 'uspw_before_prize_selection', 'sync_with_crm', 10, 3 );
function sync_with_crm( $campaign_id, $weighted_prizes, $user_data ) {
    if ( empty( $user_data['email'] ) ) {
        return;
    }
    $api_key = get_option( 'my_crm_api_key' );
    if ( ! $api_key ) {
        return;
    }
    wp_remote_post( 'https://api.example-crm.com/v1/contacts', [
        'headers' => [ 'Authorization' => 'Bearer ' . $api_key, 'Content-Type' => 'application/json' ],
        'body' => wp_json_encode( [
            'email' => $user_data['email'],
            'firstname' => $user_data['name'] ?? '',
            'campaign_id' => $campaign_id,
        ] ),
    ] );
}

Notes and best practices

  • This action runs during a live AJAX spin. Keep callbacks fast — slow blocking calls (remote requests, heavy queries) delay the visitor’s result. For non-urgent work, schedule it with wp_schedule_single_event() or an async queue.
  • The hook is for observation only. It cannot add, remove, or reweight slices — the draw uses the server’s own copy of the pool. There is no filter counterpart for editing the pool at this stage.
  • Do not assume any $user_data key exists. Guard every field with isset() or the null-coalescing operator, since campaigns collect different fields and phone is a Pro-only input.
  • If you need the outcome instead of the pre-draw state, use uspw_after_prize_selected (fires after the winner is chosen) or uspw_after_coupon_won.

Related Documentation

Conclusion

The uspw_before_prize_selection action gives Pro-plugin developers a read-only window onto the eligible prize pool and the visitor’s data, one step before the secure server-side draw runs. Use it for analytics, A/B bucketing, and CRM syncing — keep the callback lightweight, guard your data keys, and reach for uspw_after_prize_selected when you need the outcome. Remember it only fires when Ultimate Spin Wheel Pro is active. For help, visit the wowDevs support center.

How can we help?