Changeset 3351633
- Timestamp:
- 08/28/2025 03:10:21 AM (7 months ago)
- Location:
- metrepay/trunk
- Files:
-
- 2 edited
-
metrepay.php (modified) (12 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
metrepay/trunk/metrepay.php
r3299938 r3351633 4 4 Plugin URI: https://wordpress.org/plugins/metrepay 5 5 Description: Pasarela de pago para integracion con MetrePay y Woocomerce 6 Version: 1. 5.16 Version: 1.6.0 7 7 Author: Rugertek 8 8 Author URI: https://rugertek.com/ … … 96 96 $this->custom_id_1 = sanitize_text_field($this->get_option('custom_id_1')); 97 97 $this->custom_id_2 = 'yes' === sanitize_text_field($this->get_option('custom_id_2')); 98 $this->subscription_installments = intval($this->get_option('subscription_installments', 12)); 98 99 $this->header_token = $this->mpay_local_generate_string(); 99 100 … … 154 155 'title' => __('Débito automático', 'metrepay'), 155 156 'label' => __('Permitir pagos en cuotas por débitos automáticos', 'metrepay'), 156 'description' => __('Aplica cuando el carrito tiene solamente 1 producto con atributo "cuotas" y valor numérico en el mismo. Si se activa, los links de pago tienen login requerido.', 'metrepay'),157 'description' => __('Aplica cuando el carrito tiene solamente 1 producto con etiqueta de suscripción. Si se activa, los links de pago tienen login requerido.', 'metrepay'), 157 158 'type' => 'checkbox', 158 159 'default' => 'no' 160 ), 161 'subscription_installments' => array( 162 'title' => __('Cantidad de pagos para suscripciones', 'metrepay'), 163 'type' => 'number', 164 'description' => __('Número de pagos (cuotas) que se aplicarán para productos con etiqueta de suscripción en débito automático.', 'metrepay'), 165 'default' => '12', 166 'custom_attributes' => array( 167 'min' => '1', 168 'max' => '60' 169 ), 159 170 ), 160 171 'links_login_required' => array( … … 235 246 { 236 247 return $this->custom_id_2; 248 } 249 250 public function get_subscription_installments() 251 { 252 return $this->subscription_installments; 237 253 } 238 254 … … 334 350 335 351 try { 352 $this->logger->info('Sending payment request to MetrePay API', array_merge($this->context, array('order_id' => $order_id))); 336 353 $response = $this->mpay_local_data_post($data); 337 354 $result = json_decode($response, true); 338 355 339 error_log(json_encode($data)); 340 error_log(json_encode($result)); 356 $this->logger->info('Payment request successful', array_merge($this->context, array( 357 'order_id' => $order_id, 358 'payment_url' => isset($result['publicPayUrl']) ? $result['publicPayUrl'] : 'N/A' 359 ))); 341 360 342 361 // Delete the cookie … … 348 367 ); 349 368 } catch (\Throwable $th) { 369 $this->logger->error('Payment processing failed: ' . $th->getMessage(), array_merge($this->context, array('order_id' => $order_id))); 350 370 $this->mpay_local_show_error_to_user($th); 351 $this->logger-> log('error',__('Error al procesar el pago', 'metrepay'), $this->context);371 $this->logger->error(__('Error al procesar el pago', 'metrepay'), $this->context); 352 372 } 353 373 } … … 368 388 369 389 if (!isset(WC()->cart)) { 390 $this->logger->info('Cart not available, skipping subscription check', $this->context); 370 391 return; 371 392 } 372 393 373 394 $cart = WC()->cart->get_cart(); 374 // For RP just 1 item is allowed 395 $this->logger->info('Checking cart for subscription eligibility. Cart items count: ' . count($cart), $this->context); 396 397 // New conditions for automatic debit (subscription): 398 // 1. Cart has only 1 product 399 // 2. Product quantity is 1 400 // 3. Product can be any type (not just variable) 401 // 4. Product has a subscription tag 402 // 5. Automatic debit is enabled in settings 375 403 if (count($cart) == 1 && $this->get_active_recurrent_payment()) { 376 404 foreach ( $cart as $cart_item_key => $cart_item ) { 377 405 $product = $cart_item['data']; 378 $installments_quantity = $product->get_attribute('cuotas'); 379 if (isset($installments_quantity) 380 && is_numeric($installments_quantity)) { 381 $installments_quantity = intval($installments_quantity); 382 if ($installments_quantity > 0) { 383 $can_be_recurrent_payment = true; 384 } 385 } 406 $quantity = $cart_item['quantity']; 407 408 $this->logger->debug('Analyzing product: ID=' . $product->get_id() . ', Type=' . $product->get_type() . ', Quantity=' . $quantity, $this->context); 409 410 // Check if quantity is exactly 1 411 if ($quantity == 1) { 412 // Check if product has subscription tags 413 if ($this->has_subscription_tag($product)) { 414 $installments_quantity = $this->get_subscription_installments(); 415 $can_be_recurrent_payment = true; 416 $this->logger->debug('Product qualifies for subscription: installments=' . $installments_quantity, $this->context); 417 } else { 418 $this->logger->debug('Product does not have subscription tags', $this->context); 419 } 420 } else { 421 $this->logger->debug('Product quantity is not 1, cannot be subscription', $this->context); 422 } 386 423 } 387 } 388 389 error_log('can_be_recurrent_payment: ' . $can_be_recurrent_payment); 424 } else { 425 if (count($cart) != 1) { 426 $this->logger->debug('Cart has more than 1 item, cannot be subscription', $this->context); 427 } 428 if (!$this->get_active_recurrent_payment()) { 429 $this->logger->debug('Automatic debit is disabled in settings', $this->context); 430 } 431 } 432 433 $this->logger->debug('Final subscription check result: can_be_recurrent_payment=' . ($can_be_recurrent_payment ? 'true' : 'false'), $this->context); 434 390 435 if ($can_be_recurrent_payment) { 391 436 // We setup the cookie 392 437 $this->mpay_local_set_cookie('mp_installments_quantity', $installments_quantity); 393 438 $this->mpay_local_set_cookie('mp_payment_method', 'RECURRENT_PAYMENT'); 394 // Known warning -> PHP Warning: Cannot modify header information - headers already sent by blablabla 395 // Another file was outputting information before this php file. 439 $this->logger->debug('Set cookies for recurrent payment: installments=' . $installments_quantity, $this->context); 396 440 } else { 397 441 // The cart is only for "SINGLE PAYMENT" … … 399 443 $this->mpay_local_delete_cookie('mp_installments_quantity'); 400 444 $this->mpay_local_set_cookie('mp_payment_method', 'SINGLE_PAYMENT'); 445 $this->logger->debug('Set cookies for single payment', $this->context); 401 446 } 402 447 403 448 if (isset($_COOKIE['mp_installments_quantity'])) { 404 error_log('mp_installments_quantity: ' . sanitize_text_field($_COOKIE['mp_installments_quantity']));449 $this->logger->info('Final cookie mp_installments_quantity: ' . sanitize_text_field($_COOKIE['mp_installments_quantity']), $this->context); 405 450 } else { 406 error_log('mp_installments_quantity: NULL'); 407 } 451 $this->logger->info('Final cookie mp_installments_quantity: NULL', $this->context); 452 } 453 } 454 455 /** 456 * Check if a product has subscription tags 457 * Looks for tags like: suscripción, suscripcion, subscription, etc. 458 */ 459 private function has_subscription_tag($product) 460 { 461 $product_id = $product->get_id(); 462 $tags = wp_get_post_terms($product_id, 'product_tag'); 463 464 if (is_wp_error($tags) || empty($tags)) { 465 $this->logger->debug('Product ID ' . $product_id . ' has no tags', $this->context); 466 return false; 467 } 468 469 // Palabras clave "base", sin duplicar mayúsculas ni tildes 470 $subscription_keywords = array('suscripcion', 'subscription'); 471 472 // Función helper para normalizar strings (case + quitar tildes) 473 $normalize = function($string) { 474 $string = mb_strtolower($string, 'UTF-8'); 475 $unwanted = array('á'=>'a','é'=>'e','í'=>'i','ó'=>'o','ú'=>'u','ü'=>'u','ñ'=>'n'); 476 return strtr($string, $unwanted); 477 }; 478 479 foreach ($tags as $tag) { 480 $tag_name = $normalize($tag->name); 481 $this->logger->debug('Checking tag: ' . $tag->name, $this->context); 482 483 foreach ($subscription_keywords as $keyword) { 484 if (strpos($tag_name, $keyword) !== false) { 485 $this->logger->debug( 486 'Found subscription tag: ' . $tag->name . ' (matched keyword: ' . $keyword . ')', 487 $this->context 488 ); 489 return true; 490 } 491 } 492 } 493 494 $this->logger->debug('No subscription tags found for product ID ' . $product_id, $this->context); 495 return false; 408 496 } 409 497 … … 453 541 function mpay_local_data_post($data) { 454 542 $url = $this->mpay_local_get_mp_url(); 455 error_log(json_encode($url)); 456 error_log('MP API REQ BODY: ' . json_encode($data)); 543 544 // Obtenemos el token y mostramos solo los primeros 6 caracteres 545 $authToken = $this->get_auth_token(); 546 $authTokenPreview = substr($authToken, 0, 6) . '...'; 547 548 // Log de depuración 549 $request_log = array( 550 'url' => $url, 551 'headers' => array( 552 'Api-Token' => $authTokenPreview, // no mostramos todo 553 'Content-Type' => 'application/json', 554 ), 555 'body' => $data, // payload completo 556 ); 557 558 $this->logger->info('MP API request', array_merge($this->context, $request_log)); 457 559 458 560 $args = array( … … 464 566 'headers' => array( 465 567 'Content-Type' => 'application/json', 466 'Api-Token' => $ this->get_auth_token()568 'Api-Token' => $authToken 467 569 ), 468 570 ); 571 469 572 $response = wp_remote_post($url, $args); 470 573 471 574 if (is_wp_error($response)) { 472 error_log('Error: ' . $response->get_error_message());575 $this->logger->error('WP Error: ' . $response->get_error_message(), $this->context); 473 576 throw new Exception(__("Error procesando petición a MetrePay", 'metrepay'), 1); 474 577 } 475 578 476 // Verifica el código de estado de la respuesta477 579 $http_code = wp_remote_retrieve_response_code($response); 478 580 … … 480 582 $error_msg = "HTTP Error Code: $http_code - Error message from server: " 481 583 . wp_remote_retrieve_body($response); 482 error_log($error_msg); 483 $this->logger->log('error', $error_msg, $this->context); 584 $this->logger->error($error_msg, $this->context); 484 585 throw new Exception(__("Petición HTTP falló con código ", 'metrepay') . $http_code, $http_code); 485 586 } … … 487 588 return wp_remote_retrieve_body($response); 488 589 } 590 489 591 490 592 function mpay_local_set_cookie($name, $value) { -
metrepay/trunk/readme.txt
r3299938 r3351633 3 3 Tags: metrepay, payment 4 4 Requires at least: 5.3 5 Tested up to: 6.8. 16 Stable tag: 1. 5.15 Tested up to: 6.8.2 6 Stable tag: 1.6.0 7 7 Requires PHP: 7.3.5 8 8 License: GPLv3 … … 60 60 * Fixed the amount value formatting: it now includes decimal places when needed (e.g. 10.01), and uses integers when the value is whole (e.g. 10). 61 61 * Removed the "provider slug" setting field, as it's no longer required for commerce configuration. 62 63 = 1.6.0 = 64 * Updated automatic debit detection to use product tags instead of "cuotas" attribute. 65 * Improved subscription detection based on tags like "suscripción", "subscription", etc. 66 * Added configurable subscription installments setting (default: 12 payments). 67 * Automatic debits now support any product type, not just variable products. 68 * Enhanced logging system with WooCommerce logger.
Note: See TracChangeset
for help on using the changeset viewer.