Pago realizado

Una vez que se ha realizado el pago, puede obtener información sobre la transacción recién creada de dos maneras distintas.

Si define una URL de retorno utilizando el parámetro kr-post-url-success, el cliente JavaScript publicará el resultado en la página indicada. Consulte la sección: Retorno del navegador.

En caso de que, en el marco de una aplicación web de una sola página, desee recuperar la transacción recién creada en JavaScript, consulte el siguiente artículo: Aplicaciones web de una sola página.

Retorno del navegador

Una vez que el pago se ha realizado, el cliente JavaScript envía el resultado del pago a la URL definida por el parámetro kr-post-url-success mediante un formulario en modo POST. El formulario enviado mediante modo POST contiene los siguientes datos:

Parámetro Valor
kr-hash c3c0323c748fdb7c2d24bd39ada99663526236828efa795193bebfdea022fe58
kr-hash-algorithm sha256_hmac
kr-hash-key sha256_hmac
kr-answer-type V4/Payment
kr-answer {“shopId”:”33148340”,”orderCycle”:”CLOSED”,”orderStatus”:”PAID”, (…)

Estos parámetros corresponden a:

Parámetro Descripción
kr-hash Hash del objeto JSON almacenado en kr-answer. Permite comprobar la autenticidad de la respuesta.
kr-hash-algorithm Algoritmo utilizado para calcular el hash. Su valor es sha256_hmac.
kr-answer-type Tipo del objeto JSON contenido en kr-answer.
kr-hash-key Tipo de clave utilizada para firmar kr-answer. Su valor puede ser sha256_hmac (retorno del navegador) o password (IPN).
kr-answer Objeto que contiene el resultado del pago, codificado en JSON.

El parámetro kr-answer contiene la información sobre el estado de la sesión de pago:

{
    "shopId": "69876357",
    "orderCycle": "CLOSED",
    "orderStatus": "PAID",
    "serverDate": "2018-09-27T14:02:17+00:00",
    "orderDetails": {
        "orderTotalAmount": 990,
        "orderCurrency": "EUR",
        "mode": "TEST",
        "orderId": null,
        "_type": "V4/OrderDetails"
    },
    "customer": {
        "billingDetails": {
            "address": null,
            "category": null,
            "cellPhoneNumber": null,
            "city": null,
            "country": null,
            "district": null,
            "firstName": null,
            "identityCode": null,
            "language": "EN",
            "lastName": null,
            "phoneNumber": null,
            "state": null,
            "streetNumber": null,
            "title": null,
            "zipCode": null,
            "_type": "V4/Customer/BillingDetails"
        },
        "email": "sample@example.com",
        "reference": null,
        "shippingDetails": {
            "address": null,
            "address2": null,
            "category": null,
            "city": null,
            "country": null,
            "deliveryCompanyName": null,
            "district": null,
            "firstName": null,
            "identityCode": null,
            "lastName": null,
            "legalName": null,
            "phoneNumber": null,
            "shippingMethod": null,
            "shippingSpeed": null,
            "state": null,
            "streetNumber": null,
            "zipCode": null,
            "_type": "V4/Customer/ShippingDetails"
        },
        "extraDetails": {
            "browserAccept": null,
            "fingerPrintId": null,
            "ipAddress": "90.71.64.161",
            "browserUserAgent": "Mozilla/5.0",
            "_type": "V4/Customer/ExtraDetails"
        },
        "shoppingCart": {
            "insuranceAmount": null,
            "shippingAmount": null,
            "taxAmount": null,
            "cartItemInfo": null,
            "_type": "V4/Customer/ShoppingCart"
        },
        "_type": "V4/Customer/Customer"
    },
    "transactions": [{
        "shopId": "69876357",
        "uuid": "5b158f084502428499b2d34ad074df05",
        "amount": 990,
        "currency": "EUR",
        "paymentMethodType": "CARD",
        "paymentMethodToken": null,
        "status": "PAID",
        "detailedStatus": "AUTHORISED",
        "operationType": "DEBIT",
        "effectiveStrongAuthentication": "DISABLED",
        "creationDate": "2018-09-27T14:02:16+00:00",
        "errorCode": null,
        "errorMessage": null,
        "detailedErrorCode": null,
        "detailedErrorMessage": null,
        "metadata": null,
        "transactionDetails": {
            "liabilityShift": "NO",
            "effectiveAmount": 990,
            "effectiveCurrency": "EUR",
            "creationContext": "CHARGE",
            "cardDetails": {
                "paymentSource": "EC",
                "manualValidation": "NO",
                "expectedCaptureDate": "2018-09-27T14:02:16+00:00",
                "effectiveBrand": "CB",
                "pan": "497010XXXXXX0055",
                "expiryMonth": 11,
                "expiryYear": 2021,
                "country": "FR",
                "emisorCode": null,
                "effectiveProductCode": "F",
                "legacyTransId": "927516",
                "legacyTransDate": "2018-09-27T14:02:05+00:00",
                "paymentMethodSource": "NEW",
                "authorizationResponse": {
                    "amount": 990,
                    "currency": "EUR",
                    "authorizationDate": "2018-09-27T14:02:16+00:00",
                    "authorizationNumber": "3fe7a1",
                    "authorizationResult": "0",
                    "authorizationMode": "FULL",
                    "_type": "V4/PaymentMethod/Details/Cards/CardAuthorizationResponse"
                },
                "captureResponse": {
                    "refundAmount": null,
                    "captureDate": null,
                    "captureFileNumber": null,
                    "refundCurrency": null,
                    "_type": "V4/PaymentMethod/Details/Cards/CardCaptureResponse"
                },
                "threeDSResponse": {
                    "authenticationResultData": {
                        "transactionCondition": "COND_3D_ERROR",
                        "enrolled": "UNKNOWN",
                        "status": "UNKNOWN",
                        "eci": null,
                        "xid": null,
                        "cavvAlgorithm": null,
                        "cavv": null,
                        "signValid": null,
                        "brand": "VISA",
                        "_type": "V4/PaymentMethod/Details/Cards/CardAuthenticationResponse"
                    },
                    "_type": "V4/PaymentMethod/Details/Cards/ThreeDSResponse"
                },
                "installmentNumber": null,
                "markAuthorizationResponse": {
                    "amount": null,
                    "currency": null,
                    "authorizationDate": null,
                    "authorizationNumber": null,
                    "authorizationResult": null,
                    "_type": "V4/PaymentMethod/Details/Cards/MarkAuthorizationResponse"
                },
                "_type": "V4/PaymentMethod/Details/CardDetails"
            },
            "parentTransactionUuid": null,
            "mid": "6969696",
            "sequenceNumber": 1,
            "_type": "V4/TransactionDetails"
        },
        "_type": "V4/PaymentTransaction"
    }],
    "_type": "V4/Payment"
}

¿Cómo obtener la respuesta?

Los SDK a su disposición le permiten extraer fácilmente los datos POST:

/* Use client SDK helper to retrieve POST parameters */
$formAnswer = $client->getParsedFormAnswer();

En PHP, si no utiliza nuestro SDK, simplemente obtenga el contenido de la variable superglobal $_POST.

Verificar la firma del navegador (hash)

Para detectar posibles fraudes, es necesario comprobar la autenticidad del campo kr-answer.

El campo kr-hash contiene el hash de kr-answer generado con la clave HMAC-SHA-256.

Esta clave está disponible en su Back Office (menú Configuración > Tienda, pestaña Claves de API REST, sección API REST: claves utilizadas para calcular / verificar el campo kr-hash).

Para comprobar la validez de la firma con nuestros SDK:

if (!$client->checkHash()) {
    //something wrong, probably a fraud ....
    signature_error($formAnswer['kr-answer']['transactions'][0]['uuid'], $hashKey, 
                    $client->getLastCalculatedHash(), $_POST['kr-hash']);
    throw new Exception("invalid signature");
}

Ejemplo de implementación de la verificación del hash en PHP:

    /**
     * check kr-answer object signature
     */
    public function checkHash($key=NULL)
    {
        $supportedHashAlgorithm = array('sha256_hmac');

        /* check if the hash algorithm is supported */
        if (!in_array($_POST['kr-hash-algorithm'],  $supportedHashAlgorithm)) {
            throw new LyraException("hash algorithm not supported:" . $_POST['kr-hash-algorithm'] .". Update your SDK");
        }

        /* on some servers, / can be escaped */
        $krAnswer = str_replace('\/', '/', $_POST['kr-answer']);

        /* if key is not defined, we use kr-hash-key POST parameter to choose it */
        if (is_null($key)) {
            if ($_POST['kr-hash-key'] == "sha256_hmac") {
                $key = $this->_hashKey;
            } elseif ($_POST['kr-hash-key'] == "password") {
                $key = $this->_password;
            } else {
                throw new LyraException("invalid kr-hash-key POST parameter");
            }
        }
    
        $calculatedHash = hash_hmac('sha256', $krAnswer, $key);
        $this->_lastCalculatedHash = $calculatedHash;

        /* return true if calculated hash and sent hash are the same */
        return ($calculatedHash == $_POST['kr-hash']);
    }
}

Verificar la transacción

Basta con comprobar el parámetro orderStatus contenido en kr-answer. Si el valor del campo es PAID, la transacción ha sido pagada. Consulte Referencias de estado para más detalles.

Gestionar la notificación de fin de pago (IPN)

Si se interrumpe la conexión a la red o si el comprador cierra su navegador, es posible que nunca reciba los parámetros del formulario.

Utilizando la IPN está seguro de recibir datos en todos sin importar el caso.

Los datos de la IPN son más seguros que los que han pasado por el navegador del comprador. Se envían directamente a sus servidores. Por consiguiente, no pueden ser alterados por un plugin corrupto o un spyware instalado en el navegador del comprador.

Para comprender cómo implementar las IPN, consulte: Uso de la IPN