Form Redirect (V2&V3)
The digest
parameter is a SHA-512 hash calculated from the concatenation of your merchantKey
, order_number
, amount
, and currency
(as strings).
Formula: SHA512(merchantKey + order_number + amount + currency)
Example: If merchantKey
is 2345klj
, order_number
is abcdef
, amount
is 54321
, and currency
is EUR
, the plaintext to hash would be 2345kljabcdef54321EUR
.
Digest formula above gives a result as follows: digest = SHA512.hexdigest(2345kljabcdef54321EUR)
=>
f71b8c1560bd7511ba2f0307b3823c06dd39042cd77480543e3d7bf9f3eefa6debed252979ba8edc7a82d9f111
You can check digest on this link Calculate Digest
Components & SDK
For request authentication we use Authorization
header created from:
authorization schema
: String =WP3-v2
authenticity_token
: String = value from merchant’s configurationtimestamp
: Integer = unix timestamp (eg PHP’stime()
)body_as_string
: String = Json encoded request body, egjson_encode($data)
digest
: String =sha512(merchant_key + timestamp + authenticity_token + body_as_string)
You can check digest on this link Calculate Digest
Parts above are joined by space, so Authorization
header should be in this form:
Authorization: schema authenticity_token timestamp digest
Example: Authorization: WP3-v2 abc...def 1585229134 314d32d1...0b49
Request endpoint is <base_url>/v2/payment/new
where base_url is:
https://ipgtest.monri.com
for TEST environmenthttps://ipg.monri.com
for PROD environment
TIP: Parametrize merchant_key
, authenticity_token
and base_url so it can be easily changed when you are ready for
production environment.
Payment/new response contains:
status
: String: approved | declined -id
: String - Unique payment identifier used to track payment flow on Monri’s
side. Useful for debugging if something goes wrong. Save this value in your database.client_secret
: String - Value you’ll send to your application which then will use this secret to confirm payment
using Monri Components.
Request example in PHP:
$data = [
'amount' => 100, //minor units = 1EUR
// unique order identifier
'order_number' => 'random' . time(),
'currency' => 'EUR',
'transaction_type' => 'purchase',
'order_info' => 'Create payment session order info',
'scenario' => 'charge'
'supported_payment_methods' => ['67f35b84811188a5c581b063c4f21bd6760c93b2a04d7ac4f8845dd5bbb3f5c6']
];
$body_as_string = Json::encode($data); // use php's standard library equivalent if Json::encode is not available in your code
$base_url = 'https://ipgtest.monri.com'; // parametrize this value
$ch = curl_init($base_url . '/v2/payment/new');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $body_as_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$timestamp = time();
$digest = hash('sha512', $key . $timestamp .$authenticity_token. $body_as_string);
$authorization = "WP3-v2 $authenticity_token $timestamp $digest";
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($body_as_string),
'Authorization: ' . $authorization
)
);
$result = curl_exec($ch);
if (curl_errno($ch)) {
curl_close($ch);
$response = ['client_secret' => null, 'status' => 'declined', 'error' => curl_error($ch)];
} else {
curl_close($ch);
$response = ['status' => 'approved', 'client_secret' => Json::decode($result)['client_secret']];
}
var_dump($response);
Callback
Callback is back-off system that sends response to endpoint you define and can be set under your merchant profile, under option Callback URL. Callback is a HTTP POST request with all the transaction parameters for each approved transaction.
For declined transactions and/or specific transaction steps please refer to WebHooks
Monri system expects HTTP 200 OK status response code to terminate the job, otherwise we’ll send the data periodically until we receive 200.
POST request is sent to your endpoint in JSON format and here is a list of parameters included in callback request:
{
"id":186562,
"acquirer":"integration_acq",
"order_number":"a6b62d07cc89aa0",
"order_info":"order info for a6b62d07cc89aa0",
"amount":100,
"currency":"EUR",
"ch_full_name":"John Doe",
"outgoing_amount":100,
"outgoing_currency":"EUR",
"approval_code":"914783",
"response_code":"0000",
"response_message":"approved",
"reference_number":"000002902038",
"systan":"186561",
"eci":"05",
"xid":"fake authenticated xid +=",
"acsv":"fake authenticated cavv +=",
"cc_type":"visa",
"status":"approved",
"created_at":"2019-09-06T14:24:44.906+02:00",
"transaction_type":"purchase",
"enrollment":"Y",
"authentication":"Y",
"pan_token":null,
"masked_pan":"434179-xxx-xxx-0044",
"issuer":"zaba-hr",
"number_of_installments":null,
"custom_params":"{a:b, c:d}"
}
Callback source check
To confirm that a callback request originates from Monri, inspect the POST
request headers. The authorization
and http_authorization
headers contain a digest used for validation.
Sample Headers:
header | value |
---|---|
accept-encoding | gzip;q=1.0,deflate;q=0.6,identity;q=0.3 |
authorization | WP3-callback d5e4528ad8a0e0f4262e518c663d5ff83cd4a8f381db68f9d30f99961409ceebb719c16d423757fc36c532b902c987012f5825dc8d32dde3a9b7ed95876be77a |
content-type | application/json |
http_authorization | WP3-callback d5e4528ad8a0e0f4262e518c663d5ff83cd4a8f381db68f9d30f99961409ceebb719c16d423757fc36c532b902c987012f5825dc8d32dde3a9b7ed95876be77a |
user-agent | Faraday v0.15.4 |
content-length | 621 |
connection | keep-alive |
The authorization
and http_authorization
headers are generated using the following logic:
digest = sha512(merchant_key + body)
authorization_header_value = WP3-callback digest
Validation Steps
To validate the callback request:
- Check the Authorization Scheme
Ensure theauthorization
header starts withWP3-callback
. - Extract the Digest
Retrieve the digest value that follows the scheme. - Verify the Digest
Recalculate the digest using yourmerchant_key
and the raw request body, then compare it to the one provided in the header.
Success URL
Returned digest for Success URL is calculated as SHA512(key+success_url without digest). You must check for this value at merchant application before updating status of transaction because malicious user can forge this URL.
You can check digest on this link Calculate Digest
Success URL return digest is calculated using following formula: digest = SHA512(key + succesURL(without DIGEST))
- key:
2345klj
- success url (without digest):
https://ipgtest.monri.com/shop/success?acquirer=integration_acq&amount=100&approval_code=629762&authentication=Y&cc_type=visa&ch_full_name=John+Doe¤cy=USD&custom_params=%7Ba%3Ab%2C+c%3Ad%7D&enrollment=Y&language=en&masked_pan=434179-xxx-xxx-0044&number_of_installments=&order_number=02beded6e6106a0&response_code=0000
- digest:
digest = SHA512('2345kljhttps://ipgtest.monri.com/shop/success?acquirer=integration_acq&amount=100&approval_code=629762&authentication=Y&cc_type=visa&ch_full_name=John+Doe¤cy=USD&custom_params=%7Ba%3Ab%2C+c%3Ad%7D&enrollment=Y&language=en&masked_pan=434179-xxx-xxx-0044&number_of_installments=&order_number=02beded6e6106a0&response_code=0000')
- resulting digest:
b96025517326db3b952ba783281701bf48cd1fffa4fb61f0c05847e6498919f99630fbfd575ce9ea9f361ec8bb9bf9e0d349dee0c5474a5141ce91b3e1f95ef3
IMPORTANT
Success URL should expire after some sensible amount of time or protected using session.