BankStore integration JET-IFRAME

The JET-IFRAME system of PAYCOMET allows you to integrate in a simple and safe the payment gateway keeping your payment forms.

Thanks to its iframes system, sensitive data never passes through the client's system. The integration of this system does not require add additional security measures.

  1. Introduction
  2. Product configuration
  3. Form
  4. Return the call
  5. Usage examples

Introduction

The JET-IFRAME integration is part of the solution BankStore and performs the pre-tokenizations to be able to execute collection operations. It is independent of the user interface and especially recommended for integrations for mobile devices.

How does it work?

Using javascript two iframes are loaded inside the form as fields to collect the values of the PAN and the CVC2, and the styles defined in said DIV are applied to them. When the form is submitted, JET-IFRAME initiates a process in which the iframes collect and send the necessary information to PAYCOMET to return a temporary token and insert in the client's original form in a hidden field. Once this process is finished, the form is sent on as usual. The client will receive on his server through the post of his form the fields of the same, except the PAN and the CVC2, which will never be accessible. You will also receive the variable "paytpvToken ", necessary along with other parameters that we will see later to start operating.

Product configuration

In order to use the BankStore JET-IFRAME service in your store, you must be in possession of the necessary configuration parameters. These can be obtained through the customer control panel (new version)

Once inside the platform, you can review the configuration of the product through the menu My products -> Configure product

After clicking on the "Edit" button of the chosen product, a panel with the basic informatio?n of the product will appear under the section "Technical configuration of the product". In particular, the data needed during the integration process are:

  • JET ID

If your JET ID has not yet been generated, you can click on the link Generate JET ID in your control panel.

At that moment your JET ID will be generated. With this identifier you can make the calls that we explain in the following sections.

Integration

Instructions for integration

All of these fields are required: cardHolderName , dateMonth , dateYear .    The data-paycomet attribute must be maintained with its corresponding values.    The attribute name should not appear in these fields

 
    <input type="text" data-paycomet="cardHolderName">
<input type="text" data-paycomet="dateMonth">
<input type="text" data-paycomet="dateYear">

The place where the card will be inserted and the CVC2 code must have a DIV over the INPUT.

 
    <div id="paycomet-pan" data-paycomet="paNumber" style="style for card number"></ div>
<div id="paycomet-cvc2" data-paycomet="cvc2" style="style for CVC2 code"></ div>
 

The div with id "paycomet-pan" and "paycomet-cvc2" are required.

The indicated ids of div "paycomet-pan" and "paycomet-cvc2" must be maintained.

The style that is defined in-line in the div will be the one with the input. In other words, to define the styles of these fields     it must be put in the style attribute of each DIV. Only in-line styles will be taken, the rest will be ignored.



By default, the PAN field has a mask that shows the type of card in an icon on the left, inside the INPUT and a TICK at the end that indicates whether the format is correct. If you do not want to incorporate this design just enter a hidden field in the form as follows:


<input type="hidden" data-paycomet="no-mask" value="">


You must include "https://secure.paytpv.com/gateway/paycomet..js" at the end of the document

 <script src="https://secure.paytpv.com/gateway/paycomet.jetiframe.js"></ script> 

The send button must be INPUT, not BUTTON

 <input type="submit">Pay 2.02 & euro; with paycomet 

Payment form

Following is an example of how to adapt your payment form in order to use the JET-IFRAME solution.

Trade form before integration:


<div class="container">
<div class="row">
	<aside class="col-sm-6">
		<article class="card">
			<div class="card-body p-5">
				<p> <img src="http://bootstrap-ecommerce.com/main/images/icons/pay-visa.png">
					<img src="http://bootstrap-ecommerce.com/main/images/icons/pay-mastercard.png">
					<img src="http://bootstrap-ecommerce.com/main/images/icons/pay-american-ex.png">
				</p>
				<p class="alert alert-success">Some text success or error</p>

				<form role="form" action="index.php">
					<input type="hidden" name="amount" value="1234">
					<div class="form-group">
						<label for="username">Full name (on the card)</label>
						<div class="input-group">
							<div class="input-group-prepend">
								<span class="input-group-text"><i class="fa fa-user"></i></span>
							</div>
							<input type="text" class="form-control" name="username" placeholder="" required="">
						</div> <!-- input-group.// -->
					</div> <!-- form-group.// -->

					<div class="form-group">
						<label for="cardNumber">Card number</label>
						<div class="input-group">
							<div class="input-group-prepend">
								<span class="input-group-text"><i class="fa fa-credit-card"></i></span>
							</div>
							<input type="text" class="form-control" name="cardNumber" placeholder="">
						</div> <!-- input-group.// -->
					</div> <!-- form-group.// -->

					<div class="row">
						<div class="col-sm-8">
						<div class="form-group">
						<label><span class="hidden-xs">Expiration</span> </label>
						<div class="form-inline">
							<select class="form-control" style="width:45%" data-paycomet="dateMonth">
								<option>MM</option>
								<option value="01">01 - January</option>
								<option value="02">02 - February</option>
								<option value="03">03 - March</option>
								<option value="04">04 - April</option>
								<option value="05">05 - May</option>
							</select>
							<span style="width:10%; text-align: center"> / </span>
							<select class="form-control" style="width:45%" data-paycomet="dateYear">
								<option>YY</option>
								<option value="18">2018</option>
								<option value="19">2019</option>
								<option value="20">2020</option>
							</select>
						</div>
					</div>
						</div>
						<div class="col-sm-4">
							<div class="form-group">
								<label data-toggle="tooltip" title=""
									data-original-title="3 digits code on back side of the card">CVV <i
										class="fa fa-question-circle"></i></label>
								<input class="form-control" required="" type="text">
							</div> <!-- form-group.// -->
						</div>
					</div> <!-- row.// -->
					<button class="subscribe btn btn-primary btn-block" type="button"> Confirm </button>
				</form>
			</div> <!-- card-body.// -->
		</article> <!-- card.// -->
	</aside>
</div>
</div>


Trade form after integration:


<div class="container">
<div class="row">
	<aside class="col-sm-6">
		<article class="card">
			<div class="card-body p-5">
				<p> <img src="http://bootstrap-ecommerce.com/main/images/icons/pay-visa.png">
					<img src="http://bootstrap-ecommerce.com/main/images/icons/pay-mastercard.png">
					<img src="http://bootstrap-ecommerce.com/main/images/icons/pay-american-ex.png">
				</p>
				<p class="alert alert-success">Some text success or error</p>

				<form role="form" id="paycometPaymentForm" action="index.php"  method="POST">
					<input type="hidden" name="amount" value="1234">
					<input type="hidden" data-paycomet="apiID" value="qJQ9s6KX7M41LyCDxFn2fwprBN3gWRZb">
					<div class="form-group">
						<label for="username">Full name (on the card)</label>
						<div class="input-group">
							<div class="input-group-prepend">
								<span class="input-group-text"><i class="fa fa-user"></i></span>
							</div>
							<input type="text" class="form-control" name="username" data-paycomet="cardHolderName" placeholder="" required="">
						</div> <!-- input-group.// -->
					</div> <!-- form-group.// -->

					<div class="form-group">
						<label for="cardNumber">Card number</label>
						<div class="input-group">
							<div class="input-group-prepend">
								<span class="input-group-text"><i class="fa fa-credit-card"></i></span>
							</div>
							<div id="paycomet-pan" style="padding:0px; height:36px;"></div>
							<input paycomet-style="width: 100%; height: 21px; font-size:14px; padding-left:7px; padding-top:8px; border:0px;" paycomet-name="pan">
						</div> <!-- input-group.// -->
					</div> <!-- form-group.// -->

					<div class="row">
						<div class="col-sm-8">
							<div class="form-group">
								<label><span class="hidden-xs">Expiration</span> </label>
								<div class="form-inline">
									<select class="form-control" style="width:45%" data-paycomet="dateMonth">
										<option>MM</option>
										<option value="01">01 - January</option>
										<option value="02">02 - February</option>
										<option value="03">03 - March</option>
										<option value="04">04 - April</option>
										<option value="05">05 - May</option>
									</select>
									<span style="width:10%; text-align: center"> / </span>
									<select class="form-control" style="width:45%" data-paycomet="dateYear">
										<option>YY</option>
										<option value="18">2018</option>
										<option value="19">2019</option>
										<option value="20">2020</option>
									</select>
								</div>
							</div>
						</div>

						<div class="col-sm-4">
							<div class="form-group">
								<label data-toggle="tooltip" title=""
									data-original-title="3 digits code on back side of the card">CVV <i
										class="fa fa-question-circle"></i></label>
								<div id="paycomet-cvc2" style="height: 36px; padding:0px;"></div>
								<input paycomet-name="cvc2" paycomet-style="border:0px; width: 100%; height: 21px; font-size:12px; padding-left:7px; padding-tap:8px;">
							</div> <!-- form-group.// -->
						</div>

					</div> <!-- row.// -->
					<button class="subscribe btn btn-primary btn-block" type="submit"> Confirm </button>
				</form>
				<div id="paymentErrorMsg">

				</div>
			</div> <!-- card-body.// -->
		</article> <!-- card.// -->
	</aside>
</div>
</div>
<script src="https://secure.paytpv.com/gateway/paycomet.jetiframe.js?lang=en"></script>

What has changed?

  • The method must be POST
  • The hidden field is included
    <input type="hidden" data-paycomet="apiID" value="your-jet-id" >
  • The name field of the card holder happens to have the attribute: data-paycomet="cardholdername"
  • On the field of PAN a div is included with id="paycomet-pan" with the inline size where the iframe will be located.
    <div id="paycomet-pan" style="width: 433px; height: 29px;"></div>
  • In the input of the PAN an attribute is added with the styles that field will have: paycomet-style="width:419px; height:21px; font-size:12px; padding-left:7px;"
  • An attribute is added to the bread input: paycomet-name="pan"
  • In the PAN input all attributes are deleted but the new ones.
  • In the selectors of month and year are added attributes: data-paycomet="dateMonth" and data-paycomet="dateYear"
  • In the selectors of month and year the values ​​are adjusted so that they have the format accepted by paycomet: mm y yy.
  • On the CVC2 field a div is included with id="paycomet-cvc2" with the inline size where the iframe will be located.
    <div id="paycomet-cvc2" style="width: 134px; height: 29px;"></div>
  • In the CVC2 input an attribute is added with the styles that field will have: paycomet-style="width: 120px; height: 21px; font-size : 12px; padding-left: 7px; "
  • In the CVC2 input an attribute is added: paycomet-name=cvc2"
  • In the CVC2 input all attributes are deleted but the new ones.
  • A new div is added to host the error messages. The user can freely add styles in CSS or inline for the contents of this div:
  • The script that will run the entire system is added < script src=https://secure.paytpv.com/gateway/paycomet.jetiframe.js?lang=en"></script>. A parameter "lang" may be indicated with the language code you want for web notifications.

Return of the call

After sending the form, the call to the callback function or the action defined in the form, you will receive the temporary token with which you must make a    call "add_user_token" through PayComet web services (see Bankstore XML API )

In the following example we can see how to use this temporary token in php to create a permanent token and to start operating with the user

Usage examples

Next we will show an example of code where the action of the previous form is received where the basic operations are carried out to make a payment.

In this case, after dynamically adding the token to the form, we have received it as the variable paytpvToken . With this token (remember that it is only valid for five minutes) we can create the necessary signature to use the SOAP API provided by PayComet. With the SOAP client already created, we can perform a series of operations. The first thing will be to register the user and if it is the first time he uses the platform it will be saved for future purchases. By invoking "add_user_token" we will return a token that will serve to indicate to PayComet future operations on it without the need to re-enter the card or the vendor to store any data of the client. The token can be saved and related to any user identifier that the vendor system has (cookies, registered users ...) without incurring unsafe practices. Once the user has registered, we can proceed with the collection operation (or any of those provided in the PayComet API). It is recommended to know and use the PHP API of PayComet: https://github.com/PayTpv/PAYTPV-XML-Bankstore/blob/master/class/Paytpv_bankstore.php as shown in the following example: With web services:


/**
 * PAYCOMET JET IFRAME callback
 * Tracking ID: SSX-7MS-JX3J
 *
 * @author PAYCOMET
 * @copyright Copyright (c) 2019, PAYCOMET 
 * @version 1.0 2016-05-01
 */


if (isset($_POST["paytpvToken"])) {
    date_default_timezone_set("Europe/Madrid");

    $token = $_POST["paytpvToken"];

    if ($token && strlen($token) == 64) {

        $endPoint       = "https://secure.paytpv.com/gateway/xml_bankstore.php?wsdl";
        $merchantCode   = "ktd5142s";
        $terminal       = "6987";
        $password       = "7dwmzxchkvq5p8sny1b4";
        $jetID          = "qJQ9s6KX7M41LyCDxFn2fwprBN3gWRZb";
        $productDescription         = "XML_BANKSTORE TEST productDescription";
        $owner                      = "XML_BANKSTORE TEST owner";

        $signature
            = sha1(
                $merchantCode
                .$token
                .$jetID
                .$terminal
                .$password
        );


        $ip             = "172.33.22.32";

        try {
            $context = stream_context_create(array(
                'ssl' => array(
                    'verify_peer' => false,
                    'verify_peer_name' => false,
                    'allow_self_signed' => true
                )
            ));
            
            $clientSOAP = new SoapClient($endPoint, array('stream_context' => $context));
            $addUserTokenResponse
                = $clientSOAP->add_user_token(
                    $merchantCode,
                    $terminal,
                    $token,
                    $jetID,
                    $signature,
                    $ip
                );
            echo " Proceso correcto. Se ha obtenido el token";
            var_dump($addUserTokenResponse);

$order = "MERCHANTORDER-" . date("Y/m/d h:I:s");
            $signature 
                = sha1(
                    $merchantCode
                    .$addUserTokenResponse["DS_IDUSER"]
                    .$addUserTokenResponse["DS_TOKEN_USER"]
                    .$terminal.$_POST["amount"]
                    .$order
                    .$password
            );
            $productDescription     = "XML_BANKSTORE TEST productDescription";
            $owner                  = "XML_BANKSTORE TEST owner";
            
            $executePurchaseResponse
                = $clientSOAP->execute_purchase(
                    $merchantCode,
                    $terminal,
                    $addUserTokenResponse["DS_IDUSER"],
                    $addUserTokenResponse["DS_TOKEN_USER"],
                    $_POST["amount"],
                    $order,
                    "EUR",
                    $signature,
                    $ip,
                    $productDescription,
                    $owner
                );
            
            if ($executePurchaseResponse["DS_RESPONSE"] == "1") {
                // OK
                return true;
            } else {
                //KO
                var_dump($executePurchaseResponse["DS_ERROR_ID"]);
                return false;
            }
        
        var_dump($executePurchaseResponse);
        } catch(SoapFault $e){
            var_dump($e);
        }
    } else {
        var_dump("Error, no se ha obtenido token");
        return false;
    }
    return false;
}
?>

<html>

<head>
</head>

<body>

    <h3>TEST DATA </h3>
    Card : 4539 2320 7664 8253 <br/>
    CVC: 123 <br/>
    Expires: 05 / 20 <br/>
    <br/>
    <br/>
    <br/>
    <form action="index.php" method="POST" id="paycometPaymentForm">
        <input type="hidden" data-paycomet="apiID" id="pc_jetid" name="pc_jetid" value="qJQ9s6KX7M41LyCDxFn2fwprBN3gWRZb" />
        <input type="hidden" id="amount" name="amount" value="202">
        Titular de la tarjeta: <br />
        <input type="text" data-paycomet="cardHolderName"> <br />
        Dirección<br />
        <input type="text" name="address"><br />
        Teléfono:<br />
        <input type="text" name="phone"> <br />
        Número de tarjeta <br />
        <div style="width:500px; height:35px">
            <div id="paycomet-pan" data-paycomet="paNumber" style="border:1px solid orange;"></div> <br />
        </div>
        Código cvc2 <br />
        <div style="width:500px; height:35px">
            <div id="paycomet-cvc2" data-paycomet="cvc2" style="border:1px solid green;"></div><br />
        </div>
        Caducidad:<br />
        mes
        <input type="text" data-paycomet="dateMonth">
        año
        <input type="text" data-paycomet="dateYear"> <br />
        <br/>
        <br/>
        Pagar 2,02 euros con Paytpv <br/>

        <input type="submit">
    </form>
    <div id="paymentErrorMsg"></div>
    <script src="https://secure.paytpv.com/gateway/paycomet.jetiframe.js?lang=en"></script>
</body>

</html>

With the php API


/**
 * PAYCOMET JET callback
 * Tracking ID: SSX-7MS-JX3J
 *
 * @author PAYCOMET 
 * @copyright Copyright (c) 2019, PAYCOMET 
 * @version 1.0 2016-05-01
 */

    include("class/Paytpv_bankstore.php");
	date_default_timezone_set("Europe/Madrid");

	$token = $_POST["paytpvToken"];

	if ($token && strlen($token) == 64) {

		$endPoint		= "https://secure.paytpv.com/gateway/xml-bankstore?wsdl";
		$merchantCode	= "************";
		$terminal		= "************";
		$password		= "************";
		$jetID			= "************";

		$signature		= sha1($merchantCode.$token.$jetID.$terminal.$password);

		$ip				= $_SERVER["REMOTE_ADDR"];

        $paycomet 
            = new Paytpv_bankstore($merchantCode, $terminal, $password, $jetID);
        $resp = $paycomet->AddUserToken($token);
        $idUser = $resp->DS_IDUSER;
        $tokenUser = $resp->DS_TOKEN_USER;
        $purchaseResult 
            = $paycomet->ExecutePurchase(
                $resp->DS_IDUSER,
                $resp->DS_TOKEN_USER,
                $_POST["amount"],
                "REFERENCIAPEDIDO",
                "EUR"
        );

        if ($purchaseResult->DS_RESPONSE == "1") {
            return true;
        } else {
            var_dump($purchaseResult->DS_ERROR_ID);
            return false;
        }
	} else {
		var_dump("Error, no se ha obtenido token");
        return false;
	}
    return false;