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.

Define the URL in the Merchant Back Office

To configure the notification:

  1. Login to the Back Office Marchand
  2. Go to the following menu: Settings > Notification rules.
  1. Right-click Instant Payment Notification.
  2. Select Manage the rule.
  3. In the General settings section, enter the E-mail address(es) to notify in case of failure.
  4. Check the Automatic retry in case of failure checkbox if you want to allow the gateway to automatically resend the notification in case of failure (can be resent up to 4 times).
  5. In the IPN URL section of the REST API, enter your page URL in the fields ''Target URL of the IPN to notify in TEST mode'' and ''Target URL of the IPN to notify in PRODUCTION mode''.
  6. Save the changes.

If the target server of the IPN is offline, an e-mail will be sent to the address you specified in rule configuration.

This e-mail contains:

  • The HTTP error code returned by your server
  • Elements of analysis
  • Explanation of the error''s consequences
  • Instructions for restarting the IPN (via the Merchant Back Office)

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 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 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 in JSON format.

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 kr-answer hash generated with the password (that starts with testpassword_* or prodpassword_*).

The password is available in your Back Office (Settings menu > Shop, REST API keys tab, REST API keys section).

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 = $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. The SHA256 key is used for checking the kr-hash value.
password Password Data received via the IPN (server to server call). The password is used for checking the kr-hash value.

Transaction object

The transaction object is contained in the kr-answer POST parameter in JSON format:

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

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

You can use any standard function 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 = $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

If a restriction is set up on the Merchant side, the IP address range 194.50.38.0/24 will have to be authorized.

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