Recent

Author Topic: How to use the Elavon Converge Payment Gateway  (Read 16934 times)

RedOctober

  • Sr. Member
  • ****
  • Posts: 450
How to use the Elavon Converge Payment Gateway
« on: May 28, 2021, 11:22:05 pm »
Platform:  Lazarus 2.0.10, FPC 3.2.0, Brook 5 Framework 5.4.9,  Microsoft Server 2016

I am trying to send a token request to the Elavon Converge server.  When I use simple Key=Value pairs in the request body, it works.  But when I use, what I call a "XML" style format in the body, it fails with a "bad request".   The Elavon Converge help cannot understand what is wrong, but they said I shd be using PHP.  How do I send a Request body with the "XML" style formatting, in PHP?

Here is what I'm trying to emulate.  I have all the correct authorization numbers:  (All examples are in the "XML" sytle)

https://developer.elavon.com/na/docs/converge/1.0.0/integration-guide/transaction_types/credit_card/sale


Here is what works, I can get a token from Elavon using this formatting in the body:
Code: Pascal  [Select][+][-]
  1. ssl_merchant_id=(withheld)
  2. ssl_user_id=(withheld)
  3. ssl_pin=(withheld)
  4. ssl_transaction_type=ccsale
  5.  

When I use the following XML style format, shown below, it fails with a "bad request"

Code: XML  [Select][+][-]
  1. <ssl_merchant_id>(withheld)</ssl_merchant_id>
  2. <ssl_user_id>(withheld)</ssl_user_id>
  3. <ssl_pin>(withheld)</ssl_pin>
  4. <ssl_transaction_type>ccsale</ssl_transaction_type>
  5.  


Here are my TIdHTTP component settings:

Code: Pascal  [Select][+][-]
  1.     xHandler.SSLOptions.SSLVersions := [sslvTLSv1_2];
  2.  
  3.     xHTTP.AllowCookies := True;
  4.     xHTTP.Request.BasicAuthentication := False;
  5.  
  6.     xHTTP.Request.ContentType := 'application/x-www-form-urlencoded';  //  <-- This ContentType is required by Elavon, shd it be different for PHP (XML style) content?
  7.     xHTTP.Request.Accept := '*/*';
  8.  
  9.     xHTTP.HTTPOptions := xHTTP.HTTPOptions + [hoForceEncodeParams, hoKeepOrigProtocol];
  10.     xHTTP.ProtocolVersion := pv1_1;

Thanks in advance for any help you can provide.

[Edited to fix title]
« Last Edit: June 10, 2021, 12:37:47 am by trev »

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: How do I send a Request in PHP format?
« Reply #1 on: May 28, 2021, 11:41:12 pm »
It has nothing to do, I think, with the language you use; the point is that you must send an HTTP request in the format expected by the server, whether your program is in PHP, Pascal, or whatever.

Of course, the request message must be correct HTTP, so if you're sending an XML document you can't tell the server your request is "form-URL-encoded", because it isn't.

What I don't know off the top of my head is what type you should use for XML, sorry :-[

Maybe they can tell it to you? Or it they have some kind of "integration" library, check it and see how they are doing it ...
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

sstvmaster

  • Sr. Member
  • ****
  • Posts: 299
Re: How do I send a Request in PHP format?
« Reply #2 on: May 28, 2021, 11:47:20 pm »
Maybe:
Code: Pascal  [Select][+][-]
  1. xHTTP.Request.ContentType := 'application/xml; charset="utf-8"';
  2.  
greetings Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1088
  • Professional amateur ;-P
Re: How do I send a Request in PHP format?
« Reply #3 on: May 29, 2021, 03:02:59 am »
Hi RedOctober,

First of all, can I ask you to make sense of the mess that you got yourself into, please?

Lemme ask you some questions and maybe we can get this sorted out:

First of all, if you have it working with form encoded, why are you trying to do it another way?

Second would be, why are you trying to send XML when you declare that you're sending form encoded?

And third, why are you sending badly formed XML and expecting any positive results?

If you can answer me some of these questions maybe we can help you progress further.

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

RedOctober

  • Sr. Member
  • ****
  • Posts: 450
Re: How do I send a Request in PHP format?
« Reply #4 on: May 29, 2021, 03:33:53 am »
Hi Gus, yes, you may ask.  Here are the answers:

Background:

My goal is to use Elavon's Hosted Payments Page (HPP) to take payments from customers on-line.  They give instructions how to do that in the following links.  All of which I am told, are PHP or CURL examples.  They don't support Lazarus, Indy components, Free Pascal etc. (I must be the first to attempt this) So when ever I ask Elavon developer help a question, I'm just a pain in their ass and they usually give me a terse answer just to get rid of me.  That is why I am turning to this forum for help.

https://developer.elavon.com/na/docs/converge/1.0.0/integration-guide/transaction_types/credit_card/sale
https://developer.elavon.com/na/docs/converge/1.0.0/integration-guide/integration_methods/hosted_payments
https://developer.elavon.com/na/docs/converge/1.0.0/test-cards
https://developer.elavon.com/na/docs/converge/1.0.0/overview

The first step, is to obtain a token from a "get token" URL, then, I'm to use that token in a redirect of the customer's browser to a different URL. 
I was able to obtain a token, after many weeks of frustration, using Postman as an intermediary tool. 

Just obtaining a token and redirecting, ends up sending the customer to a blank Hosted Payments Page, where the customer is able to enter their own product description, (even though they will be choosing a product from my website, which clearly has a description), what ever price they want (even zero), and fill in what ever tax they want, even zero, then click the pay button.

To have "un-editable" fields in the Hosted Payments Page, I was told that I have to pass all product information, in the initial "get token" request, then, when the customer is redirected, the Hosted Payments Page will be populated with all that info (supposedly, I haven't got that far yet).  The format that you have to send the product info info in, in the initial "get token" request,  is shown at the bottom of this page:

https://developer.elavon.com/na/docs/converge/1.0.0/integration-guide/transaction_types/credit_card/sale

You see that the format is not form encoded key,value pairs.  It looks like XML, but it's not that either.

I think the easiest way to solve this, is if an experienced TIdHTTP programmer wd obtain a developer account with Elavon and tinker with it.  I'm very close to being a beginner with TIdHTTP, even though I've built API interfaces for RingCentral and Data 24/7 and CDYNE.  PayPal "buy now" buttons are a breeze compared to Elavon.

So, to answer your questions specifically:

Quote
First of all, if you have it working with form encoded, why are you trying to do it another way?

Because the Elavon dev help personel and Elavon examples require two different formats for data submission.  I can get one to work (get token), the other I can't (submit product info).

Quote
Second would be, why are you trying to send XML when you declare that you're sending form encoded?
and
Quote
And third, why are you sending badly formed XML and expecting any positive results?

Bc I'm a dum-ass beginner throwing myself at the mercy of Lazarus gurus for help.

I was also told to send the body in Raw format, what ever that is. So, again, form-encoded versus (something else).  The Elavon help group is of no help to us Lazarus devs.

Thanks for any help you can provide Gus.


Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1088
  • Professional amateur ;-P
Re: How do I send a Request in PHP format?
« Reply #5 on: May 29, 2021, 03:57:31 am »
Hi RedOctober,

Hi Gus, yes, you may ask.  Here are the answers:

Ahhh, now that's more like it, some docs and some more info for us to bite into.

I've had a diagonal look at the docs you gave and I know how I can give you some examples using TidHTTP.

Unfortunately, for me, I decided to have a quick query on the forum right at the end of my fuse.
I should've been more wise and just gotten to bed, instead of opening a site that makes you think...

I'll resume this tomorrow. In the meantime, and with the trove of info you gave, maybe someone in a diff time zone can do it before I wake up.
If not, you got my promise that I'll whip something up right after I wake up.

Heading to bed and I'll resume this after I've had some beauty sleep.

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

nanobit

  • Full Member
  • ***
  • Posts: 154
Re: How do I send a Request in PHP format?
« Reply #6 on: May 29, 2021, 07:39:16 am »
How do I send a Request in PHP format?

Normally, certain urls (like your buy page) on your webserver are php files (scripts)
which show html to your visitors and send http requests to the payment processor.
In the simplest case there is no need for own programs (binaries) on the web server.
But if allowed on your webserver, exec() can be called from php script to run
programs (possibly for sending emails (confirmation, license key) to your customer).

Note: My comment was under this assumption:
If payment gateways provide the SDK in other languages (PHP, ...),
then it should be faster to use their SDK than porting their SDK to Pascal
and using an own web server app (cgi) although this is possible as well.
« Last Edit: May 29, 2021, 11:51:59 am by nanobit »

RedOctober

  • Sr. Member
  • ****
  • Posts: 450
Re: How do I send a Request in PHP format?
« Reply #7 on: May 29, 2021, 04:18:07 pm »
Hi everyone working on a solution for this issue:

My web server is a stand alone Windows .exe, Brook 5 Framework, built using Lazarus 2.0.10 and Indy components to talk to external APIs.  My web server will show product info to the customer, and the customer will click a "buy now" button to go to the Elavon Hosted Payments Page to take payment. I don't want to be dealing with credit cards on my server.

This is the reason I must deal with Elavon. They are our credit card processor company.  So, some how, I must overcome this snag, which, in the end, will be a very simple matter of configuring the IIdHTTP properties correctly, and formatting the request correctly.  That is where I am having trouble.

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1088
  • Professional amateur ;-P
Re: How do I send a Request in PHP format?
« Reply #8 on: May 29, 2021, 04:47:21 pm »
Hey RedOctober,

Let me start by telling you that the tech support at Elavon is maybe not that technical in nature but has a few scripts they follow. If you're lucky enough to ask a question on those scripts, you get a canned answer, also on said scripts.

What they should've told you is that you need an HTTP Client. A recent name to something that has been rising in use due to REST API's and other web centric services.

All top languages now have, at least, one HTTP Client implementation on their rooster, if not many.

As is the case, in FPC/Lazarus, there's at least 3 of them, that I know of:

It really doesn't matter what language you use, what matters is how you use the HTTP Client.

I'm still in the middle of making a small project that will help you in all this. I like to be thorough and give, as complete as I can provide, examples.

I'll be using the Indy10 HTTP Client, since it's what you already have on your server.
I'll also be using an XML library to deal with the XML de/serializing. Working with XML in an OOP way is less prone to issues than if you would just do it via strings.

Please be a bit more patient, and I'll have something for you.

Cheers,
Gus
« Last Edit: May 29, 2021, 04:49:55 pm by Gustavo 'Gus' Carreno »
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1088
  • Professional amateur ;-P
Re: How do I send a Request in PHP format?
« Reply #9 on: May 29, 2021, 09:12:07 pm »
Hey RedOctober,

I've finally completed my example. You'll find it attached.

It gives you an idea on how to create the XML you need via the laz2_* libraries that deal with XML in UTF-8 format.

It also gives you a way to test back and forth the values you need to send.

The Log memo is read-only but the XML Memo can be edited and it's content is what is sent to the URL(Elavon Endpoint)

I've tested it with an echo server that I quickly made with PHP:
Code: PHP  [Select][+][-]
  1. <?php
  2. if ($_SERVER['REQUEST_METHOD'] == 'POST') {
  3.     $entityBody = file_get_contents('php://input');
  4.     echo $entityBody;
  5. } else {
  6. ?>
  7. <html>
  8.     <head>
  9.         <title>Test Elavon</title>
  10.     </head>
  11.     <body>
  12.         <div>
  13.             <h1>Test Elavon</h1>
  14.             <p>Need to post some XML</p>
  15.         </div>
  16.     </body>
  17. </html>
  18. <?php
  19. }
  20.  

I'm getting back the same XML that I input, so at least the POST is working.
I've not tested with HTTPS, but that's also easy to overcome. I'm probably just missing a Unit for that.
I'll let you figure out what you need to do from now on.

Please gimme some feed back if this helps at all.

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1088
  • Professional amateur ;-P
Re: How do I send a Request in PHP format?
« Reply #10 on: May 29, 2021, 09:21:05 pm »
Hey RedOctober,

This version has the OpenSSL code.

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

PierceNg

  • Sr. Member
  • ****
  • Posts: 369
    • SamadhiWeb
Re: How do I send a Request in PHP format?
« Reply #11 on: May 30, 2021, 05:14:26 am »
My goal is to use Elavon's Hosted Payments Page (HPP) to take payments from customer
https://developer.elavon.com/na/docs/converge/1.0.0/integration-guide/transaction_types/credit_card/sale#ccsalexamples-id

Going by the example on that page, you need to wrap your '<ssl_blahblah>' elements within a '<txn>' pair:

<txn>
    <ssl_merchant_id>my_merchant_id</ssl_merchant_id>
    <ssl_user_id>my_user_id</ssl_user_id>
    <ssl_pin>my_pin</ssl_pin>
    <ssl_test_mode>false</ssl_test_mode>
    <ssl_transaction_type>ccsale</ssl_transaction_type>
    <ssl_card_number>000000000000000</ssl_card_number>
    <ssl_exp_date>1215</ssl_exp_date>
    <ssl_amount>1.00</ssl_amount>
</txn>


According to the section Implementation Guidelines on this page https://developer.elavon.com/na/docs/converge/1.0.0/integration-guide/integration_methods/xmlapi,

Quote
Converge doesn't expect a fully validated XML document, but an XML-formatted request assigned to URL encoded variables called xmldata. Only the Converge-specific elements for the transaction itself are supported.

See the part that I underlined. The language is unclear, as it says 'variables' (plural) but only names one variable 'xmldata'. So try this:
  • use <txn></txn> to wrap your <ssl_blahblah> elements
  • submit the request parameters as form-url-encoding of 'xmldata=<txn>...</txn>'

RedOctober

  • Sr. Member
  • ****
  • Posts: 450
Re: How do I send a Request in PHP format?
« Reply #12 on: June 02, 2021, 01:20:19 am »
Hi Gus and Peirce.  I have not forgotten about you.  Gus, I tried to POST the XML using your test app.  Their server is still reporting "Bad request". Yet your XML is correctly formed according to the Elavon dev help website.

I have informed Elavon help that my tool (Lazarus) is more like PostMan than CURL, and if they could come up with a PostMan example of what is on their dev help page, it would be much easier for me to translate, than me trying to piece together what is supposed to happen from their dev help web pages.  So far, they have not given up on me, and they told me they are working on it.

What ever I learn, I will make a post in this forum explaining how to use Lazarus to interact with Elavon's Hosted Payment Page.


trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: How do I send a Request in PHP format?
« Reply #13 on: June 02, 2021, 01:39:19 am »
The tool is almost completely irrelevant. The issue is not the tool, but the proper format of the HTTP request to send to the server. This was pointed our earlier.

You also said "When I use simple Key=Value pairs in the request body, it works.  But when I use, what I call a "XML" style format in the body, it fails with a 'bad request'."

So, one has to ask, why change what works?

egsuh

  • Hero Member
  • *****
  • Posts: 1266
Re: How do I send a Request in PHP format?
« Reply #14 on: June 02, 2021, 03:26:54 am »
As PierceNg wrote, doesn't this need something like following?
When I press "submit" it displays error message - Invalid Credentials. I think you may correct it.

Quote
<!Doctype html>
<html>
<head>
<meta charset=utf8>
</head>
<body><form action="https://api.demo.convergepay.com/VirtualMerchantDemo/processxml.do" method="post">
Here is the data<br>
<textarea name="xmldata" rows=20 cols=80> <txn>
  <ssl_merchant_id>my_merchant_id</ssl_merchant_id>
  <ssl_user_id>my_user_id</ssl_user_id>
  <ssl_pin>my_pin</ssl_pin>
  <ssl_test_mode>false</ssl_test_mode>
  <ssl_transaction_type>ccsale</ssl_transaction_type>
  <ssl_card_number>000000000000000</ssl_card_number>
  <ssl_exp_date>1215</ssl_exp_date>
  <ssl_amount>1.00</ssl_amount>
</txn>
</textarea>
<br>
<input type=submit value="submit">
</form>
</body>
</html>

Of course you may use following: 

Quote
  <input type=text name="ssl_merchant_id" value="my_merchant_id">
  <input type=text name="ssl_user_id" value="my_user_id">

with different action address of the form.


BTW, how did you setup Brook 5 ?

 

TinyPortal © 2005-2018