- 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.
154 lines
5.2 KiB
PHP
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()];
|
|
}
|
|
}
|
|
}
|