IRIS - Direct integration

Direct API integration with IRIS (Custom Solution)

For merchants who want full control over the checkout experience on their own site, EveryPay supports IRIS via Direct API integration. This approach requires development resources but allows IRIS to be integrated directly into a custom checkout page without redirecting customers to EveryPay’s hosted Payform.

Overview of the integration steps

Typical flow:

  • Display IRIS button
  • Create an IRIS session
  • Initiate an IRIS pay attempt
  • Receive the tokenized attempt on your callback url
  • Perform the payment with source token
  • If callback url not received, perform the payment with source token after receiving the Webhook event

• Step 1: Frontend Integration

Iris resources (logos, icons, etc.) can be downloaded from the following link: IRIS assets

Example HTML structure for the IRIS button:

iris_direct.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Iris Payment</title>
    <style>
        body {
            font-family: Roboto, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f5f5f5;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
        }

        .payment-container {
            background: white;
            border-radius: 12px;
            padding: 40px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
            max-width: 400px;
            width: 100%;
            text-align: center;
        }

        .iris-button-container {
            margin: 20px 0;
        }

        .iris-button {
            background-color: #000;
            color: white;
            border: none;
            border-radius: 8px;
            padding: 12px 24px;
            font-size: 16px;
            cursor: pointer;
            width: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: background-color 0.3s;
        }

        .iris-button:hover {
            background-color: #333;
        }

        .iris-logo {
            height: 24px;
            width: 24px;
            margin-right: 8px;
        }

        .payment-info {
            background-color: #e9ecef;
            padding: 15px;
            border-radius: 8px;
            margin-bottom: 20px;
        }

        h1 {
            color: #333;
            margin-bottom: 30px;
        }
    </style>
</head>
<body>

<div class="payment-container">
    <h1>Iris Payment</h1>

    <div class="payment-info">
        <strong>Amount:</strong> €100.00<br>
        <strong>Customer:</strong> Test Customer
    </div>

    <div class="iris-button-container">
        <button class="iris-button" id="irisButton">
            <svg class="iris-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 622.66669 252.53333" height="252.53333" width="622.66669" id="svg2" version="1.1" style="height: 24px; width: 64px;">
                <g transform="matrix(1.3333333,0,0,-1.3333333,0,252.53333)" id="g10">
                    <g transform="scale(0.1)" id="g12">
                        <path id="path14" d="m 1771.21,238.43 c 0,18.179 -10.68,23.332 -23.33,23.332 h -68.01 c -2.37,0 -4.35,-1.981 -4.35,-4.352 V 149.461 c 0.79,-10.27 8.7,-18.973 18.98,-20.172 h 53.38 c 12.65,0 23.33,10.289 23.33,23.332 z M 1747.88,96.4805 h -45.47 c -12.26,0 -22.15,6.3285 -26.89,12.6605 V 4.35156 C 1675.52,1.98828 1673.54,0 1671.18,0 h -30.06 v 281.922 c 0,6.726 5.54,12.258 12.65,12.258 h 94.11 c 31.63,0 57.73,-16.602 57.73,-55.75 v -86.211 c 0,-33.199 -26.1,-55.7385 -57.73,-55.7385" style="fill: rgb(255, 255, 255); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path16" d="m 2100.93,130.09 h 67.22 c 2.37,0 3.95,1.969 3.95,4.34 v 62.871 c -1.98,-3.563 -5.93,-5.531 -10.28,-5.93 h -60.89 c -13.05,0 -23.33,-10.281 -23.33,-23.32 v -14.629 c 0,-13.063 10.28,-23.332 23.33,-23.332 z m 105.18,108.73 V 109.141 c 0,-7.121 -5.54,-12.6605 -12.66,-12.6605 h -4.35 -17.4 -70.77 c -32.03,0 -57.73,25.6995 -57.73,57.7185 v 12.262 c 0,32.027 25.7,57.738 57.73,57.738 h 66.82 c 2.37,0 4.35,1.973 4.35,4.34 v 9.891 c 0,12.652 -8.3,23.332 -23.72,23.332 h -78.68 c -2.38,0 -4.35,1.976 -4.35,4.347 v 28.071 h 83.03 c 32.03,0 57.73,-19.371 57.73,-55.36" style="fill: rgb(255, 255, 255); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path18" d="m 2610.17,294.18 c 2.37,0 4.35,-1.578 4.35,-3.961 V 57.7305 C 2614.52,25.6992 2588.42,0 2556.79,0 h -97.27 v 28.4688 c 0,2.371 1.98,4.3593 4.36,4.3593 h 92.91 c 12.65,0 23.33,10.6719 23.33,23.3125 v 53.0004 c -5.14,-6.332 -14.63,-12.6605 -27.28,-12.6605 h -44.69 c -32.03,0 -57.72,26.0975 -57.72,57.7185 V 294.18 h 30.05 c 2.37,0 4.34,-1.578 4.34,-3.961 V 152.621 c 0,-12.641 10.29,-23.332 23.33,-23.332 h 52.59 c 10.29,1.602 18.59,9.902 19.38,20.172 V 294.18 h 30.05" style="fill: rgb(255, 255, 255); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path20" d="M 3100.03,236.441 V 96.4805 h -30.05 c -2.37,0 -4.35,1.9687 -4.35,4.3475 V 238.43 c 0,12.652 -10.29,23.332 -23.33,23.332 h -51.4 c 3.95,-2.383 7.12,-6.34 7.12,-11.082 V 96.4805 h -30.05 c -2.37,0 -4.35,1.9687 -4.35,4.3475 V 257.41 c 0,2.371 -1.98,4.352 -4.35,4.352 h -59.71 c -1.97,0 -3.55,-1.59 -3.95,-3.571 V 100.828 c 0,-2.3788 -1.98,-4.3475 -4.35,-4.3475 h -30.05 V 268.469 c 0,14.242 11.47,25.711 25.7,25.711 h 155.39 c 32.03,0 57.73,-25.711 57.73,-57.739" style="fill: rgb(255, 255, 255); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path22" d="m 3402.46,261.762 c -13.05,0 -23.32,-7.512 -23.32,-23.332 v -21.352 c 0,-2.379 1.58,-3.957 3.95,-4.348 h 92.12 c 2.38,0 4.35,1.969 4.35,4.348 v 21.352 c 0,15.82 -7.51,23.332 -22.93,23.332 z m -57.72,-107.563 v 83.832 c 0,36.778 25.7,56.149 57.72,56.149 h 52.98 c 32.03,0 57.73,-19.371 57.73,-56.149 V 192.57 c 0,-6.73 -0.79,-12.269 -10.28,-12.269 h -108.33 c -6.34,0 -11.86,2.758 -15.42,7.519 v -35.199 c 0,-13.043 10.27,-23.332 23.32,-23.332 h 98.06 c 2.37,0 4.35,-1.969 4.35,-4.34 V 96.4805 h -102.41 c -32.02,0 -57.72,25.6995 -57.72,57.7185" style="fill: rgb(255, 255, 255); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path24" d="M 3927.12,236.441 V 96.4805 h -30.05 c -2.37,0 -4.36,1.9687 -4.36,4.3475 V 238.43 c 0,12.652 -10.28,23.332 -23.32,23.332 h -71.57 c -2.37,0 -4.34,-1.981 -4.34,-4.352 V 100.828 c 0,-2.3788 -1.99,-4.3475 -4.36,-4.3475 h -30.05 V 268.469 c 0,14.242 11.47,25.711 25.71,25.711 h 84.61 c 32.03,0 57.73,-25.711 57.73,-57.739" style="fill: rgb(255, 255, 255); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path26" d="M 4271.46,124.949 V 96.4805 h -39.93 c -31.63,0 -57.72,25.6995 -57.72,57.7185 v 235.672 h 30.05 c 2.37,0 4.34,-1.992 4.34,-4.359 V 286.66 c 1.99,4.352 6.33,7.129 11.47,7.129 h 41.91 v -28.48 c 0,-2.36 -1.97,-3.957 -4.34,-3.957 H 4208.2 V 152.621 c 0,-13.043 10.29,-23.332 23.33,-23.332 h 35.59 c 2.37,0 4.34,-1.969 4.34,-4.34" style="fill: rgb(255, 255, 255); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path28" d="m 4499.19,215.5 v 26.48 c 0,32.032 22.14,52.2 54.17,52.2 h 108.33 v -28.071 c 0,-2.371 -1.97,-4.347 -4.35,-4.347 h -103.98 c -13.05,0 -19.77,-6.34 -19.77,-19.383 v -11.457 c 0,-1.981 1.58,-3.57 3.56,-4.352 l 122.17,-28.871 c 6.33,-1.187 10.68,-6.73 10.68,-13.039 v -35.199 c 0,-34.402 -24.52,-52.9805 -56.54,-52.9805 h -111.91 v 28.0705 c 0,2.371 1.99,4.34 4.36,4.34 h 107.55 c 13.04,0 24.51,7.519 24.51,20.57 v 18.59 c 0,1.98 -1.58,3.551 -3.56,3.949 l -124.16,30.441 c -6.31,1.188 -11.06,6.731 -11.06,13.059" style="fill: rgb(255, 255, 255); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path30" d="m 711.227,1893.98 c -2.375,0 -4.7,-0.18 -7.047,-0.18 v -343.79 c 2.347,0.04 4.672,0.19 7.047,0.19 202.015,0 366.423,-163.88 367.343,-365.69 h 343.8 c -0.95,391.33 -319.58,709.47 -711.143,709.47" style="fill: rgb(61, 106, 186); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path32" d="m 1078.57,1184.51 c 0,-0.6 0.06,-1.18 0.06,-1.76 0,-202.602 -164.841,-367.441 -367.403,-367.441 -2.375,0 -4.707,0.171 -7.043,0.179 v -343.75 c 2.336,-0.039 4.668,-0.179 7.043,-0.179 392.113,0 711.173,319.011 711.173,711.191 0,0.58 -0.03,1.16 -0.03,1.76 h -343.8" style="fill: rgb(54, 158, 149); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path34" d="M 704.184,1550.01 V 1893.8 C 315.836,1889.99 1.01172,1573.5 0.0234375,1184.51 H 343.785 c 1,199.44 161.606,361.71 360.399,365.5" style="fill: rgb(238, 43, 52); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path36" d="m 343.773,1182.75 c 0,0.58 0.012,1.16 0.012,1.76 H 0.0195313 C 0.0195313,1183.91 0,1183.33 0,1182.75 0,792.961 315.266,475.512 704.184,471.738 v 343.75 C 504.809,819.281 343.773,982.492 343.773,1182.75" style="fill: rgb(245, 126, 23); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path38" d="m 711.227,1647.12 c -1.547,0 -3.086,-0.07 -4.61,-0.08 v -224.5 c 1.524,0.04 3.063,0.14 4.61,0.14 131.91,0 239.253,-107.02 239.859,-238.76 H 1175.6 c -0.68,255.52 -208.737,463.2 -464.373,463.2" style="fill: rgb(37, 71, 144); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path40" d="m 951.086,1183.91 c 0,-0.43 0.027,-0.77 0.027,-1.15 0,-132.31 -107.613,-239.924 -239.89,-239.924 -1.551,0 -3.082,0.086 -4.602,0.121 V 718.48 c 1.52,-0.031 3.051,-0.128 4.602,-0.128 256.047,0 464.377,208.336 464.377,464.408 v 1.15 H 951.086" style="fill: rgb(39, 115, 109); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path42" d="m 706.621,1422.55 v 224.49 C 453.043,1644.52 247.457,1437.89 246.836,1183.91 h 224.48 c 0.614,130.23 105.493,236.17 235.305,238.64" style="fill: rgb(201, 30, 37); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path44" d="m 471.277,1182.75 c 0,0.38 0.047,0.74 0.047,1.16 H 246.84 v -1.16 c 0,-254.539 205.828,-461.82 459.785,-464.27 V 942.953 C 576.422,945.418 471.277,1051.99 471.277,1182.75" style="fill: rgb(206, 91, 30); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path46" d="m 1630.38,1710.76 c 0,91.47 137.21,89.64 137.21,0 V 616.781 c 0,-84.152 -137.21,-87.82 -137.21,0 V 1710.76" style="fill: rgb(255, 255, 255); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path48" d="M 2179.17,979 V 624.09 c 0,-84.149 -133.54,-84.149 -133.54,-1.828 V 1672.34 c 0,38.43 27.44,64.03 67.68,64.03 h 433.57 c 316.49,0 477.48,-179.28 477.48,-393.33 0,-184.75 -100.62,-318.31 -325.64,-356.727 L 2995.09,666.16 c 69.51,-69.5 -31.11,-150 -91.47,-87.808 L 2534.07,979 Z m 0,115.25 h 369.54 c 239.65,0 343.93,111.59 340.27,248.79 -1.82,150.02 -128.06,270.76 -340.27,270.76 h -369.54 v -519.55" style="fill: rgb(255, 255, 255); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path50" d="m 3273.12,1710.76 c 0,91.47 137.2,89.64 137.2,0 V 616.781 c 0,-84.152 -137.2,-87.82 -137.2,0 V 1710.76" style="fill: rgb(255, 255, 255); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                        <path id="path52" d="m 3724.95,860.09 c 47.56,-151.84 250.63,-184.781 396.98,-184.781 155.5,0 396.99,47.57 396.99,232.336 0,159.155 -192.09,171.965 -393.32,188.445 -252.47,20.12 -523.23,43.9 -523.23,316.48 0,241.48 278.08,349.41 501.26,349.41 192.09,0 431.75,-45.73 508.59,-254.29 27.44,-73.17 -96.96,-106.1 -124.4,-43.9 -54.89,139.03 -250.63,162.82 -382.36,162.82 -122.56,0 -360.39,-49.4 -360.39,-215.88 0,-159.15 182.95,-175.61 395.15,-192.09 250.64,-21.94 519.56,-34.76 519.56,-309.171 0,-279.891 -312.83,-365.86 -537.85,-365.86 -186.61,0 -471.98,64.012 -532.36,283.551 -21.94,80.485 120.75,107.934 135.38,32.93" style="fill: rgb(255, 255, 255); fill-opacity: 1; fill-rule: nonzero; stroke: none;"></path>
                    </g>
                </g>
            </svg>
        </button>
    </div>

    <div id="result"></div>
</div>
</html>

• Step 2: Add the logic to handle the IRIS button click

Example JavaScript code to handle the IRIS button click and process the payment:

checkout.html
...
<script>
    // Configuration
    const config = {
        publicKey: 'pk_xxxxx',
        amount: 10000, // Amount in cents
        currency: 'eur',
        merchantName: 'Merchant Name',
    };

    // DOM elements
    const irisButton = document.getElementById('irisButton');

    // Mock iris callback handler (simulates the backend validation)
    const irisCallbackHandler = async (data) => {
        try {
            // Call the Iris session validation endpoint on your server
            // This endpoint should interact with EveryPay's /iris/sessions endpoint
            // and return the session signature
            // Use your own server URL here
            // Reference to "Step 3: Create IRIS session" in documentation
            const response = await fetch('/your-iris-session-url', {
                method: "POST",
                mode: "cors",
                cache: "no-cache",
                credentials: "same-origin",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(data),
            });

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            const result = await response.json();
            console.log('Session validation result:', result);

            // Return the signature for further processing
            return result.signature;
        } catch (error) {
            console.error('Iris session validation failed:', error);
            throw error;
        }
    };

    // Main payment processing function
    // Reference to "Step 3: Create Source Token with IRIS session" in documentation
    const processIrisPayment = async (data, sessionSignature) => {
        try {
            // Prepare payment data
            const paymentData = {
                flow: 'direct',
                token: sessionSignature,
                pk: config.publicKey,
                amount: config.amount,
                currency: config.currency,
                uuid: data.uuid,
                callback_url: 'https://merchant-domain.com/callback',
            };

            console.log('Sending payment request via form submission:', paymentData);

            // Create a form element dynamically
            const form = document.createElement('form');
            form.method = 'POST';
            form.action = 'https://sandbox-payform-api.everypay.gr/api/payment-methods/iris';
            form.style.display = 'none';

            // Add all payment data as hidden form fields
            Object.keys(paymentData).forEach(key => {
                const input = document.createElement('input');
                input.type = 'hidden';
                input.name = key;
                input.value = paymentData[key];
                form.appendChild(input);
            });

            // Append form to body and submit
            document.body.appendChild(form);
            form.submit();

            // Clean up - remove form after submission
            setTimeout(() => {
                document.body.removeChild(form);
            }, 100);
        } catch (error) {
            console.error('Payment processing failed:', error);
        }
    };

    const handleIrisClick = async () => {
        try {
            let data ={
                uuid: generateUUID(),
                amount: config.amount,
                currency: config.currency,
                merchantName: config.merchantName,
                country: 'GR'
            };

            // Call the iris callback handler to get sessionSignature token
            const sessionSignature = await irisCallbackHandler(data);

            if (sessionSignature) {
                // Process the payment with the received token
                await  processIrisPayment(data, sessionSignature);
            } else {
                throw new Error('Failed to validate Iris sessionSignature');
            }

        } catch (error) {
            console.error('Iris click handler failed:', error);
        }
    };

    const generateUUID = () => {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            const r = Math.random() * 16 | 0;
            const v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    };

    // Event listeners
    irisButton.addEventListener('click', handleIrisClick);

    // Initialize
    console.log('Iris Direct page loaded with config:', config);
</script>

• Step 3: Create IRIS session (Backend)

Check the code below for an implementation example of your backend.

backend.php
  <?php

  header('Content-Type: application/json');

  // Get the raw POST data
  $input = file_get_contents('php://input');
  $data = json_decode($input, true);

  $sk = 'your-private-key';
  $postRequest = array(
  'amount'=> $data['amount'] ,
  'currency'=> $data['currency'],
  'country'=> $data['country'],
  'uuid'=> $data['uuid'] ?? null,
  'callback_url'=> 'https://merchant-domain.com/callback',
  'md'=> 'your-md-data' ?? null,
  );

  $cURLConnection = curl_init('https://sandbox-api.everypay.gr/iris/sessions');
  curl_setopt($cURLConnection, CURLOPT_USERPWD, "$sk:");
  curl_setopt($cURLConnection, CURLOPT_POSTFIELDS, $postRequest);
  curl_setopt($cURLConnection, CURLOPT_RETURNTRANSFER, true);

  $apiResponse = curl_exec($cURLConnection);
  curl_close($cURLConnection);

  // $apiResponse - available data from the API request to be returned to frontend
  $jsonArrayResponse = json_decode($apiResponse);
backend.php
  <?php

  header('Content-Type: application/json');

  // Get the raw POST data
  $input = file_get_contents('php://input');
  $data = json_decode($input, true);

  $sk = 'your-private-key';
  $postRequest = array(
  'amount'=> $data['amount'] ,
  'currency'=> $data['currency'],
  'country'=> $data['country'],
  'uuid'=> $data['uuid'] ?? null,
  'callback_url'=> 'https://merchant-domain.com/callback',
  'md'=> 'your-md-data' ?? null,
  );

  $cURLConnection = curl_init('https://api.everypay.gr/iris/sessions');
  curl_setopt($cURLConnection, CURLOPT_USERPWD, "$sk:");
  curl_setopt($cURLConnection, CURLOPT_POSTFIELDS, $postRequest);
  curl_setopt($cURLConnection, CURLOPT_RETURNTRANSFER, true);

  $apiResponse = curl_exec($cURLConnection);
  curl_close($cURLConnection);

  // $apiResponse - available data from the API request to be returned to frontend
  $jsonArrayResponse = json_decode($apiResponse);

Typical flow:

  • Receive payment details from your frontend
  • Perform IRIS session request. For details on iris session creation check API specification /iris/sessions
  • Return the response.signature to your Frontend

Example Request

curl --location 'https://sandbox-api.everypay.gr/iris/sessions' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --header 'Authorization: Basic secret_key' \
  --data-urlencode 'amount=500' \
  --data-urlencode 'currency=EUR' \
  --data-urlencode 'country=GR' \
  --data-urlencode 'callback_url=http://merchant.com/your_callback' \
  --data-urlencode 'uuid=uuid' \
  --data-urlencode 'md=md-data'
curl --location 'https://api.everypay.gr/iris/sessions' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --header 'Authorization: Basic secret_key' \
  --data-urlencode 'amount=500' \
  --data-urlencode 'currency=EUR' \
  --data-urlencode 'country=GR' \
  --data-urlencode 'callback_url=http://merchant.com/your_callback' \
  --data-urlencode 'uuid=uuid' \
  --data-urlencode 'md=md-data'

• Step 4: Create Source Token with IRIS session

You need to create a payment source token using the IRIS session signature received from the previous step. API specification for this step can be found on the /payment-methods/iris endpoint.

Example Request

curl --location --request POST 'https://sandbox-payform-api.everypay.gr/api/payment-methods/iris \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'amount=1000' \
--data-urlencode 'pk=pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--data-urlencode 'callback_url=http://merchant.com/callback' \
--data-urlencode 'token=signature' \
--data-urlencode 'flow=direct' \
--data-urlencode 'currency=EUR'
curl --location --request POST 'https://payform-api.everypay.gr/api/payment-methods/iris \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'amount=1000' \
--data-urlencode 'pk=pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--data-urlencode 'callback_url=http://merchant.com/callback' \
--data-urlencode 'token=signature' \
--data-urlencode 'flow=direct' \
--data-urlencode 'currency=EUR'

• Step 5: Handling Responses

Responses will be sent to your callback_url.

Successful Iris Response

curl --location --request POST 'http://merchant.com/your_callback' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'token=src_xxxxxxxxxxxxxxxxxxxxxxxx' \
--data-urlencode 'md=data_sent_by_the_merchant' \
--data-urlencode 'type=iris' \
--data-urlencode 'hash=Base 64 encoded signature to verify using your secret key'
Signature Verification Example:
  1. Base64 decode the hash field →

     hash1|{"callback_url":"http://merchant.com/your_callback",
       "token":"src_xxxxxxxxxxxxxxxxxxxxxxxx",
       "md":"Order 1234567",
       "type":"iris"}
    
  2. Generate signature using HMAC-SHA256 (Pseudo code)

    Hmacsha256(‘{"callback_url":"http://merchant.com/your_callback","token":"src_xxxxxxxxxxxxxxxxxxxxxxxx","md":"Order 1234567", "type": "iris"}” }’, sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
    
  3. Compare generated hash with received hash.

Failed request example

curl --location --request POST 'http://merchant.com/your_callback' \
 --header 'Content-Type: application/x-www-form-urlencoded' \
 --data-urlencode 'error_status=402' \
 --data-urlencode 'error_code=12345' \
 --data-urlencode 'error_message=Error message' \
 --data-urlencode 'hash=hash_that_must_be_validated' \
 --data-urlencode 'md=data_sent_by_the_merchant'

• Step 6: Create IRIS Payment

After receiving a successful response in your_callback url you have to proceed with creating the IRIS payment to the api

curl --location --request POST 'https://sandbox-api.everypay.gr/payments’ \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic secret_key' \
--data-urlencode 'token=src_xxxxxxxxxxxxxxxxxxxxxxxx' \
--data-urlencode 'amount=amount_in_cents' \
curl --location --request POST 'https://sandbox-api.everypay.gr/payments’ \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic secret_key' \
--data-urlencode 'token=src_xxxxxxxxxxxxxxxxxxxxxxxx' \
--data-urlencode 'amount=amount_in_cents' \

For more details regarding the payment creation please refer to the /payments endpoint in our api.

Check Step 8 for more information on how to handle the callback and webhook.

As IRIS payments are performed outside our platform, it is possible that the user may interrupt the redirection to your callback. As a safety measure we highly recommend you to register to the Webhook New Payment (IRIS) in order to be notified for successful payments.

Once an IRIS payment is completed, EveryPay will send a notification to your registered webhook URL with the payment details.

Successful Iris Response

{
  "token": "src_xxxxxxxxxxxxxxxx",
  "md": "merchant data",
  "hash": "..." // Base 64 encoded signature to verify using your secret key
}

Failed Iris Response

{
  "md": "merchant data",
  "hash": "...", // Base 64 encoded signature to verify using your secret key
  "error_status": 400,
  "error_code": 41001,
  "error_message": "This is an error"
}

Once Webhook is received, if the transaction is successful you need to make a POST request to /payments endpoint in our api as described in Step 6.

Check Step 8 for more information on how to handle the callback and webhook.

• Step 8: Handle Callback and Webhook

Sometimes you might not get the callback because the user may close or interrupt the payment flow.

But you will always get the webhook for successful IRIS payments.

There are three possible sequences:

  • First you receive Callback and then Webhook notification
  • First you receive Webhook notification and then Callback
  • You only receive Webhook notification

No matter which one you receive, you can call /payments once using the token.

  • The first request will succeed.
  • A second request with the same token will return an error:
{
    "error": {
    "status": 400,
    "code": 41001,
    "message": "Payment source src_XQJ6nwaWR51wr7CBbqsjPrKl has already been used"
    }
}

Recommendation

Always rely on the webhook to complete your logic, because it is guaranteed for successful IRIS payments.