Antes del acomodo de contenedores para los tabs

This commit is contained in:
DANYDHSV 2026-02-12 12:17:11 -06:00
parent aa42284cc5
commit bd313fdfa4
3 changed files with 803 additions and 38 deletions

View File

@ -1 +1,35 @@
{"ipserver":"venus.siip.mx","apitoken":"gvcnIJqXdUjneVSjhl6THLlQcYXJyIFCcwHKVba2bvIrNraanCTb5VeoWuJ0TFZ9","unmsApiToken":"079c28f5-888c-457d-bd7a-0a4202590f75","tokencallbell":"g8thcZkXGd3xBj2g3TtYNYFMH1fuesbJ.b6a940ea7d78cf6c9e42f067b21c8ddf96e9fa2a9e307bfd0c7c7c4d7fa38f79","tokenstripe":"sk_test_51OkG0REFY1WEUtgRH6UxBK5pu80Aq5Iy8EcdPnf0cOWzuVLQTpyLCd7CbPzqMsWMafZOHElCxhEHF7g8boURjWlJ00tBwE0W1M","hostServerFTP":"siip.mx","usernameServerFTP":"siip0001","passServerFTP":"$spGiT,[wa)n","ipPuppeteer":"172.16.5.134","portPuppeteer":"4100","idPaymentAdminCRM":"1180","cashPaymentMethodId":true,"courtesyPaymentMethodId":true,"bankTransferPaymentMethodId":true,"paypalPaymentMethodId":true,"creditCardPaypalPaymentMethodId":true,"creditCardStripePaymentMethodId":true,"stripeSubscriptionCreditCardPaymentMethodId":true,"paypalSubscriptionPaymentMethodId":true,"mercadopagoPaymentMethodId":true,"checkPaymentMethodId":true,"customPaymentMethodId":true,"oxxoPayPaymentMethodId":true,"creditDebitCardPaymentMethodId":true,"notificationTypeText":false,"installersDataWhatsApp":"{\r\n \"instaladores\": [\r\n {\r\n \"id\": 1019,\r\n \"nombre\": \"Mucio Robledo\",\r\n \"whatsapp\": \"4181878106\"\r\n },\r\n {\r\n \"id\": 1173,\r\n \"nombre\": \"Ángel Arvizu\",\r\n \"whatsapp\": \"4181878106\"\r\n },\r\n {\r\n \"id\": 1172,\r\n \"nombre\": \"Juan Rostro\",\r\n \"whatsapp\": \"4181878106\"\r\n },\r\n {\r\n \"id\": 1015,\r\n \"nombre\": \"Daniel Humberto\",\r\n \"whatsapp\": \"4181878106\"\r\n },\r\n {\r\n \"id\": 1131,\r\n \"nombre\": \"Gricelda Avalos\",\r\n \"whatsapp\": \"4181817609\"\r\n }\r\n ]\r\n}","debugMode":true,"minioEndpoint":"http://172.16.5.134:9002","minioPublicUrl":"https://aws-venus.siip.mx","minioAccessKey":"minioadmin","minioSecretKey":"minioadmin","minioBucket":"vouchers-oxxo","logging_level":true} {
"ipserver": "venus.siip.mx",
"apitoken": "gvcnIJqXdUjneVSjhl6THLlQcYXJyIFCcwHKVba2bvIrNraanCTb5VeoWuJ0TFZ9",
"unmsApiToken": "079c28f5-888c-457d-bd7a-0a4202590f75",
"tokencallbell": "g8thcZkXGd3xBj2g3TtYNYFMH1fuesbJ.b6a940ea7d78cf6c9e42f067b21c8ddf96e9fa2a9e307bfd0c7c7c4d7fa38f79",
"tokenstripe": "sk_test_51OkG0REFY1WEUtgRH6UxBK5pu80Aq5Iy8EcdPnf0cOWzuVLQTpyLCd7CbPzqMsWMafZOHElCxhEHF7g8boURjWlJ00tBwE0W1M",
"hostServerFTP": "siip.mx",
"usernameServerFTP": "siip0001",
"passServerFTP": "$spGiT,[wa)n",
"ipPuppeteer": "172.16.5.134",
"portPuppeteer": "4100",
"idPaymentAdminCRM": "1180",
"cashPaymentMethodId": true,
"courtesyPaymentMethodId": true,
"bankTransferPaymentMethodId": true,
"paypalPaymentMethodId": true,
"creditCardPaypalPaymentMethodId": true,
"creditCardStripePaymentMethodId": true,
"stripeSubscriptionCreditCardPaymentMethodId": true,
"paypalSubscriptionPaymentMethodId": true,
"mercadopagoPaymentMethodId": true,
"checkPaymentMethodId": true,
"customPaymentMethodId": true,
"oxxoPayPaymentMethodId": true,
"creditDebitCardPaymentMethodId": true,
"notificationTypeText": false,
"installersDataWhatsApp": "{\"instaladores\":[{\"id\":1019,\"nombre\":\"Mucio Robledo\",\"whatsapp\":\"4181878106\"},{\"id\":1173,\"nombre\":\"Ángel Arvizu\",\"whatsapp\":\"4181878106\"},{\"id\":1172,\"nombre\":\"Juan Rostro\",\"whatsapp\":\"4181878106\"},{\"id\":1015,\"nombre\":\"Daniel Humberto\",\"whatsapp\":\"4181878106\"},{\"id\":1131,\"nombre\":\"Gricelda Avalos\",\"whatsapp\":\"4181817609\"}]}",
"debugMode": true,
"minioEndpoint": "http:\/\/172.16.5.134:9002",
"minioPublicUrl": "https:\/\/aws-venus.siip.mx",
"minioAccessKey": "minioadmin",
"minioSecretKey": "minioadmin",
"minioBucket": "vouchers-oxxo",
"logging_level": true
}

View File

@ -6466,3 +6466,450 @@ Response Patch CallBell: {"contact":{"uuid":"74cc2bb45eb8409f92cd5dba99200d26","
[2026-02-12 14:09:34.552617] [debug] Payload recibido: {"uuid":"3aa571f2-735c-415e-b930-65384c44b2fd","changeType":"edit","entity":"payment","entityId":"959","eventName":"payment.edit","extraData":{"entity":{"id":959,"clientId":135,"methodId":"1dd098fa-5d63-4c8d-88b7-3c27ffbbb6ae","checkNumber":null,"createdDate":"2026-02-12T08:09:28-0600","amount":200,"currencyCode":"MXN","note":null,"receiptSentDate":null,"providerName":null,"providerPaymentId":null,"providerPaymentTime":null,"paymentCovers":[],"creditAmount":200,"userId":1180,"attributes":[]},"entityBeforeEdit":{"id":959,"clientId":135,"methodId":"1dd098fa-5d63-4c8d-88b7-3c27ffbbb6ae","checkNumber":null,"createdDate":"2026-02-12T08:09:28-0600","amount":200,"currencyCode":"MXN","note":null,"receiptSentDate":null,"providerName":null,"providerPaymentId":null,"providerPaymentTime":null,"paymentCovers":[],"creditAmount":200,"userId":null,"attributes":[]}}} [2026-02-12 14:09:34.552617] [debug] Payload recibido: {"uuid":"3aa571f2-735c-415e-b930-65384c44b2fd","changeType":"edit","entity":"payment","entityId":"959","eventName":"payment.edit","extraData":{"entity":{"id":959,"clientId":135,"methodId":"1dd098fa-5d63-4c8d-88b7-3c27ffbbb6ae","checkNumber":null,"createdDate":"2026-02-12T08:09:28-0600","amount":200,"currencyCode":"MXN","note":null,"receiptSentDate":null,"providerName":null,"providerPaymentId":null,"providerPaymentTime":null,"paymentCovers":[],"creditAmount":200,"userId":1180,"attributes":[]},"entityBeforeEdit":{"id":959,"clientId":135,"methodId":"1dd098fa-5d63-4c8d-88b7-3c27ffbbb6ae","checkNumber":null,"createdDate":"2026-02-12T08:09:28-0600","amount":200,"currencyCode":"MXN","note":null,"receiptSentDate":null,"providerName":null,"providerPaymentId":null,"providerPaymentTime":null,"paymentCovers":[],"creditAmount":200,"userId":null,"attributes":[]}}}
[2026-02-12 14:09:34.765480] [debug] Evento recibido: payment.edit [2026-02-12 14:09:34.765480] [debug] Evento recibido: payment.edit
[2026-02-12 17:47:39.723829] [notice] Logging level set to:debug
[2026-02-12 17:47:39.724526] [debug] Payload recibido: {
"id": "evt_3T03zLEFY1WEUtgR0arRMtpq",
"object": "event",
"api_version": "2023-10-16",
"created": 1770918459,
"data": {
"object": {
"id": "pi_3T03zLEFY1WEUtgR0DHILSoP",
"object": "payment_intent",
"amount": 13000,
"amount_capturable": 0,
"amount_details": {
"tip": {}
},
"amount_received": 0,
"application": null,
"application_fee_amount": null,
"automatic_payment_methods": null,
"canceled_at": null,
"cancellation_reason": null,
"capture_method": "automatic",
"client_secret": "pi_3T03zLEFY1WEUtgR0DHILSoP_secret_zc3za7fdg1RofUMWuubxmI5ui",
"confirmation_method": "automatic",
"created": 1770918459,
"currency": "mxn",
"customer": "cus_QJk0PDx5ClqJ4w",
"customer_account": null,
"description": null,
"excluded_payment_method_types": null,
"invoice": null,
"last_payment_error": null,
"latest_charge": null,
"livemode": false,
"metadata": {
"signedInAdminId": "1180",
"createdBy": "UCRM",
"ucrm_client_id": "135",
"clientId": "135",
"paymentType": "card.one_time",
"tipoPago": "OXXO"
},
"next_action": null,
"on_behalf_of": null,
"payment_method": null,
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"installments": null,
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
},
"customer_balance": {
"funding_type": null
},
"oxxo": {
"expires_after_days": 3
}
},
"payment_method_types": [
"customer_balance",
"card",
"oxxo"
],
"processing": null,
"receipt_email": null,
"review": null,
"setup_future_usage": null,
"shipping": null,
"source": null,
"statement_descriptor": null,
"statement_descriptor_suffix": null,
"status": "requires_payment_method",
"transfer_data": null,
"transfer_group": null
}
},
"livemode": false,
"pending_webhooks": 2,
"request": {
"id": "req_GEfu6plAXDWnJJ",
"idempotency_key": "a5b26454-36fa-4969-a480-004a230b20cb"
},
"type": "payment_intent.created"
}
[2026-02-12 17:47:39.724617] [info] No UUID found in the webhook data
[2026-02-12 17:47:40.399321] [notice] Logging level set to:debug
[2026-02-12 17:47:40.399910] [debug] Payload recibido: {
"id": "evt_3T03zLEFY1WEUtgR0C83Nzrq",
"object": "event",
"api_version": "2023-10-16",
"created": 1770918459,
"data": {
"object": {
"id": "pi_3T03zLEFY1WEUtgR0DHILSoP",
"object": "payment_intent",
"amount": 13000,
"amount_capturable": 0,
"amount_details": {
"tip": {}
},
"amount_received": 0,
"application": null,
"application_fee_amount": null,
"automatic_payment_methods": null,
"canceled_at": null,
"cancellation_reason": null,
"capture_method": "automatic",
"client_secret": "pi_3T03zLEFY1WEUtgR0DHILSoP_secret_zc3za7fdg1RofUMWuubxmI5ui",
"confirmation_method": "automatic",
"created": 1770918459,
"currency": "mxn",
"customer": "cus_QJk0PDx5ClqJ4w",
"customer_account": null,
"description": null,
"excluded_payment_method_types": null,
"invoice": null,
"last_payment_error": null,
"latest_charge": null,
"livemode": false,
"metadata": {
"signedInAdminId": "1180",
"createdBy": "UCRM",
"ucrm_client_id": "135",
"clientId": "135",
"paymentType": "card.one_time",
"tipoPago": "OXXO"
},
"next_action": {
"oxxo_display_details": {
"expires_after": 1771221599,
"hosted_voucher_url": "https://payments.stripe.com/oxxo/voucher/test_YWNjdF8xT2tHMFJFRlkxV0VVdGdSLF9UeHp6ckVndVgzV29Sd0JEbXU0VjFWUGtNMkpoZlls010014pmxDgd",
"number": "12345678901234657890123456789012"
},
"type": "oxxo_display_details"
},
"on_behalf_of": null,
"payment_method": "pm_1T03zLEFY1WEUtgRwuM12UMQ",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"installments": null,
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
},
"customer_balance": {
"funding_type": null
},
"oxxo": {
"expires_after_days": 3
}
},
"payment_method_types": [
"customer_balance",
"card",
"oxxo"
],
"processing": null,
"receipt_email": null,
"review": null,
"setup_future_usage": null,
"shipping": null,
"source": null,
"statement_descriptor": null,
"statement_descriptor_suffix": null,
"status": "requires_action",
"transfer_data": null,
"transfer_group": null
}
},
"livemode": false,
"pending_webhooks": 2,
"request": {
"id": "req_MMq7YzMfxtDQJi",
"idempotency_key": "23ed3241-e643-409d-8854-1db6dc541924"
},
"type": "payment_intent.requires_action"
}
[2026-02-12 17:47:40.400048] [info] No UUID found in the webhook data
[2026-02-12 17:50:46.490076] [notice] Logging level set to:debug
[2026-02-12 17:50:46.490170] [debug] Payload recibido: {
"id": "evt_3T03zLEFY1WEUtgR0ivaPX4X",
"object": "event",
"api_version": "2023-10-16",
"created": 1770918645,
"data": {
"object": {
"id": "pi_3T03zLEFY1WEUtgR0DHILSoP",
"object": "payment_intent",
"amount": 13000,
"amount_capturable": 0,
"amount_details": {
"tip": {}
},
"amount_received": 13000,
"application": null,
"application_fee_amount": null,
"automatic_payment_methods": null,
"canceled_at": null,
"cancellation_reason": null,
"capture_method": "automatic",
"client_secret": "pi_3T03zLEFY1WEUtgR0DHILSoP_secret_zc3za7fdg1RofUMWuubxmI5ui",
"confirmation_method": "automatic",
"created": 1770918459,
"currency": "mxn",
"customer": "cus_QJk0PDx5ClqJ4w",
"customer_account": null,
"description": null,
"excluded_payment_method_types": null,
"invoice": null,
"last_payment_error": null,
"latest_charge": "py_3T03zLEFY1WEUtgR0673liwP",
"livemode": false,
"metadata": {
"signedInAdminId": "1180",
"createdBy": "UCRM",
"ucrm_client_id": "135",
"clientId": "135",
"paymentType": "card.one_time",
"tipoPago": "OXXO"
},
"next_action": null,
"on_behalf_of": null,
"payment_method": "pm_1T03zLEFY1WEUtgRwuM12UMQ",
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"installments": null,
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
},
"customer_balance": {
"funding_type": null
},
"oxxo": {
"expires_after_days": 3
}
},
"payment_method_types": [
"customer_balance",
"card",
"oxxo"
],
"processing": null,
"receipt_email": null,
"review": null,
"setup_future_usage": null,
"shipping": null,
"source": null,
"statement_descriptor": null,
"statement_descriptor_suffix": null,
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
}
},
"livemode": false,
"pending_webhooks": 2,
"request": {
"id": null,
"idempotency_key": null
},
"type": "payment_intent.succeeded"
}
[2026-02-12 17:50:46.490228] [info] No UUID found in the webhook data
[2026-02-12 17:50:46.490241] [info] Evento de pago exitoso (Stripe PI) recibido.
[2026-02-12 17:50:46.497361] [notice] Logging level set to:debug
[2026-02-12 17:50:46.497544] [debug] Payload recibido: {
"id": "evt_3T03zLEFY1WEUtgR0JRawKR4",
"object": "event",
"api_version": "2023-10-16",
"created": 1770918646,
"data": {
"object": {
"id": "py_3T03zLEFY1WEUtgR0673liwP",
"object": "charge",
"amount": 13000,
"amount_captured": 13000,
"amount_refunded": 0,
"application": null,
"application_fee": null,
"application_fee_amount": null,
"balance_transaction": "txn_3T03zLEFY1WEUtgR0z6Fxn0w",
"billing_details": {
"address": {
"city": null,
"country": null,
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": "juanvaliente@gmail.com",
"name": "Juan Escutia",
"phone": null,
"tax_id": null
},
"calculated_statement_descriptor": null,
"captured": true,
"created": 1770918645,
"currency": "mxn",
"customer": "cus_QJk0PDx5ClqJ4w",
"description": null,
"destination": null,
"dispute": null,
"disputed": false,
"failure_balance_transaction": null,
"failure_code": null,
"failure_message": null,
"fraud_details": {},
"invoice": null,
"livemode": false,
"metadata": {
"signedInAdminId": "1180",
"createdBy": "UCRM",
"ucrm_client_id": "135",
"clientId": "135",
"paymentType": "card.one_time",
"tipoPago": "OXXO"
},
"on_behalf_of": null,
"order": null,
"outcome": {
"advice_code": null,
"network_advice_code": null,
"network_decline_code": null,
"network_status": "approved_by_network",
"reason": null,
"risk_level": "not_assessed",
"seller_message": "Payment complete.",
"type": "authorized"
},
"paid": true,
"payment_intent": "pi_3T03zLEFY1WEUtgR0DHILSoP",
"payment_method": "pm_1T03zLEFY1WEUtgRwuM12UMQ",
"payment_method_details": {
"oxxo": {
"number": "12345678901234657890123456789012"
},
"type": "oxxo"
},
"radar_options": {},
"receipt_email": null,
"receipt_number": null,
"receipt_url": "https://pay.stripe.com/receipts/payment/CAcaFwoVYWNjdF8xT2tHMFJFRlkxV0VVdGdSKPaluMwGMgb932C7DTc6LBYyWCPvYwrg0nMtcZ5C7oxVkuk_3cPDYs067ts0z5YifovbNf_WY2hX9kqV",
"refunded": false,
"review": null,
"shipping": null,
"source": null,
"source_transfer": null,
"statement_descriptor": null,
"statement_descriptor_suffix": null,
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
}
},
"livemode": false,
"pending_webhooks": 2,
"request": {
"id": null,
"idempotency_key": null
},
"type": "charge.succeeded"
}
[2026-02-12 17:50:46.498635] [info] No UUID found in the webhook data
[2026-02-12 17:50:47.882810] [notice] Logging level set to:debug
[2026-02-12 17:50:47.883034] [debug] Payload recibido: {"uuid":"937b465f-b827-4d21-9fdb-07ca7ab5502c","changeType":"insert","entity":"payment","entityId":"960","eventName":"payment.add","extraData":{"entity":{"id":960,"clientId":135,"methodId":"1dd098fa-5d63-4c8d-88b7-3c27ffbbb6ae","checkNumber":null,"createdDate":"2026-02-12T11:50:47-0600","amount":130,"currencyCode":"MXN","note":null,"receiptSentDate":null,"providerName":null,"providerPaymentId":null,"providerPaymentTime":null,"paymentCovers":[],"creditAmount":130,"userId":null,"attributes":[]},"entityBeforeEdit":null}}
[2026-02-12 17:50:48.101706] [debug] Evento recibido: payment.add
[2026-02-12 17:50:48.101851] [debug] Notification encodificado en JSON:{"uuid":"937b465f-b827-4d21-9fdb-07ca7ab5502c","changeType":"insert","entity":"payment","entityId":960,"message":null,"clientId":135,"eventName":"payment.add","clientData":{"id":135,"userIdent":null,"previousIsp":null,"isLead":false,"clientType":1,"companyName":null,"companyRegistrationNumber":null,"companyTaxId":null,"companyWebsite":null,"street1":"13 Calle San Antonio","street2":null,"city":"Dolores Hidalgo Cuna de la Independencia Nacional","countryId":173,"stateId":null,"zipCode":"37806","fullAddress":"Calle San Antonio 13, Lindavista, Dolores Hidalgo Cuna de la Independencia Nacional, Gto., M\u00e9xico","invoiceStreet1":null,"invoiceStreet2":null,"invoiceCity":null,"invoiceStateId":null,"invoiceCountryId":null,"invoiceZipCode":null,"invoiceAddressSameAsContact":true,"note":null,"sendInvoiceByPost":null,"invoiceMaturityDays":null,"stopServiceDue":null,"stopServiceDueDays":null,"organizationId":1,"tax1Id":null,"tax2Id":null,"tax3Id":null,"registrationDate":"2024-06-18T00:00:00-0600","leadConvertedAt":null,"companyContactFirstName":null,"companyContactLastName":null,"isActive":false,"firstName":"Juan","lastName":"Escutia","username":null,"contacts":[{"id":139,"clientId":135,"email":"juanvaliente@gmail.com","phone":"4181878106","name":null,"isBilling":false,"isContact":false,"types":[{"id":1000,"name":"WhatsApp"}]}],"attributes":[{"id":137,"clientId":135,"customAttributeId":10,"name":"Stripe Customer ID","key":"stripeCustomerId","value":"cus_QJk0PDx5ClqJ4w","clientZoneVisible":true},{"id":138,"clientId":135,"customAttributeId":11,"name":"Clabe Interbancaria","key":"clabeInterbancaria","value":"002180674088308545","clientZoneVisible":true},{"id":222,"clientId":135,"customAttributeId":17,"name":"Password Antena Cliente","key":"passwordAntenaCliente","value":"gYAIEK:Be}SK*01z5+\/V","clientZoneVisible":false},{"id":310,"clientId":135,"customAttributeId":15,"name":"Site","key":"site","value":"El Lindero","clientZoneVisible":false},{"id":311,"clientId":135,"customAttributeId":16,"name":"Antena\/Sectorial","key":"antenaSectorial","value":"San Vicente","clientZoneVisible":false},{"id":312,"clientId":135,"customAttributeId":22,"name":"ip","key":"ip","value":"172.16.86.64","clientZoneVisible":false},{"id":313,"clientId":135,"customAttributeId":24,"name":"adminpass","key":"adminpass","value":"admin1390","clientZoneVisible":true},{"id":314,"clientId":135,"customAttributeId":29,"name":"instalador","key":"instalador","value":"Chanclas","clientZoneVisible":true}],"accountBalance":10110,"accountCredit":10110,"accountOutstanding":0,"currencyCode":"MXN","organizationName":"SIIP Pruebas","bankAccounts":[],"tags":[{"id":12,"name":"PAGO ELI","colorBackground":"#0050a1","colorText":"#fff"}],"invitationEmailSentDate":null,"avatarColor":"#f9a825","addressGpsLat":21.1468281,"addressGpsLon":-100.9577464,"isArchived":false,"generateProformaInvoices":null,"usesProforma":false,"hasOverdueInvoice":false,"hasOutage":false,"hasSuspendedService":false,"hasServiceWithoutDevices":true,"referral":null,"hasPaymentSubscription":false,"hasAutopayCreditCard":false},"serviceData":null,"invoiceData":null,"paymentData":{"id":960,"clientId":135,"methodId":"1dd098fa-5d63-4c8d-88b7-3c27ffbbb6ae","checkNumber":null,"createdDate":"2026-02-12T11:50:47-0600","amount":130,"currencyCode":"MXN","note":null,"receiptSentDate":null,"providerName":null,"providerPaymentId":null,"providerPaymentTime":null,"paymentCovers":[],"creditAmount":130,"userId":null,"attributes":[]}}
[2026-02-12 17:50:48.102773] [info] Verificando existencia de atributo 'tipoPagoStripe' para Payment ID: 960
[2026-02-12 17:50:48.123004] [info] Microservice found metadata: tipoPago = 'OXXO'
[2026-02-12 17:50:48.204173] [info] Payment 960 has no User ID. Assigning Stripe User ID: 1180
[2026-02-12 17:50:48.284580] [info] Payment 960 has wrong Method ID (1dd098fa-5d63-4c8d-88b7-3c27ffbbb6ae). Patching to b01c0b35-b42c-48d9-9ad9-ea6591adfbbb via Microservice.
[2026-02-12 17:50:49.299741] [info] Payment Method ID patched successfully.
[2026-02-12 17:50:49.401597] [info] PATCHING Payment 960: Setting tipoPagoStripe = 'OXXO Pay'
Eviando comprobante de pago al cliente: 135 con número: 524181878106
El archivo PDF se ha descargado y guardado correctamente en: /data/ucrm/data/plugins/siip-whatsapp-notifications/src/Facade/../../comprobantes/Comprobante_Juan_Escutia.pdf
El archivo PDF es válido y tiene contenido: /data/ucrm/data/plugins/siip-whatsapp-notifications/src/Facade/../../comprobantes/Comprobante_Juan_Escutia.pdf
Procesando PDF con microservicio: http://172.16.5.134:8050/process
Imagen generada por microservicio guardada en: /data/ucrm/data/plugins/siip-whatsapp-notifications/src/Facade/../../comprobantes/Comprobante_Juan_Escutia.jpg
[2026-02-12 17:50:51.892160] [info] Archivo subido exitosamente a MinIO: https://aws-venus.siip.mx/vouchers-oxxo/Comprobante_Juan_Escutia_1770918651.jpg
Imagen subida a MinIO: https://aws-venus.siip.mx/vouchers-oxxo/Comprobante_Juan_Escutia_1770918651.jpg
Archivos temporales (PDF/JPG) eliminados tras subida exitosa.
Proceso de obtención de imagen finalizado.
La cadena CURL que se envia es: {
"to": "524181878106",
"from": "whatsapp",
"type": "document",
"content": {
"text": "S/M",
"url": "https://aws-venus.siip.mx/vouchers-oxxo/Comprobante_Juan_Escutia_1770918651.jpg"
},
"template_values": ["Juan Escutia", "$130", "$10110 a favor"],
"template_uuid": "57ead79cebd14902921477922403093b",
"optin_contact": true
}
Response del CallBell: {"message":{"uuid":"af87e517f9974775acb50ace754533da","status":"enqueued"}}
Hay menos de 100 archivos en el directorio. No se eliminarán archivos.
La notificación fue enviada correctamente con estado: enqueued
Notificacion data: {"uuid":"937b465f-b827-4d21-9fdb-07ca7ab5502c","changeType":"insert","entity":"payment","entityId":960,"message":null,"clientId":135,"eventName":"payment.add","clientData":{"id":135,"userIdent":null,"previousIsp":null,"isLead":false,"clientType":1,"companyName":null,"companyRegistrationNumber":null,"companyTaxId":null,"companyWebsite":null,"street1":"13 Calle San Antonio","street2":null,"city":"Dolores Hidalgo Cuna de la Independencia Nacional","countryId":173,"stateId":null,"zipCode":"37806","fullAddress":"Calle San Antonio 13, Lindavista, Dolores Hidalgo Cuna de la Independencia Nacional, Gto., M\u00e9xico","invoiceStreet1":null,"invoiceStreet2":null,"invoiceCity":null,"invoiceStateId":null,"invoiceCountryId":null,"invoiceZipCode":null,"invoiceAddressSameAsContact":true,"note":null,"sendInvoiceByPost":null,"invoiceMaturityDays":null,"stopServiceDue":null,"stopServiceDueDays":null,"organizationId":1,"tax1Id":null,"tax2Id":null,"tax3Id":null,"registrationDate":"2024-06-18T00:00:00-0600","leadConvertedAt":null,"companyContactFirstName":null,"companyContactLastName":null,"isActive":false,"firstName":"Juan","lastName":"Escutia","username":null,"contacts":[{"id":139,"clientId":135,"email":"juanvaliente@gmail.com","phone":"4181878106","name":null,"isBilling":false,"isContact":false,"types":[{"id":1000,"name":"WhatsApp"}]}],"attributes":[{"id":137,"clientId":135,"customAttributeId":10,"name":"Stripe Customer ID","key":"stripeCustomerId","value":"cus_QJk0PDx5ClqJ4w","clientZoneVisible":true},{"id":138,"clientId":135,"customAttributeId":11,"name":"Clabe Interbancaria","key":"clabeInterbancaria","value":"002180674088308545","clientZoneVisible":true},{"id":222,"clientId":135,"customAttributeId":17,"name":"Password Antena Cliente","key":"passwordAntenaCliente","value":"gYAIEK:Be}SK*01z5+\/V","clientZoneVisible":false},{"id":310,"clientId":135,"customAttributeId":15,"name":"Site","key":"site","value":"El Lindero","clientZoneVisible":false},{"id":311,"clientId":135,"customAttributeId":16,"name":"Antena\/Sectorial","key":"antenaSectorial","value":"San Vicente","clientZoneVisible":false},{"id":312,"clientId":135,"customAttributeId":22,"name":"ip","key":"ip","value":"172.16.86.64","clientZoneVisible":false},{"id":313,"clientId":135,"customAttributeId":24,"name":"adminpass","key":"adminpass","value":"admin1390","clientZoneVisible":true},{"id":314,"clientId":135,"customAttributeId":29,"name":"instalador","key":"instalador","value":"Chanclas","clientZoneVisible":true}],"accountBalance":10110,"accountCredit":10110,"accountOutstanding":0,"currencyCode":"MXN","organizationName":"SIIP Pruebas","bankAccounts":[],"tags":[{"id":12,"name":"PAGO ELI","colorBackground":"#0050a1","colorText":"#fff"}],"invitationEmailSentDate":null,"avatarColor":"#f9a825","addressGpsLat":21.1468281,"addressGpsLon":-100.9577464,"isArchived":false,"generateProformaInvoices":null,"usesProforma":false,"hasOverdueInvoice":false,"hasOutage":false,"hasSuspendedService":false,"hasServiceWithoutDevices":true,"referral":null,"hasPaymentSubscription":false,"hasAutopayCreditCard":false},"serviceData":null,"invoiceData":null,"paymentData":{"id":960,"clientId":135,"methodId":"b01c0b35-b42c-48d9-9ad9-ea6591adfbbb","checkNumber":null,"createdDate":"2026-02-12T11:50:47-0600","amount":130,"currencyCode":"MXN","note":null,"receiptSentDate":null,"providerName":null,"providerPaymentId":null,"providerPaymentTime":null,"paymentCovers":[],"creditAmount":130,"userId":null,"attributes":[]}}
Dentro del proceso del patch:
Datos traidos con payment api: [{"id":960,"clientId":135,"methodId":"b01c0b35-b42c-48d9-9ad9-ea6591adfbbb","checkNumber":null,"createdDate":"2026-02-12T11:50:47-0600","amount":130,"currencyCode":"MXN","note":null,"receiptSentDate":null,"providerName":null,"providerPaymentId":null,"providerPaymentTime":null,"paymentCovers":[],"creditAmount":130,"userId":1180,"attributes":[{"id":"a16c0d85-18e3-4874-951c-27181c70181e","paymentId":960,"customAttributeId":20,"name":"Tipo Pago Stripe","key":"tipoPagoStripe","value":"OXXO Pay","clientZoneVisible":true}]}]
Nombre del cliente que se va a actualizar: Juan Escutia
UUID: 74cc2bb45eb8409f92cd5dba99200d26
JSON con los datos a actualizar: {"name":"Juan Escutia","custom_fields":{"Site":"El Lindero","Estado":"\ud83d\udfe2 Activo ","URL":"\ud83c\udf10 https:\/\/sistema.siip.mx\/crm\/client\/135","Nombre":"\ud83d\udc64 Juan Escutia","Cliente":135,"Fecha Ultima Actualizacion":"\ud83d\udcc6\ud83d\udd04\ufe0f 12\/02\/2026 11:50","Saldo Actual":"\ud83d\udcb210110 a favor","Monto Ultimo Pago":"\ud83d\udcb2 130","Clabe Interbancaria":null,"Fecha Ultimo Pago":"\ud83d\udcc6\ud83d\udcb8 12\/02\/2026 11:50 con Desconocido, revisar metodos de pago no contemplados","Antena\/Sectorial":"San Vicente","Domicilio":"\ud83d\udccd Calle San Antonio 13, Lindavista, Dolores Hidalgo Cuna de la Independencia Nacional, Gto., M\u00e9xico","Resumen":"{\"Cliente\": \"135\",\"Nombre\": \"Juan Escutia\",\"URL\": \"https:\/\/sistema.siip.mx\/crm\/client\/135\",\"Saldo Actual\": \"\ud83d\udcb210110 a favor\",\"Monto Ultimo Pago\": \"$ 130\",\"Estado\": \"Activo\",\"Fecha Ultimo Pago\": \" 12\/02\/2026 11:50 con Desconocido, revisar metodos de pago no contemplados\",\"Fecha Ultima Actualizacion\": \"12\/02\/2026 11:50\",\"Clabe Interbancaria\": \"\",\"Site\": \"El Lindero\",\"Antena\/Sectorial\": \"San Vicente\",\"Password Antena\": {\"Servicio 1\":\"gYAIEK:Be}SK*01z5+\\\/V\"}}","password-antena":"{\"Servicio 1\":\"gYAIEK:Be}SK*01z5+\\\/V\"}"}}
DEBUG COMPARACIÓN - CallBell Saldo Actual: '💲9980 a favor'
DEBUG COMPARACIÓN - UCRM Saldo Actual: '💲10110 a favor'
DEBUG COMPARACIÓN - CallBell Estado: '🟢 Activo '
DEBUG COMPARACIÓN - UCRM Estado: '🟢 Activo '
EJECUTANDO PATCH - Se detectaron cambios
Response Patch CallBell: {"contact":{"uuid":"74cc2bb45eb8409f92cd5dba99200d26","name":"Juan Escutia","phoneNumber":"5214181878106","avatarUrl":null,"createdAt":"2024-01-08T17:04:13Z","closedAt":"2026-02-01T15:22:57Z","source":"whatsapp","funnelId":null,"href":"https://dash.callbell.eu/contacts/74cc2bb45eb8409f92cd5dba99200d26","conversationHref":"https://dash.callbell.eu/chat/53c8229c428c4081b197ab136feab73b","tags":["s0LOCS","PRUEBAS"],"assignedUser":null,"customFields":{"user entry point":"inbound_message","Clabe Interbancaria":"124180650741646979","Estado":"🟢 Activo ","user name":"Daniel Humberto","Cliente":"135","URL":"🌐 https://sistema.siip.mx/crm/client/135","Domicilio":"📍 Calle San Antonio 13, Lindavista, Dolores Hidalgo Cuna de la Independencia Nacional, Gto., México","Saldo Actual":"💲10110 a favor","Monto Ultimo Pago":"💲 130","Fecha Ultima Actualizacion":"📆🔄️ 12/02/2026 11:50","Nombre":"👤 Juan Escutia","password-antena":"{\"Servicio 1\":\"gYAIEK:Be}SK*01z5+\\/V\"}","Resumen":"{\"Cliente\": \"135\",\"Nombre\": \"Juan Escutia\",\"URL\": \"https://sistema.siip.mx/crm/client/135\",\"Saldo Actual\": \"💲10110 a favor\",\"Monto Ultimo Pago\": \"$ 130\",\"Estado\": \"Activo\",\"Fecha Ultimo Pago\": \" 12/02/2026 11:50 con Desconocido, revisar metodos de pago no contemplados\",\"Fecha Ultima Actualizacion\": \"12/02/2026 11:50\",\"Clabe Interbancaria\": \"\",\"Site\": \"El Lindero\",\"Antena/Sectorial\": \"San Vicente\",\"Password Antena\": {\"Servicio 1\":\"gYAIEK:Be}SK*01z5+\\/V\"}}","Site":"El Lindero","Fecha Ultimo Pago":"📆💸 12/02/2026 11:50 con Desconocido, revisar metodos de pago no contemplados","Antena/Sectorial":"San Vicente"},"team":{"uuid":"5faeed738d6a44ccacf6509762eb288d","name":"General","default":true,"members":5,"createdAt":"2023-11-07T00:37:10Z"},"channel":{"uuid":"dbaa248932634e7ea4346a320960c24a","title":null,"discardedAt":null,"type":"whatsapp","main":true},"blockedAt":null}}
[2026-02-12 17:50:55.061886] [notice] Logging level set to:debug
[2026-02-12 17:50:55.062030] [debug] Payload recibido: {"uuid":"63196e0e-277f-4ff0-96f0-f45d50bacecb","changeType":"edit","entity":"payment","entityId":"960","eventName":"payment.edit","extraData":{"entity":{"id":960,"clientId":135,"methodId":"1dd098fa-5d63-4c8d-88b7-3c27ffbbb6ae","checkNumber":null,"createdDate":"2026-02-12T11:50:47-0600","amount":130,"currencyCode":"MXN","note":null,"receiptSentDate":null,"providerName":null,"providerPaymentId":null,"providerPaymentTime":null,"paymentCovers":[],"creditAmount":130,"userId":1180,"attributes":[]},"entityBeforeEdit":{"id":960,"clientId":135,"methodId":"1dd098fa-5d63-4c8d-88b7-3c27ffbbb6ae","checkNumber":null,"createdDate":"2026-02-12T11:50:47-0600","amount":130,"currencyCode":"MXN","note":null,"receiptSentDate":null,"providerName":null,"providerPaymentId":null,"providerPaymentTime":null,"paymentCovers":[],"creditAmount":130,"userId":null,"attributes":[]}}}
[2026-02-12 17:50:55.236004] [debug] Evento recibido: payment.edit

View File

@ -588,17 +588,103 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
font-weight: 600; font-weight: 600;
} }
/* THEME TOGGLE (Restored) */ /* UNIFIED INPUT GROUP (Premium Focus) */
.input-group-unified {
display: flex;
align-items: stretch;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg-body);
transition: all 0.2s ease;
overflow: hidden;
/* Ensures children don't overflow corners */
}
.input-group-unified:focus-within {
border-color: var(--primary);
box-shadow: 0 0 0 2px rgba(37, 211, 102, 0.2);
/* Green glow for OXXO theme consistency or use primary */
}
.input-group-unified .input-prefix {
position: relative;
padding: 10px 15px;
background: transparent;
border: none;
color: var(--text-muted);
display: flex;
align-items: center;
font-weight: 500;
}
.input-group-unified .form-control {
flex: 1;
padding: 12px;
border: none;
background: transparent;
color: var(--text-main);
font-size: 1rem;
outline: none;
/* Remove default focus outline */
box-shadow: none;
/* Remove default shadow */
}
.input-group-unified .form-control:focus {
outline: none;
box-shadow: none;
}
/* THEME TOGGLE (Premium) */
.theme-toggle { .theme-toggle {
background: var(--bg-card); background: var(--bg-card);
border: 1px solid var(--border); border: 1px solid var(--border);
padding: 10px; padding: 4px 12px 4px 8px;
border-radius: 10px; /* Slightly more padding on right for balance */
border-radius: 50px;
cursor: pointer; cursor: pointer;
transition: var(--transition); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 10px;
position: relative;
overflow: hidden;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
}
.theme-toggle:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
border-color: var(--primary);
}
.theme-toggle:active {
transform: translateY(0);
}
.theme-icon-box {
width: 28px;
height: 28px;
border-radius: 50%;
background: var(--bg-body);
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
color: var(--text-main);
border: 1px solid var(--border);
}
.theme-toggle:hover .theme-icon-box {
transform: rotate(15deg) scale(1.1);
}
.theme-text {
font-weight: 600;
font-size: 0.85rem;
color: var(--text-main);
letter-spacing: 0.5px;
text-transform: uppercase;
} }
/* Modal & Tables */ /* Modal & Tables */
@ -869,9 +955,23 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
Menú Principal Menú Principal
</button> </button>
<!-- RESTORED THEME BUTTON --> <!-- RESTORED THEME BUTTON -->
<!-- PREMIUM THEME BUTTON -->
<button class="theme-toggle" id="themeBtn" onclick="toggleTheme()"> <button class="theme-toggle" id="themeBtn" onclick="toggleTheme()">
<span class="theme-icon">☀️</span> <div class="theme-icon-box">
<span class="theme-text" id="themeText">Modo Oscuro</span> <!-- Icon injected by JS -->
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="theme-icon-svg">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</div>
<span class="theme-text" id="themeText">Modo Claro</span>
</button> </button>
</div> </div>
</div> </div>
@ -1060,9 +1160,9 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
<div class="form-grid"> <div class="form-grid">
<div class="form-group"> <div class="form-group">
<label>Monto a Cobrar</label> <label>Monto a Cobrar</label>
<div class="input-group"> <div class="input-group-unified">
<span class="input-prefix">$</span> <span class="input-prefix">$</span>
<input type="number" id="stripeAmount" class="form-control input-with-prefix" placeholder="0.00"> <input type="number" id="stripeAmount" class="form-control" placeholder="0.00">
</div> </div>
</div> </div>
@ -1138,30 +1238,59 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
</div> </div>
</div> </div>
<div id="oxxoDetailContainer" class="card" style="display: none;"> <div id="oxxoDetailContainer" style="display: none; margin-top: 2rem;">
<div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 1.5rem;"> <div class="stripe-grid" style="display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: start;">
<div> <!-- Left Column: Form & Client Info -->
<div> <div class="card" style="height: 100%; display: flex; flex-direction: column;">
<h3> <!-- Client Header -->
<img src="?action=image&file=client.webp" class="client-header-icon"> <span id="oxxoClientName">Nombre</span> <div style="border-bottom: 1px solid var(--border); padding-bottom: 1rem; margin-bottom: 1.5rem;">
</h3> <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 0.5rem;">
<p id="oxxoClientIdDisplay" style="color: var(--text-muted);">ID: #0</p> <img src="?action=image&file=client.webp" class="client-header-icon" style="width: 32px; height: 32px; border-radius: 50%;">
<h3 style="margin: 0; font-size: 1.1rem; color: var(--text-main);"><span id="oxxoClientName">Nombre del Cliente</span></h3>
</div> </div>
<div style="text-align: right; display: flex; flex-direction: column; align-items: flex-end; gap: 8px;"> <div style="display: flex; justify-content: space-between; align-items: center;">
<span class="badge" id="oxxoBalanceBadge" style="background: #fee2e2; color: #ef4444;">Saldo: $0.00</span> <p id="oxxoClientIdDisplay" style="color: var(--text-muted); margin: 0; font-size: 0.9rem;">ID: #0</p>
<a id="btnOxxoCrm" href="#" target="_blank" class="btn btn-uniform" style="padding: 5px 12px; font-size: 0.8rem;"> <span class="badge" id="oxxoBalanceBadge" style="background: #fee2e2; color: #ef4444; font-size: 0.8rem; padding: 2px 8px; border-radius: 4px;">Saldo: $0.00</span>
<img src="?action=image&file=crm.webp" class="icon-crm"> Ver en CRM
</a>
</div> </div>
</div> </div>
<div style="max-width: 400px;"> <!-- OXXO Form -->
<input type="number" id="oxxoAmount" class="form-control" placeholder="Monto (MXN)" style="margin-bottom: 1rem;"> <div style="flex: 1; display: flex; flex-direction: column; justify-content: center;">
<button id="btnCreateOxxoIntent" class="btn btn-secondary" style="width: 100%; border-color: #ef4444; color: #ef4444;"> <div style="text-align: center; margin-bottom: 1.5rem;">
<img src="?action=image&file=oxxo-logo.png" style="height: 20px;"> Generar Ficha OXXO Pay <img src="?action=image&file=oxxo-logo.png" style="max-width: 100px; height: auto;">
</button> </div>
<div class="form-group" style="margin-bottom: 1.5rem;">
<label style="font-weight: 500; margin-bottom: 0.5rem; display: block; color: var(--text-main);">Monto a Cobrar</label>
<div class="input-group-unified">
<span class="input-prefix">$</span>
<input type="number" id="oxxoAmount" class="form-control" placeholder="0.00">
</div>
</div>
<div class="actions-row" style="display: flex; flex-direction: column; gap: 1rem;">
<button id="btnCreateOxxoIntent" class="btn btn-primary" style="width: 100%; justify-content: center; background-color: #E20613; border-color: #E20613; color: white; display: flex; align-items: center; gap: 10px; padding: 12px; border-radius: 8px; font-weight: 600; font-size: 1rem; transition: all 0.2s;">
Generar Ficha OXXO Pay
</button>
<a id="btnOxxoCrm" href="#" target="_blank" class="btn btn-uniform" style="text-align: center; display: block; width: 100%; padding: 10px; border-radius: 8px; background: var(--bg-body); border: 1px solid var(--border); color: var(--text-muted); font-size: 0.9rem;">
<img src="?action=image&file=crm.webp" class="icon-crm" style="vertical-align: middle; margin-right: 5px; width: 16px; opacity: 0.7;"> Ver en CRM
</a>
</div>
</div>
</div>
<!-- Right Column: Ficha Preview -->
<div class="card" id="oxxoFichaContainer" style="height: 100%; min-height: 450px; display: flex; align-items: center; justify-content: center; background: var(--bg-body); border: 1px dashed var(--border); position: relative;">
<div id="oxxoPlaceholder" style="text-align: center; color: var(--text-muted);">
<img src="?action=image&file=oxxo-payments.png" style="max-width: 80px; opacity: 0.5; margin-bottom: 1rem; filter: grayscale(1);">
<h4 style="margin: 0; font-weight: 500;">Vista Previa</h4>
<p style="margin: 5px 0 0 0; font-size: 0.9rem;">La ficha generada aparecerá aquí</p>
</div>
<div id="oxxoResult" style="display:none; width: 100%; height: 100%;">
<!-- Generated Ficha will be injected here -->
</div>
</div>
</div> </div>
<div id="oxxoInlineResult" style="margin-top: 1.5rem; display: none;"></div>
</div> </div>
</section> </section>
</div> </div>
@ -1246,13 +1375,24 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
function updateThemeBtn() { function updateThemeBtn() {
const btn = document.getElementById('themeBtn'); const btn = document.getElementById('themeBtn');
const listBox = btn.querySelector('.theme-icon-box');
const text = document.getElementById('themeText'); const text = document.getElementById('themeText');
// Icons
const iconSun = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg>`;
const iconMoon = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#6366f1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>`;
if (store.theme === 'dark') { if (store.theme === 'dark') {
btn.querySelector('.theme-icon').textContent = '🌙'; listBox.innerHTML = iconMoon;
text.textContent = 'Modo Claro';
} else {
btn.querySelector('.theme-icon').textContent = '☀️';
text.textContent = 'Modo Oscuro'; text.textContent = 'Modo Oscuro';
// Add subtle glow for active mode
btn.style.borderColor = '#6366f1';
btn.style.background = 'rgba(30, 41, 59, 0.8)'; // Darker bg
} else {
listBox.innerHTML = iconSun;
text.textContent = 'Modo Claro';
btn.style.borderColor = '#f59e0b';
btn.style.background = '#fff';
} }
} }
document.documentElement.setAttribute('data-theme', store.theme); document.documentElement.setAttribute('data-theme', store.theme);
@ -1555,6 +1695,12 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
document.getElementById('oxxoBalanceBadge').textContent = `Saldo: $${parseFloat(data.accountOutstanding||0).toFixed(2)}`; document.getElementById('oxxoBalanceBadge').textContent = `Saldo: $${parseFloat(data.accountOutstanding||0).toFixed(2)}`;
document.getElementById('oxxoAmount').value = data.accountOutstanding > 0 ? data.accountOutstanding : ''; document.getElementById('oxxoAmount').value = data.accountOutstanding > 0 ? data.accountOutstanding : '';
document.getElementById('btnOxxoCrm').href = `${store.publicUrl}/client/${data.id}`; document.getElementById('btnOxxoCrm').href = `${store.publicUrl}/client/${data.id}`;
// Reset View
document.getElementById('oxxoPlaceholder').style.display = 'block';
document.getElementById('oxxoResult').style.display = 'none';
document.getElementById('oxxoResult').innerHTML = '';
document.getElementById('oxxoDetailContainer').style.display = 'block'; document.getElementById('oxxoDetailContainer').style.display = 'block';
}); });
@ -1566,7 +1712,7 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
const btn = document.getElementById('btnCreateOxxoIntent'); const btn = document.getElementById('btnCreateOxxoIntent');
const original = btn.innerHTML; const original = btn.innerHTML;
btn.disabled = true; btn.disabled = true;
btn.textContent = 'Procesando...'; btn.innerHTML = '<span class="spinner" style="border: 2px solid #fff; border-top: 2px solid transparent; width: 16px; height: 16px; border-radius: 50%; display: inline-block; animation: spin 1s linear infinite; margin-right: 8px;"></span> Procesando...';
const fd = new FormData(); const fd = new FormData();
fd.append('action', 'create_oxxo_intent'); fd.append('action', 'create_oxxo_intent');
@ -1581,17 +1727,119 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
const d = await res.json(); const d = await res.json();
if (d.success) { if (d.success) {
const url = d.data.voucher_image_url || `?action=image&file=${d.data.voucher_filename}`; const url = d.data.voucher_image_url || `?action=image&file=${d.data.voucher_filename}`;
const resDiv = document.getElementById('oxxoInlineResult');
resDiv.style.display = 'block'; // Hide Placeholder
resDiv.innerHTML = `<div class="card" style="text-align:center;border:1px solid #22c55e;"><h3 style="color:#15803d">¡Ficha Generada!</h3><p style="font-size:1.5rem;font-weight:bold">${d.data.oxxo_reference}</p><img src="${url}" style="max-width:100%; height:auto; margin:10px 0; border:1px solid #eee; border-radius:8px;"><br><a href="${url}" target="_blank" class="btn btn-primary">Descargar Ficha</a></div>`; document.getElementById('oxxoPlaceholder').style.display = 'none';
// Show Result
const resDiv = document.getElementById('oxxoResult');
resDiv.style.display = 'flex';
resDiv.innerHTML = `
<div style="text-align:center; width: 100%; animation: fadeIn 0.5s ease-out;">
<div style="background: #dcfce7; color: #15803d; width: 60px; height: 60px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 1rem;">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><polyline points="20 6 9 17 4 12"></polyline></svg>
</div>
<h3 style="color:var(--text-main); margin-bottom: 0.5rem;">¡Ficha Generada!</h3>
<p style="color:var(--text-muted); margin-bottom: 1.5rem;">Referencia OXXO Pay</p>
<div style="background: white; padding: 10px; border-radius: 8px; border: 1px solid var(--border); display: inline-block; margin-bottom: 1.5rem;">
<p style="font-size:1.4rem; font-weight:bold; letter-spacing: 2px; margin: 0; color: #000;">${d.data.oxxo_reference}</p>
</div>
<img src="${url}" style="max-width:100%; height:auto; display: block; margin: 0 auto 1.5rem; border:1px solid var(--border); border-radius:8px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);">
<div style="display: flex; gap: 10px; justify-content: center;">
<a href="${url}" target="_blank" class="btn btn-primary" style="display: inline-flex; align-items: center; gap: 8px;">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
Descargar Ficha
</a>
</div>
</div>`;
} else showToast(d.error, true); } else showToast(d.error, true);
} catch (e) { } catch (e) {
showToast('Error conexión', true); console.error(e);
showToast('Error de conexión', true);
} }
btn.disabled = false; btn.disabled = false;
btn.innerHTML = original; btn.innerHTML = original;
}; };
// --- INPUT VALIDATION & UX ---
function setupNumericInput(inputId) {
const input = document.getElementById(inputId);
if (!input) return;
// 1. Focus input when clicking prefix (if exists)
const group = input.closest('.input-group');
if (group) {
const prefix = group.querySelector('.input-prefix');
if (prefix) {
prefix.onclick = () => input.focus();
prefix.style.cursor = 'text';
}
}
// 2. Strict Numeric Validation (Robust)
input.addEventListener('keydown', (e) => {
// Allow control keys: Backspace, Delete, Tab, Escape, Enter, Arrows, Home, End
const allowedKeys = ['Backspace', 'Delete', 'Tab', 'Escape', 'Enter', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'];
if (allowedKeys.includes(e.key) || e.ctrlKey || e.metaKey || e.altKey) {
return;
}
// Block invalid chars for number input: e, E, +, -
// Note: We allow '.' if not already present
if (['e', 'E', '+', '-'].includes(e.key)) {
e.preventDefault();
return;
}
// Allow numbers and dot
const isDigit = /^[0-9]$/.test(e.key);
const isDot = e.key === '.';
if (!isDigit && !isDot) {
e.preventDefault();
}
if (isDot && input.value.includes('.')) {
e.preventDefault();
}
});
// 3. Fallback Sanitization (on input)
input.addEventListener('input', (e) => {
let val = input.value;
// If browser allowed something invalid, clean it
// Keep only numbers and dots
// Also ensure only one dot
const clean = val.replace(/[^0-9.]/g, '');
// Handle multiple dots
const parts = clean.split('.');
if (parts.length > 2) {
input.value = parts[0] + '.' + parts.slice(1).join('');
} else if (val !== clean) {
input.value = clean;
}
});
// Prevent paste of invalid text
input.addEventListener('paste', (e) => {
const paste = (e.clipboardData || window.clipboardData).getData('text');
if (!/^\d*\.?\d*$/.test(paste)) {
e.preventDefault();
}
});
// Prevent scrolling changing value
input.addEventListener('wheel', (e) => e.preventDefault());
}
// Initialize Validation for Amounts
setupNumericInput('oxxoAmount');
setupNumericInput('stripeAmount');
// --- INSTALLER MODAL LOGIC --- // --- INSTALLER MODAL LOGIC ---
function renderTable() { function renderTable() {
const tbody = document.querySelector('#installersTable tbody'); const tbody = document.querySelector('#installersTable tbody');
@ -1607,6 +1855,42 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
} }
renderTable(); renderTable();
window.editInstaller = function(index) {
const installer = store.installers[index];
if (!installer) return;
document.getElementById('editIndex').value = index;
document.getElementById('installerId').value = installer.id;
document.getElementById('installerName').value = installer.nombre;
document.getElementById('installerWhatsApp').value = installer.whatsapp;
document.getElementById('modalOverlay').style.display = 'flex';
}
window.deleteInstaller = async function(index) {
if (!confirm('¿Estás seguro de que deseas eliminar este instalador?')) return;
store.installers.splice(index, 1);
renderTable();
const fd = new FormData();
fd.append('action', 'save_installers');
fd.append('installers_data', JSON.stringify({
instaladores: store.installers
}));
try {
await fetch('?action=save_installers', {
method: 'POST',
body: fd
});
showToast('Instalador eliminado correctamente');
} catch (e) {
console.error(e);
showToast('Error al eliminar', true);
}
}
function openInstallerModal() { function openInstallerModal() {
document.getElementById('modalOverlay').style.display = 'flex'; document.getElementById('modalOverlay').style.display = 'flex';
document.getElementById('installerForm').reset(); document.getElementById('installerForm').reset();