PHP code example of pimia / pimia-php

1. Go to this page and download the library: Download pimia/pimia-php library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

pimia / pimia-php example snippets


use GuzzleHttp\Client;
use GuzzleHttp\Psr7\HttpFactory;
use Pimia\{Config, PimiaClient, Scopes};
use Pimia\Http\PsrTransport;
use Pimia\OAuth\{InMemoryTokenStore, OAuthClient, PkceChallenge};

$config = new Config(
    baseUrl: 'https://acme.pimia.es',
    clientId: getenv('PIMIA_CLIENT_ID'),
    clientSecret: getenv('PIMIA_CLIENT_SECRET') ?: null,
    redirectUri: 'https://miapp.example/callback',
);

$factory = new HttpFactory();
$transport = new PsrTransport(new Client(), $factory, $factory);

// 1. Autorización
$pkce = PkceChallenge::create();          // guarda $pkce->verifier en sesión
$oauth = new OAuthClient($config, $transport);
$url = $oauth->authorizeUrl([Scopes::INVOICES_READ], PkceChallenge::state(), $pkce);

// 2. Callback: canje + persistencia
$tokens = new InMemoryTokenStore();       // en producción: tu BD
$tokens->save($oauth->exchangeCode($code, PkceChallenge::fromVerifier($verifierDeSesion)));

// 3. Uso
$pimia = new PimiaClient($config, $transport, $tokens);
$invoices = $pimia->invoices->list(['page' => 1]);

$pimia = PimiaClient::withBorrowedToken(
    baseUrl: "https://{$tenant}.pimia.es",
    accessToken: $bearerDeQuienLlama,
    transport: $transport,
    // La empresa activa viaja en cabecera, como en todo el API. OMÍTELA cuando
    // no la sepas: `company:` vacía es una cabecera presente que no casa con
    // ninguna empresa.
    headers: $empresa === null ? [] : ['company' => (string) $empresa],
    // Atiendes una petición web: los reintentos del SDK DUERMEN, y dormir
    // dentro de la petición de un usuario es una petición colgada.
    maxRateLimitRetries: 0,
);

$empresa = $pimia->bootstrap->currentCompanyId();
$censo = $pimia->crm->assignableUsers();

$suscripcion = $pimia->billing->integrador->subscription();
$portal = $pimia->billing->integrador->portal('https://app.erpstudio.es/perfil');
header('Location: '.$portal['data']['url']);

$clave = bin2hex(random_bytes(16));
$client->estimates->create($presupuesto, $clave);

$r = $client->requestWithMeta('POST', '/estimates', body: $presupuesto, idempotencyKey: $clave);

if ($r->meta->idempotentReplay) {
    // ya existía: no se ha creado nada nuevo
}

use Pimia\Exception\WebhookVerificationException;
use Pimia\Webhooks\WebhookEvent;
use Pimia\Webhooks\WebhookVerifier;

$verifier = new WebhookVerifier(getenv('PIMIA_WEBHOOK_SECRET'));

try {
    // ⚠️ El cuerpo CRUDO. En Laravel, $request->getContent() — nunca
    // json_encode($request->all()): Pimia firma los bytes que envía y
    // reserializar rompe la firma sin que se vea por qué.
    $hook = $verifier->verify($request->headers->all(), $request->getContent());
} catch (WebhookVerificationException $e) {
    return response($e->reason, 400);
}

// Pimia reintenta: la misma entrega llega con el mismo id.
if ($yaProcesado($hook->delivery)) {
    return response('', 200);
}

match ($hook->event) {
    WebhookEvent::EstimateAccepted => $facturar($hook->payload['id']),
    WebhookEvent::InvoicePaid      => $cobrar($hook->payload['id']),
    default                        => null, // incluye el catálogo futuro
};

return response('', 200); // responde rápido; el trabajo pesado, a una cola

use Pimia\OwnerConfirmationRequired;

$result = $pimia->put('/users/42', ['role' => 'admin']);
$pending = OwnerConfirmationRequired::fromResponse($result);
if ($pending !== null) {
    mostrarPendiente($pending->message); // $pending->id identifica la solicitud.
} else {
    mostrarUsuarioActualizado($result);
}

// Cuotas: es el ÚNICO modo que crea o adopta recurrente al activar.
$client->contracts->create([
    'title' => 'Mantenimiento', 'customer_id' => 5, 'starts_at' => '2026-10-01',
    'billing_mode' => 'INSTALLMENTS', 'amount' => 12000, 'billing_every' => 'MONTHLY',
]);

// Hitos: total opcional, guía ordenada en céntimos, proyecto y clausulado.
$client->contracts->create([
    'title' => 'Reforma', 'customer_id' => 5, 'starts_at' => '2026-10-01',
    'billing_mode' => 'MILESTONES', 'total_amount' => 450000,
    'project_id' => 11, 'contract_model_version_id' => 9,
    'milestones' => [
        ['description' => 'Fase 1', 'amount' => 150000, 'planned_date' => '2026-11-01', 'position' => 1],
        ['description' => 'Fase 2', 'amount' => 300000, 'planned_date' => null, 'position' => 2],
    ],
]);

$diccionario = $client->contracts->models->variables('MILESTONES');
// $diccionario['meta']['limits'] y ['block_types'] vienen del servidor.

$modelo = $client->contracts->models->create([
    'name' => 'Mantenimiento',
    'draft_revision' => 0,
    'content' => [
        ['type' => 'heading', 'level' => 2, 'text' => [['type' => 'text', 'value' => 'Objeto', 'bold' => true]]],
        ['type' => 'paragraph', 'text' => [['type' => 'variable', 'key' => 'customer.name']]],
        ['type' => 'table', 'variable' => 'contract.milestones'],
        ['type' => 'signature'], // dónde firma el cliente: uno, ni cero ni dos
    ],
]);
$client->contracts->models->publish($modelo['data']['id']); // versión INMUTABLE

$vista = $client->contracts->documentPreview(7, ['name' => 'Ana', 'email' => '[email protected]']);
$pdf = $client->contracts->downloadDocumentPreview(7, $vista['data']['reference']); // bytes
$client->contracts->sendForSignature(7, [
    'name' => 'Ana', 'email' => '[email protected]',
    'document_version_id' => $vista['data']['reference'],
]);

try { $client->contracts->documentPreview(7); }
catch (ValidationException $e) { $motivos = Contracts::documentBlockers($e->body); }

$sent = $client->contracts->sendForSignature(7, [
    'name' => 'Ana', 'email' => '[email protected]', 'send_email' => true,
], 'contrato-7-firma-1');
// $sent['data'] contiene el contrato; $sent['signingUrl'] permite firmarlo.
$status = $client->contracts->signatureStatus(7);
$accepted = $client->contracts->remindSignature(7); // 202: ['success' => bool]
$client->contracts->cancelSignature(7); // cancela la firma, no el contrato
bash
composer