Finalized payment
Once the payment is finalized, you can retrieve the information about the newly created transaction in two different ways.
If you define a return URL using the kr-post-url-success parameter, the JavaScript client will post the result to the specified page. See the following section: Browser return.
In case you want to retrieve the transaction newly created in JavaScript as part of a single-page web application, please refer to the following article: Single-page applications.
Browser return
When the payment has been made, the JavaScript client transmits the payment result to the URL defined by the kr-post-url-success parameter via a form in POST mode. The posted form contains the following data:
Parameter | Value |
---|---|
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", (...) |
These 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. Its value is sha256_hmac. |
kr-answer-type | Type the JSON object stored in kr-answer. |
kr-hash-key | Type of key used to sign kr-answer. Can be set to sha256_hmac (browser return) or password (IPN). |
kr-answer | Object containing the payment result, encoded in JSON. |
The kr-answer parameter contains information about the status of the payment session:
{ "shopId": "73239078", "orderCycle": "CLOSED", "orderStatus": "PAID", "serverDate": "2022-01-21T09:28:17+00:00", "orderDetails": { "orderTotalAmount": 990, "orderEffectiveAmount": 990, "orderCurrency": "EUR", "mode": "TEST", "orderId": "myOrderId-475882", "metadata": null, "_type": "V4/OrderDetails" }, "customer": { "billingDetails": { "address": null, "category": null, "cellPhoneNumber": null, "city": null, "country": null, "district": null, "firstName": null, "identityCode": null, "language": "FR", "lastName": null, "phoneNumber": null, "state": null, "streetNumber": null, "title": null, "zipCode": null, "legalName": 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": "185.244.73.2", "browserUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36", "_type": "V4/Customer/ExtraDetails" }, "shoppingCart": { "insuranceAmount": null, "shippingAmount": null, "taxAmount": null, "cartItemInfo": null, "_type": "V4/Customer/ShoppingCart" }, "_type": "V4/Customer/Customer" }, "transactions": [ { "shopId": "73239078", "uuid": "1c8356b0e24442b2acc579cf1ae4d814", "amount": 990, "currency": "EUR", "paymentMethodType": "CARD", "paymentMethodToken": null, "status": "PAID", "detailedStatus": "AUTHORISED", "operationType": "DEBIT", "effectiveStrongAuthentication": "ENABLED", "creationDate": "2022-01-21T09:28:16+00:00", "errorCode": null, "errorMessage": null, "detailedErrorCode": null, "detailedErrorMessage": null, "metadata": null, "transactionDetails": { "liabilityShift": "YES", "effectiveAmount": 990, "effectiveCurrency": "EUR", "creationContext": "CHARGE", "cardDetails": { "paymentSource": "EC", "manualValidation": "NO", "expectedCaptureDate": "2022-01-27T09:38:10+00:00", "effectiveBrand": "VISA", "pan": "497011XXXXXX1003", "expiryMonth": 12, "expiryYear": 2025, "country": "FR", "issuerCode": 17807, "issuerName": "Banque Populaire Occitane", "effectiveProductCode": null, "legacyTransId": "929936", "legacyTransDate": "2022-01-21T09:28:16+00:00", "paymentMethodSource": "NEW", "authorizationResponse": { "amount": 990, "currency": "EUR", "authorizationDate": "2022-01-21T09:28:16+00:00", "authorizationNumber": "3fe205", "authorizationResult": "0", "authorizationMode": "FULL", "_type": "V4/PaymentMethod/Details/Cards/CardAuthorizationResponse" }, "captureResponse": { "refundAmount": null, "refundCurrency": null, "captureDate": null, "captureFileNumber": null, "effectiveRefundAmount": null, "effectiveRefundCurrency": null, "_type": "V4/PaymentMethod/Details/Cards/CardCaptureResponse" }, "threeDSResponse": { "authenticationResultData": { "transactionCondition": null, "enrolled": null, "status": null, "eci": null, "xid": null, "cavvAlgorithm": null, "cavv": null, "signValid": null, "brand": null, "_type": "V4/PaymentMethod/Details/Cards/CardAuthenticationResponse" }, "_type": "V4/PaymentMethod/Details/Cards/ThreeDSResponse" }, "authenticationResponse": { "id": "30eaa40d-dd76-4617-b527-4bed6240b81c", "operationSessionId": "ae6f2ad3ffea41bb8faf1aefabad87b9", "protocol": { "name": "THREEDS", "version": "2.1.0", "network": "VISA", "challengePreference": "NO_PREFERENCE", "simulation": true, "_type": "V4/Charge/Authenticate/Protocol" }, "value": { "authenticationType": "CHALLENGE", "authenticationId": { "authenticationIdType": "dsTransId", "value": "bafdb21f-e3d6-4d1c-b4f6-d1668b7f7f21", "_type": "V4/Charge/Authenticate/AuthenticationId" }, "authenticationValue": { "authenticationValueType": "CAVV", "value": "BqLgDBHYRaCBpip3Fn3+erKT9vg=", "_type": "V4/Charge/Authenticate/AuthenticationValue" }, "status": "SUCCESS", "commerceIndicator": "05", "extension": { "authenticationType": "THREEDS_V2", "threeDSServerTransID": "30eaa40d-dd76-4617-b527-4bed6240b81c", "dsTransID": "bafdb21f-e3d6-4d1c-b4f6-d1668b7f7f21", "acsTransID": "bd6e58b4-6f37-4993-b428-9096766d83a6", "_type": "V4/Charge/Authenticate/AuthenticationResultExtensionThreedsV2" }, "reason": { "_type": "V4/Charge/Authenticate/AuthenticationResultReason" }, "_type": "V4/Charge/Authenticate/AuthenticationResult" }, "_type": "V4/AuthenticationResponseData" }, "installmentNumber": null, "installmentCode": null, "markAuthorizationResponse": { "amount": null, "currency": null, "authorizationDate": null, "authorizationNumber": null, "authorizationResult": null, "_type": "V4/PaymentMethod/Details/Cards/MarkAuthorizationResponse" }, "cardHolderName": null, "identityDocumentNumber": null, "identityDocumentType": null, "_type": "V4/PaymentMethod/Details/CardDetails" }, "fraudManagement": { "_type": "V4/PaymentMethod/Details/FraudManagement" }, "subscriptionDetails": { "subscriptionId": null, "_type": "V4/PaymentMethod/Details/SubscriptionDetails" }, "parentTransactionUuid": null, "mid": "9999999", "sequenceNumber": 1, "taxAmount": null, "preTaxAmount": null, "taxRate": null, "externalTransactionId": null, "nsu": null, "tid": "001", "acquirerNetwork": "CB", "taxRefundAmount": null, "userInfo": "JS Client", "paymentMethodTokenPreviouslyRegistered": null, "occurrenceType": "UNITAIRE", "_type": "V4/TransactionDetails" }, "_type": "V4/PaymentTransaction" } ], "subMerchantDetails": null, "_type": "V4/Payment" }
How do I retrieve the response?
The provided SDKs allow you to easily extract POST data:
/* Use client SDK helper to retrieve POST parameters */ $formAnswer = $client->getParsedFormAnswer();
In PHP, if you do not use our SDK, simply retrieve the contents of the $_POST Superglobal.
Verify the browser 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 HMAC-SHA-256 key.
This key is available in your Back Office ( Settings > Shop menu, REST API keys tab, REST API: keys used to calculate / check the kr-hash field section).
To verify the validity of the signature with our SDKs:
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"); }
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']); } }
Verifying the transaction
All you need to do is verify the orderStatus parameter in kr-answer. If the field value is PAID, the transaction has been paid. See the status reference for more information.
Managing the Instant Payment Notification (IPN)
In case of a network failure or if the buyer closes their browser, you might never receive the form parameters.
Using the IPN guarantees that you will receive data in any case.
The IPN data will be more secure than the data passed by the buyer's browser. It is sent directly to your servers. Therefore, it cannot be altered by a corrupted plug-in or spyware installed on the buyer's browser.
To understand how to implement IPNs, go to: Using IPNs