Sermepa PHP Library

repository·master·Indexed 42 days ago

https://github.com/ssheduardo/sermepa

A PHP library for integrating the Redsys/Sermepa payment gateway, supporting banks such as Santander, Sabadell, LaCaixa, and BBVA. It provides functionality for various transaction types, payment methods (including Bizum, PayPal, and GooglePay/ApplePay), and multiple environments including REST and InSite embedded payments via iframes. Supports PHP 7.1.3 up to 8.5.

Tokens
50.7K
Snippets
54
Records
68
Agent score
50%

What's inside Sermepa

  1. Understand Redsys response codes

    master

    The bank returns a code in the Ds_Response field.

    Crucial: A successful payment is indicated by a code between 0000 and 0099. Always cast the response to an integer for comparison: $DsResponse = (int) $parameters['Ds_Response'];.

    Common codes:

    • 0000 to 0099: Payment approved
    • 0100 to 0199: OK, CVV verification mandatory
    • 0201: Signature error
    • 0204: Data error
    • 0209: Card error
    • 0214: Incorrect expiry date
    • 0290: Card not authorized
    • 0404: Merchant configuration error
    • 9913: Communication error
    • 9993: User abandoned operation
    • 9997: Timeout
    • 9999: General error
  2. Manage saved cards (Tokens)

    master

    1. Saving a card for future use

    To save a card, call setIdentifier() without parameters. The bank's response will contain Ds_Merchant_Identifier and Ds_ExpiryDate, which you should store.

    2. Using a saved reference

    To perform a recurring payment using a stored identifier:

    • Call setIdentifier('STORED_IDENTIFIER').
    • Call setMerchantDirectPayment(true) to bypass 3D Secure authentication.

    3. Deleting a reference (token)

    To delete a stored reference, use transaction type 44 (refer to MerchantTransactionTypes::ANULACION_DE_REFERENCIA).

    // 1. Create reference (first payment)
    $redsys->setIdentifier();
    
    // 2. Use reference (recurring payments)
    $redsys->setIdentifier('IDENTIFICADOR_GUARDADO');
    $redsys->setMerchantDirectPayment(true);
    
    // 3. Delete a reference (token)
    use Redsys\Merchant\MerchantTransactionTypes;
    
    $redsys = new Tpv();
    $redsys->setAmount(0)
        ->setOrder('1234AB')
        ->setMerchantcode('999008881')
        ->setCurrency('978')
        ->setTransactiontype(MerchantTransactionTypes::ANULACION_DE_REFERENCIA) // 44
        ->setTerminal('1')
        ->setIdentifier('IDENTIFICADOR_A_BORRAR')
        ->setEnvironment('restTest');
    
    $signature = $redsys->generateMerchantSignature('TU_CLAVE_SECRETA');
    $redsys->setMerchantSignature($signature);
    
    $response = json_decode($redsys->send(), true);
  3. Use InSite for embedded payment forms

    master

    InSite allows you to embed the payment form directly into your website. You can use two modes:

    1. Unified Mode: Use createInSiteForm(...) to generate an embedded form. You can customize the appearance using parameters like $containerId, $buttonStyle, $bodyStyle, $inputStyle, and $language.
    2. JSON Mode: Use createInSiteFormJSON(array) to generate the form configuration as JSON.

    To execute a payment using an operation ID, use sendInSite(string $idOper, string $key). You can check the current status with getInSiteMode() and retrieve the required JavaScript URL via getInSiteJsUrl().

  4. Quickstart: Create a payment form with Tpv

    master

    Use the Sermepa\Tpv\Tpv class to configure a payment request and generate the HTML form required to redirect the user to the gateway.

    Key methods:

    • setAmount(int): Amount in cents (e.g., 2500 for 25.00€).
    • setOrder(string): Your unique order reference.
    • setMerchantcode(string): Your Redsys merchant code.
    • setCurrency(string): Currency code (e.g., '978' for Euros).
    • setTransactiontype(string): Type of transaction (e.g., '0' for Authorization).
    • setEnvironment(string): Set to test for sandbox or live for production.
    • generateMerchantSignature(string): Generates the signature using your secret key.
    • createForm(): Returns the HTML <form> string to be echoed in your view.
    use Sermepa\
    Tpv\
    Tpv;
    
    $redsys = new Tpv();
    $redsys->setAmount(2500)           // 25.00€
        ->setOrder('1234AB')
        ->setMerchantcode('999008881')
        ->setCurrency('978')           // Euros
        ->setTransactiontype('0')       // Autorización
        ->setTerminal('1')
        ->setMethod('C')                // Solo tarjeta
        ->setNotification('https://tusitio.com/notificacion')
        ->setUrlOk('https://tusitio.com/ok')
        ->setUrlKo('https://tusitio.com/ko')
        ->setEnvironment('test');       // Entorno de pruebas
    
    $signature = $redsys->generateMerchantSignature('TU_CLAVE_SECRETA');
    $redsys->setMerchantSignature($signature);
    
    echo $redsys->createForm();
  5. Validate bank response in a callback (Notification)

    master

    When Redsys sends a notification (callback) to your server, you must validate the signature and check the response code to ensure the payment was successful and legitimate.

    1. Use getMerchantParameters(string $Ds_MerchantParameters) to decode the encoded parameters sent in the $_POST request.
    2. Use check(string $key, array $postData) to verify the HMAC-SHA256 signature using your secret key and the $_POST data.
    3. Check the Ds_Response value within the decoded parameters. A successful payment typically has a response code between 0 and 99.
    <?php
    use Sermepa\Tpv\Tpv;
    use Sermepa\Tpv\TpvException;
    
    try {
        $key = 'YOUR_SECRET_KEY';
        $redsys = new Tpv();
    
        // 1. Decode parameters
        $parameters = $redsys->getMerchantParameters($_POST['Ds_MerchantParameters']);
    
        // 2. Extract response and order
        $DsResponse = (int) $parameters['Ds_Response'];
        $DsOrder = $parameters['Ds_Order'];
    
        // 3. Validate signature and response
        if ($redsys->check($key, $_POST)) {
            if ($DsResponse >= 0 && $DsResponse <= 99) {
                // Payment approved
                error_log("Pago exitoso - Pedido: $DsOrder, Respuesta: $DsResponse");
            } else {
                // Payment denied
                error_log("Pago denegado - Pedido: $DsOrder, Respuesta: $DsResponse");
            }
        } else {
            // Invalid signature
            error_log("Firma inválida - Pedido: $DsOrder");
        }
    
    } catch (TpvException $e) {
        error_log('Error TPV: ' . $e->getMessage());
        http_response_code(500);
    }
  6. Integrate InSite (Embedded Payment) via iframe

    master

    InSite allows you to embed a payment form directly into your website using an iframe, ensuring card data never touches your server (PCI DSS compliance).

    Prerequisite: Your domain must be registered in the Redsys Administration Portal. Contact your bank or Redsys support to configure allowed domains.

    Integration Flow

    1. Generate InSite Form: Render the iframe on your page.
    2. User Completes Payment: User enters data inside the Redsys iframe.
    3. Obtain Operation ID: Redsys returns an idOper (valid for 30 minutes).
    4. Execute Payment: Send the idOper via the REST API.
    use Sermepa		Tpv;
    use Redsys\Merchant\MerchantInsiteLanguage;
    
    $redsys = new Tpv();
    $redsys->setEnvironment('insiteSandbox')  // or 'insiteLive' for production
        ->setOrder('1234AB')
        ->setMerchantcode('999008881')        // Your FUC
        ->setTerminal('1');
    
    // Generate InSite HTML form
    $htmlForm = $redsys->createInSiteForm(
        'card-form',              // Container ID
        'background: #007bff;',   // Button style
        'color: white;',          // Body style
        'padding: 10px;',         // Box style
        'font-size: 14px;',       // Input style
        'Pagar',
        MerchantInsiteLanguage::ISO_ES,
        true,
        false,
        'inline'
    );
    
    echo $htmlForm;
  7. Use the REST API for direct payments (no form)

    master

    For direct payments without user redirection (server-to-server), use the send() method. This is suitable for recurring payments or when using stored tokens.

    Key configuration for REST:

    • setMerchantDirectPayment(true)
    • setVersion('HMAC_SHA256_V1')
    • setEnvironment('restTest') or restLive.
    • setMerchantCofIni('N')
    use Sermepa\Tpv\Tpv;
    use Sermepa\Tpv\TpvException;
    
    try {
        $key = 'TU_CLAVE_SECRETA';
    
        $redsys = new Tpv();
        $redsys->setAmount(2500)
            ->setOrder('1234AB')
            ->setMerchantcode('999008881')
            ->setCurrency('978')
            ->setTransactiontype('0')
            ->setIdentifier('IDENTIFICADOR_GUARDADO')
            ->setMerchantDirectPayment(true)
            ->setVersion('HMAC_SHA256_V1')
            ->setEnvironment('restTest')
            ->setMerchantCofIni('N');
    
        $signature = $redsys->generateMerchantSignature($key);
        $redsys->setMerchantSignature($signature);
    
        $response = json_decode($redsys->send(), true);
    
        // Check for API error
        if (isset($response['errorCode'])) {
            throw new Exception("Error: " . $response['errorCode']);
        }
    
        // Decode response parameters
        $parameters = $redsys->getMerchantParameters($response['Ds_MerchantParameters']);
        $DsResponse = (int) $parameters['Ds_Response'];
    
        if ($redsys->check($key, $response) && $DsResponse <= 99) {
            // Payment successful
        }
    } catch (TpvException $e) {
        echo 'Error TPV: ' . $e->getMessage();
    }
  8. Send card data directly

    master

    If your merchant account is authorized by the bank to handle sensitive data, you can pass card details directly to the library to avoid user redirection.

    Warning: This requires specific bank authorization.

    $redsys->setPan('4548812049400004');     // Card number
    $redsys->setExpiryDate('1228');          // Expiry (AAMM)
    $redsys->setCVV2('123');                 // CVV2
  9. Execute InSite Payment with Operation ID

    master

    After the user completes the payment in the iframe, you must capture the idOper (returned in a hidden field named token) and call sendInSite to finalize the transaction via the REST API.

    Important: The order parameter used in this step must match the order used when generating the InSite form.

    use Sermepa\Tpv\Tpv;
    use Sermepa\Tpv\TpvException;
    
    try {
        $key = 'TU_CLAVE_SECRETA';
        $idOper = $_POST['token'];    // ID received from the iframe
        $order = '1234AB';             // MUST be the same order used in createInSiteForm
    
        $redsys = new Tpv();
        $redsys->setEnvironment('insiteRestLive')  // or 'insiteRestSandbox'
            ->setAmount(2500)
            ->setOrder($order)
            ->setMerchantcode('999008881')
            ->setCurrency('978')
            ->setTransactiontype('0')
            ->setTerminal('1');
    
        // Execute payment with the operation ID
        $response = json_decode($redsys->sendInSite($idOper, $key), true);
    
        // Decode response
        $parameters = $redsys->getMerchantParameters($response['Ds_MerchantParameters']);
        $DsResponse = (int) $parameters['Ds_Response'];
    
        if ($DsResponse >= 0 && $DsResponse <= 99) {
            // Payment approved
        } else {
            // Payment denied
        }
    
    } catch (TpvException $e) {
        echo 'Error TPV: ' . $e->getMessage();
    }
  10. Validate bank responses in notification URLs

    master

    When the bank calls your notification URL (configured via setNotification), you must validate the signature and the response code to ensure the payment is legitimate.

    Use getMerchantParameters() to decode the Ds_MerchantParameters POST field and check() to verify the signature.

    use Sermepa\Tpv\Tpv;
    use Sermepa\Tpv\TpvException;
    
    try {
        $redsys = new Tpv();
        $key = 'TU_CLAVE_SECRETA';
    
        // Decode received parameters
        $parameters = $redsys->getMerchantParameters($_POST['Ds_MerchantParameters']);
        $DsResponse = (int) $parameters['Ds_Response'];
    
        // Validate signature and response
        if ($redsys->check($key, $_POST) && $DsResponse <= 99) {
            // Payment successful (Ds_Response = 0000 to 0099)
            // Update order, send email, etc.
        } else {
            // Payment failed
        }
    } catch (TpvException $e) {
        error_log('Error TPV: ' . $e->getMessage());
    }