Consultor Eletrônico



Kbase P150943: How to communicate with PayPal from the ABL to validate a credit card transaction
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   02/05/2011
Status: Verified

GOAL:

How to communicate with PayPal from the ABL to validate a credit card transaction

GOAL:

How to transmit credit card transactions to PayPal using SSL sockets

GOAL:

How to do an HTTPS POST to PayPal

GOAL:

How to process credit card transactions using PayPal's Payfow Pro interface

FACT(s) (Environment):

All Supported Operating Systems
OpenEdge 10.x

FIX:

The following ABL code shows how to use SSL sockets to communicate with PayPal, using their Payflow Pro interface to process a credit card transaction. Please note that the purpose of this sample code is to show how to do the SSL communication. Consult PayPal documentation for information on constructing the request and processing the response from PayPal.

DEFINE INPUT PARAMETER p-client AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER p-host AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER p-port AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER p-transstr AS CHARACTER NO-UNDO FORMAT "x(300)".
DEFINE INPUT PARAMETER p-timeout AS INTEGER NO-UNDO.
DEFINE OUTPUT PARAMETER p-respmsg AS CHARACTER NO-UNDO FORMAT "x(300)".

/* Milliseconds to wait for data in READ-RESPONSE procedure */
&SCOPED-DEFINE TIMEOUTMS 15000


DEFINE VARIABLE vhSocket AS HANDLE NO-UNDO.
DEFINE VARIABLE gl-rc AS LOGICAL NO-UNDO.
DEFINE VARIABLE gl-loop AS LOGICAL NO-UNDO INITIAL YES.
DEFINE VARIABLE vcWebResp AS CHARACTER NO-UNDO.
CREATE SOCKET vhSocket.

vhSocket:CONNECT('-H ' + p-host + ' -S ' + string(p-port) + " -ssl -nohostverify") NO-ERROR.

IF vhSocket:CONNECTED() EQ FALSE THEN
DO:
ASSIGN
p-respmsg = "Unable to communicate with payment gateway. Please try again later".
vhSocket:DISCONNECT().
DELETE OBJECT vhSocket NO-ERROR.
RETURN.
END.

vhSocket:SET-READ-RESPONSE-PROCEDURE('getResponse', THIS-PROCEDURE) NO-ERROR.

RUN PostRequest('/', p-transstr).

DO WHILE gl-loop = YES ON STOP UNDO, LEAVE ON QUIT UNDO, LEAVE:
WAIT-FOR READ-RESPONSE OF vhSocket.
IF vhSocket:CONNECTED() = FALSE THEN
LEAVE.
END.

vhSocket:DISCONNECT() NO-ERROR.

DELETE OBJECT vhSocket NO-ERROR.


PROCEDURE getResponse PRIVATE:
DEFINE VARIABLE vData AS MEMPTR NO-UNDO.
DEFINE VARIABLE li-msgsize AS INTEGER NO-UNDO.

IF vhSocket:CONNECTED() = FALSE THEN
DO:>
gl-loop = NO.
RETURN.
END.

/* Check how much data is in the socket in order to allocate the correct number of
bytes for the MEMPTR (PayPal does not provide the size as part of the message).
If there is no data in the socket, keep trying until some arrives.
Time out after a predefined time period with no data.
*/

li-msgsize = vhSocket:GET-BYTES-AVAILABLE().
IF li-msgsize = 0 THEN
DO:
ETIME(YES).
DO WHILE li-msgsize = 0 AND ETIME < {&TIMEOUTMS}:
li-msgsize = vhSocket:GET-BYTES-AVAILABLE().
END.
END.

set-byte-order(vData) = BIG-ENDIAN.
set-size(vData) = li-msgsize.

gl-rc = vhSocket:READ(vData, 1, li-msgsize, READ-EXACT-NUM).

IF gl-rc = FALSE THEN
DO:
set-size(vData) = 0.
gl-loop = NO.
RETURN.
END.

ASSIGN
vcWebResp = vcWebResp + get-string(vData,1,li-msgsize).

IF LENGTH(vcwebresp) <> 0 THEN
ASSIGN p-respmsg = SUBSTRING(vcwebresp,R-INDEX(vcwebresp,"RESULT",LENGTH(vcwebresp)),LENGTH(vcwebresp) + 1 - r-index(vcwebresp,"RESULT",LENGTH(vcwebresp))).

set-size(vData) = 0.
END PROCEDURE.

PROCEDURE PostRequest PRIVATE:
DEFINE INPUT PARAMETER postUrl AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER postData AS CHARACTER NO-UNDO.
DEFINE VARIABLE vData AS MEMPTR NO-UNDO.
DEFINE VARIABLE vRequest AS CHARACTER NO-UNDO.
DEFINE V.ARIABLE vReturnCode AS LOGICAL NO-UNDO.


ASSIGN
vRequest = 'POST ' +
postUrl +
' HTTPS/1.1' +
chr(13) +
chr(10) +
'Connect: close' +
chr(13) +
chr(10) +
'Content-Length: ' +
string(LENGTH(postdata,"raw")) +
chr(13) +
chr(10) +
'Content-Type: text
amevalue' +
chr(13) +
chr(10) +
'Host: ' + p-host +
chr(13) +
chr(10) +
'X-VPS-REQUEST-ID: 634234 ' +
chr(13) +
chr(10) +
'X-VPS-CLIENT-TIMEOUT: 240' +
chr(13) +
chr(10) +
chr(13) +
chr(10) +
postData +
chr(13) +
chr(10).

set-byte-order(vData) = BIG-ENDIAN.
set-size(vData) = LENGTH(vRequest,"raw").
put-string(vData,1,LENGTH(vRequest,"raw")) = vRequest.

vReturnCode = vhSocket:WRITE(vData, 1, LENGTH(vRequest,"raw")).

set-size(vData) = 0.

END PROCEDURE. .