Actualización que ajusta los permisos de acceso a la API del CRM y NMS, además se realizaron cambios en el menú de ajustes para agregar el campo del toke de la api de nms y el campo del id del administrador para pagos en linea con Stripe, además se hizo el ajuste para el bug que no permitía realizar intenciones de pago cuando la cantidad trae signo de pesos

This commit is contained in:
server 2025-07-31 15:23:49 -06:00
parent c9e2466353
commit a0f286969a
10 changed files with 2346 additions and 8158 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 92 KiB

View File

@ -1 +1 @@
{"ipserver":"172.16.5.134","apitoken":"6abef18c-783d-4dd0-b530-be6e6a7bbd1d","tokencallbell":"g8thcZkXGd3xBj2g3TtYNYFMH1fuesbJ.b6a940ea7d78cf6c9e42f067b21c8ddf96e9fa2a9e307bfd0c7c7c4d7fa38f79","tokenstripe":"sk_test_51OkG0REFY1WEUtgRH6UxBK5pu80Aq5Iy8EcdPnf0cOWzuVLQTpyLCd7CbPzqMsWMafZOHElCxhEHF7g8boURjWlJ00tBwE0W1M","unmsApiToken":null,"hostServerFTP":"siip.mx","usernameServerFTP":"siip0001","passServerFTP":"$spGiT,[wa)n","cashPaymentMethodId":false,"courtesyPaymentMethodId":false,"bankTransferPaymentMethodId":true,"paypalPaymentMethodId":true,"creditCardPaypalPaymentMethodId":true,"creditCardStripePaymentMethodId":true,"stripeSubscriptionCreditCardPaymentMethodId":true,"paypalSubscriptionPaymentMethodId":true,"mercadopagoPaymentMethodId":true,"checkPaymentMethodId":true,"customPaymentMethodId":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,"logging_level":true}
{"ipserver":"172.16.5.134","apitoken":"gvcnIJqXdUjneVSjhl6THLlQcYXJyIFCcwHKVba2bvIrNraanCTb5VeoWuJ0TFZ9","unmsApiToken":null,"tokencallbell":"g8thcZkXGd3xBj2g3TtYNYFMH1fuesbJ.b6a940ea7d78cf6c9e42f067b21c8ddf96e9fa2a9e307bfd0c7c7c4d7fa38f79","tokenstripe":"sk_test_51OkG0REFY1WEUtgRH6UxBK5pu80Aq5Iy8EcdPnf0cOWzuVLQTpyLCd7CbPzqMsWMafZOHElCxhEHF7g8boURjWlJ00tBwE0W1M","hostServerFTP":"siip.mx","usernameServerFTP":"siip0001","passServerFTP":"$spGiT,[wa)n","ipPuppeteer":"172.16.5.134","idPaymentAdminCRM":"1180","cashPaymentMethodId":false,"courtesyPaymentMethodId":false,"bankTransferPaymentMethodId":true,"paypalPaymentMethodId":true,"creditCardPaypalPaymentMethodId":true,"creditCardStripePaymentMethodId":true,"stripeSubscriptionCreditCardPaymentMethodId":true,"paypalSubscriptionPaymentMethodId":true,"mercadopagoPaymentMethodId":true,"checkPaymentMethodId":true,"customPaymentMethodId":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,"logging_level":true}

File diff suppressed because one or more lines are too long

View File

@ -5,7 +5,7 @@
"displayName": "SIIP - Procesador de Pagos en línea con Stripe, Oxxo y Transferencia, Sincronizador de CallBell y Envío de Notificaciones y comprobantes vía WhatsApp",
"description": "Este plugin sincroniza los clientes del sistema UISP CRM con los contactos de WhatsApp en CallBell, además procesa pagos de Stripe como las trasferencias bancarias y genera referencias de pago vía OXXO, además envía comprobantes de pago en formato imagen PNG o texto vía Whatsapp a los clientes",
"url": "https://siip.mx/",
"version": "2.8.8",
"version": "2.9.0",
"unmsVersionCompliancy": {
"min": "2.1.0",
"max": null
@ -23,10 +23,17 @@
{
"key": "apitoken",
"label": "Token de la API UCRM",
"description": "Token de autenticación para el uso de la API del sistema UISP UCRM. Contiene 36 caracteres, ejemplo: 3d3fa6c9-e268-6e8b-b4d5-aae394d99d7d",
"description": "Token de autenticación necesario para el uso de la API del sistema UISP UCRM, se utiliza para gestionar cualquier información de los clientes. Contiene 64 caracteres y se genera desde el módulo de Ajustes del UISP CRM en la opción de 'Seguridad' y en la sección de 'Claves app'.",
"required": 1,
"type": "text"
},
{
"key": "unmsApiToken",
"label": "Token de la API UNMS",
"description": "Token de autenticación necesario para el uso de la API del sistema UISP UNMS, se utiliza para gestionar información de antenas u otros dispositivos de red. Contiene 34 caracteres y se genera desde el módulo de Ajustes del UISP Network en la opción de 'Usuarios' y en apartado de 'API tokens'.",
"required": 0,
"type": "text"
},
{
"key": "tokencallbell",
"label": "Token de la API de CallBell",
@ -37,17 +44,10 @@
{
"key": "tokenstripe",
"label": "Token de la API de Stripe",
"description": "Token de autenticación para el uso de la API de Stripe que maneja las funciones realacionadas con los pagos en línea. ",
"description": "Token de autenticación para el uso de la API de Stripe que maneja las funciones realacionadas con los pagos en línea (Transferencia y OXXO PAGO). ",
"required": 1,
"type": "text"
},
{
"key": "unmsApiToken",
"label": "Token de la API UNMS",
"description": "Token API creado para este plugin en la seccion Network de UNMS, solo necesario cuando se utiliza UNMS v1",
"required": 0,
"type": "text"
},
{
"key": "hostServerFTP",
"label": "IP o dominio del servidor FTP",
@ -58,14 +58,28 @@
{
"key": "usernameServerFTP",
"label": "Usuario FTP",
"description": "Nombre de usuario para inicio de sesión el servidor FTP",
"description": "Nombre de usuario para inicio de sesión el servidor FTP, necesario para la carga de comprobantes de pago del sistema y su posterior envío",
"required": 1,
"type": "text"
},
{
"key": "passServerFTP",
"label": "Password FTP",
"description": "Contraseña para inicio de sesión en el servidor FTP",
"description": "Contraseña para inicio de sesión en el servidor FTP, necesario para la carga de comprobantes de pago del sistema y su posterior envío",
"required": 1,
"type": "text"
},
{
"key": "ipPuppeteer",
"label": "Dirección IP del servicio de Puppeteer",
"description": "Dirección IP del contenedor docker que ejecuta el servicio de Puppeteer para la generación de comprobantes de pago en formato imagen PNG",
"required": 1,
"type": "text"
},
{
"key": "idPaymentAdminCRM",
"label": "ID del usuario para pagos en línea",
"description": "ID del usuario administrador del CRM asigando para realizar pagos en línea con Stripe. Todos los pagos que llegan desde Stripe se asignan a este usuario. Se recomienda crear un usuario exclusivo para este fin.",
"required": 1,
"type": "text"
},

View File

@ -366,6 +366,17 @@ abstract class AbstractMessageNotifierFacade
$responseClients = $clientGuzzleHttp->request('GET', "clients/" . $clientId);
$arrayClientCRM = json_decode($responseClients->getBody()->getContents(), true);
// $this->logger->debug('Valor de $arrayClientCRM en verifyJobActionToDo: ' . json_encode($arrayClientCRM) . PHP_EOL);
//ejemplo de $arrayClientCRM: {"id":2,"userIdent":null,"previousIsp":null,"isLead":false,"clientType":1,"companyName":null,"companyRegistrationNumber":null,"companyTaxId":null,"companyWebsite":null,"street1":"Chiapas 31","street2":null,"city":"Dolores Hidalgo Cuna de la Independencia Nacional","countryId":173,"stateId":null,"zipCode":"37800","fullAddress":"Chiapas 31, Dolores Hidalgo Cuna de la Independencia Nacional, 37800","invoiceStreet1":null,"invoiceStreet2":null,"invoiceCity":null,"invoiceStateId":null,"invoiceCountryId":null,"invoiceZipCode":null,"invoiceAddressSameAsContact":true,"note":"Cliente espacial, el m\u00e1s chido","sendInvoiceByPost":null,"invoiceMaturityDays":null,"stopServiceDue":null,"stopServiceDueDays":null,"organizationId":1,"tax1Id":null,"tax2Id":null,"tax3Id":null,"registrationDate":"2024-01-25T00:00:00-0600","leadConvertedAt":null,"companyContactFirstName":null,"companyContactLastName":null,"isActive":true,"firstName":"Daniel Humberto","lastName":"Soto Villegas","username":"danydhsv","contacts":[{"id":2,"clientId":2,"email":"dhsv.141089@gmail.com","phone":"5214181878106","name":null,"isBilling":false,"isContact":false,"types":[]},{"id":170,"clientId":2,"email":null,"phone":"5214181148783","name":null,"isBilling":false,"isContact":false,"types":[{"id":1000,"name":"WhatsApp"}]}],"attributes":[{"id":112,"clientId":2,"customAttributeId":10,"name":"Stripe Customer ID","key":"stripeCustomerId","value":"cus_PetN1dhr4rx0kX","clientZoneVisible":true},{"id":113,"clientId":2,"customAttributeId":11,"name":"Clabe Interbancaria","key":"clabeInterbancaria","value":"0021804341999569810","clientZoneVisible":true},{"id":178,"clientId":2,"customAttributeId":15,"name":"Site","key":"site","value":"0LOCS","clientZoneVisible":false},{"id":179,"clientId":2,"customAttributeId":16,"name":"Antena\/Sectorial","key":"antenaSectorial","value":"Sectorial-4b 172.16.13.16\/24","clientZoneVisible":false},{"id":200,"clientId":2,"customAttributeId":14,"name":"Chat de CallBell","key":"chatDeCallbell","value":"https","clientZoneVisible":false},{"id":202,"clientId":2,"customAttributeId":17,"name":"Password Antena Cliente","key":"passwordAntenaCliente","value":"gYAIEK:Be}SK*01z5+\/V","clientZoneVisible":false}],"accountBalance":-200,"accountCredit":100,"accountOutstanding":300,"currencyCode":"MXN","organizationName":"SIIP Pruebas","bankAccounts":[],"tags":[],"invitationEmailSentDate":null,"avatarColor":"#f1df43","addressGpsLat":21.1564414,"addressGpsLon":-100.9383654,"isArchived":false,"generateProformaInvoices":null,"usesProforma":false,"hasOverdueInvoice":false,"hasOutage":true,"hasSuspendedService":false,"hasServiceWithoutDevices":true,"referral":null,"hasPaymentSubscription":false,"hasAutopayCreditCard":false}
//buscar en los attributes del cliente el atributo de con la key "passwordAntenaCliente" y almacenar su valor en la variable $passwordAntenaClienteCRM
$passwordAntenaClienteCRM = '';
foreach ($arrayClientCRM['attributes'] as $attribute) {
if ($attribute['key'] === 'passwordAntenaCliente') {
$passwordAntenaClienteCRM = $attribute['value'];
$this->logger->debug('Valor de $passwordAntenaClienteCRM en verifyJobActionToDo: ' . $passwordAntenaClienteCRM . PHP_EOL);
break;
}
}
$clientFullName = sprintf("%s %s", $arrayClientCRM['firstName'], $arrayClientCRM['lastName']);
@ -596,6 +607,23 @@ abstract class AbstractMessageNotifierFacade
"gmapsLocation" => $googleMapsUrl,
];
//obtener la contraseña de la antena con el método getVaultCredentialsByClientId y compararlo con el campo de la contraseña de la antena en el CRM
$passwordVault = $this->getVaultCredentialsByClientId($arrayClientCRM['id']);
// Validar si la contraseña de la antena del cliente en el CRM es igual a la contraseña de la antena del cliente en el Vault
if ($passwordAntenaClienteCRM === $passwordVault) {
$this->logger->debug('La contraseña de la antena del cliente en el CRM
es igual a la contraseña de la antena del cliente en el Vault.' . PHP_EOL);
$jsonInstallerJobNotificationData['passwordAntenaCliente'] = $passwordAntenaClienteCRM;
} else {
$this->logger->debug('La contraseña de la antena del cliente en el CRM
no es igual a la contraseña de la antena del cliente en el Vault.' . PHP_EOL);
$jsonInstallerJobNotificationData['passwordAntenaCliente'] = $passwordVault;
}
//Enviar notificación al instalador nuevo
$attempts = 0;
@ -1596,15 +1624,16 @@ abstract class AbstractMessageNotifierFacade
$configManager = \Ubnt\UcrmPluginSdk\Service\PluginConfigManager::create();
$config = $configManager->loadConfig();
$ucrmBaseUri = $config['ipserver'];
$authToken = $config['apitoken'];
$ipServer = $config['ipserver'];
$ucrmToken = $config['apitoken'];
$unmsToken = $config['unmsApiToken'];
if ($ucrmBaseUri === '172.16.5.134') { //opción solo para el servidor de pruebas
if ($ipServer === '172.16.5.134') { //opción solo para el servidor de pruebas
return 'gYAIEK:Be}SK*01z5+/V';
}
$unmsBaseUri = 'https://' . $ucrmBaseUri . '/nms/api/v2.1/';
$ucrmBaseUri = 'https://' . $ucrmBaseUri . '/crm/api/v1.0/';
$unmsBaseUri = 'https://' . $ipServer . '/nms/api/v2.1/';
$ucrmBaseUri = 'https://' . $ipServer . '/crm/api/v1.0/';
//$authToken = '7adc9198-50b1-41d0-9bfa-d4946902ed89';
// Crear una instancia del cliente Guzzle
@ -1619,14 +1648,14 @@ abstract class AbstractMessageNotifierFacade
]);
$this->logger->info('Consulta por ID: ' . $clientId . PHP_EOL);
$this->logger->debug('Consulta por ID: ' . $clientId . PHP_EOL);
try {
//Obtener id del sitio por medio del servicio
$responseServices = $clientUcrm->get('clients/services?clientId=' . $clientId, [
'headers' => [
'X-Auth-Token' => $authToken,
'X-Auth-Token' => $ucrmToken,
'Content-Type: application/json',
],
]);
@ -1640,7 +1669,7 @@ abstract class AbstractMessageNotifierFacade
//si el statusCode es 404 significa que no se encontró el cliente
if ($statusCode == 404) {
$this->logger->error('No se encontró el cliente con el ID proporcionado: ' . $clientId . PHP_EOL);
return 'Error: No se encontró el cliente con el ID proporcionado: ' . $clientId; // Return early if the client is not found
return 'No se encontró el cliente con el ID proporcionado: ' . $clientId; // Return early if the client is not found
}
return 'Error: ' . $reason; // Return early if the request fails
@ -1659,7 +1688,7 @@ abstract class AbstractMessageNotifierFacade
$unmsSiteID = $dataServices[0]['unmsClientSiteId']; // Example: 9c6798f3-0254-4e5b-bc3b-9da82fe16e46
} else {
$this->logger->error('No se encontraron servicios para el cliente proporcionado: ' . $clientId . PHP_EOL);
return "Error: No se encontraron servicios para el cliente proporcionado: " . $clientId; // Return early if no services are found
return "No se encontraron servicios para el cliente proporcionado: " . $clientId; // Return early if no services are found
}
} else {
@ -1670,7 +1699,7 @@ abstract class AbstractMessageNotifierFacade
try {
$responseDevicesBySite = $clientUnms->request('GET', 'devices?siteId=' . $unmsSiteID, [
'headers' => [
'X-Auth-Token' => $authToken,
'X-Auth-Token' => $unmsToken,
],
]);
} catch (RequestException $requestException) {
@ -1681,8 +1710,8 @@ abstract class AbstractMessageNotifierFacade
$reason = $response->getReasonPhrase();
//si el statusCode es 404 significa que no se encontró el cliente
if ($statusCode == 404) {
$this->logger->error('No se encontró el devicie con el ID proporcionado: ' . $clientId . PHP_EOL);
return 'Error: No se encontró el devicie con el ID proporcionado: ' . $clientId; // Return early if the client is not found
$this->logger->error('No se encontró el device con el ID proporcionado: ' . $clientId . PHP_EOL);
return 'No se encontró el device con el ID proporcionado: ' . $clientId; // Return early if the client is not found
}
$this->logger->error('Error: ' . $reason . PHP_EOL);
return 'Error: ' . $reason; // Return early if the request fails
@ -1713,7 +1742,7 @@ abstract class AbstractMessageNotifierFacade
} else {
$this->logger->error('No se encontraron dispositivos para el sitio proporcionado: ' . $unmsSiteID . PHP_EOL);
return "Error: No se encontraron dispositivos para el sitio proporcionado."; // Return early if no devices are found
return "No se encontraron dispositivos para el sitio proporcionado."; // Return early if no devices are found
}
} else {
@ -1724,7 +1753,7 @@ abstract class AbstractMessageNotifierFacade
try {
$responseDevicesBySite = $clientUnms->request('GET', 'devices/' . $deviceID, [
'headers' => [
'X-Auth-Token' => $authToken,
'X-Auth-Token' => $unmsToken,
],
]);
} catch (RequestException $requestException) {
@ -1736,7 +1765,7 @@ abstract class AbstractMessageNotifierFacade
//si el statusCode es 404 significa que no se encontró el cliente
if ($statusCode == 404) {
$this->logger->error('No se encontró el device con el ID proporcionado: ' . $clientId . PHP_EOL);
return 'Error: No se encontró el device con el ID proporcionado: ' . $clientId; // Return early if the client is not found
return 'No se encontró el dispositivo de red con el ID proporcionado: ' . $clientId; // Return early if the client is not found
}
return 'Error: ' . $reason; // Return early if the request fails
@ -1757,7 +1786,7 @@ abstract class AbstractMessageNotifierFacade
//print_r('ID del device al que está conectado el cliente: ' . $idDevice . PHP_EOL);
$responsePasswordVault = $clientUnms->request('GET', 'vault/' . $idClientDevice . '/credentials', [
'headers' => [
'X-Auth-Token' => $authToken,
'X-Auth-Token' => $unmsToken,
],
]);
} catch (RequestException $requestException) {
@ -1769,7 +1798,7 @@ abstract class AbstractMessageNotifierFacade
//si el statusCode es 404 significa que no se encontró el cliente
if ($statusCode == 404) {
$this->logger->error('No se encontró el device con el ID proporcionado: ' . $clientId . PHP_EOL);
return 'Error: No se encontró el device con el ID proporcionado: ' . $clientId; // Return early if the client is not found
return 'No se encontró el dispositivo de red con el ID proporcionado: ' . $clientId; // Return early if the client is not found
}
$this->logger->error('Error: ' . $reason . PHP_EOL);
return 'Error: ' . $reason; // Return early if the request fails
@ -1788,7 +1817,7 @@ abstract class AbstractMessageNotifierFacade
return $passwordVault;
} else {
$this->logger->error('No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida.' . PHP_EOL);
return "Error: No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida."; // Return early if the password is not found
return "No se encontró una contraseña en la bóveda para la antena de este cliente, es altamente probable que conserve una contraseña conocida."; // Return early if the password is not found
}
} else {
@ -1798,7 +1827,7 @@ abstract class AbstractMessageNotifierFacade
} else {
$this->logger->error('Falla en la solicitud. Código de estado HTTP: ' . $responseDevicesBySite->getStatusCode() . PHP_EOL);
return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $responseDevicesBySite->getStatusCode(); // Return early if the request fails
return 'Error: Falla en la solicitud. Código de estado HTTP: ' . $responseDevicesBySite->getStatusCode(); // Return early if the request fails
}

View File

@ -13,7 +13,6 @@ use GuzzleHttp\Exception\RequestException;
use Ubnt\UcrmPluginSdk\Service\UcrmApi;
use Ubnt\UcrmPluginSdk\Service\PluginConfigManager;
use Ubnt\UcrmPluginSdk\Service\PluginLogManager;
use Dompdf\Dompdf;
/*
@ -180,14 +179,18 @@ abstract class AbstractOxxoOperationsFacade
if ($amount === null) {
$amount = abs($arrayClientCRM['accountOutstanding']); //Monto adeudado del cliente
} else {
$this->logger->info("Monto proporcionado directamente: $amount " . PHP_EOL);
//la variable $amount debe ser numérica pero en ocasiones la solicitud puede traer signos o alguna letra ingresada mal por el cliente, se debe analizar para limpiar cualquier caracter que no sea numérico
if(!is_numeric($amount)) {
$amount = preg_replace('/[^\d.]/', '', $amount); // Eliminar todo lo que no sea dígito o punto decimal
}
$this->logger->debug("Monto proporcionado directamente: $amount " . PHP_EOL);
}
if ($amount > 10) {
$amountInCents = intval($amount * 100); // Convertir a centavos
try {
$this->logger->info("Creando referencia en Stripe por $amount para el cliente $stripeCustomerId" . PHP_EOL);
$this->logger->debug("Creando referencia en Stripe por $amount para el cliente $stripeCustomerId" . PHP_EOL);
$guzzleClient = new Client([
'timeout' => 5, // Timeout de 5 segundos
]);

View File

@ -58,14 +58,12 @@ abstract class AbstractStripeOperationsFacade
*/
public function createPaymentIntent($event_json)
{
// if ($event_json['data']['object']['type'] != 'funded') {
// return;
// }
// $this->logger->info("Evento recibido: " . json_encode($event_json) . PHP_EOL);
$this->logger->info("Iniciando creación de PaymentIntent en Stripe." . PHP_EOL);
$configManager = \Ubnt\UcrmPluginSdk\Service\PluginConfigManager::create();
$config = $configManager->loadConfig();
$StripeToken = $config['tokenstripe'];
$idPaymentAdmin = $config['idPaymentAdminCRM']; //ID del administrador que crea el PaymentIntent
$stripe = new \Stripe\StripeClient($StripeToken); //Token de clave privada para la API de Stripe
// Asegurarse de que 'customer' esté presente en la estructura del evento
@ -85,13 +83,23 @@ abstract class AbstractStripeOperationsFacade
$this->logger->info("Error: net_amount not found in event data." . PHP_EOL);
return;
}
$amount = $event_json['data']['object']['net_amount'];
//convertir en positivo
if ($event_json['data']['object']['net_amount'] < 0) {
$this->logger->warning("Error: net_amount es negativo." . PHP_EOL);
return;
}
//imprimir la cantidad del PaymentIntent
$this->logger->info("Cantidad del PaymentIntent: " . $amount . PHP_EOL);
try {
// Obtener información del cliente desde Stripe
$stripeQuery = $stripe->customers->retrieve($customerId, []);
$UCRM_clientID = $stripeQuery['metadata']['ucrm_client_id'];
$UCRM_clientID = $stripeQuery['metadata']['ucrm_client_id']; // ID del cliente en Ubiquiti UISP
// Obtener información del administrador actual
$this->ucrmApi = UcrmApi::create();
@ -115,7 +123,7 @@ abstract class AbstractStripeOperationsFacade
'clientId' => $UCRM_clientID, // ID del cliente en Ubiquiti
'createdBy' => 'UCRM',
'paymentType' => 'card.one_time',
'signedInAdminId' => $currentUserAdmin[0]['id'],
'signedInAdminId' => $idPaymentAdmin, // ID del administrador que crea el PaymentIntent
'tipoPago' => 'Transferencia Bancaria'
],
]);

View File

@ -128,9 +128,22 @@ class Plugin
if ($jsonData) {
switch ($jsonData['type']) {
case 'customer_cash_balance_transaction.created':
$this->logger->info('Evento de transfencia al cliente encontrado: ' . json_encode($jsonData) . PHP_EOL);
if ($jsonData['data']['object']['type'] === 'funded' || $jsonData['data']['object']['type'] === 'applied_to_payment') {
if ($jsonData['data']['object']['type'] === 'funded') {
$this->logger->info('Evento de transferencia de un cliente recibido: ' . json_encode($jsonData) . PHP_EOL);
$this->pluginNotifierFacade->createPaymentIntent($jsonData);
}
if ($jsonData['data']['object']['type'] === 'applied_to_payment') {
$this->logger->info('Se aplicó el saldo en Stripe de un pago: ' . json_encode($jsonData) . PHP_EOL);
}elseif ($jsonData['data']['object']['type'] === 'unapplied_from_payment'){
//ejemplo de json para transferencia de dinero cancelada: {"id":"evt_1RlEGgEFY1WEUtgR6Bp2DzDP","object":"event","api_version":"2023-10-16","created":1752606717,"data":{"object":{"id":"ccsbtxn_1RlEGfEFY1WEUtgRv8jAUGmE","object":"customer_cash_balance_transaction","created":1752606717,"currency":"mxn","customer":"cus_PetN1dhr4rx0kX","ending_balance":18000,"livemode":false,"net_amount":18000,"type":"unapplied_from_payment","unapplied_from_payment":{"payment_intent":"pi_3RlDPdEFY1WEUtgR1JBgNhTQ"}}},"livemode":false,"pending_webhooks":2,"request":{"id":"req_954mskVBfAI0jn","idempotency_key":"749518f6-baa0-4ae9-99e4-8029a35719aa"},"type":"customer_cash_balance_transaction.created"}
$paymentIntentId = $jsonData['data']['object']['unapplied_from_payment']['payment_intent'];
//Se canceló una transferencia de dinero, imprimir que se canceló y además el monto neto
$this->logger->warning('Evento de transferencia cancelada para el pago: ' . $paymentIntentId . PHP_EOL);
$this->logger->warning('Monto neto de la transferencia cancelada: ' . $jsonData['data']['object']['net_amount'] . PHP_EOL);
}
break;
case 'payout.failed':
@ -144,7 +157,10 @@ class Plugin
$this->logger->info('Detalles del evento: ' . json_encode($jsonData));
break;
case 'inbound_payment.payment_attempt':
//$this->logger->info('Evento de Pago de OXXO recibido: '. json_encode($jsonData) . PHP_EOL);
//$this->logger->info('Evento de Pago de OXXO recibido: ' . json_encode($jsonData) . PHP_EOL);
break;
case 'cash_balance.funds_available':
$this->logger->info('Evento de Pago de fondos disponibles recibido: ' . json_encode($jsonData) . PHP_EOL);
break;
case 'energy.alert':
$this->logger->info('Evento de Energía recibido: ' . $jsonData['message'] . PHP_EOL);
@ -155,7 +171,7 @@ class Plugin
// Construir la URL basada en el "client_id"
// $url = "https://siip.mx/wp/wp-content/uploads/img/voucher.png";
if (! empty($jsonData['amount'])) {
$this->logger->info('Referencia persnoalizada, Valor del monto: ' . $jsonData['amount'] . PHP_EOL);
$this->logger->info('Referencia personalizada, Valor del monto: ' . $jsonData['amount'] . PHP_EOL);
$intentos = 0;
do {
// if ($intentos > 1) {

View File

@ -5,7 +5,7 @@
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '8d8a1ec64831255d9841b3db558e14f4224d41fb',
'reference' => 'c9e2466353fb8267004cbfadeba945609396a346',
'name' => 'ucrm-plugins/sms-twilio',
'dev' => false,
),
@ -307,7 +307,7 @@
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '8d8a1ec64831255d9841b3db558e14f4224d41fb',
'reference' => 'c9e2466353fb8267004cbfadeba945609396a346',
'dev_requirement' => false,
),
),