149 thoughts on “First Data Global E4 Gateway API PHP Example”

  1. Well. I don’t know what any of that means but I’m impressed all to h-ll that you wrote that code. I’m a firm believer in getting an expert to do the heavy lifting and you, Cindy Cullen, are looking like a True Expert in First Data Global E4 Gateway API PHP from where I’m sitting!!!!

  2. i have used same implementatoin with jquery ajax call.
    but it is returning “internal server error 500” on demo account in success callback.

    here is my code.

    var url = ‘https://api.demo.globalgatewaye4.firstdata.com/transaction/v11’;
    var gateWayid = “AD0838-01”;
    var password = “wolf1234”;
    var transactoin = “00”;
    var amount =”1.0″;
    var holder = “Test”;
    var cc_number = “411111111111111”;
    var expiry = “0314”;

    function upload() {
    url: ‘https://api.demo.globalgatewaye4.firstdata.com/transaction/v8’,
    type: ‘POST’,
    data: ‘{“gateway_id”:”‘ + gateWayid + ‘”,”password”:”‘ + password + ‘”, “transaction_type”:”‘ + transactoin + ‘”,”amount”:”‘ + amount + ‘”,”cardholder_name”:”‘ + holder + ‘”,”cc_number”:”‘ + cc_number + ‘”,”cc_expiry”:”‘ + expiry + ‘”}’,
    dataType: ‘json’,
    contentType: “application/json; charset=utf-8”,
    success: function (res) {
    error: function (res) {
    alert(“Bad thing happend! ” + res.statusText);

    1. I see that you are using version 8 of the api. The code I listed worked with v11, so not sure if it’s something with the versions.

      1. I’m not sure you can do this — but I sure wish you could. The ajax call is being made from your server, but connecting to firstdata, and that poses a same-origin issue. For an AJAX call to work, the site making the call needs to be the same as the destination of the AJAX call. The best way to resolve this is to use jsonp. See http://www.json-p.org/

        To use jsonp, it means firstdata would need to support it. And I see nothing to say they do.

        In other words, I don’t think you can use javascript to post a transaction to firstdata. Stripe does this, but they act as the merchant — obviating the need for firstdata.

  3. Oh, wow! This is great – I’m just about to start working on this stuff, and for the same reasons was going with REST/JSON.

    Thanks a lot for posting this, I’m sure it’s going to save me a bunch of trouble.

      1. Oh, I’ve got the HMAC sha1 business working so you can use v12 of the service, using PHP. Drop me a line sometime if you’re having trouble with it, as it gave me some headaches getting that to work.

  4. Is it mandatory I have to use SSL enabled site. I am running your site but I am getting “Unauthorized Request. Bad or missing credentials”. Can you please help. I am stuck with this.

    1. I had the same problem at first. Make sure you have the correct username and password. I was sure that I did, but the password had not saved when setting it. I thought I had saved it, but I hadn’t. My suggestion is to make sure you have the correct password for the site you are trying to access. Make sure it’s the test site username and password if you are on the test site OR the live username and password if you are on the live site. Then reset your password for that site and make sure (double check it!) it’s been saved.

      1. Thank you Cindy. I sorted out that problem but now I am getting another result: “Date header missing”. Can you please help me on this.

        1. Maxwell Appleton

          This is a bit late, but I received the same “Date Header missing” because I had used v12 for the API. If you switch it to v11 it should work… at least it did in my case..

          v12 uses the HMAC signature calculation thing…

          The HMAC is calculated with the SHA-1 algorithm on the following:

          Request Method + n
          + Content-type + n
          + Content Digest (SHA-1) + n
          + Sending Time + n
          + Request URL
          The sending time is expressed in ISO 8601 format, e.g: 2012-09-21T00:50:09Z.

      2. I can’t seem to get around this “Unauthorized Request” error. I know I’m using the correct gateway ID and gateway password. What am I missing? Your comment seems to suggest the use of my account username and account password, but I don’t see those referenced in the example code…

        1. Rob, Make sure you are using the correct URL for your gateway ID and password. If you are using the production URL, you will need your production gateway and password. If you are using the demo url, then you will need the credentials for your demo site.

          1. Thanks Cindy, it turns out I wasn’t using the json property values. For example, the property value for the gateway key for json is gateway_key, not ExactID.

            But now I’m getting an Internal Server Error response back… Not sure what to make of that yet.

  5. I am last facing problem with Authorization. It is telling “Expected signature ‘gKRub6rj2Z0c6luHDFcsR1yZ85w=’, received signature ‘2/HvUnOliDVVN2XVuDjeSa2NT6I=’.”… Do you have any idea on it.

  6. Hi Cindy! I’m also seeing the date header missing error. Authentication works but the date header missing error immediately follows. Have any thoughts? Thanks!

    My simple curl example producing the error:

    curl -v
    -H 'Content-Type: application/json; charset=UTF-8'
    -H 'Accept: application/json'
    -d '{
    "gateway_id": "AD9232-01",
    "password": "password",
    "transaction_type": "00",
    "amount": 11,
    "cardholder_name": "Test",
    "cc_number": "4111111111111111",
    "cc_expiry": "0314"

  7. Thanks to John Fiala we may have the solution to the date header errors. He says he got the following code to work:

    // Prepare the Data:
    $json_request = json_encode($nvp);

    // HMAC Hash
    // @see https://firstdata.zendesk.com/entries/22069302-api-security-hmac-hash.
    $content_type = ‘application/json; charset=UTF-8’;
    $hmackey = $payment_method[‘settings’][‘hmac_key’];
    $key_id = $payment_method[‘settings’][‘key_id’];
    $hashtime = gmdate(“c”);
    $content_digest = sha1($json_request);
    $api_uri = ‘/transaction/v12’;
    $hashstr = “POSTn” . $content_type . “n” . $content_digest . “n” . $hashtime . “n” . $api_uri;
    $authstr = base64_encode(hash_hmac(“sha1”, $hashstr, $hmackey, TRUE));

    $curl_headers = array(‘Content-Type: ‘ . $content_type, ‘Accept: application/json’);
    $curl_headers[] = ‘Authorization: GGE4_API ‘ . $key_id . ‘:’ . $authstr;
    $curl_headers[] = ‘X-GGe4-Date: ‘ . $hashtime;
    $curl_headers[] = ‘X-GGe4-Content-SHA1: ‘ . $content_digest;

    // Setup the cURL request.
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_VERBOSE, 0);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json_request);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_NOPROGRESS, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);
    $result = curl_exec($ch);

  8. My client just switched from Authorize.net to First Data and your post really helps me get started 🙂 Thank you so much!!!

  9. Hi bro,

    Thanks for this code. Very useful to me. One more help my site moved to live. Whats is the url for global first data payment gateway.


  10. Hi,
    Saw your post. I am new to php and i really do not know how to follow the code that you have posted. I copied your code and pasted it to a new test.php file and tried to run it but it results in just an empty page. Hopefully because what i have done is not the right way. I have to integrate this payment gateway into our company website but do not know how and where to start. Could you please please help me? Please send any example files that are working to my mail please or guide me in the right path.

    Email id : getsyed.a@gmail.com

    Thanks in advance.

    1. Syed,

      You will need to change the gateway_id and password to make it work. You should be able to look in your log file to see what error you are getting that is causing the blank page. It’s hard to give you direction without the error information.

  11. This helped me (especially the hmac_key reply above)…thank you! But does anyone know the variable name for CVV2 Code? I’ve tried the obvious “cvv” “cvv_code” “cvv2_code” “cvvcode” … ?

    1. How about ‘cvv2’? I haven’t tried it but you didn’t list that one. All the other documentation calls it that.

      1. That’s what I figured. But, after doing some reading, it turns out “cvv2” returns a response code:

        “M” = CVV2 / CVC2/CVD Match.
        “N” = CVV2 / CVC2/CVD No Match.
        “P” = Not Processed.
        “S” = Merchant has indicated that CVV2 / CVC2/CVD is not present on the card.
        “U” = Issuer is not certified and / or has not provided Visa encryption keys.

        The response code is returned if you set the following variable and pass the actual CVV or CVV2 code below:

        “cvd_presence_ind” => “1”
        “cc_verification_str2” => “$cvvcodehere”

        Thanks to this blog, I can wrap up a client project and collect the remaining 50% due tomorrow! =)


  12. I couldn’t find these in the documentation. Here is a var_dump of all the valid variable names. I hope someone finds this list helpful!

    [“cavv_algorithm”]=> NULL
    [“customer_ref”]=> NULL
    [“cc_number”]=> string(16) “############1111”
    [“merchant_province”]=> string(6) “Nevada”
    [“bank_resp_code_2”]=> NULL
    [“logon_message”]=> NULL
    [“client_ip”]=> string(15) “”
    [“currency_code”]=> string(3) “USD”
    [“ean”]=> NULL
    [“sequence_no”]=> string(6) “000023”
    [“tax2_amount”]=> NULL
    [“pan”]=> NULL
    [“merchant_postal”]=> string(5) “89109”
    [“retrieval_ref_no”]=> string(7) “0521915”
    [“authorization”]=> NULL
    [“error_description”]=> NULL
    [“transaction_approved”]=> int(1)
    [“virtual_card”]=> NULL
    [“bank_message”]=> string(8) “Approved”
    [“xid”]=> NULL
    [“merchant_name”]=> string(10) “Demo Store”
    [“credit_card_type”]=> string(4) “Visa”
    [“surcharge_amount”]=> NULL
    [“cvv2”]=> string(1) “I”
    [“user_name”]=> NULL
    [“track2”]=> NULL
    [“avs”]=> NULL
    [“tax1_amount”]=> NULL
    [“amount”]=> float(45)
    [“message”]=> NULL
    [“fraud_suspected”]=> NULL
    [“merchant_city”]=> string(9) “Las Vegas”
    [“bank_resp_code”]=> string(3) “100”
    [“reference_3”]=> NULL
    [“cvd_presence_ind”]=> int(0)
    [“partial_redemption”]=> int(0)
    [“card_cost”]=> NULL
    [“gateway_id”]=> string(9) “ADxxxx-xx”
    [“amount_requested”]=> NULL
    [“gross_amount_currency_id”]=> NULL
    [“cardholder_name”]=> string(10) “BOB MARLEY”
    [“zip_code”]=> NULL
    [“track1”]=> NULL
    [“exact_message”]=> string(18) “Transaction Normal”
    [“merchant_country”]=> string(13) “United States”
    [“secure_auth_result”]=> NULL
    [“transaction_type”]=> string(2) “00”
    [“cc_verification_str2”]=> NULL
    [“ecommerce_flag”]=> NULL
    [“error_number”]=> NULL
    [“success”]=> NULL
    [“reference_no”]=> NULL
    [“cavv”]=> NULL
    [“correlation_id”]=> NULL
    [“previous_balance”]=> NULL
    [“cc_expiry”]=> string(4) “0114”
    [“merchant_url”]=> string(0) “”
    [“tax2_number”]=> NULL
    [“transaction_tag”]=> int(4679288)
    [“transarmor_token”]=> NULL
    [“transaction_error”]=> int(0)
    [“timestamp”]=> NULL
    [“exact_resp_code”]=> string(2) “00”
    [“secure_auth_required”]=> NULL
    [“merchant_address”]=> string(27) “1234 Any StreetDrive Avenue”
    [“password”]=> NULL
    [“payer_id”]=> NULL
    [“cc_verification_str1”]=> NULL
    [“client_email”]=> NULL
    [“cavv_response”]=> NULL
    [“ctr”]=> string(505) “=========== TRANSACTION RECORD ========== Demo Store 1234 Any StreetDrive Avenue Las Vegas, NV 89109 United States TYPE: Purchase ACCT: Visa $ 45.00 USD CARD NUMBER : ############1111 DATE/TIME : 21 May 13 00:07:06 REFERENCE # : 000023 M AUTHOR. # : ETxxxxxx TRANS. REF. : Approved – Thank You 100 Please retain this copy for your records. Cardholder will pay above amount to card issuer pursuant to cardholder agreement. =========================================”
    [“current_balance”]=> NULL
    [“language”]=> NULL
    [“authorization_num”]=> string(8) “ETxxxxxx”
    [“tax1_number”]=> NULL

  13. hi ,

    i m newbie in php , i want integrate it with test details in php , as u have mentioned we need to replace gateway_id , password but i m not able to find gateway_id and password in my test a/c details.

    please help


    1. If you log in to your account you should see a Terminal link on the right. I found my gateway_id and Password in the online terminal section.

  14. now i m getting “Bad Request (22) – Invalid Credit Card Number” error , no idea how to resolve this issue .


    1. According to the error codes I found, this means a bad check digit, length, or other credit card problem.

      1. thanks for reply ,

        in $data array , there is no parameter for cvv code , so i add $cvv_code and it works fine with test details so is it work properly with live server details also because right now i don’t have live server details ?

  15. Having problems w/ REST and forbidden error from Windows script (works on Linux) – using /transaction/v11
    D:sitesDEVELO~1>C:WINNTcurl -k -H “Content-Type: text/xml; charset=UTF-8″
    -d ”
    05 AD6779-05 8dk9pa35 0.00 4111111111111111 Visa 1015 Donald Duck ” https://api.demo.globalgatewaye4.firstdata.com/transaction/v11

    403 Forbidden

    You don’t have permission to access /transaction/v11
    on this server.

    Apache Server at api.demo.globalgatewaye4.firstdata.com Port 8002

  16. DefenseDesigns

    Thanks for the code. This was a good starting point.

    HINT: If you are having trouble parsing the response data disable the return headers.

  17. Hello Cindy, thank you for your code, I have been testing it but I just receive no response from CURL whatsoever, I checked and I have CURL activated by default, so that is not the problem, do you have any idea on what might be causing this trouble?

    I am using XAMPP on localhost and Linux on production… none of them seem to be working at all

    I would really appreciate your help

    1. Hi Michel,

      It’s hard to help without seeing your code. Make sure you are using the correct URL. Otherwise, you will need to post your code or contact me off the blog.

  18. I have added another post about adding First Data Global E4 Gateway API to Gravity Forms and WordPress here. You can find all posts on First Data here.

  19. Hello.
    I need some your help.
    I’ using script from post
    >>Cindy says:
    >>March 2, 2013 at 12:00 am
    >>Thanks to John Fiala we may have the solution to the date header errors. He says >>he got the following code to work:
    >>// Prepare the Data:
    >>$json_request = json_encode($nvp);
    >>// HMAC Hash…
    But I receive from server only
    “Expected signature ‘WqFCXgYFn6XPEUrSlu5rEdKHxqo=’, received signature ‘sRtud+P4E+k9EpkZGIvAnvt12s0=’.”
    Are you have any ideas?

    1. Hi! I experienced this error too, fortunately I found out the problem when I tried the sample python code they provided. In my case, the cause was the way I was creating the value of the ‘Authorization’ header: I was using the full url during the creation of of the message for the hmac which is https://api.demo.globalgatewaye4.firstdata.com/transaction/v12. The correct way to do it is to use only ‘/transaction/v12’ instead of the complete one.
      Check the Terminal you are using and go to the API Access tab. You will notice that the Request URI field is not a complete URL. Hope this helps someone. 🙂

  20. Thanks for making this so clear & easy. Do you know how to submit a transaction to have the information added to a recurring billing plan instead of just processing the charge? I’ve read FirstData’s documentation and know it’s possible but their example didn’t make sense like yours did. Thanks.

    1. Jim, I’ve not tried this, but I did find this page: https://firstdata.zendesk.com/entries/407563-Recurring-First-Data-Global-Gateway-e4-Payment-Page-Integration

      My best guess at this point would be take the recurring fields at the bottom of the page and add them to the CURL options as key/value pairs like the other variables. In other words, take this:

      <input type=”hidden” name=”x_recurring_billing_amount” value=”19.95″ />
      <input type=”hidden” name=”x_recurring_billing_id” value=”MB-HOSTE-5-4″ />
      <input type=”hidden” name=”x_recurring_billing” value=”TRUE” />
      <input type=”hidden” name=”x_recurring_billing_start” value=”2010-11-11″ />
      <input type=”hidden” name=”x_recurring_billing_end” value=”2011-01-11″ />

      and add it to the data variable like this:

      $data = array(“gateway_id” => “AD1234-00”, “password” => “password”, “transaction_type” => “00”, “amount” => “11”, “cardholder_name” => “Test”, “cc_number” => “411111111111111”, “cc_expiry” => “0314”, “x_recurring_billing_amount” => “19.95”, “x_recurring_billing_id” => “MB-HOSTE-5-4”, “x_recurring_billing” => “TRUE”, “x_recurring_billing_start” => “2013-11-11”, “x_recurring_billing_end”, “2014-12-31”);

      Again, not sure if that will work, but that’s what I would try first. Of course, you will also need to make the changes inside your first data account like this page describes as well.

      Please let us know if you get it working! Thanks!

      1. Well, I called First Data tech support and was told that the API can’t handle recurring billing. The only way they can do it is through their Hosted Checkout, where the payment form is displayed on their site. Certainly a surprise to me, especially considering that was my main reason for switching to them and I was told by both the sales person and her manager that it was not a problem. Thanks for trying though.

        1. I suppose they expect you to write the code to handle the recurring billing? A cron job maybe to charge folks when it’s time to bill them again? You could just call this same code each time.

  21. Hi Cindy , your code saves me a lot of time , there is just one problem , what are the required fields for the production environment if you can guide me

    1. I don’t think it’s any different for the production environment. You will just need to change the URL, the api key and password. Everything else should stay the same. I found that I could get by with just these fields:
      $data = array(“gateway_id” => “AD1234-00”, “password” => “password”, “transaction_type” => “00”, “amount” => “11”, “cardholder_name” => “Test”, “cc_number” => “411111111111111”, “cc_expiry” => “0314”);

        1. Check your username and password. Make sure that you are using the correct credentials for the correct endpoint. Don’t use the test credentials on the live site or vice versa. Also, when you generate your keys make sure you are saving them. It can be a little tricky when saving because you have to save them twice sort of – generated it, accept it then save the whole form.

  22. Global gateway is a dream until a customer has a foreign address with special language characters, won’t process the transaction.
    Is anyone successfully processing foreign transactions that include language characters? If so, please share…

  23. How can I use transaction api in PHP to find out recurring orders status?

    I mean I have recurring orders and which used to recurred on scheduled but first data will not give any info regarding to that order whether recurring done or not.

    Thanks in advance.

  24. Hey! Thanks for providing sample for GGe4. I’m trying to code to V12 using the HMAC sample and your original sample code for V11, but I seem to have run into an error combining the code. I keep getting: Bad Authorization header ‘GGE4_API :xxxxxxxxxxx, where the xxx change with each request.

    My code is below – any help would be greatly appreciated! Thanks, John

    "mygate", "password" => "mypass", "transaction_type" => "00", "amount" => "11.00", "cardholder_name" => "TEST TEST", "cc_number" => "5656565656565656", "cc_expiry" => "000");
    $json_request = json_encode($nvp);

    // HMAC Hash
    $content_type = 'application/json; charset=UTF-8';
    $hmackey = $payment_method['settings']['my-key-here'];
    $key_id = $payment_method['settings']['my-key-id'];
    $hashtime = gmdate('c');
    $content_digest = sha1($json_request);
    $api_uri = '/transaction/v12';
    $hashstr = "POSTn" . $content_type . "n" . $content_digest . "n" . $hashtime . "n" . $api_uri;
    $authstr = base64_encode(hash_hmac("sha1", $hashstr, $hmackey, TRUE));

    $curl_headers = array('Content-Type: ' . $content_type.' Accept: application/json');
    $curl_headers[] = 'Authorization: GGE4_API ' . $key_id . ':' . $authstr;
    $curl_headers[] = 'X-GGe4-Date: ' . $hashtime;
    $curl_headers[] = 'X-GGe4-Content-SHA1: ' . $content_digest;

    // Setup the cURL request.
    $ch = curl_init( $url );
    curl_setopt($ch, CURLOPT_VERBOSE, 0);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json_request);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_NOPROGRESS, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);

    $result = curl_exec($ch);

    if ($result) {
    if ($result->bank_resp_code == '100') {
    } else {
    } else {

  25. Didn’t seem to copy all of the beginning of the code:

    $url = 'https://api.globalgatewaye4.firstdata.com/transaction/v12';
    // Prepare the Data:
    $nvp = array("gateway_id" => "mygate", "password" => "mypass",

  26. Thanks for a quick reply! So do I execute the HMAC request before the actual transaction request, or is it done simultaneously? In my code, I’ve combined them to run simultaneously.

    I guess I simply do not know where to use your original code for the transaction and then code for the HMAC… My combined method gives the bad authorization error.

    Thanks, John

  27. I think they should be run simultaneously. Single quotes vs. double quotes may matter in some cases, so check those and other syntax differences. Also, make sure you have the correct ID’s for the appropriate site – test vs. live/production. Make sure your passwords have been set appropriately.

  28. Hi,
    The Code below i am using for first data payment for mobile application.But i am getting error callback not even success callback.So please suggest me where am i mistaking..

    var url = “https://api.demo.globalgatewaye4.firstdata.com/transaction/v11”;
    var gateWayid = “AD0838-01”;
    var password = “wolf1234”;
    var transactoin = “00”;
    var amount =”1.0″;
    var holder = “Test”;
    var cc_number = “411111111111111”;
    var expiry = “0314”;

    function upload() {
    url: ‘http://www.google.com’,

    type: ‘POST’,
    url: ‘https://api.demo.globalgatewaye4.firstdata.com/transaction/v11’,
    data: {gateway_id:gateWayid,password:password,transaction_type:transactoin,amount:amount,cardholder_name:holder,cc_number:cc_number,cc_expiry:expiry},
    dataType: ‘json’,
    contentType: “application/json; charset=utf-8”,
    success: function (res) {
    error: function (res) {
    alert(“Bad thing happend! ” + res.statusText);
    url: “https://api.demo.globalgatewaye4.firstdata.com/transaction/v8”,
    type: ‘POST’,
    dataType: ‘json’,
    contentType: “application/json; charset=utf-8”,
    success: function (res) {
    error: function (res) {
    alert(“Bad thing happend! ” + res.statusText);


    Copy Text

    A function is triggered when the button is clicked. The function copies the text from Field1 into Field2.

  29. Hi Cindy,
    I used had used soap method and then changed to use json, but i keep getting this “Unrecognized gateway response.” error. I have no ideas why. Meanwhile i am doing my integration with YII framework, here is the code http://pastebin.com/MVPZsYwk, every thing else works well, all data is properly parsed.

    1. I’m not very experienced with soap API. I’ve only used the First Data REST API. If you just want to use json, why not try the shorter REST methods?

  30. I have done everything i can, but i still can’t get the desired result, here is a dump of the resulting data from my integration

    {“amount”:”31.25″,”cc_number”:”768273993434″,”transaction_type”:”00″,”gateway_id”:”B56287-01″,”Password”:”70133r24″,”reference_no”:”11551806917693853″,”cardholder_name”:”Presh”}” array(5) { [0]=> string(30) “Content-Type: application/json” [1]=> string(61) “X-GGe4-Content-SHA1: f9b0bd8c3ed5066e3063f640e194014c6a7bc66e” [2]=> string(33) “X-GGe4-Date: 2014-02-23T12:55:33Z” [3]=> string(59) “Authorization: GGE4_API 158141:mgL9AIBaAS0qXiCE/uoIUjDvO/w=” [4]=> string(24) “Accept: application/json” } array(10) { [“cache-control”]=> string(8) “no-cache” [“content-type”]=> string(24) “text/html; charset=utf-8” [“date”]=> string(29) “Sun, 23 Feb 2014 11:55:38 GMT” [“server”]=> string(6) “Apache” [“status”]=> string(3) “401” [“x-rack-cache”]=> string(16) “invalidate, pass” [“x-request-id”]=> string(32) “f41df5f807bcff81b60cadb91c8bb652” [“x-ua-compatible”]=> string(16) “IE=Edge,chrome=1” [“content-length”]=> string(2) “49” [“connection”]=> string(10) “keep-alive” } Unauthorized Request. Bad or missing credential

    Please Cindy help me take a look and tell me what i am doing wrong.

    1. My first guess is that you have the wrong username or password for the test or live site. Make sure you save the password once you change it. Since it’s hidden, I’ve made the mistake of changing the password and forgetting to save it. Seems as though I remember there is an extra step to make sure it’s changed completely – not as intuitive as I thought it should be.

  31. Pingback: Why I Will Never Use First Data Global E4 Gateway API and Will Try to Discourage My Clients - Cullen Web Services

  32. Hello sir

    when i perform the code it give me errorUnauthorized Request. Bad or missing credentials.

    are i need change api setting under terminal . i mean reuest uri and request content. after that it will be work fine

    1. I think you have the wrong username and password set in your code. Make sure you have the correct username and password for the live or test url that you have set. Set the password and then make sure you save it.

  33. Hello Cindy,
    Hope you are doing fine. Thanks for such a nice, easy and working tutorial.
    One question though,
    Is there a way to delete TransArmor token from GGe4 system? If so then please guide.

    Thanks in Advance,

  34. Hi

    I am using the below code for credit card transactions. It works fine if i use “cc_number” parameter but when i replace it with “transarmor_token” parameter it gives “Server Error. Please contact Support. (19) – Unable to Process Transaction” error. Please help. I want to use transarmor_token field.

    $data_array = array(
    ‘gateway_id’ => ,
    ‘password’ => ,
    ‘transaction_type’ => ’05’,
    ‘amount’ => ’10’,
    ‘transarmor_token’ => ‘4190852032111881’,
    //’cc_number’ => ‘4012888888881881’,
    ‘cc_expiry’ => ‘1214’,
    ‘cardholder_name’ => ‘xyz’

    $data_string = json_encode($data_array);

    $content_type = ‘application/json; charset=UTF-8’;
    $content_digest = sha1($data_string);
    $hashtime = gmdate(‘c’);

    $hashstr = “POST\n”.$content_type.”\n”.$content_digest.”\n”.$hashtime.”\n/transaction/v13″;
    $authstr = base64_encode(hash_hmac(‘sha1’, $hashstr, $hmackey, true));

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, ‘https://api.demo.globalgatewaye4.firstdata.com/transaction/v13’);

    curl_setopt($ch, CURLOPT_VERBOSE, 0);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_NOPROGRESS, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(‘Content-Type: ‘.$content_type, ‘Accept: application/json’,
    ‘Authorization: GGE4_API ‘.$key_id.’:’.$authstr, ‘x-gge4-Date: ‘.$hashtime, ‘x-GGe4-Content-SHA1: ‘.$content_digest));

    $result = curl_exec($ch);
    echo $result;

    1. I had this problem recently. I have to send the Credit Card expiration date and the card type. If I leave one of those off, I got the error too.

      1. var request = {
        transaction_type: ’00’,
        amount: amount,
        credit_card_type: cardType,
        transarmor_token: token,
        cardholder_name: cardholderName,
        cc_expiry: expDate

        When I try and send the transarmor_token, I get Bad Request (22) – Invalid Credit Card Number. Any thoughts?

        1. Now it’s returning “Invalid Transarmor Token”
          I’m in the demo site, so the token I am using is ############1111

  35. Thank You Cindy for providing this example code. I had success implementing a PHP REST/JSON implementation using your example.

    However, my client recently reported that all attempts to post transactions to the First Data Global Gateway were starting to return errors.

    My investigations established that the “https” URL for First Data was causing the failure and I added the following statement to set the SSL_VERIFYPEER option to FALSE and everything started working again.

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

  36. I have added another post about adding First Data Global E4 Gateway API to Gravity Forms and WordPress here.——– By cindy

    The link is not working now. Cindy can you help me to get those code?

    1. The URL you have listed here shows v14 and the error shows v11. Make sure you are using the same version in the URL as you are using in the HMAC hash string.

  37. Hi Cindy,I encountered the same problem,I come from China,and Can not read English…There are examples of it can be downloaded?谢谢

    1. Make sure these match:

      $url = ‘https://api.demo.globalgatewaye4.firstdata.com/transaction/v14‘;

      $content_type = ‘application/json; charset=UTF-8’;
      $hashtime = gmdate(“c”);
      $content_digest = sha1($data_string);
      $api_uri = ‘/transaction/v14’;
      $hashstr = “POST\n”.$content_type.”\n”.$content_digest.”\n”.$hashtime.”\n”.$api_uri;
      $authstr = base64_encode(hash_hmac(“sha1”,$hashstr,HMAC_KEY,TRUE));

      $curl_headers = array(‘Content-Type:’.$content_type, ‘Accept: application/json’);
      $curl_headers[] = ‘Authorization: GGE4_API ‘.KEY_ID.’:’.$authstr;
      $curl_headers[] = ‘X-GGe4-Date:’.$hashtime;
      $curl_headers[] = ‘X-GGe4-Content-SHA1:’.$content_digest;

  38. Hi, Cindy

    Thanks for reply , i used the same version of Api version i.e V12 with proper HMAC hash string but still receiving same error ,

  39. Hi,
    I am trying to implement the GGE4 through mobile android platform by using SOAP service ,
    Below are my code to access the GGE4 SOAP service from my application.

    String SOAP_ACTION = “http://api.demo.globalgatewaye4.firstdata.com/vplug-in/transaction/rpc-enc/SendAndCommit”;
    String URL = “https://api.demo.globalgatewaye4.firstdata.com/transaction/v12”;

    String response = null;
    try {
    HttpClient httpClient = new DefaultHttpClient();

    HttpPost httpPost = new HttpPost(URL);

    String bodynew = “”
    + ” ”
    + ” ”
    + ” ”
    + “”
    + ” ”
    + ” 01″
    + ” 15.75″
    + ” 4111111111111111″
    + ” 08/30/2016″
    + ” Walter Sobchak”
    + “”
    + ” ” + “”;

    StringEntity se = new StringEntity(bodynew, HTTP.UTF_8);

    httpPost.addHeader(“SOAPAction”, SOAP_ACTION);
    httpPost.addHeader(BasicScheme.authenticate(new UsernamePasswordCredentials(“AGXXXX-XX”,”ajx1XXd3″),”UTF-8″, false));
    httpPost.addHeader(“authorization”, “GGE4_API 12:nCAxZo9gqYzBcS5gm6OFXXXQAaPDjox”);
    httpPost.addHeader(“x-gge4-date”, “2014-09-10T11:11:48Z”);
    httpPost.addHeader(“x-gge4-content-sha1”, “Ezrq8V56zfTDhwGzotGXXqROks=”);


    HttpResponse httpResponse = httpClient.execute(httpPost);
    HttpEntity resEntity = httpResponse.getEntity();
    response = EntityUtils.toString(resEntity);

    DocumentBuilderFactory factory = DocumentBuilderFactory
    DocumentBuilder builder = factory.newDocumentBuilder();
    StringReader sr = new StringReader(response);
    InputSource is = new InputSource(sr);
    Document XMLResponse = builder.parse(is);
    NodeList elements = XMLResponse.getElementsByTagName(“ERRORS”);
    Boolean error = Boolean.valueOf(elements.item(0)
    HashMap Data = new HashMap();

    } catch (Exception e) {
    Log.e(LOG_TAG, e.getMessage());
    } finally {
    Log.v(LOG_TAG + ” Response”, response);

    1. Request Method + \n
      + Content-type + \n
      + Content Digest (SHA-1) + \n
      + Sending Time + \n
      + Request URL

      Here is how I implemented in php for REST not SOAP:
      Note: The KEY_ID and HMAC_KEY comes from the top of your terminal page as seen here: https://firstdata.zendesk.com/entries/22069302-API-Security-HMAC-Hash;
      FD_ID = Your First Data ID and
      FD_PW = Your First Data Password as seen in the image here:

      Make sure you generate and SAVE the HMAC key and the password for it to work correctly.


      $url = ‘https://api.demo.globalgatewaye4.firstdata.com/transaction/v14’;
      $data = array(“gateway_id” => FD_ID, “password” => FD_PW, “transaction_type” => “00”, “amount” => $_POST[‘chargetotal’], “cardholder_name” => $_POST[‘bname’], “cc_number” => str_replace(” “,”,$_POST[‘cardnumber’]), “cc_expiry” => $_POST[‘expmonth’].substr($_POST[‘expyear’],2,2), “CVDCode” => $_POST[‘cvm’], “Address” => array(“Address1” => $_POST[‘baddr1’], “Address2” => $_POST[‘baddr2’], “City” => $_POST[‘bcity’], “Zip” => $_POST[‘bzip’], “State” => $_POST[‘bstate’]));

      $data_string= json_encode($data);

      $content_type = ‘application/json; charset=UTF-8’;
      $hashtime = gmdate(“c”);
      $content_digest = sha1($data_string);
      $api_uri = ‘/transaction/v14’;
      $hashstr = “POST\n”.$content_type.”\n”.$content_digest.”\n”.$hashtime.”\n”.$api_uri;
      $authstr = base64_encode(hash_hmac(“sha1”,$hashstr,HMAC_KEY,TRUE));

      $curl_headers = array(‘Content-Type:’.$content_type, ‘Accept: application/json’);
      $curl_headers[] = ‘Authorization: GGE4_API ‘.KEY_ID.’:’.$authstr;
      $curl_headers[] = ‘X-GGe4-Date:’.$hashtime;
      $curl_headers[] = ‘X-GGe4-Content-SHA1:’.$content_digest;

      // Initializing curl
      $ch = curl_init( $url );
      curl_setopt($ch, CURLOPT_CUSTOMREQUEST, “POST”);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);

  40. Hello Cindy ,
    I’m facing problem in calling Web api “Tagged Refund” of GGe4 payment gateway.
    please suggest how to call third web api “Tagged Refund” Service. and im call web service from c# code in asp.net.

    Thank you

    1. You will need to use the transaction type for tagged refunds – 34, I think. Also, you will need a transaction tag from a previous GGE4 transaction.

  41. Hello,
    Please review the below C# code that i’m using for Tagged refund service and i’m passing all the required fields to the service.

    StringBuilder Json_builder = new StringBuilder();
    StringBuilder string_builder = new StringBuilder();
    using (StringWriter string_writer = new StringWriter(Json_builder))
    using (JsonTextWriter xml_writer = new JsonTextWriter(string_writer))
    { //build XML string
    //xml_writer.Formatting = System.Xml.Formatting.Indented;

    //xml_writer.WritePropertyName(“ExactID”);//Gateway ID






    using (StringWriter string_writer = new StringWriter(string_builder))
    using (XmlTextWriter xml_writer = new XmlTextWriter(string_writer))
    { //build XML string
    //xml_writer.Formatting = System.Xml.Formatting.Indented;
    xml_writer.WriteElementString(“ExactID”, “AG0920-05”);//Gateway ID
    xml_writer.WriteElementString(“Password”, “9f1bl7sn”);//Password
    string xml_string = string_builder.ToString();
    string Json_string = Json_builder.ToString();

    //SHA1 hash on XML string
    ASCIIEncoding encoder = new ASCIIEncoding();
    byte[] xml_byte = encoder.GetBytes(xml_string);
    SHA1CryptoServiceProvider sha1_crypto = new SHA1CryptoServiceProvider();
    string hash = BitConverter.ToString(sha1_crypto.ComputeHash(xml_byte)).Replace(“-“, “”);
    string hashed_content = hash.ToLower();

    //assign values to hashing and header variables
    string keyID = “167015”;//key ID
    string key = “IFhtcMcjW35YrQGcMQYdy_Tmza41VmtP”;//Hmac key
    string method = “POST\n”;
    string type = “application/json; charset=UTF-8”;//REST XML
    string time = DateTime.UtcNow.ToString(“yyyy-MM-ddTHH:mm:ssZ”);
    string uri = “/transaction/v13”;

    string hash_data = method + type + “\n” + hashed_content + “\n” + time + “\n” + uri;
    //hmac sha1 hash with key + hash_data
    HMAC hmac_sha1 = new HMACSHA1(Encoding.UTF8.GetBytes(key)); //key
    byte[] hmac_data = hmac_sha1.ComputeHash(Encoding.UTF8.GetBytes(hash_data)); //data
    //base64 encode on hmac_data
    string base64_hash = Convert.ToBase64String(hmac_data);
    string url = “https://api.demo.globalgatewaye4.firstdata.com” + uri; //DEMO Endpoint

    //begin HttpWebRequest
    HttpWebRequest web_request = (HttpWebRequest)WebRequest.Create(url);
    web_request.Method = “POST”;
    web_request.ContentType = type;
    web_request.Accept = “application/json”;
    web_request.Headers.Add(“x-gge4-date”, time);
    web_request.Headers.Add(“x-gge4-content-sha1”, hashed_content);
    web_request.Headers.Add(“Authorization”, “GGE4_API ” + keyID + “:” + base64_hash);
    web_request.ContentLength = Json_string.Length;

    // write and send request data
    using (StreamWriter stream_writer = new StreamWriter(web_request.GetRequestStream()))
    //get response and read into string
    string response_string;
    using (HttpWebResponse web_response = (HttpWebResponse)web_request.GetResponse())
    using (StreamReader response_stream = new StreamReader(web_response.GetResponseStream()))
    response_string = response_stream.ReadToEnd();

    //load xml
    XmlDocument xmldoc = new XmlDocument();
    XmlNodeList nodelist = xmldoc.SelectNodes(“TransactionResult”);

    //bind XML source DataList control
    //DataList1.DataSource = nodelist;
    //output raw XML for debugging

    string request = “Request” + web_request.Headers.ToString() + System.Web.HttpUtility.HtmlEncode(xml_string);
    string response = “Response” + web_response.Headers.ToString() + System.Web.HttpUtility.HtmlEncode(response_string);
    //read stream for remote error response
    catch (WebException ex)
    if (ex.Response != null)
    using (HttpWebResponse error_response = (HttpWebResponse)ex.Response)
    using (StreamReader reader = new StreamReader(error_response.GetResponseStream()))
    string remote_ex = reader.ReadToEnd();
    string error = remote_ex;
    or how should i pass the credentials to the web api?

    But stilll it gives error of 401(Unauthorization).

    Please suggest.
    Thank you.

    1. Sorry Mukul, I don’t understand the C# code well enough to help with that. Hopefully, someone who has more C# experience will respond. Anyone?

  42. Pingback: First Data Global Gateway API - Rolling Your Own Recurring Payments Using TransArmor Token PHP JSON REST Example - Cullen Web Services

  43. Alfredo Castillo

    Another way to write it in php.

    $gatewayid = “”; // insert gateway_id
    $password = “”; // insert password
    $transactionType = “00”; // transaction type
    $amount = “900.00”; // amount to charge
    $cardnumber = “4111111111111111”; //test creditcard number
    $expiration = “1115”; // any expiration date
    $name = “”; // insert card holder name
    $HMAC_KEY = “”; // insert HMAC key
    $KEY_ID = “” // insert key id;

    $url = “https://api.demo.globalgatewaye4.firstdata.com/transaction/v14”;
    $data = array(
    “gateway_id” => $gatewayid,
    “password” => $password,
    “transaction_type” => $transactionType,
    “amount” => $amount,
    “cc_number” => $cardnumber,
    “cc_expiry” => $expiration,
    “cardholder_name” => $name

    $data_string= json_encode($data);
    $content_type = ‘application/json; charset=UTF-8’;
    $hashtime = gmdate(“c”);
    $content_digest = sha1($data_string);
    $api_uri = ‘/transaction/v14’;
    $hashstr = “POST\n”.$content_type.”\n”.$content_digest.”\n”.$hashtime.”\n”.$api_uri;
    $authstr = base64_encode(hash_hmac(“sha1”,$hashstr,$HMAC_KEY,TRUE));

    $options = array(
    ‘http’ => array(
    ‘header’ => “Content-Type:” . $content_type . “\r\n” .
    “Accept: application/json\r\n” .
    “Authorization: GGE4_API ” . $KEY_ID . “:” . $authstr . “\r\n” .
    “X-GGe4-Date:” . $hashtime . “\r\n” .
    “X-GGe4-Content-SHA1:” . $content_digest,
    ‘method’ => ‘POST’,
    ‘content’ => $data_string

    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);

    $data = json_decode($result);

  44. Cindy – any tips on a custom redirect on approval URL for Global Gateway E4? I have a feeling I’m missing something basic but I’ve gotten everything else to work. The last payment processing system we used had a standard variable for this but in all of FirstData’s documentation, I can only find one for hosted payment pages, not for use with the API. Tips?


    1. Maggie, you need to do the redirect in your PHP code:

      // set up variables (see original post)

      // Initializing curl
      $ch = curl_init( $url );
      curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
      curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);

      // Getting results
      $result = curl_exec($ch);

      // Getting jSON result string
      $data_string = json_decode($result);

      if ($data_string) {
      if ($data_string->bank_resp_code == '100') {
      // add code for processing successful payments
      header("Location: http://example.com/thankyou.php");
      } else {
      // add code for processing failed payments
      header("Location: http://example.com/error.php");
      } else {
      // something went wrong!

      Replace the header("Location: ...."); links with your own redirect links.

      Does that help?

  45. Cindy,

    Thanks for the informative post

    My code is working fine– it’s POST’ing, my Authorization is being accepted beautifully, and I get a nice response/receipt

    However–I’m curious, to add an extra bit of security (or maybe because I’m a glutton for punishment)– I am trying to verify the RESPONSE’s Authorization. Have you been able to do that?

    A response header looks something like this:

    HTTP/1.1 201
    Authorization: GGE4_API 999999:w+AuSlMWoaiueOw8uNRHu9K4buU=
    Cache-Control: max-age=0, private, must-revalidate
    Content-Type: application/json; charset=utf-8
    Date: Mon, 20 Oct 2014 19:11:46 GMT
    ETag: "b50682eee494199449605b0e0c4703fb"
    Location: https://api.demo.globalgatewaye4.firstdata.com/transaction/v12/34569515
    Server: Apache
    Status: 201
    X-GGE4-CONTENT-SHA1: da0d8512e1aa14897c47da597a4a1e4ec7040713
    X-GGE4-Date: 2014-10-20T19:11:46Z
    X-Rack-Cache: invalidate, pass
    X-Request-Id: d004033b9a813866f94d0a2ec2f12182
    X-UA-Compatible: IE=Edge,chrome=1
    Content-Length: 1325
    Connection: keep-alive

    I’m trying to use my hashing function to double check that the ‘Authorization’ in the response is correct

    Here’s my function (same one used to build the POST’s authorization code– which works fine)

    function e4hash($args) {
    $hashstr = implode("\n",$args);
    return "GGE4_API ".MY_KEY.":".base64_encode(hash_hmac("sha1",$hashstr,MY_HMAC,1));

    I assume that the RESPONSE Authorization follows the same format as the POST, namely:

    Request Method + \n
    + Content-type + \n
    + Content Digest (SHA-1) + \n
    + Sending Time + \n
    + Request URL

    I have tried variations of the following and I can never reproduce the response’s Authorization, what am I missing?

    "HTTP/1.1 201",
    "application/json; charset=utf-8",

    In this case the result of the above code does not equal “GGE4_API 999999:w+AuSlMWoaiueOw8uNRHu9K4buU=”
    like it should

    Do you know if the RESPONSE authorization uses different fields than what I have provided? It still should rely on the same HMAC associated with the account (/POST’ing) correct?

    Any help would be appreciated


    1. Can you show me the complete JSON request header that contains the HMAC (please hide all sensitive data)? Believe it or not, First Data tech support is not able to provide a sample even after numerous requests. Many thanks.

  46. Ah hah!

    A completely different hash of values,

    The value is created with a SHA 1 Hash using the following parameter string:
    sharedsecret + approvalcode + chargetotal + currency + txndatetime + storename

    Thanks Cindy, I’ve been searching forever, don’t know how I missed this PDF!

  47. Pingback: First Data Unauthorized Request. Bad or missing credentials: Things are not always as they seem. - Cullen Web Services

  48. Hi, thanks a bunch for the code. This code on this page seems to work fine for me. Do you know if there is any reason to move to the higher versions, or should I just stay at v11?

    Thanks again,

  49. Please provide the example of the First Data Payment Gateway Recurring , we need the code for the php integration ,Please provide code as soon as possible.

  50. Sam or Cindy,

    Are either of you interested in updating or providing a solution for osCommerce sites? The current module in the “addons” section of the osCommerce site are generating an error and moving to JSON would be a nice change.


    1. You probably need to set up or activate your terminal in your First Data Account. You may need to call their customer support to fix this.

  51. We are getting “invalid signature received” error. And we are using this code. So please help me.

    $data_array = array(
    ‘gateway_id’ => ‘AJ5603-05’,
    ‘password’ => ‘qkbpymzrw12ydx1b4ol2yvqx234y694k’,
    ‘transaction_type’ => ’00’,
    ‘amount’ => ‘10.00’,
    ‘cc_number’ => ‘4111111111111111’,
    ‘cc_expiry’ => ‘0517’,
    ‘cardholder_name’ => ‘Test’

    $data_string = json_encode($data_array);

    $content_type = ‘application/json; charset=UTF-8’;
    $content_digest = sha1($data_string);
    $hashtime = gmdate(‘c’);
    //print_r($content_digest); die;
    $hmackey = ‘mDuuVWLN5mqG_RpygFfl5z~A~3edpF0i’;
    $key_id = ‘271178’;
    $hashstr = ‘POST\n’.$content_type.’\n’.$content_digest.’\n’.$hashtime.’\n/transaction/v12′;
    $authstr = base64_encode(hash_hmac(‘sha1’, $hashstr, $hmackey, true));

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, ‘https://api.demo.globalgatewaye4.firstdata.com/transaction/v12’);

    curl_setopt($ch, CURLOPT_VERBOSE, 0);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_NOPROGRESS, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);

    $header = array(
    ‘Content-Type: ‘.$content_type,
    ‘Accept: application/json’,
    ‘Authorization: GGE4_API ‘.$key_id.’:’.$authstr,
    ‘x-gge4-Date: ‘.$hashtime,
    ‘x-GGe4-Content-SHA1: ‘.$content_digest

    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

    $result = curl_exec($ch);


      1. Hi
        Pls help me to know why allway i get message: “Internal Server Error”. But, I saw transaction in payment manager.

        Thanks you

        class Payment {
        public $cc_name;
        public $cc_number;
        public $cc_cvv;
        public $cc_month;
        public $cc_year;
        public $email;
        public $transaction_id;

        public function charge() {
        //get from account API settings these are not valid keys, key_id, gateway_id or password
        $key = ‘pjtLWm65BtuqpI~Nq67xsSGkkYd_srz5’;
        $key_id = 261260;
        $gateway_id = ‘AJ2306-01’;
        $endpoint = ‘https://api.demo.globalgatewaye4.firstdata.com/transaction/v14’;
        //$endpoint = ‘https://api.globalgatewaye4.firstdata.com/transaction/v14’;
        $password = ‘ge35tro64qttojii0ub7fewb2xys6622’;

        $myorder = array(
        ‘gateway_id’ => $gateway_id,
        ‘password’ => $password,
        ‘transaction_type’ => ’00’,
        ‘amount’ => 51,
        ‘cardholder_name’ => $this->cc_name,
        ‘cc_number’ => $this->cc_number,
        ‘cc_expiry’ => ‘0916’, //format 0414
        ‘cvd_code’ => $this->cc_cvv,
        ‘client_ip’ => $_SERVER[‘REMOTE_ADDR’],
        ‘client_email’ => $this->email,
        ‘zip_code’ => $billing->zip,
        ‘address’ => array(
        ‘address1’ => ‘Data ton’,
        ‘address2’ => ”,
        ‘city’ => ‘Ha Noi’,
        ‘state’ => ‘HN’,
        ‘zip’ => ‘10000’

        $data_string = json_encode($myorder);

        $ch = curl_init ();
        curl_setopt ($ch, CURLOPT_URL,$endpoint);
        curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, “POST”);
        curl_setopt ($ch, CURLOPT_POSTFIELDS, $data_string);
        curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt ($ch, CURLOPT_VERBOSE, 1);

        $content_digest = sha1($data_string);

        $current_time = gmdate(‘Y-m-dTH:i:s’) . ‘Z’;
        $current_time = str_replace(‘GMT’, ‘T’, $current_time);
        $hashtime = gmdate(“c”);

        $code_string = “POST\napplication/json; charset=UTF-8\n{$content_digest}\n{$hashtime}\n/transaction/v14″;
        $code = base64_encode(hash_hmac(‘sha1’,$code_string,$key,true));

        /*$header_array = array(
        ‘Content-Type: application/json’,
        ‘Content-Length: ‘ . strlen($data_string),
        ‘X-GGe4-Content-SHA1: ‘. $content_digest,
        ‘X-GGe4-Date: ‘ . $current_time,
        ‘Authorization: GGE4_API ‘ . $key_id . ‘:’ . $code,

        $curl_headers = array(‘Content-Type:application/json; charset=UTF-8’, ‘Accept:application/json’);
        $curl_headers[] = ‘Authorization: GGE4_API ‘ . $key_id . ‘:’ . $code;
        $curl_headers[] = ‘X-GGe4-Date: ‘ . $hashtime;
        $curl_headers[] = ‘X-GGe4-Content-SHA1: ‘ . $content_digest;

        curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);
        $result = curl_exec ($ch);

        //$result = json_decode($result);
        echo ”; print_r($result); exit();
        if ($result->transaction_approved == ‘0’) {
        return array(‘success’=>false,’error’=>$result->bank_message);
        } else {
        $this->transaction_id = $result->transaction_tag;
        return array(‘success’=>true);

        $payment = new Payment();
        $payment->cc_name = ‘Test Tester’;
        $payment->cc_number = ‘4111111111111111’;
        $payment->cc_cvv = ‘123’;
        $payment->email = ‘test@test.com’;
        $result = $payment->charge();

        1. Internal Server errors are sometimes related to your server setup. Can you look at the log files to see why you are getting the error?

  52. Lívio Carvalho

    Friends I have a problem that I do not know what to do. I am using the v11 version api below the array I am sending:

    $url = ‘https://api.globalgatewaye4.firstdata.com/transaction/v11’;
    $data = array(“gateway_id” => “XXXX”, “password” => “XXXXXX”, “transaction_type” => “00”, “amount” => “1.00”, “cardholder_name” => “ayres escanhuela”, “cc_number” => “8798600004242274”, “cc_verification_str2” => “345”, “cvd_presence_ind” => 1, “ecommerce_flag” => “0”, “cc_expiry” => “0320”);

    My problem is that even sending the wrong cvv the transaction is successfully approved. Can you help me ?

  53. Hello Cindy,
    Hope you doing good!
    Your code helps me alot and you are wonderful I must sat that.
    Could you please tell me how can I use the first data api with other currencies because by default it is US please help me out, it is not like PAYPAL that we have option to mention currency in API code.
    If there is any option please let me know!

    1. No, I don’t have any refund code posted. I haven’t had a chance to use that part of the API, but hopefully some of the code here on the site will help you get the calls working correctly. Here is a list of the First Data API posts I have on the site.

      1. Sorry,

        I found lots of help for first data payment gateway for payment process, but not for refund process.

        I have researched found some help from other. I hope it works for me.

        Thanks for help.

    1. I can’t help you with asp.net, but I would think there are any number of ways to do it. By the time you get the transarmor token, you just need to be able to get it back again when you need it.

  54. Hi Cullen, this is Madhav. Can you let me know how to declared mandatory * input to State, Address, Zip/postal code in payeezy iframe integration.

Leave a Comment

Your email address will not be published.

Scroll to Top