Developer Hooks Reference for Ultimate Spin Wheel
Ultimate Spin Wheel ships with eight PHP hooks that let developers extend the spin flow — validation, prize selection, data enrichment, and winner emails — without editing core files. They live in includes/core/class-spin-wheel.php and are placed at key points in the server-side spin request. This page documents each one with its type, signature, and parameters, verified against the plugin source.
Important: These Hooks Require the Pro Plugin
Every uspw_* hook on this page is wrapped in a Pro gate. In the code, each one only fires when apply_filters( 'ultimate_spin_wheel_pro_init', false ) returns true — which happens only when the separate Ultimate Spin Wheel Pro plugin is installed and active. On the free plugin alone these hooks never run, so any callbacks you attach to them will not execute. Treat this entire reference as (Pro).
Naming Convention
All hooks are prefixed with uspw_ and follow standard WordPress conventions. Filters expect you to return a value; actions do not. The Pro gate ultimate_spin_wheel_pro_init is itself a filter you can read to detect whether Pro is active.
Hook Execution Order
During a single spin request the hooks fire in roughly this sequence:
uspw_before_spin_validation— before eligibility is confirmed.uspw_before_prize_selection— before the weighted draw runs.uspw_after_prize_selected— after the winning slice and code are resolved.uspw_after_coupon_won— after a coupon is awarded (fires in both the legacy and the modern spin paths).uspw_before_save_entry— before the entry is written to the database.uspw_after_entry_saved— after the row is inserted.uspw_before_send_winner_email— before the winner email is sent.uspw_email_sent_result— after the send attempt returns.
1. uspw_before_spin_validation
Type: Filter. Run custom eligibility checks before the spin is processed. Returning false blocks the spin and the visitor is told they are not eligible.
$can_spin = apply_filters( 'uspw_before_spin_validation', $can_spin, $campaign_id, $user_data );
bool $can_spin— whether the user may spin (defaulttrue).int $campaign_id— the campaign ID.array $user_data— submittedemail,phone, andname.
Use cases: block specific email domains, add custom rate limiting, require login, or apply time-based restrictions.
2. uspw_before_prize_selection
Type: Action. Fires just before the server runs the weighted random draw, giving you the full pool of eligible prizes.
do_action( 'uspw_before_prize_selection', $campaign_id, $weighted_prizes, $user_data );
int $campaign_id— the campaign ID.array $weighted_prizes— the eligible prizes with their weights.array $user_data— submitted user data.
Use cases: track prize-pool analytics, log visitor behaviour, or push real-time notifications before the draw resolves.
3. uspw_after_prize_selected
Type: Action. Fires after the winning slice is drawn and its coupon code resolved, but before the entry is saved.
do_action( 'uspw_after_prize_selected', $selected_prize, $campaign_id, $user_data, $won_code );
array $selected_prize— the winning slice details.int $campaign_id— the campaign ID.array $user_data— submitted user data.string $won_code— the resolved coupon code awarded.
Use cases: send real-time winner alerts, trigger marketing automation, or sync the win to an external analytics platform.
4. uspw_after_coupon_won
Type: Action. Fires after a coupon is awarded to a winner. It appears in both the legacy client-declared save path and the modern server-side spin path.
do_action( 'uspw_after_coupon_won', $campaign_id, $data );
int $campaign_id— the campaign ID.array $data— entry data including the coupon code, coupon title, email, and name.
Use cases: fire a custom webhook per win, log wins to an external system, or sync with a loyalty program.
5. uspw_before_save_entry
Type: Filter. Modify or enrich the entry array before it is written to the database. Return the modified $data.
$data = apply_filters( 'uspw_before_save_entry', $data, $campaign_id );
array $data— the entry data about to be saved.int $campaign_id— the campaign ID.
Use cases: attach UTM attribution, add geolocation, normalize phone numbers, or calculate a lead-quality score before storage.
6. uspw_after_entry_saved
Type: Action. Fires immediately after the entry row is inserted into the custom leads table (wp_wdengage_entries), giving you the new row ID.
do_action( 'uspw_after_entry_saved', $entry_id, $data, $campaign_id );
int $entry_id— the database row ID of the saved entry.array $data— the complete entry data.int $campaign_id— the campaign ID.
Use cases: sync the lead to a CRM, trigger a Zapier webhook, push to Google Sheets, or queue a background job.
7. uspw_before_send_winner_email
Type: Filter. Customize the winner email arguments before wp_mail() is called. Return the modified $email_args.
$email_args = apply_filters( 'uspw_before_send_winner_email', $email_args, $data, $campaign_id );
array $email_args— email parameters:to,subject,message,headers.array $data— the entry data.int $campaign_id— the campaign ID.
Use cases: route the mail through a transactional service, translate the copy by location, add an expiration timer, or A/B test templates.
8. uspw_email_sent_result
Type: Action. Fires after the send attempt, reporting whether the winner email went out.
do_action( 'uspw_email_sent_result', $email_sent, $data, $campaign_id );
bool $email_sent— whether the email was sent successfully.array $data— the entry data.int $campaign_id— the campaign ID.
Use cases: log delivery status, implement retry logic, or record email performance in your CRM.
Best Practices
- Match the argument count. When adding a callback, declare the correct priority and accepted-args count, for example
add_action( 'uspw_after_entry_saved', 'my_function', 10, 3 ). - Validate and sanitize. Never trust the submitted data. Check for required fields and sanitize values (for example
sanitize_email()) inside your callback. - Offload heavy work. For slow tasks such as external API calls, schedule a background event rather than blocking the spin response.
- Fail gracefully. Wrap remote calls and check
is_wp_error()so a failed integration never breaks the visitor’s spin experience. - Confirm Pro is active. Because these hooks only fire under Pro, gate your own logic with
apply_filters( 'ultimate_spin_wheel_pro_init', false )when you need to branch on it.
Related Documentation
- Win Probabilities: How the server-side weighted draw picks a winner before the wheel animates.
- Prize & Coupon Configuration: Static codes, unique pools, and the coupon types the hooks operate on.
Conclusion
These eight hooks cover the full server-side spin flow — from validation through prize selection, saving, and winner email — and give developers clean extension points without touching core files. Remember that every one is Pro-gated: it fires only when Ultimate Spin Wheel Pro is active. For implementation help, review the source in includes/core/class-spin-wheel.php or contact the wowDevs support center.