{"id":41835,"date":"2025-11-03T23:12:47","date_gmt":"2025-11-03T23:12:47","guid":{"rendered":"https:\/\/relywp.com\/?post_type=docs&#038;p=41835"},"modified":"2025-11-15T12:21:38","modified_gmt":"2025-11-15T12:21:38","password":"","slug":"acciones-y-filtros-para-desarrolladores","status":"publish","type":"docs","link":"https:\/\/relywp.com\/es\/docs\/simple-points-rewards-woocommerce\/acciones-y-filtros-para-desarrolladores\/","title":{"rendered":"Desarrolladores: Acciones y filtros"},"content":{"rendered":"<p>Esta p\u00e1gina documenta todas las acciones y filtros p\u00fablicos disponibles en <strong>Simple Points &amp; Rewards (Pro)<\/strong> para ampliar el comportamiento o integrarlo con c\u00f3digo personalizado.<\/p>\n\n\n\n<p><em>El c\u00f3digo proporcionado en esta p\u00e1gina es s\u00f3lo un ejemplo y debe utilizarse con precauci\u00f3n y realizando las pruebas adecuadas.<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Ciclo de vida de los puntos b\u00e1sicos<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Filtrar: <code>spar_user_points<\/code><\/h3>\n\n\n\n<p>Modificar el saldo devuelto (visualizado) de un usuario.<\/p>\n\n\n\n<p><strong>Par\u00e1metros:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>int $points<\/code> Saldo almacenado del usuario meta <code>puntos_espar<\/code>.<\/li>\n\n\n\n<li><code>int $user_id<\/code><\/li>\n<\/ul>\n\n\n\n<p><strong>Ejemplo:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>add_filter( 'spar_user_points', function( $points, $user_id ) {\n    \/\/ A\u00f1ade una bonificaci\u00f3n virtual de 100pt para los administradores\n    if ( user_can( $user_id, 'manage_options' ) ) {\n        $points += 100;\n    }\n    return $points;\n}, 10, 2 );<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Filtrar: <code>spar_update_user_points_args<\/code><\/h3>\n\n\n\n<p>Ajuste los argumentos antes de aplicar una actualizaci\u00f3n de puntos.<\/p>\n\n\n\n<p><strong>Par\u00e1metros:<\/strong> <code>(int $user_id, int $points, cadena $action, cadena $note, cadena $action_id)<\/code><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Acci\u00f3n: <code>spar_before_points_update<\/code><\/h3>\n\n\n\n<p>Dispara antes de una actualizaci\u00f3n de saldo.<\/p>\n\n\n\n<p><strong>Par\u00e1metros:<\/strong> <code>(int $user_id, int $points, cadena $action, cadena $note, cadena $action_id)<\/code><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Acci\u00f3n: <code>spar_after_points_update<\/code><\/h3>\n\n\n\n<p>Dispara despu\u00e9s de una actualizaci\u00f3n de equilibrio.<\/p>\n\n\n\n<p><strong>Par\u00e1metros:<\/strong> <code>(int $user_id, int $new_balance, int $delta, cadena $action, cadena $note, cadena $action_id)<\/code><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Acci\u00f3n: <code>spar_points_added<\/code><\/h3>\n\n\n\n<p>El gancho de retrocompensaci\u00f3n se dispara cuando se a\u00f1aden puntos.<\/p>\n\n\n\n<p><strong>Par\u00e1metros:<\/strong> <code>(int $user_id, int $points, cadena $note, cadena $action_id)<\/code><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Acci\u00f3n: <code>spar_points_removed<\/code><\/h3>\n\n\n\n<p>Se activa cuando se quitan puntos.<\/p>\n\n\n\n<p><strong>Par\u00e1metros:<\/strong> <code>(int $user_id, int $points, cadena $note, cadena $action_id)<\/code><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><\/h3>\n\n\n\n<h3 class=\"wp-block-heading\">Filtrar: <code>spar_points_history_per_page<\/code><\/h3>\n\n\n\n<p>Controla cu\u00e1ntas filas de registro por p\u00e1gina se muestran en el historial.<\/p>\n\n\n\n<p><strong>Par\u00e1metros:<\/strong> <code>(int $per_page, int $user_id)<\/code><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Filtrar: <code>spar_user_points_history<\/code><\/h3>\n\n\n\n<p>Modificar la respuesta del historial ensamblado.<\/p>\n\n\n\n<p><strong>Par\u00e1metros:<\/strong> <code>(array $result, int $user_id)<\/code> donde <code>$result = [ 'logs' =&gt; [], 'pagination' =&gt; [] ]<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Acci\u00f3n: <code>spar_user_level_changed<\/code><\/h3>\n\n\n\n<p>Se activa cuando un usuario pasa a un nuevo nivel.<\/p>\n\n\n\n<p><strong>Par\u00e1metros:<\/strong> <code>(int $user_id, array $new_level, array|null $previous_level, int $lifetime_total_earned)<\/code><\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Pedidos (ingresos\/deducciones)<\/h2>\n\n\n\n<p>Filtros y acciones para otorgar o quitar puntos durante los eventos de pedido.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>spar_order_points_rate<\/code> - Anular el c\u00e1lculo de puntos por unidad monetaria.<\/li>\n\n\n\n<li><code>spar_order_base_points<\/code> - Ajustar los puntos base antes de los niveles\/multiplicadores.<\/li>\n\n\n\n<li><code>spar_order_fixed_points<\/code> - Ajustar los puntos de nivel fijo.<\/li>\n\n\n\n<li><code>spar_order_points_multiplier<\/code> - Ajuste el multiplicador efectivo de la orden.<\/li>\n\n\n\n<li><code>spar_order_awarded_points<\/code> - Ajustar los puntos finales concedidos por un pedido.<\/li>\n\n\n\n<li><code>spar_order_points_action_text<\/code> - Modificar la nota de registro para los puntos de pedido concedidos.<\/li>\n\n\n\n<li><code>spar_before_award_order_points<\/code> \/ <code>spar_after_award_order_points<\/code> - Antes y despu\u00e9s de la concesi\u00f3n de puntos.<\/li>\n\n\n\n<li><code>spar_order_points_to_deduct<\/code> - Ajuste el n\u00famero de puntos a eliminar en caso de reembolso o cancelaci\u00f3n.<\/li>\n\n\n\n<li><code>spar_order_deduction_action_id<\/code> - Cambiar el ID de acci\u00f3n utilizado para el registro de deducciones.<\/li>\n\n\n\n<li><code>spar_order_deduction_action_text<\/code> - Modificar el mensaje de registro para los eventos de deducci\u00f3n.<\/li>\n\n\n\n<li><code>spar_after_deduct_order_points<\/code> - Incendio tras restar puntos por cambio de estado del pedido.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Canje y vales<\/h2>\n\n\n\n<p>Ganchos relacionados con el canje de recompensas, la creaci\u00f3n de vales y el flujo de canje del front-end.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>spar_before_reward_redemption<\/code> - Antes de tramitar el canje de una recompensa.<\/li>\n\n\n\n<li><code>spar_reward_object<\/code> - Ajuste la matriz de recompensa antes de la l\u00f3gica.<\/li>\n\n\n\n<li><code>spar_reward_cost_points<\/code> - Modificar el n\u00famero de puntos necesarios.<\/li>\n\n\n\n<li><code>spar_can_redeem_reward<\/code> - Permitir o denegar el rescate.<\/li>\n\n\n\n<li><code>spar_reward_redemption_refunded<\/code> - Despedido cuando falla el rescate y reembolsado.<\/li>\n\n\n\n<li><code>spar_after_reward_redemption<\/code> - Despu\u00e9s de la redenci\u00f3n exitosa.<\/li>\n\n\n\n<li><code>spar_reward_voucher_meta<\/code> - Modificar cup\u00f3n meta.<\/li>\n\n\n\n<li><code>spar_reward_voucher_created<\/code> - Cuando se crea el puesto de cup\u00f3n.<\/li>\n\n\n\n<li><code>spar_voucher_claimed<\/code> - Cuando se reclama un vale.<\/li>\n<\/ul>\n\n\n\n<p><strong>Ganchos de integraci\u00f3n frontend:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>spar_before_handle_redeem_request<\/code><\/li>\n\n\n\n<li><code>spar_redeem_product_redirect_url<\/code><\/li>\n\n\n\n<li><code>spar_redeem_success_redirect<\/code><\/li>\n\n\n\n<li><code>spar_before_apply_coupon_from_query<\/code> \/ <code>spar_after_apply_coupon_from_query<\/code><\/li>\n\n\n\n<li><code>spar_ajax_before_apply_voucher<\/code> \/ <code>spar_ajax_after_apply_voucher<\/code><\/li>\n\n\n\n<li><code>spar_voucher_ferred<\/code>, <code>spar_voucher_pending_invalid<\/code>, <code>spar_voucher_auto_applied<\/code><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Correos electr\u00f3nicos<\/h2>\n\n\n\n<p>Gancho gen\u00e9rico de resultado de env\u00edo de correo electr\u00f3nico compartido en todos los tipos:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Acci\u00f3n: <code>spar_email_sent<\/code><\/h3>\n\n\n\n<p><strong>Par\u00e1metros:<\/strong> <code>(string $type, bool $sent, string $to, string $subject, int $user_id, string $context_id)<\/code><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Tipo $<\/code>: <code>puntos_ganados<\/code> | <code>vale_reclamado<\/code><\/li>\n\n\n\n<li><code>$context_id<\/code>: Para points_earned esto es <code>$action_id<\/code>; para voucher_claimed este es el <code>c\u00f3digo_vale<\/code>.<\/li>\n<\/ul>\n\n\n\n<p><strong>Filtros:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>spar_email_points_earned_subject<\/code><\/li>\n\n\n\n<li><code>spar_email_points_earned_body<\/code><\/li>\n\n\n\n<li><code>spar_email_voucher_claimed_subject<\/code><\/li>\n\n\n\n<li><code>spar_email_voucher_claimed_body<\/code><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Niveles<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>spar_badge_icons<\/code><\/li>\n\n\n\n<li><code>spar_todos_los_niveles<\/code><\/li>\n\n\n\n<li><code>spar_user_level<\/code><\/li>\n\n\n\n<li><code>spar_user_next_level<\/code><\/li>\n\n\n\n<li><code>spar_level_progress<\/code><\/li>\n\n\n\n<li><code>spar_user_points_multiplier<\/code><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Mi cuenta \/ Shortcode UI<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>spar_rewards_menu_label<\/code><\/li>\n\n\n\n<li><code>spar_account_menu_items<\/code> - Filtra la matriz final del men\u00fa despu\u00e9s de la inserci\u00f3n.<\/li>\n\n\n\n<li><code>spar_rewards_overview_html<\/code><\/li>\n\n\n\n<li><code>spar_rewards_visible_tabs<\/code><\/li>\n\n\n\n<li><code>spar_before_rewards_tab<\/code><\/li>\n\n\n\n<li><code>spar_after_rewards_tab<\/code><\/li>\n\n\n\n<li><code>spar_render_tab_{key}<\/code> - Las llaves: <code>gane<\/code>, <code>reclamar<\/code>, <code>niveles<\/code>, <code>historia<\/code>, <code>vales<\/code>.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Cupones (lista admin)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Filtrar: <code>spar_reward_coupon_prefixes<\/code><\/h3>\n\n\n\n<p>Ajuste qu\u00e9 prefijos de c\u00f3digo de cup\u00f3n se ocultan de la tabla de lista de cupones por defecto (por ejemplo, vales de recompensa, cupones de referencia).<\/p>\n\n\n\n<p><strong>Por defecto:<\/strong> <code>[ 'gift-', 'voucher-', 'ref-' ]<\/code><\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Ejemplos r\u00e1pidos<\/h2>\n\n\n\n<p><strong>Conceda 50 puntos extra fijos en todos los pedidos completados para la funci\u00f3n VIP:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>add_filter( 'spar_order_awarded_points', function( $points, $order_id, $user_id ) {\n    if ( user_can( $user_id, 'vip_customer' ) ) {\n        $points += 50;\n    }\n    return $points;\n}, 10, 3 );<\/code><\/pre>\n\n\n\n<p><strong>Se necesitan 20% puntos menos para canjear cualquier recompensa en el Black Friday:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>add_filter( 'spar_reward_cost_points', function( $cost, $reward, $user_id ) {\n    if ( date( 'm-d' ) === '11-28' ) {\n        $cost = (int) round( $cost * 0.8 );\n    }\n    return max( 1, $cost );\n}, 10, 3 );<\/code><\/pre>\n\n\n\n<p><strong>Sustituya el asunto\/cuerpo del correo electr\u00f3nico del vale reclamado:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>add_filter( 'spar_email_voucher_claimed_subject', function( $subject, $ctx ) {\n    return '\u00a1Tu bono est\u00e1 activo! C\u00f3digo: ' . $ctx['voucher_code'];\n}, 10, 2 );\n\nadd_filter( 'spar_email_voucher_claimed_body', function( $body, $ctx ) {\n    return wpautop( 'Utiliza tu c\u00f3digo al pagar para ahorrar. \u00a1Disfr\u00fatalo!' );\n}, 10, 2 );<\/code><\/pre>\n\n\n\n<p><strong>Reacciona a las subidas de nivel:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>add_action( 'spar_user_level_changed', function( $user_id, $new_level, $prev_level ) {\n    \/\/ Etiquetar en CRM, etc.\n}, 10, 3\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Funciones<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Gesti\u00f3n de puntos (a\u00f1adir\/eliminar mediante programaci\u00f3n)<\/h3>\n\n\n\n<p><strong><code>spar_update_user_points( int $user_id, int $points, string $action, string $note = '', string $action_id = 'custom' )<\/code><\/strong><\/p>\n\n\n\n<p>Actualizar el saldo de un usuario e insertar una fila de registro.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>$acci\u00f3n<\/code>: <code>'a\u00f1adir'<\/code> o <code>'eliminar'<\/code><\/li>\n\n\n\n<li><code>$note<\/code>: texto breve colocado en el registro de puntos (almacenado de forma desinfectada)<\/li>\n\n\n\n<li><code>$action_id<\/code>clave de m\u00e1quina estable para el evento, por ejemplo <code>reembolso_pedido<\/code>, <code>inscr\u00edbase en<\/code>, <code>review_bonus<\/code><\/li>\n<\/ul>\n\n\n\n<p><strong>Ejemplos:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\/**\n * A\u00f1ade 50 puntos con una nota de registro clara y una clave de acci\u00f3n personalizada.\n *\/\n$user_id = get_current_user_id();\nif ( $user_id ) {\n    $points = absint( 50 );\n    $note = sanitize_text_field( &#039;Promo Bonus&#039; );\n    $action_id = sanitize_key( &#039;promo_bonus&#039; );\n\n    spar_update_user_points( $user_id, $points, &#039;add&#039;, $note, $action_id );\n}\n\n\/**\n * Eliminar 30 puntos (por ejemplo, ajuste manual de admin).\n *\/\n$user_id = 123;\n$points = absint( 30 );\n$note = sanitize_text_field( &#039;Ajuste manual&#039; );\n$action_id = sanitize_key( &#039;admin_adjust&#039; );\n\nspar_update_user_points( $user_id, $points, &#039;remove&#039;, $note, $action_id );<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">C\u00e1lculo de puntos de pedido (para previsiones\/estimaciones)<\/h3>\n\n\n\n<p>Ayudantes para calcular los mismos valores que el plugin utiliza al otorgar puntos de pedido.<\/p>\n\n\n\n<p>\u00datil para mostrar \u201cGanar\u00e1s X puntos\u201d en p\u00e1ginas de productos o carritos.<\/p>\n\n\n\n<p><strong><code>spar_get_order_points_rate( cadena $currency_code = '' ): float<\/code><\/strong><\/p>\n\n\n\n<p>Devuelve puntos por 1,0 unidad monetaria despu\u00e9s de ajustes y filtros.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n$rate = (float) spar_get_order_points_rate( get_woocommerce_currency() );<\/code><\/pre>\n\n\n\n<p><strong><code>spar_calculate_order_base_points( WC_Order $order ): int<\/code><\/strong><\/p>\n\n\n\n<p>Puntos basados en el gasto antes de multiplicadores y niveles.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n$order = wc_get_order( $order_id );\n$base = (int) spar_calculate_order_base_points( $order );<\/code><\/pre>\n\n\n\n<p><strong><code>spar_calculate_fixed_order_points_for_total( float $total, string $currency ): array<\/code><\/strong><\/p>\n\n\n\n<p>Devoluci\u00f3n de resultados de nivel fijo:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>puntos<\/code> (int) puntos de nivel actuales<\/li>\n\n\n\n<li><code>siguiente_delta<\/code> (float|null) gasto necesario para alcanzar el siguiente nivel<\/li>\n\n\n\n<li><code>siguientes_puntos<\/code> (int|null) puntos ganados en el siguiente nivel<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>cart-&gt;get_total( 'edit' ); \/\/ O tu propio total.\n$info = spar_calculate_fixed_order_points_for_total( $total, get_woocommerce_currency() );\n$current_points = (int) $info['points'];<\/code><\/pre>\n\n\n\n<p><strong>Ejemplo: \u201cGanar\u00e1 X puntos\u201d en las p\u00e1ginas de productos<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\nadd_action( &#039;woocommerce_single_product_summary&#039;, function() {\n    if ( ! is_user_logged_in() || empty( WC()-&gt;carro ) ) {\n        devolver;\n    }\n\n    $currency = get_woocommerce_currency();\n    $rate = (float) spar_get_order_points_rate( $currency );\n\n    if ( $rate &lt;= 0 ) {\n        return;\n    }\n\n    global $product;\n\n    $price    = (float) wc_get_price_excluding_tax( $product );\n    $estimate = (int) floor( $price * $rate );\n\n    if ( $estimate &gt; 0 ) {\n        echo &#039;&lt;p class=&quot;spar-estimate&quot;&gt;&#039;. esc_html(\n            sprintf(\n                __( &#039;Gana aproximadamente %d puntos por este art&iacute;culo&#039;, &#039;simple-points-and-rewards&#039; ),\n                1TP4Estimaci&oacute;n\n            )\n        ) . &#039;&lt;\/p&gt;&#039;;\n    }\n}, 25 );<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Ayuda de nivel<\/h3>\n\n\n\n<p><strong><code>spar_get_user_points_multiplier( int $user_id ): float<\/code><\/strong><\/p>\n\n\n\n<p>Devuelve el multiplicador basado en el nivel actual, o <code>1.0<\/code> si los niveles est\u00e1n desactivados.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n$multiplier = function_exists( &#039;spar_get_user_points_multiplier&#039; )\n    ? (float) spar_get_user_points_multiplier( get_current_user_id() )\n    : 1.0;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Adjudicaci\u00f3n\/deducci\u00f3n vinculada a pedidos (activaci\u00f3n manual)<\/h3>\n\n\n\n<p>El plugin premia o deduce autom\u00e1ticamente en los eventos de pedido en funci\u00f3n de la configuraci\u00f3n. Para ejecutar la l\u00f3gica de adjudicaci\u00f3n manualmente:<\/p>\n\n\n\n<p><strong><code>spar_award_order_points( int $order_id ): void<\/code><\/strong><\/p>\n\n\n\n<p>Idempotente si los puntos ya est\u00e1n almacenados en el orden meta.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\/\/ Usar con cuidado; normalmente controlado por ajustes y hooks.\nspar_award_order_points( (int) $order_id );<\/code><\/pre>\n\n\n\n<p><strong><code>spar_deduct_refunded_order_points( int $order_id ): void<\/code><\/strong><\/p>\n\n\n\n<p>Deduce los puntos previamente concedidos por pedidos reembolsados, cancelados o fallidos, cuando est\u00e1 activado.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\nspar_deduct_refunded_order_points( (int) $order_id );<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Recompensas personalizadas<\/h3>\n\n\n\n<p>Puede crear una recompensa de tipo \u201cPersonalizada (gancho de desarrollador)\u201d en la pesta\u00f1a de configuraci\u00f3n de recompensas. Una recompensa personalizada le permite deducir puntos y luego ejecutar su propia l\u00f3gica cuando el cliente la reclama.<\/p>\n\n\n\n<p>Campos:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Descripci\u00f3n breve: se muestra a los clientes en la lista de formas de canjear.<\/li>\n\n\n\n<li>ID de recompensa del desarrollador: identificador \u00fanico en min\u00fasculas (letras, n\u00fameros, guiones, guiones bajos) que puede utilizar para distinguir varias recompensas personalizadas.<\/li>\n<\/ul>\n\n\n\n<p>Gancho despedido tras reclamaci\u00f3n exitosa y deducci\u00f3n de puntos:<br><code>spar_custom_reward_claimed( $user_id, $developer_id, $reward_array, $points_spent )<\/code><\/p>\n\n\n\n<p>Ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>add_action( 'spar_custom_reward_claimed', function( $user_id, $developer_id, $reward, $points_spent ) {\n  if ( 'vip_access' === $developer_id ) {\n    \/\/ Conceder funci\u00f3n VIP, o establecer una meta bandera de usuario\n    $user = get_user_by( 'ID', $user_id );\n    if ( $user &amp;&amp; ! in_array( 'vip', $user-&gt;roles, true ) ) {\n      $user-&gt;add_role( 'vip' );\n    }\n    \/\/ Opcional: notificar al usuario\n    wp_mail( $user-&gt;user_email, 'Acceso VIP concedido', '\u00a1Disfruta de tus nuevas ventajas VIP!' );\n  }\n}, 10, 4 );<\/code><\/pre>\n\n\n\n<p>Si tu l\u00f3gica falla y necesitas devolver puntos, llama:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>spar_update_user_points( $user_id, $points_spent, 'add', 'Refund: custom reward failed', 'redeem_refund' );<\/code><\/pre>\n\n\n\n<p>Esto mantiene la flexibilidad del plugin para tipos de recompensa a medida. .<\/p>","protected":false},"excerpt":{"rendered":"<p>Esta p\u00e1gina documenta todas las acciones p\u00fablicas y filtros disponibles en Simple Points &amp; Rewards (Pro) para extender el comportamiento o integrar con c\u00f3digo personalizado. El c\u00f3digo proporcionado en esta p\u00e1gina es s\u00f3lo de ejemplo y debe ser utilizado con precauci\u00f3n y pruebas adecuadas. Core points lifecycle Filtro: spar_user_points Modificar el saldo devuelto (mostrar) de un usuario. [...]<\/p>\n<p><a class=\"btn btn-secondary understrap-read-more-link\" href=\"https:\/\/relywp.com\/es\/docs\/simple-points-rewards-woocommerce\/acciones-y-filtros-para-desarrolladores\/\">Leer m\u00e1s...<span class=\"screen-reader-text\"> de los desarrolladores: Acciones y filtros<\/span><\/a><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":"","_links_to":"","_links_to_target":""},"doc_category":[55],"doc_tag":[],"knowledge_base":[52],"class_list":["post-41835","docs","type-docs","status-publish","hentry","doc_category-developers","knowledge_base-simple-points-rewards-woocommerce"],"acf":[],"year_month":"2026-04","word_count":1616,"total_views":"759","reactions":{"happy":"0","normal":"0","sad":"0"},"author_info":{"name":"Elliot Sowersby","author_nicename":"elliot","author_url":"https:\/\/relywp.com\/es\/author\/elliot\/"},"doc_category_info":[{"term_name":"Developers","term_url":"https:\/\/relywp.com\/es\/docs\/simple-points-rewards-woocommerce\/desarrolladores\/"}],"doc_tag_info":[],"knowledge_base_info":[{"term_name":"Simple Points and Rewards","term_url":"https:\/\/relywp.com\/es\/docs\/simple-points-rewards-woocommerce\/","term_slug":"simple-points-rewards-woocommerce"}],"knowledge_base_slug":["simple-points-rewards-woocommerce"],"_links":{"self":[{"href":"https:\/\/relywp.com\/es\/wp-json\/wp\/v2\/docs\/41835","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/relywp.com\/es\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/relywp.com\/es\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/relywp.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/relywp.com\/es\/wp-json\/wp\/v2\/comments?post=41835"}],"version-history":[{"count":15,"href":"https:\/\/relywp.com\/es\/wp-json\/wp\/v2\/docs\/41835\/revisions"}],"predecessor-version":[{"id":42372,"href":"https:\/\/relywp.com\/es\/wp-json\/wp\/v2\/docs\/41835\/revisions\/42372"}],"wp:attachment":[{"href":"https:\/\/relywp.com\/es\/wp-json\/wp\/v2\/media?parent=41835"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/relywp.com\/es\/wp-json\/wp\/v2\/doc_category?post=41835"},{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/relywp.com\/es\/wp-json\/wp\/v2\/doc_tag?post=41835"},{"taxonomy":"knowledge_base","embeddable":true,"href":"https:\/\/relywp.com\/es\/wp-json\/wp\/v2\/knowledge_base?post=41835"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}