Integration Guide

After having Tokenized Payments turned on by Everypay on your account, it is fairly easy to integrate them into your system. All you need to do is invoke the right function from Everypay JS and add some extra data on the payload that you initiate the Payform.

• Step 1: Import EveryPay script

In case you are not already using the Payform for payments you need to define our JS library. If you have already defined our library on your page then move to the next step

everypay.tokenized() requires Everypay.js, as the only way to integrate our solution, which collects sensitive payment information and deals with fraud detection.
Always load Everypay.js from js.everypay.gr to remain compliant. Do not include the script in a bundle or host it yourself.
checkout.html
<html>
<head>
  <title>Page Title</title>
</head>

<body>
  <div>
    <!-- My App -->
  </div>
  <script src="https://sandbox-js.everypay.gr/v3"></script>
</body>
</html>
checkout.html
<body>
  ...
  <script src="https://js.everypay.gr/v3"></script>
</body>

• Step 2: Define the payment element

Create a div element with id="pay-form". This element is where the form will be positioned within your page.

The form needs to be able to preoccupy some space. Even though it might not show itself in the first instance, its where the error messages for the users are going to show.

This element is required by Everypay.js

checkout.html
 <body>
    <div>
      <!-- My App -->
      ...
      <div class="custom-control custom-radio">
        <input id="credit" name="paymentMethod" type="radio" class="custom-control-input" onclick="everypay.showForm()" required>
        <label class="custom-control-label" for="credit">Credit card</label>
        <div id="pay-form"></div>
      </div>
      ...
    </div>
  </body>

• Step 3: Creating the payload

everypay.tokenized accepts a Payload as the first argument.

The Payload object looks like this:

var payload = {
    ...,
    data: {
        customerToken: 'cus_dspVPLR2VD1x6qCmLrQUTqO4', //required field
        cardType: 'visa', //required field
        cardExpMonth: '01', //required field
        cardExpYear: '2021', //required field
        cardLastFour: '9395', //required field
        cardHolderName: 'John Doe', //optional field
    },
    display: {
       cvvInput: true/false //optional field
    }
}

Read more Tokenization Specific Options Here

The payload can be exactly the same as the everypay.payform()* (Payload options), with the only difference being the required card data to be passed within the payload.data object as the example above.

• Step 4: Mount the form

Let's create the previously declared function in our scripts section. Now lets call the everypay.tokenized() function. The everypay.tokenized() function expects a payload and a response handler.

The payload can be exactly the same as the everypay.payform() (Payload options).

<body>
  <div>
    <!-- My App -->
    ...
    <div class="custom-control custom-radio">
      <input id="credit" name="paymentMethod" type="radio" class="custom-control-input" required>
      <label class="custom-control-label" for="credit">Credit card</label>
      <div id="pay-form"></div>
    </div>
    ...
  </div>
</body>
<script>

var payload = {
  pk: 'your-public-key',
  amount: 1000,
  locale: 'el',
  txnType: 'tds',
  data: {
      customerToken: 'cus_dspVPLR2VD1x6qCmLrQUTqO4',
      cardType: 'visa',
      cardExpMonth: '01',
      cardExpYear: '2021',
      cardLastFour: '9395',
      cardHolderName: 'Mel Brooks'
  }
}

function handleResponse(r) {
  if (r.response === 'success') {
      // You have the token! Submit it to your backend
      axios.post("https://mybackend/endpoint", {
        token: r.token
        })
      .then(response => {
        console.log(response); // This is a response from your backend. Handle it as you wish.
      })
      .catch(error => {
        console.log(error); // This is a response from your backend. Handle it as you wish.
      }) 
  }
  else {
      // Inform the user if there was an error
  }
}

everypay.tokenized(payload,handleResponse);

</script>

Multiple cards

In the case of multiple cards all you need to do is invoke everypay.tokenized() with a different payload and that will change the container within <div id="pay-form"></div>.

<div class="d-block my-3">
          <div class="custom-control custom-radio">
            <input name="paymentMethod" type="radio" class="custom-control-input" onclick="useSavedCard(payload)" required>
            <label class="custom-control-label">xxxx 9395 card</label>
            <div id="pay-form"></div>
          </div>
          <div class="custom-control custom-radio">
            <input name="paymentMethod" type="radio" class="custom-control-input" onclick="useSavedCard(otherPayload)" required>
            <label class="custom-control-label">xxxx 2023 card</label>
          </div>
</div>
...
<div id="pay-form"></div>

<script>
    const payload= { 
        pk: 'your-public-key',
        amount: 5000,
        data: {
          customerToken: 'cus_flMfLZjrNxFnlKhzvbdaDKJL',
          cardType: 'visa',
          cardExpMonth: '04',
          cardExpYear: '2023',
          cardLastFour: '9395',
          cardHolderName: 'Mel Brooks',
        },
    }
    
    const otherPayload= { 
        pk: 'your-public-key',
        amount: 5000,
        data: {
          customerToken: 'cus_flMfLZjrNxFnlKhzvbdaDKJL',
          cardType: 'mastercard',
          cardExpMonth: '04',
          cardExpYear: '2023',
          cardLastFour: '123',
          cardHolderName: 'John Doe',
        },
    }
    
    function useSavedCard(acceptedPayload) {
      everypay.tokenized(acceptedPayload, handleResponse);
    }
    
    function handleResponse(r) {
        console.log('r', r);
    }
</script>

• Step 5: Handle the response

Once the form is submitted, our handleResponse function will receive a response object, which declares the authentication status for that card.

If the authentication is successful, the response returns a token and uuid*.

If the authentication has failed, the response will return an error message and uuid*.

{ response: "success",
  token: "ctn_Yj0NIWKRpfiwsOgXG27kxnvO",
  uuid: "16a2b2f0-474d-45f9-a4a9-e4a3a827e8cd" }
  {response: "error", 
  {msg: { code: "20024", message: "Provided card's last four digits are invalid.", status: "400"}},
  uuid: "4eae8bda-c812-4cce-847c-938faef8dc4d"}

*uuid: a unique guid that refers to that specific instance of the form. You can store that in your own database as a reference towards that specific instance of the authentication process.

• Step 6: Charge the card

After you have acquired a token from a successful authentication, it is time to proceed with the payment and charge the card yourself - using our API.

*In order to charge the customers card you, have to make a POST Request with a Payload that includes the token, amount, secret-key and some extra information to Everypay's payments API.

*This request must be server to server, as it contains your secret-key. You should never expose your secret-key client-side.

If the response is successful, it means that the payment has gone through and the card has been successfully charged.

We suggest that you keep the responses, attached to that specific transaction in your database.

Here are some examples:

<?php
$pk = 'your-private-key'
$postRequest = array(
    'token' => 'ctn_Yj0NIWKRpfiwsOgXG27kxnvO',
    'amount' => '10000',
    'description' => 'Order No.123'
);

$cURLConnection = curl_init('https://api.everypay.gr/payments');
curl_setopt($cURLConnection, CURLOPT_USERPWD, $pk:);
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
$jsonArrayResponse = json_decode($apiResponse);
require 'net/http'
require 'uri'

uri = URI.parse("https://api.everypay.gr/payments")
request = Net::HTTP::Post.new(uri)
request.basic_auth("your-secret-key", "")
request.body = "token=ctn_KJ53Qx3ZGaNLttUNxyB5JQO3&amount=1000&description=Order #GGA-435167"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

# response.code
# response.body
import requests

data = {
  'token': 'ctn_KJ53Qx3ZGaNLttUNxyB5JQO3',
  'amount': '1000',
  'description': 'Order #GGA-435167'
}

response = requests.post('https://api.everypay.gr/payments', data=data, auth=('your-secret-key', ''))
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.commons.codec.binary.Base64;


public class HttpBasicAuth {

    public static void main(String[] args) {

        try {
            URL url = new URL ("https://api.everypay.gr/payments");

            Base64 b = new Base64();
            String encoding = b.encodeAsString(new String("your-secret-key:").getBytes());
            
            String urlParameters  = "token=ctn_KJ53Qx3ZGaNLttUNxyB5JQO3&amount=1000&description=Order1";
            byte[] postData = urlParameters.getBytes( StandardCharsets.UTF_8 );

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);
            connection.setRequestProperty  ("Authorization", "Basic " + encoding);
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
            connection.setRequestProperty("charset", "utf-8");
            
            try(DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) {
                wr.write( postData );
            }
            InputStream content = (InputStream)connection.getInputStream();
            BufferedReader in   = 
                new BufferedReader (new InputStreamReader (content));
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } 
        catch(Exception e) {
            e.printStackTrace();
        }
    }
}
const https = require('https')
const querystring = require('querystring');

const form = querystring.stringify({
  token: 'ctn_Yj0NIWKRpfiwsOgXG27kxnvO',
  amount: '10000',
  description: 'Order No.123'
});

const auth = 'Basic ' + new Buffer("{your-private-key}:").toString('base64');

const options = {
  hostname: 'api.everypay.gr',
  path: '/payments',
  method: 'POST',
  headers: {
    "Proxy-Authorization": auth,
    'Content-Type': 'application/x-www-form-urlencoded',
  }
}

const req = https.request(options, res => {
  console.log(`statusCode: ${res.statusCode}`)

  res.on('data', d => {
    console.log('response', d);
  })
})

req.on('error', error => {
  console.error(error)
})

req.write(form)
req.end()
using (var httpClient = new HttpClient())
{
  using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.everypay.gr/payments"))
  {
    var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes("sk_PqSohnrYrRI1GUKOZvDkK5VVWAhnlU3R:"));
    request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}"); 

    var contentList = new List<string>();
    contentList.Add("token=ctn_KJ53Qx3ZGaNLttUNxyB5JQO3");
    contentList.Add("amount=1000");
    contentList.Add("description=Order #GGA-435167");
    request.Content = new StringContent(string.Join("&", contentList));
    request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded"); 

    var response = await httpClient.SendAsync(request);
  }
}