siip-stripe-payment_intents/src/PaymentIntentService.php
DANYDHSV c43bb924d7 feat: lanzamiento inicial del plugin Generador de Payment Intents
- Implementado servicio backend [PaymentIntentService](cci:2://file:///home/unms/data/ucrm/ucrm/data/plugins/siip-stripe-payment_intents/src/PaymentIntentService.php:8:0-152:1) para manejar interacciones con API de UCRM y Stripe.
- Creado frontend moderno y responsivo en HTML/JS dentro de [public.php](cci:7://file:///home/unms/data/ucrm/ucrm/data/plugins/siip-stripe-payment_intents/public.php:0:0-0:0).
- Agregada búsqueda con autocompletado para clientes.
- Agregada validación para Stripe Customer ID y monto mínimo.
- Integrada la creación de Payment Intents de Stripe para fondos tipo `customer_balance`.
- Agregada documentación (README.md, CHANGELOG.md) y limpieza de archivos legado.
2025-12-16 13:56:31 -06:00

154 lines
5.2 KiB
PHP

<?php
namespace App;
use GuzzleHttp\Client;
use Stripe\StripeClient;
use Stripe\Exception\ApiErrorException;
class PaymentIntentService
{
private $ucrmApiUrl;
private $ucrmApiKey;
private $stripeApiKey;
private $httpClient;
private $stripeClient;
public function __construct($ucrmApiUrl, $ucrmApiKey, $stripeApiKey)
{
$this->ucrmApiUrl = rtrim($ucrmApiUrl, '/');
$this->ucrmApiKey = $ucrmApiKey;
$this->stripeApiKey = $stripeApiKey;
$this->httpClient = new Client([
'base_uri' => $this->ucrmApiUrl . '/api/v1.0/',
'headers' => [
'X-Auth-App-Key' => $this->ucrmApiKey,
'Accept' => 'application/json',
],
'verify' => false, // Initial script had verify false, keeping it but risky in prod without caution
'timeout' => 10,
]);
$this->stripeClient = new StripeClient($this->stripeApiKey);
}
public function searchClients($query)
{
try {
$response = $this->httpClient->get('clients', [
'query' => [
'query' => $query,
'limit' => 5
]
]);
$clients = json_decode($response->getBody(), true);
return array_map(function ($client) {
return [
'id' => $client['id'],
'firstName' => $client['firstName'],
'lastName' => $client['lastName'],
'username' => $client['username'],
'fullAddress' => $client['fullAddress'] ?? '',
'companyName' => $client['companyName'],
'clientType' => $client['clientType'], // 1 = residential, 2 = company
];
}, $clients);
} catch (\Exception $e) {
return ['error' => $e->getMessage()];
}
}
public function getClientDetails($clientId)
{
try {
$response = $this->httpClient->get("clients/{$clientId}");
$client = json_decode($response->getBody(), true);
$stripeCustomerId = null;
if (isset($client['attributes'])) {
foreach ($client['attributes'] as $attribute) {
if ($attribute['key'] === 'stripeCustomerId' || $attribute['name'] === 'Stripe Customer ID') {
$stripeCustomerId = $attribute['value'];
break;
}
}
}
return [
'id' => $client['id'],
'fullName' => ($client['clientType'] == 1)
? $client['firstName'] . ' ' . $client['lastName']
: $client['companyName'],
'stripeCustomerId' => $stripeCustomerId,
'email' => $this->getClientEmail($client),
'accountOutstanding' => $client['accountOutstanding'] ?? 0
];
} catch (\Exception $e) {
return ['error' => $e->getMessage()];
}
}
private function getClientEmail($clientData)
{
if (!empty($clientData['contacts'])) {
foreach ($clientData['contacts'] as $contact) {
if (!empty($contact['email'])) {
return $contact['email'];
}
}
}
return $clientData['username'] ?? ''; // Fallback, though username might not be email
}
public function createPaymentIntent($clientId, $amount, $stripeCustomerId, $adminId = null)
{
if ($amount < 10) {
throw new \Exception("El monto debe ser mayor a 10 MXN");
}
try {
$amountCentavos = intval($amount * 100);
$paymentIntent = $this->stripeClient->paymentIntents->create([
'amount' => $amountCentavos,
'currency' => 'mxn',
'customer' => $stripeCustomerId,
'payment_method_types' => ['customer_balance'],
'payment_method_data' => ['type' => 'customer_balance'],
'confirm' => true,
'payment_method_options' => [
'customer_balance' => [
'funding_type' => 'bank_transfer',
'bank_transfer' => ['type' => 'mx_bank_transfer']
],
],
'metadata' => [
'clientId' => $clientId,
'createdBy' => 'UCRM Plugin',
'paymentType' => 'card.one_time',
'signedInAdminId' => $adminId, // Will be passed from session or fixed
'tipoPago' => 'Transferencia Bancaria Manual'
],
]);
return [
'success' => true,
'id' => $paymentIntent->id,
'status' => $paymentIntent->status,
'amount' => $paymentIntent->amount / 100,
'currency' => $paymentIntent->currency
];
} catch (ApiErrorException $e) {
return ['success' => false, 'error' => $e->getMessage()];
} catch (\Exception $e) {
return ['success' => false, 'error' => $e->getMessage()];
}
}
}