Using the IPN (notification URL)

IPN stands for Instant Payment Notification. When a transaction is created or its status changes, our servers issue an IPN calling a Notification URL located on your servers. This allows you to be notified in real time about the changes that affected the transaction.

Fore more general information on the IPN, see the following article: IPN: background information

An IPN is the only way to be notified in the following cases:

  • The buyer has lost Internet connection
  • The buyer closed their browser during the payment
  • Transaction is rejected

Therefore, it is imperative to integrate IPNs!

Functioning

When the buyer validates the payment, a transaction is created. Our servers will attempt to communicate with your servers to transmit all the information concerning the transaction.

Step Description
1 The buyer has clicked the “pay” button: submission of the form via the buyer''s browser to our servers. This call is made automatically by our JavaScript client
2 Once the transaction has been processed, we make a call via our servers to the URL that you have defined. The complete transaction object will be sent to allow you to update your information system before the browser return. The IPN (Instant Payment Notification).
3 Our servers return the payment result to the JavaScript client
4 The JavaScript client POSTs the payment form to your servers

Step 3 occurs only after your servers have responded (the maximum delay is 30 seconds). This allows you to update your information system before the buyer is redirected to your purchase confirmation page.

Définir l’URL dans le Back Office Expert

To enable the notification:

  • 1: Connectez vous sur : https://secure.lyra.com/portal/
  • 2: Go to the following menu: Settings > Notification rules.
  • 3: Right-click Instant Payment Notification URL at the end of payment
  • 4: Select Manage the rule
  • 5: Enter the notification URLs in the Notification URL of the form API V1, V2 area for TEST and PRODUCTION
  • 6: Enter the notification URLs in the API REST area: Notification URL of the Krypton API for TEST and PRODUCTION
  • 7: Enter your e-mail address in E-mail address(es) to notify in case of failure
  • 8: To specify several e-mail addresses, separate them with a semi-colon
  • 9: Save the changes

If the target server of the IPN is offline, you will receive an e-mail at the address specified at step 7.

This e-mail contains:

  • The HTTP error code returned by your server
  • Elements of analysis
  • Explanation of the error''s consequences
  • Les instructions pour relancer l’IPN (à travers le Back Office Expert)

Specifying the URL dynamically

When creating the formToken, you can dynamically specify the target URL of the IPN using the ipnTargetUrl parameter:

{
    "amount": 990,
    "currency": "EUR",
    "ipnTargetUrl": "https://my.super.site/ipn"
}

Using IPNs

The IPN is sent to your servers using the same procedure as the JavaScript client. This allows you to use a similar code for processing the response:

  • The data is sent as a form (content-type: x-www-form-urlencoded),
  • The parameters that contain data are the same.

The differences are:

  • kr-answer contains complete transaction objects,
  • the signature included in kr-hash is calculated differently.

The IPN is sent to your servers via POST as follows:

kr-hash=c3c0323c748fdb7c2d24bd39ada99663526236828efa795193bebfdea022fe58
kr-hash-algorithm=sha256_hmac
kr-hash-key=password
kr-answer-type=V4/Payment
kr-answer={"shopId":"33148340","orderCycle":"CLOSED",(...)}

The 4 POST parameters correspond to:

Parameter Description
kr-hash Hash of the JSON object stored in kr-answer. It allows to verify the authenticity of the response
kr-hash-algorithm Algorithm used to calculate the hash
kr-hash-key Key used for signing kr-answer. Can be set to hmac_sha256 (browser return) or password (IPN).
kr-answer-type Type the JSON object stored in kr-answer
kr-answer Object containing complete transaction objects encoded in JSON

Before analyzing the contents of kr-answer, we must check if it is valid.

Verifying the IPN signature (hash)

In order to detect potential fraud, you must verify the authenticity of the kr-answer field.

The kr-hash field contains the hash of kr-answer generated with the password (that starts with testpassword_* or prodpassword_*).

To verify the validity of the signature with our SDKs:

/* Check the signature using password */

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');
}

Once the signature has been checked, you can retrieve the information related to the transaction as follows:

/* Retrieve the IPN content */
$rawAnswer = $client->getParsedFormAnswer();
$formAnswer = $rawAnswer['kr-answer'];

/* Retrieve the transaction id from the IPN data */
$transaction = $formAnswer['transactions'][0];

/* get some parameters from the answer */
$orderStatus = $formAnswer['orderStatus'];
$orderId = $answer = $formAnswer['orderDetails']['orderId'];
$transactionUuid = $transaction['uuid'];

See the next section for more information.

Example of implementing hash verification in 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']);
    }
}

The choice of the key must be based on the value of kr-hash-key:

kr-hash-key Used key Description
hmac_sha256 HMAC-SHA256 key Data received during the browser return. We use the SHA256 key to check the kr-hash value
password Password Data received via the IPN (server to server call). We use the password to check the kr-hash value

Transaction object

The transaction object is contained in the kr-answer POST parameter. It is encoded in JSON:

The kr-answer parameter contains information on the status of the payment session:

{
    "shopId": "69876357",
    "orderCycle": "CLOSED",
    "orderStatus": "PAID",
    "serverDate": "2018-09-27T14:02:17+00:00",
    "orderDetails": (...)
    "customer": (...)
    },
    "transactions": [{
        "shopId": "69876357",
        "uuid": "5b158f084502428499b2d34ad074df05",
        "amount": 990,
        (...)
        "_type": "V4/PaymentTransaction"
    }],
    "_type": "V4/Payment"
}

You can use any standard feature to access it, or via our SDK:

/* Retrieve the IPN content */
$rawAnswer = $client->getParsedFormAnswer();
$formAnswer = $rawAnswer['kr-answer'];

/* Retrieve the transaction id from the IPN data */
$transaction = $formAnswer['transactions'][0];

/* get some parameters from the answer */
$orderStatus = $formAnswer['orderStatus'];
$orderId = $answer = $formAnswer['orderDetails']['orderId'];
$transactionUuid = $transaction['uuid'];

Transaction lifecycle

To understand the meaning of the status and detailedStatus fields, go to: Status reference

Merchant server restrictions

In case some restrictions are set up by the merchant, the 194.50.38.0/24 IP address range must be authorized.

Notifications are sent from an IP address in the 194.50.38.0/24 range in Test and Production mode.