Vai al contenuto

Esempi PHP - API Salabam Solutions

Installazione

composer require firebase/jwt

Classe SSO Completa

<?php
use Firebase\JWT\JWT;

class SalabamSSO {
    private $username = 'your-company';
    private $secret = 'your-secret-key';
    private $baseUrl = 'https://ws.salabam.com';

    public function generateSSO($employee, $beneficiaries = null) {
        $payload = [
            'iss' => 'https://yourdomain.com',
            'aud' => $this->baseUrl,
            'iat' => time(),
            'exp' => time() + (4 * 3600),
            'data' => [
                'orderAuthUrl' => 'https://yourdomain.com/api/authorize',
                'orderConfirmUrl' => 'https://yourdomain.com/api/confirm',
                'orderRevokeUrl' => 'https://yourdomain.com/api/revoke',
                'employee' => $employee
            ]
        ];

        // Gestione beneficiari - 3 scenari
        if ($beneficiaries === null) {
            // Scenario 1: omesso - checkout libero
            // Non aggiungere il campo
        } elseif ($beneficiaries === []) {
            // Scenario 2: array vuoto - solo employee
            $payload['data']['beneficiaries'] = (object)[];
        } else {
            // Scenario 3: array con beneficiari
            $payload['data']['beneficiaries'] = $beneficiaries;
        }

        $jwt = JWT::encode($payload, $this->secret, 'HS256');

        // Chiamata SSO
        $response = $this->callSSO($jwt);
        return $response['data']['redirectTo'];
    }

    private function callSSO($jwt) {
        $url = "{$this->baseUrl}/ws/v1/sso/{$this->username}";

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
            'message' => 'token request',
            'jwt' => $jwt
        ]));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json'
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            throw new Exception("SSO failed: HTTP $httpCode");
        }

        return json_decode($response, true);
    }
}

Gestione Callback

<?php
// callback.php - Gestione autorizzazioni ordine

require_once 'vendor/autoload.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$secret = 'your-secret-key';

function handleAuthCallback() {
    global $secret;

    // Timeout di sicurezza
    set_time_limit(25);

    $input = json_decode(file_get_contents('php://input'), true);

    if ($input['message'] !== 'order authorization request') {
        http_response_code(400);
        echo json_encode(['status' => 'error', 'message' => 'Invalid request']);
        return;
    }

    try {
        // Decodifica JWT
        $decoded = JWT::decode($input['jwt'], new Key($secret, 'HS256'));
        $data = $decoded->data;

        $employeeId = $data->id;
        $price = floatval($data->price);
        $relation = $data->relation;

        // Log per debugging
        error_log("Auth request - ID: {$employeeId}, Relation: {$relation}, Price: €{$price}");

        // Nota: id = "0" significa beneficiario inserito a piacere
        if ($employeeId === '0') {
            error_log('Beneficiario inserito liberamente dal dipendente');
        }

        // Verifica credito disponibile
        $availableCredit = getUserCredit($employeeId);

        if ($availableCredit >= $price) {
            // Congela credito (per doppia conferma)
            freezeCredit($employeeId, $price, $data->salabamReferenceId);

            http_response_code(200);
            echo json_encode([
                'status' => 'success',
                'message' => 'order authorized'
            ]);
        } else {
            http_response_code(402);
            echo json_encode([
                'status' => 'error',
                'message' => 'insufficient credit',
                'available' => $availableCredit,
                'required' => $price
            ]);
        }

    } catch (Exception $e) {
        error_log('Authorization error: ' . $e->getMessage());
        http_response_code(500);
        echo json_encode([
            'status' => 'error',
            'message' => 'Internal server error'
        ]);
    }
}

// Funzioni di supporto
function getUserCredit($userId) {
    // Implementa la tua logica per ottenere il credito
    // Esempio con database
    $pdo = new PDO('mysql:host=localhost;dbname=welfare', $user, $pass);
    $stmt = $pdo->prepare("SELECT credit_balance FROM employees WHERE id = ?");
    $stmt->execute([$userId === '0' ? getEmployeeFromSession() : $userId]);
    return $stmt->fetchColumn();
}

function freezeCredit($userId, $amount, $referenceId) {
    // Congela il credito per la doppia conferma
    $pdo = new PDO('mysql:host=localhost;dbname=welfare', $user, $pass);
    $pdo->prepare("INSERT INTO frozen_credits (user_id, amount, reference_id, expires_at) VALUES (?, ?, ?, DATE_ADD(NOW(), INTERVAL 6 HOUR))")
         ->execute([$userId, $amount, $referenceId]);
}

// Esegui callback
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    handleAuthCallback();
}

Endpoint Conferma

<?php
// confirm.php - Conferma definitiva ordine

function handleConfirmCallback() {
    global $secret;

    $input = json_decode(file_get_contents('php://input'), true);

    try {
        $decoded = JWT::decode($input['jwt'], new Key($secret, 'HS256'));
        $data = $decoded->data;

        $employeeId = $data->id;
        $price = floatval($data->price);
        $referenceId = $data->salabamReferenceId;

        // Addebita credito definitivamente
        deductCredit($employeeId, $price);

        // Salva ordine
        saveOrder($referenceId, $data);

        // Rimuovi credito congelato
        removeFrozenCredit($referenceId);

        http_response_code(200);
        echo json_encode([
            'status' => 'success',
            'message' => 'order confirmed'
        ]);

    } catch (Exception $e) {
        error_log('Confirmation error: ' . $e->getMessage());
        http_response_code(500);
        echo json_encode([
            'status' => 'error',
            'message' => 'Internal server error'
        ]);
    }
}

function deductCredit($userId, $amount) {
    $pdo = new PDO('mysql:host=localhost;dbname=welfare', $user, $pass);
    $pdo->prepare("UPDATE employees SET credit_balance = credit_balance - ? WHERE id = ?")
         ->execute([$amount, $userId]);
}

function saveOrder($referenceId, $orderData) {
    $pdo = new PDO('mysql:host=localhost;dbname=welfare', $user, $pass);
    $pdo->prepare("INSERT INTO orders (salabam_ref, employee_id, product_name, amount, created_at) VALUES (?, ?, ?, ?, NOW())")
         ->execute([$referenceId, $orderData->id, $orderData->productName, $orderData->price]);
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    handleConfirmCallback();
}

Test dei 3 Scenari Beneficiari

<?php
// test_beneficiaries.php

$sso = new SalabamSSO();
$employee = [
    'id' => 'EMP123',
    'name' => 'Mario',
    'surname' => 'Rossi',
    'email' => 'mario.rossi@company.com',
    'fiscalCode' => 'RSSMRA85M01H501X',
    'availability' => 500.00
];

// Test Scenario 1: Campo omesso - checkout libero
$url1 = $sso->generateSSO($employee);
echo "Scenario 1 (libero): $url1\n";

// Test Scenario 2: Campo vuoto - solo employee
$url2 = $sso->generateSSO($employee, []);
echo "Scenario 2 (solo employee): $url2\n";

// Test Scenario 3: Con lista beneficiari
$beneficiaries = [
    [
        'id' => 'BEN001',
        'name' => 'Laura',
        'surname' => 'Bianchi',
        'fiscalCode' => 'BNCLRA82D45H501Y',
        'email' => 'laura.bianchi@email.com',
        'relation' => 'coniuge'
    ],
    [
        'id' => 'BEN002',
        'name' => 'Marco',
        'surname' => 'Rossi',
        'fiscalCode' => 'RSSMRC10A01H501Z',
        'relation' => 'figli'
    ]
];

$url3 = $sso->generateSSO($employee, $beneficiaries);
echo "Scenario 3 (con lista): $url3\n";

Esempio Completo WordPress

<?php
// wp-salabam-integration.php - Plugin WordPress

function salabam_create_sso_link($employee_id) {
    $employee = get_user_meta($employee_id, 'salabam_employee', true);
    $beneficiaries_mode = get_option('salabam_beneficiaries_mode', 'open');

    $sso = new SalabamSSO();

    // Gestione beneficiari dinamica
    switch ($beneficiaries_mode) {
        case 'employee_only':
            $beneficiaries = [];
            break;
        case 'family_members':
            $beneficiaries = get_user_meta($employee_id, 'family_members', true);
            break;
        default:
            $beneficiaries = null; // Campo omesso
    }

    return $sso->generateSSO($employee, $beneficiaries);
}

// Shortcode per WordPress
add_shortcode('salabam_button', function($atts) {
    if (!is_user_logged_in()) {
        return '<p>Effettua il login per accedere ai servizi Salabam.</p>';
    }

    $user_id = get_current_user_id();
    $sso_url = salabam_create_sso_link($user_id);

    return sprintf(
        '<a href="%s" class="btn btn-primary" target="_blank">Accedi a Salabam</a>',
        esc_url($sso_url)
    );
});

Questa documentazione PHP fornisce tutto il necessario per integrare le API Salabam Solutions con gestione completa di SSO, beneficiari e callback.