Spin Wheel

⌘K
  1. Home
  2. Spin Wheel
  3. Hooks & Filters (Deve...
  4. After coupon is awarded (legacy flow) (uspw_after_coupon_won)

After coupon is awarded (legacy flow) (uspw_after_coupon_won)

Run Custom Code After a Win with uspw_after_coupon_won

The uspw_after_coupon_won action lets developers run custom logic immediately after a visitor finishes a spin and the entry is saved to the database. It is the primary integration point for connecting Ultimate Spin Wheel to external systems such as CRMs, SMS gateways, or custom analytics.

Important: this hook — like every uspw_* hook in the plugin — only fires when the separate Ultimate Spin Wheel Pro plugin is active. In the free plugin the call is wrapped in if ( apply_filters( 'ultimate_spin_wheel_pro_init', false ) ), so none of the snippets below will run on a free-only install.

Key facts:

  • Type: Action (do_action).
  • Location: includes/core/class-spin-wheel.php.
  • Trigger: Fires during the spin AJAX request, after the entry row is inserted into the leads table.
  • Requires Pro: Gated behind apply_filters( 'ultimate_spin_wheel_pro_init', false ).

When It Fires: Two Spin Flows

Ultimate Spin Wheel saves a spin through one of two AJAX paths, and the hook fires from both. The payload shape passed as $data is not identical between them, so write your handlers defensively.

  • Legacy flow — the client-declared ultimate_spin_wheel_spinned action (handled by spin_wheel_spinned()). This is the flow this page documents. Here $data is the raw database insert array.
  • Modern flow — the secure server-side ultimate_spin_wheel_process_spin action (handled by spin_wheel_process_spin()), where the winner is drawn on the server. Here $data is a flat $user_data array with every field at the top level.

Parameters

  • $campaign_id (int): The ID of the spin wheel campaign.
  • $data (array): The entry data. Register with a priority and an accepted-args count of 2, e.g. add_action( 'uspw_after_coupon_won', 'my_handler', 10, 2 ).

The $data Array: Legacy vs Modern

These fields are always present as top-level keys in both flows:

  • name — visitor name (empty if the field was skipped).
  • email — visitor email.
  • phone — visitor phone (the phone input field is a Pro feature).
  • campaign_id and campaign_title.

Modern flow only — the flat $user_data array also exposes these as top-level keys: coupon_code, coupon_title, status (for example won), segment_index, optin (1 or 0), and message (the win or lose text, which may still contain the {{discount_label}} placeholder).

Legacy flow difference (read this before copying older examples): in the legacy $data array the coupon details are not at the top level. Instead, coupon_title, coupon_code, and status are nested inside $data['others_data'], which is a JSON-encoded string. The legacy array also does not include message, segment_index, or optin. It does carry an extra user_data JSON string with ip_address, device_id, and user_agent. To read a coupon in the legacy flow, decode it: $extra = json_decode( $data['others_data'], true ); then use $extra['coupon_code'].

Where the Data Lives

Both flows insert the entry into the custom leads table wp_wdengage_entries before the hook runs, so the visitor and prize data has already been persisted by the time your handler executes. Unique coupon codes are resolved on the server and are never exposed in the page source before a win.

Example Use Cases

Log Every Winner (Debugging)

Hook the action, read $data['email'] (safe in both flows), and write a line to your debug log with error_log(). To include the prize label, use $data['coupon_title'] on the modern flow, or decode $data['others_data'] first on the legacy flow.

Send Lead Data to a Webhook (Zapier / Make)

Push the win to any external service that is not natively integrated. Build a payload from the $data keys and send it with wp_remote_post(). Set 'blocking' => false so the request does not slow down the visitor’s result screen.

Note: Ultimate Spin Wheel Pro already ships native integrations for Mailchimp, MailPoet, Klaviyo, ActiveCampaign, HubSpot, Zapier, and Pabbly, so use a manual webhook only for services the plugin does not cover.

Assign a User Role to Logged-In Winners

Look the user up by their email with get_user_by( 'email', $data['email'] ) and, if a matching account exists, grant a role with $user->add_role( 'vip_customer' ). Gate it to a specific campaign by checking $data['campaign_id'] first.

Send an SMS Notification

Because collecting a phone number requires the Pro phone input field, confirm $data['phone'] is not empty, strip it to digits with preg_replace( '/[^0-9]/', '', $phone ), then call your SMS gateway with wp_remote_get() or wp_remote_post() using 'blocking' => false. Pull the coupon from $data['coupon_code'] on the modern flow, or from the decoded others_data on the legacy flow.

Important Notes

  1. Keep it non-blocking: Heavy work in a blocking external call can make the result screen hang. Use 'blocking' => false for outbound HTTP requests.
  2. Guard every key: Optional fields such as name and phone may be empty, so check with isset() or the ?? operator before using them.
  3. Mind the flow difference: If a handler needs the coupon code or status, remember the legacy flow nests those inside the others_data JSON string while the modern flow exposes them at the top level.
  4. Pro required: The hook never fires on a free-only install, so test with Ultimate Spin Wheel Pro active.

Related Documentation

Conclusion

The uspw_after_coupon_won action is a Pro-only extension point that runs your code as soon as a spin is saved, making it a clean way to push winners to SMS gateways, webhooks, or role changes. Just account for the two spin flows — the legacy flow nests coupon fields inside others_data, while the modern flow exposes them at the top level — and keep outbound calls non-blocking. If you need help, visit the wowDevs support center.

How can we help?