I am trying to

PayPal is in their own little world when it comes to authenticating their
webservice users. When you sign up they provide you with a client
certificate. Their client SSL certificate is not like a normal certificate,
Its something they generate on their own without the use of a third party
certificate authority. When you hit their server via a browser
(https://api.sandbox.paypal.com/wsdl/PayPalSvc.wsdl) you have to manually
select the client certificate to use.

When I use cfinvoke:

<cfset starguments = structnew()>
<cfset starguments.StartDate = "2004-07-12 00:00:00">
<cfinvoke
webservice = "http://api.sandbox.paypal.com/wsdl/PayPalSvc.wsdl"
method = "TransactionSearchRequest"
argumentCollection="#starguments#"
username = "myusername"
password = "mypassword"
returnVariable="result"
>

I get this error:
Could not generate stub objects for web service invocation.
Name: https://api.sandbox.paypal.com/wsdl/PayPalSvc.wsdl. WSDL:
https://api.sandbox.paypal.com/wsdl/PayPalSvc.wsdl.
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

So I go back and forth trying everything under the sun to get coldfusion to
use the certificate. The most promising thing I found was an article that
told you how to install a certificate in the coldfuision http engine using a
keytool utility that comes with coldfusion but that didn't work either.

So I talk to paypal tech support some more and they make it so I can hit the
WSDL file without the ssl and then I get errors like this:

Web service operation "TransactionSearchRequest" with parameters
{STARTDATE={2004-07-12},} could not be found.

This happens because they don't format their WSDL in a way that is
compatible with coldfusions cfinvoke tag.

So then they send me a php example on how to bypass the WSDL by hard-coding
the SOAP envelope and sending it to their server:

<?php
// details.php
// A simple PHP example that access the transaction details of a PayPal
// transaction
// By Dave Burchell, PayPal Developer Technical Support, July 2004
// For more about the PayPal API, see http://developer.paypal.com/

// please provide the parameters below
$username = "";
$password = "";
$transid = "";
$sslcertpath = "";


$SOAPrequest = <<< End_Of_Quote
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Header>
<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI"
SOAP-ENV:mustUnderstand="1">
<Credentials xmlns="urn:ebay:apis:eBLBaseComponents">
<Username>$username</Username>
<Password>$password</Password>
<Subject/>
</Credentials>
</RequesterCredentials>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<GetTransactionDetailsReq xmlns="urn:ebay:api:PayPalAPI">
<GetTransactionDetailsRequest
xsi:type="ns:GetTransactionDetailsRequestType">
<Version xsi:type="xsd:string">1.0</Version>
<TransactionID xsi:type="ebl:TransactionId">$transid</TransactionID>
</GetTransactionDetailsRequest>
</GetTransactionDetailsReq>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

End_Of_Quote;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://api.sandbox.paypal.com/2.0/");
curl_setopt($ch, CURLOPT_SSLCERT, $sslcertpath);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $SOAPrequest);

curl_exec ($ch);
if (curl_error($ch))
printf("Error %s: %s", curl_errno($ch), curl_error($ch));
curl_close ($ch);

?>

Of course I cant do this with cfhttp because there is not way for me to tell
CFHTTP which client certificate to use, Thus the move to
msxml2.ServerXMLHTTP.3.0, but I can't figure out how to use the setOption
function with coldfusion. I have used this object for other APIs int the
past but I have never had to specify a certificate.

Here is the microsoft documentation for the setOption method used in my code
below:

http://msdn.microsoft.com/library/default.asp?url=""> /xmmthsetoption.asp

Here is my code:

<cfset username="Myusername">
<cfset password="mypassword">
<cfset transactionid = "">

<cfset XMLRequest = "<?xml version=""1.0""
encoding=""UTF-8""?><SOAP-ENV:Envelope
xmlns:xsi=""http://www.w3.org/1999/XMLSchema-instance""
xmlns:SOAP-ENC=""http://schemas.xmlsoap.org/soap/encoding/""
xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/""
xmlns:xsd=""http://www.w3.org/1999/XMLSchema""
SOAP-ENV:encodingStyle=""http://schemas.xmlsoap.org/soap/encoding/""><SOAP-E
NV:Header><RequesterCredentials xmlns=""urn:ebay:api:PayPalAPI""
SOAP-ENV:mustUnderstand=""1""><Credentials
xmlns=""urn:ebay:apis:eBLBaseComponents""><Username>#username#</Username><Pa
ssword>#password#</Password><Subject/></Credentials></RequesterCredentials><
/SOAP-ENV:Header><SOAP-ENV:Body><GetTransactionDetailsReq
xmlns=""urn:ebay:api:PayPalAPI""><GetTransactionDetailsRequest
xsi:type=""ns:GetTransactionDetailsRequestType""><Version
xsi:type=""xsd:string"">1.0</Version><TransactionID
xsi:type=""ebl:TransactionId"">#transactionID#</TransactionID></GetTransacti
onDetailsRequest></GetTransactionDetailsReq></SOAP-ENV:Body></SOAP-ENV:Envel
ope>">

<cfobject type="COM"
    action="">     name="objServerXMLHttp"
class="msxml2.ServerXMLHTTP.3.0">

<cfset
objServerXMLHttp.setOption(3,"LOCAL_MACHINE\My\scotttest_api1.dealtree.com")
>

<cfset objServerXMLHttp.open("POST",
"https://api.sandbox.paypal.com/2.0/", False)>
<cfset objServerXMLHttp.send("#XMLRequest#")>

<cfdump var="#xmlResponse#">

I get this error:

An exception occurred when executing a Com method.
The cause of this exception was that: AutomationException: 0x80070057 - One
or more arguments are invalid.

The error occurred in H:\wwwroot\Process\PayPalAPI\test.cfm: line 39

37 :           class="msxml2.ServerXMLHTTP.3.0">
38 :
39 :           <cfset
objServerXMLHttp.setOption(3,"Local_Machine\My\scotttest_api1.dealtree.com")
>
40 :
41 :

<deepbreath/><sigh/> SOOOOO, then I try using the WinHttp.WinHttpRequest.5.1
because the syntax for setting a client certificate seems a little easier:
http://msdn.microsoft.com/library/default.asp?url=""> p/winhttprequest.asp

CODE:

<cfobject type="COM"
    action="">     name="objWinHttp"
class="WinHttp.WinHttpRequest.5.1">

<cfset objWinHttp.open("POST", "https://api.sandbox.paypal.com/2.0/",
False)>
<cfset
objWinHttp.SetClientCertificate("LOCAL_MACHINE\Personal\scotttest_api1.dealt
ree.com")>
<cfset objWinHttp.send("#XMLRequest#")>

<cfdump var="#xmlResponse#">

ERROR:

An exception occurred when executing a Com method.
The cause of this exception was that: AutomationException: 0x80072f0c - A
certificate is required to complete client authentication in
'WinHttp.WinHttpRequest'.

The error occurred in H:\wwwroot\Process\PayPalAPI\test.cfm: line 56

54 : <cfset objWinHttp.open("POST", "https://api.sandbox.paypal.com/2.0/",
False)>
55 : <cfset
objWinHttp.SetClientCertificate("LOCAL_MACHINE\Personal\scotttest_api1.dealt
ree.com")>
56 : <cfset objWinHttp.send("#XMLRequest#")>
57 :
58 :

Now this one is a mystery because I didn't get an error on line 55 so I must
have done the SetClientCertificate method correctly but I still get a
certificate error.

And that's pretty much where I'm at. Any thoughts?

-Scott
[Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]

Reply via email to