25 posts / 0 new
Last post
rohansureshkumar8148
Token based payments.

I have used the Payeezy.js file I want to make a payment using the response token.

I referred this page - https://developer.payeezy.com/payeezy-api/apis/post/transactions-4 but it shows the appropriate JSON. I can create the same JSON with the details but how exactly do I submit this JSON to the Payeezy server?


sadiegolf8470
Re: Token based payments.

Looking to do the same thing here. I feel, despite the documentation saying this is possible, that this is not possible. They don't even allow CORS on their endpoints, so obviously you can't POST to their given URLs.

here's what I tried, using the example values from that page of examples:

function makePayeezyTransaction() {
var data ={
"merchant_ref": "Astonishing-Sale",
"transaction_type": "purchase",
"method": "credit_card",
"amount": "1299",
"partial_redemption": "false",
"currency_code": "USD",
"credit_card": {
"type": "visa",
"cardholder_name": "John Smith",
"card_number": "4788250000028291",
"exp_date": "1020",
"cvv": "123"
}
}

var headers = { "apikey": "y6pWAJNyJyjGv66IsVuWnklkKUPFbb0a", "token": "a480ce8951daa73262734cf102641994c1e55e7cdf4c02b6", "Content-type": "application/json", "Authorization":"MzIxNTM0MDIyZTQzNjhjYjNlNmZkOWE4MzdkNzY1Nzc1NjkwYTQwODVhMDYyZDUyM2Q3YjhkMTUwMDZmNDRhNg" };

return $.ajax({
type: "POST",
url: "https://api-cert.payeezy.com/v1/transactions",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(data),
success: payeezyTransactionCallback,
error: payeezyTransactionCallback,
headers: headers
});
}

Doing that returns a "XMLHttpRequest cannot load https://api-cert.payeezy.com/v1/transactions. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'XXX' is therefore not allowed access. The response had HTTP status code 500."


rohitrajagopal3538
Re: Token based payments.

You are right. Our APIs dont support CORS requests. Also, it is not safe to do so because the API secret can get compromised via the website source code.

The token based payment will need to be made from the merchant server. 

Regards,

Payeezy team 


rohansureshkumar8148
Re: Token based payments.

@Rohit,

Can you give a code example on how to make a token based payment?


rohitrajagopal3538
Re: Token based payments.

Hi Rohan,

Here is a sample in PHP - 

<?php

$apiKey = ""
$apiSecret = ""
$token = "fdoa-a480ce8951daa73262734cf102641994c1e55e7cdf4c02b6";
$nonce = strval(hexdec(bin2hex(openssl_random_pseudo_bytes(4, $cstrong))));
$timestamp = strval(time()*1000); //time stamp in milli seconds

$payload = getPayload();

  /**
   * Generate Payload
   */

   function getPayload($args = array())
  {
    $data = "";
    
    $data = array(
              'merchant_ref'=> 'sample token txn',
              'transaction_type'=> "authorize",
              'method'=> 'token',
              'amount'=> '200',
              'currency_code'=> 'USD',
              'token'=> array(
                      'token_type'=> 'FDToken',
                      'token_data'=> array(
                          'type'=>'visa',
                          'value'=>'2537446225198291',
                          'cardholder_name'=>'JohnSmith',
                          'exp_date'=>'1030'
                          )
                    )
    );
   
    return json_encode($data, JSON_FORCE_OBJECT);
  }

$data = $apiKey . $nonce . $timestamp . $token . $payload;

$hashAlgorithm = "sha256";

### Make sure the HMAC hash is in hex -->
$hmac = hash_hmac ( $hashAlgorithm , $data , $apiSecret, false );

### Authorization : base64 of hmac hash -->
$hmac_enc = base64_encode($hmac);

$curl = curl_init('https://api-cert.payeezy.com/v1/transactions');

$headers = array(
      'Content-Type: application/json',
      'apikey:'.strval($apiKey),
      'token:'.strval($token),
      'Authorization:'.$hmac_enc,
      'nonce:'.$nonce,
      'timestamp:'.$timestamp,
    );

curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);

curl_setopt($curl, CURLOPT_VERBOSE, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

$json_response = curl_exec($curl);

$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

$response = json_decode($json_response, true);

if ( $status != 201 ) {
die("Error: call to URL $serviceURL failed with status $status, response $json_response, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl));
}

curl_close($curl);

echo "JSON response is: ".$json_response."\n";

?> 


sadiegolf8470
Re: Token based payments.

So, when sending the API secret to the js library, presumably from our merchant sites, where do you think that comes from? The website source code? Where else is it supposed to come from?

Is that not the same secret we are sending to create a token using the js library as well?

Seems like the thing you are blocking, CORS, is irrelevant to your reasoning why when you do the same things for your existing js library.

How are token based payments made from the merchant server? I'd like to see a proven usable code example.


rohitrajagopal3538
Re: Token based payments.

Hi Sadie,

When you tokenize a card, you only use the api key, js_security_key and TA_Token. Here is an example - 

https://api-cert.payeezy.com/v1/securitytokens?apikey=y6pWAJNyJyjGv66IsVuWnklkKUPFbb0a&js_security_key=js-6125e57ce5c46e10087a545b9e9d7354c23e1a1670d9e9c7&ta_token=NOIW&auth=true&callback=Payeezy.callback&type=FDToken&credit_card.type=visa&credit_card.cardholder_name=John%20Smith&credit_card.card_number=4788250000028291&credit_card.exp_date=1030&credit_card.cvv=123

For any other transaction (pre-auth, purchase, void, refund, etc.) you will need the api key, api secret and merchant token. Please see my previous comment for an example token based transaction. The merchant token and api secret are only known to the merchant.

Regards,

Payeezy team


rohansureshkumar8148
Re: Token based payments.

@Rohit,

Thanks. But could you give an example using C# and ASP.NET?


rohitrajagopal3538
Re: Token based payments.

Here is the C# example -

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            string jsonString = "{ 
                \"merchant_ref\": \"Payeezy Token test\", 
                \"transaction_type\": \"authorize\", 
                \"method\": \"token\", 
                \"amount\": \"1299\", 
                \"currency_code\": \"USD\", 
                \"token\": { 
                    \"token_type\": \"FDToken\", 
                    \"token_data\": {
                        \"type\": \"visa\",
                        \"value\": \"2537446225198291\", 
                        \"cardholder_name\": \"John\"
                        \"exp_date\": \"1030\"
                    }
                } 
            }";
            string apiKey = "<Enter API key>";
            string apiSecret = "<Enter API secret>";
            string token = "fdoa-a480ce8951daa73262734cf102641994c1e55e7cdf4c02b6";
            Random random = new Random();
            string nonce = (random.Next(0, 1000000)).ToString();

            DateTime date = DateTime.UtcNow;
            DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            TimeSpan span = (date - epoch);
            string time = span.TotalMilliseconds.ToString();

            string hashData = apiKey + nonce + time + token + jsonString;

            string base64Hash = Convert.ToBase64String(CalculateHMAC(hashData, apiSecret));

            string url = "https://api-cert.payeezy.com/v1/transactions";

            //begin HttpWebRequest
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);

            webRequest.Method = "POST";
            webRequest.Accept = "*/*";
            webRequest.Headers.Add("timestamp", time);
            webRequest.Headers.Add("nonce", nonce);
            webRequest.Headers.Add("token", token);
            webRequest.Headers.Add("apikey", apiKey);
            webRequest.Headers.Add("Authorization", base64Hash);
            webRequest.ContentLength = jsonString.Length;
            webRequest.ContentType = "application/json";

            StreamWriter writer = null;
            writer = new StreamWriter(webRequest.GetRequestStream());
            writer.Write(jsonString);
            writer.Close();

            string responseString;
            try
            {
                using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
                {
                    using (StreamReader responseStream = new StreamReader(webResponse.GetResponseStream()))
                    {
                        responseString = responseStream.ReadToEnd();
                        Console.WriteLine(webRequest.Headers.ToString() + jsonString);
                        Console.WriteLine(webResponse.Headers.ToString() + responseString);
                    }
                }
            }
            catch (WebException ex)
            {
                if (ex.Response != null)
                {
                    using (HttpWebResponse errorResponse = (HttpWebResponse)ex.Response)
                    {
                        using (StreamReader reader = new StreamReader(errorResponse.GetResponseStream()))
                        {
                            string remoteEx = reader.ReadToEnd();
                            Console.WriteLine(remoteEx);
                        }
                    }
                }
            }
            Console.ReadLine();
        }

        static byte[] CalculateHMAC(string data, string secret)
        {
            HMAC hmacSha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
            byte[] dataBytes = Encoding.UTF8.GetBytes(data);
            byte[] hmac2Hex = hmacSha256.ComputeHash(Encoding.UTF8.GetBytes(data));

            string hex = BitConverter.ToString(hmac2Hex);
            hex = hex.Replace("-", "").ToLower();
            byte[] hexArray = Encoding.UTF8.GetBytes(hex);
            return hexArray;
        }
    }
}


rohansureshkumar8148
Re: Token based payments.

Thanks Rohit.

What is the difference between purchase and authorize transaction types?

And how much time does the transarmor token remains active?


rohitrajagopal3538
Re: Token based payments.

Rohan - Authorize transaction is where you place a authorization hold for a specific amount on the customer's card. If successful, this tells the merchant that the required funds are available on the customer's credit card. Next, once the goods/services are shipped, you issue a Capture transaction to convert the authorization hold to a permanent charge.

A purchase transaction is simply a transaction where you do Authorize+Capture in one go. 


rohansureshkumar8148
Re: Token based payments.

Thanks for your help Rohit.

I've got it working now. Another requirement I have is to make this a recurring payment. How do I make that happen?


rohitrajagopal3538
Re: Token based payments.

Rohan - Please refer to this FAQ - http://developer.payeezy.com/faqs/are-recurring-payment-plans-supported-payeezy-api

Let us know if you have any questions.


rohansureshkumar8148
Re: Token based payments.

To make sure my understanding is correct - for the token based payments, do I just add the "eci_indicator"="2" to the request payload? For example,

{
"eci_indicator"="2",
"merchant_ref": "Astonishing-Sale",
"transaction_type": "authorize",
"method": "token",
"amount": "200",
"currency_code": "USD",
"token": {
"token_type": "FDToken",
"token_data": {
"type": "visa",
"value": "2537446225198291",
"cardholder_name": "JohnSmith",
"exp_date": "1030"
}
}
}

Further, what would be the frequency of the recurring payments?


rohitrajagopal3538
Re: Token based payments.

Rohan - if you are doing a recurring transaction, you will need to add the eci_indicator to the payload as you did. The frequency does not matter to Payeezy. The management of recurring payments will happen on the merchant side. A transaction will need to be sent to us for each payment.


rohansureshkumar8148
Re: Token based payments.

Thanks Rohit.

1. About the authorize transaction, how long are the funds kept on hold in the customer's account? Does the capture transaction need to be executed within that time period?

2. Is this the sample request payload for capture ( I got this from another forum thread):

{
"merchant_ref": "Astonishing-Sale",
"transaction_id": "ET160316",
"transaction_tag": "85115072",
"transaction_type": "capture",
"method": "credit_card",
"amount": "200",
"currency_code": "USD"
}

The transaction tag and id is from the response of a authorize transaction. I tried to run this request on this page: https://developer.payeezy.com/payeezy-api/apis/post/transactions-4 but this is the response I got:

{
"correlation_id": "124.1465324170686",
"Error": {
"messages": [
{
"code": "missing_transaction_id",
"description": "The transaction id is not provided"
}
]
},
"transaction_status": "Not Processed",
"validation_status": "failed",
"transaction_type": "capture",
"method": "credit_card",
"amount": "200",
"currency": "USD"
}


rohitrajagopal3538
Re: Token based payments.

Rohan,

1. Authorizations expire on a time set by the issuing bank / card brand.  The details of the exact length of the authorization hold are not exposed to First Data. Our backend processor automatically obtains new authorizations as required, even if a completion is issued against an expired authorization.

2. The transaction id should be part of the request URL and not part of the payload.


rohansureshkumar8148
Re: Token based payments.

Thanks @Rohit.

In order to test out the recurring indicator, I added it to the request payload here - https://developer.payeezy.com/payeezy-api/apis/post/transactions-3

{
"eci_indicator":"2",
"merchant_ref": "Astonishing-Sale",
"transaction_type": "authorize",
"method": "credit_card",
"amount": "1299",
"currency_code": "USD",
"credit_card": {
"type": "visa",
"cardholder_name": "John Smith",
"card_number": "4788250000028291",
"exp_date": "1020",
"cvv": "123"
}
}

But the response doesn't indicate that it is a recurring transaction in any way:
{
"correlation_id": "124.1465849004290",
"transaction_status": "approved",
"validation_status": "success",
"transaction_type": "authorize",
"transaction_id": "ET176267",
"transaction_tag": "85558127",
"method": "credit_card",
"amount": "1299",
"currency": "USD",
"cvv2": "M",
"token": {
"token_type": "FDToken",
"token_data": {
"value": "9725956120138291"
}
},
"card": {
"type": "visa",
"cardholder_name": "John Smith",
"card_number": "8291",
"exp_date": "1020"
},
"bank_resp_code": "100",
"bank_message": "Approved",
"gateway_resp_code": "00",
"gateway_message": "Transaction Normal"
}

Is this by design? How do we know if the transaction has been processed as recurring?


rohitrajagopal3538
Re: Token based payments.

Yes, it is by design. Unfortunately, only your Merchant Service Provider can verify if a given transaction was received as a recurring and offered the appropriate rates.

 


rohansureshkumar8148
Re: Token based payments.

Is it possible to do a 0 dollar authorization? We just want to store the token data for use in later recurring token based payments.


rohitrajagopal3538
Re: Token based payments.

Yes, you can do a $0 auth in 2 ways - 

1. Credit Card Payments (/transactions) - Do an authorize transaction with amount =0. This is a HTTP POST request and will need to originate from the merchant server.

2. Tokenize credit cards (/securitytokens) - Do a tokenize transaction with auth=true. This is a HTTP GET request and can even originate from a browser (javascript). Achieves the same result as above. 


charlescameron9721
Re: Token based payments.

Hi Payeezy Team.

I have used same code which you have given in #5 in same Forum Thread.

When I am using it in Sandbox.. it is working fine.. and giving me status approved and status success.

But when I am trying it using Live url and Live credentials.

It always gives below error,

[transaction_status] => Declined [validation_status] => success [transaction_type] => purchase [method] => token [amount] => 1 [currency] => USD [cvv2] => I [token] => Array ( [token_type] => FDToken [token_data] => Array ( [type] => XXXX [cardholder_name] => XXXX [exp_date] => XXXX [value] => XXXX ) ) [bank_resp_code] => 353 [bank_message] => Declined

Can you please help in this, as soon as possible?


rohitrajagopal3538
Re: Token based payments.

You will find more information about bank response codes here - https://support.payeezy.com/hc/en-us/articles/203730509-First-Data-Payeezy-Gateway-Bank-Response-Codes

353 TransArmor Invalid Token or PAN Fix TransArmor Service encountered a problem converting the given Token or PAN with the given Token Type.

donnapetrick15587
Re: Token based payments.

Hi.

Decrypted Response of apple pay payload from payeezy always coming back as

cardholder_name : Not Provided

how do I get this information? Thanks


christopherlord730
Re: Token based payments.

When you use Applepay use the card information you need to have a cardholder name. The error indicates you are not passing that in the request.