- Migrated PaymentIntentService with plugin-specific namespacing. - Added AJAX endpoints for client searching and SPEI reference generation. - Implemented global premium header with SIIP Blue gradient. - Optimized sidebar UI: increased logo size to 180px and nav icons/text. - Improved Dark Mode accessibility with high-contrast primary colors. - Added "View in CRM" functionality and automated Stripe admin logic. - Fixed layout nesting issues and polished CSS layering.
172 lines
5.8 KiB
PHP
172 lines
5.8 KiB
PHP
<?php
|
|
|
|
namespace SmsNotifier\Service;
|
|
|
|
use GuzzleHttp\Client;
|
|
use Stripe\StripeClient;
|
|
use Stripe\Exception\ApiErrorException;
|
|
|
|
class PaymentIntentService
|
|
{
|
|
private $ucrmApiUrl;
|
|
private $ucrmApiKey;
|
|
private $stripeApiKey;
|
|
private $httpClient;
|
|
private $stripeClient;
|
|
private $logger;
|
|
|
|
public function __construct($ucrmApiUrl, $ucrmApiKey, $stripeApiKey, $logger = null)
|
|
{
|
|
$this->ucrmApiUrl = rtrim($ucrmApiUrl, '/');
|
|
$this->ucrmApiKey = $ucrmApiKey;
|
|
$this->stripeApiKey = $stripeApiKey;
|
|
$this->logger = $logger;
|
|
|
|
$this->httpClient = new Client([
|
|
'base_uri' => $this->ucrmApiUrl . '/api/v1.0/',
|
|
'headers' => [
|
|
'X-Auth-App-Key' => $this->ucrmApiKey,
|
|
'Accept' => 'application/json',
|
|
],
|
|
'verify' => false,
|
|
'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;
|
|
$clabeInterbancaria = null;
|
|
if (isset($client['attributes'])) {
|
|
foreach ($client['attributes'] as $attribute) {
|
|
if ($attribute['key'] === 'stripeCustomerId' || $attribute['name'] === 'Stripe Customer ID') {
|
|
$stripeCustomerId = $attribute['value'];
|
|
}
|
|
if ($attribute['key'] === 'clabeInterbancaria' || $attribute['name'] === 'Clabe Interbancaria') {
|
|
$clabeInterbancaria = $attribute['value'];
|
|
}
|
|
}
|
|
}
|
|
|
|
return [
|
|
'id' => $client['id'],
|
|
'fullName' => ($client['clientType'] == 1)
|
|
? $client['firstName'] . ' ' . $client['lastName']
|
|
: $client['companyName'],
|
|
'stripeCustomerId' => $stripeCustomerId,
|
|
'clabeInterbancaria' => $clabeInterbancaria,
|
|
'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',
|
|
'paymentType' => 'card.one_time',
|
|
'signedInAdminId' => $adminId,
|
|
'tipoPago' => 'Transferencia Bancaria'
|
|
],
|
|
]);
|
|
|
|
$this->log("PaymentIntent created: " . $paymentIntent->id . " Status: " . $paymentIntent->status);
|
|
|
|
return [
|
|
'success' => true,
|
|
'id' => $paymentIntent->id,
|
|
'status' => $paymentIntent->status,
|
|
'amount' => $paymentIntent->amount / 100,
|
|
'currency' => $paymentIntent->currency,
|
|
'next_action' => $paymentIntent->next_action
|
|
];
|
|
|
|
} catch (ApiErrorException $e) {
|
|
return ['success' => false, 'error' => $e->getMessage()];
|
|
} catch (\Exception $e) {
|
|
return ['success' => false, 'error' => $e->getMessage()];
|
|
}
|
|
}
|
|
|
|
private function log($message)
|
|
{
|
|
if ($this->logger) {
|
|
$this->logger->debug($message);
|
|
} else {
|
|
error_log($message);
|
|
}
|
|
}
|
|
}
|