Getting Transaction Details From PayPal SOAP API (hopefully custom fields as well) - paypal

I'm trying to get transaction details from PayPal's SOAP API but I'm running into into error from PayPal. It returns the error:
The transaction id is not valid
I know it's a valid transaction ID since I'm I'm able to get transaction details using the PayPal NVP API but maybe I have the SOAP request formatted incorrectly. I followed the PayPal SOAP API examples I can find across the web to construct the SOAP XML but they are slim. I'm using mac's PAW program to send a SOAP request to PayPal's API but this problem should be reproducible using an HTTP client.
I tried to use PayPal's REST API but there's no method to get transaction details (e.g. name, email, amount paid, custom fields) . I also tried to use the NVP (Name-Value-Pair) API and I do get back the transaction details but it doesn't give me all of the stored custom fields for a transaction. When I log in to PayPal, and view a single transaction, I can see all of the custom fields for that transaction, so I know they're being stored.
The SOAP API is my last hope.
Here's the SOAP envelope request I'm using:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="urn:ebay:api:PayPalAPI" xmlns:ebl="urn:ebay:apis:eBLBaseComponents" xmlns:cc="urn:ebay:apis:CoreComponentTypes" xmlns:ed="urn:ebay:apis:EnhancedDataTypes">
<soapenv:Header>
<ns:RequesterCredentials>
<ebl:Credentials>
<ebl:Username>soap_api_username_here</ebl:Username>
<ebl:Password>soap_api_password_here</ebl:Password>
<ebl:Signature>soap_api_signature_here</ebl:Signature>
</ebl:Credentials>
</ns:RequesterCredentials>
</soapenv:Header>
<soapenv:Body>
<ns:GetTransactionDetailsReq>
<ns:GetTransactionDetailsRequest>
<ebl:Version>93.0</ebl:Version>
<ebl:TransactionID>8FX18476NR449891W</ebl:TransactionID>
</ns:GetTransactionDetailsRequest>
</ns:GetTransactionDetailsReq>
</soapenv:Body>
</soapenv:Envelope>
Here's the response I receive from the PayPal SOAP API:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cc="urn:ebay:apis:CoreComponentTypes" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:ed="urn:ebay:apis:EnhancedDataTypes" xmlns:ebl="urn:ebay:apis:eBLBaseComponents" xmlns:ns="urn:ebay:api:PayPalAPI">
<SOAP-ENV:Header>
<Security xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext" xsi:type="wsse:SecurityType"/>
<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI" xsi:type="ebl:CustomSecurityHeaderType">
<Credentials xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:UserIdPasswordType">
<Username xsi:type="xs:string"/>
<Password xsi:type="xs:string"/>
<Signature xsi:type="xs:string"/>
<Subject xsi:type="xs:string"/>
</Credentials>
</RequesterCredentials>
</SOAP-ENV:Header>
<SOAP-ENV:Body id="_0">
<GetTransactionDetailsResponse xmlns="urn:ebay:api:PayPalAPI">
<Timestamp xmlns="urn:ebay:apis:eBLBaseComponents">2016-08-02T16:43:02Z</Timestamp>
<Ack xmlns="urn:ebay:apis:eBLBaseComponents">Failure</Ack>
<CorrelationID xmlns="urn:ebay:apis:eBLBaseComponents">a464c181339f4</CorrelationID>
<Errors xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:ErrorType">
<ShortMessage xsi:type="xs:string">Transaction refused because of an invalid argument. See additional error messages for details.</ShortMessage>
<LongMessage xsi:type="xs:string">The transaction id is not valid</LongMessage>
<ErrorCode xsi:type="xs:token">10004</ErrorCode>
<SeverityCode xmlns="urn:ebay:apis:eBLBaseComponents">Error</SeverityCode>
</Errors>
<Version xmlns="urn:ebay:apis:eBLBaseComponents">93.0</Version>
<Build xmlns="urn:ebay:apis:eBLBaseComponents">000000</Build>
<PaymentTransactionDetails xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:PaymentTransactionType">
<ReceiverInfo xsi:type="ebl:ReceiverInfoType"/>
<PayerInfo xsi:type="ebl:PayerInfoType">
<PayerStatus xsi:type="ebl:PayPalUserStatusCodeType">verified</PayerStatus>
<PayerName xsi:type="ebl:PersonNameType"/>
<Address xsi:type="ebl:AddressType">
<AddressOwner xsi:type="ebl:AddressOwnerCodeType">PayPal</AddressOwner>
<AddressStatus xsi:type="ebl:AddressStatusCodeType">None</AddressStatus>
</Address>
</PayerInfo>
<PaymentInfo xsi:type="ebl:PaymentInfoType">
<TransactionType xsi:type="ebl:PaymentTransactionCodeType">none</TransactionType>
<PaymentType xsi:type="ebl:PaymentCodeType">none</PaymentType>
<PaymentStatus xsi:type="ebl:PaymentStatusCodeType">None</PaymentStatus>
<PendingReason xsi:type="ebl:PendingStatusCodeType">none</PendingReason>
<ReasonCode xsi:type="ebl:ReversalReasonCodeType">none</ReasonCode>
</PaymentInfo>
<PaymentItemInfo xsi:type="ebl:PaymentItemInfoType">
<Subscription xsi:type="ebl:SubscriptionInfoType"/>
<Auction xsi:type="ebl:AuctionInfoType"/>
</PaymentItemInfo>
</PaymentTransactionDetails>
</GetTransactionDetailsResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I'm not sure what I'm doing wrong but maybe someone with more experience can spot the error easier than I can. I responded to another user's question about the PayPal REST API and getting transaction details from that but as far as I know, there's no way to do that Get customer details after transaction . If you have found a way to accomplish this with the REST API, let me know cause I would much rather use REST than SOAP.
Thanks.

The error message is a red herring. PayPal can't find any TransactionId, reporting the empty TransactionId as invalid.
The TransactionId element belongs to the urn:ebay:api:PayPalAPI namespace. Your XML attaches it to the urn:ebay:apis:eBLBaseComponents namespace. All you need to do is change the ebl:TransactionId to ns:TransactionId.
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="urn:ebay:api:PayPalAPI" xmlns:ebl="urn:ebay:apis:eBLBaseComponents" xmlns:cc="urn:ebay:apis:CoreComponentTypes" xmlns:ed="urn:ebay:apis:EnhancedDataTypes">
<soapenv:Header>
<ns:RequesterCredentials>
<ebl:Credentials>
<ebl:Username>soap_api_username_here</ebl:Username>
<ebl:Password>soap_api_password_here</ebl:Password>
<ebl:Signature>soap_api_signature_here</ebl:Signature>
</ebl:Credentials>
</ns:RequesterCredentials>
</soapenv:Header>
<soapenv:Body>
<ns:GetTransactionDetailsReq>
<ns:GetTransactionDetailsRequest>
<ebl:Version>204.0</ebl:Version>
<ns:TransactionID>8FX18476NR449891W</ns:TransactionID>
</ns:GetTransactionDetailsRequest>
</ns:GetTransactionDetailsReq>
</soapenv:Body>
Check this example at the PayPal KB.

I would have put this as a comment but it is pretty full of goobly gook. At the expense of being way off I might be of some help maybe.
So my vb.net code sends a form to paypal which includes "notify_url".
' determining the URL to work with depending on whether sandbox or a real PayPal account should be used
If strRealOrSand = "Sand" Then
URL = "https://www.sandbox.paypal.com/cgi-bin/webscr"
business = "x#xxx.com" ' AppSettings("BusinessEmail") (sandbox account business email)
ElseIf strRealOrSand = "Real" Then
URL = "https://www.paypal.com/cgi-bin/webscr"
business = "xxx#xxx.com" ' AppSettings("BusinessEmail") (real pay pal account account business email)
End If
notify_url = "http://www.xxxxx.com/accounts/done.aspx"
<form id="payForm" method="post" action="<%Response.Write (URL)%>" >
<input type="hidden" name="cmd" value="<%Response.Write (cmd)%>" />
<input type="hidden" name="business" value="<%Response.Write (business)%>" />
<input type="hidden" name="item_name" value="<%Response.Write (item_name)%>" />
<input type="hidden" name="amount" value="<%Response.Write (amount)%>" />
<input type="hidden" name="no_shipping" value="<%Response.Write (no_shipping)%>" />
<input type="hidden" name="return" value="<%Response.Write (return_url)%>" />
<input type="hidden" name="rm" value="<%Response.Write (rm)%>" />
<input type="hidden" name="notify_url" value="<%Response.Write (notify_url)%>" />
<input type="hidden" name="cancel_return" value="<%Response.Write (cancel_url)%>" />
<input type="hidden" name="currency_code" value="<%Response.Write (currency_code)%>" />
<input type="hidden" name="custom" value="<%Response.Write (row_id)%>" />
</form>
<script type="text/javascript">
document.forms["payForm"].submit ();
</script>
</body>
Then in my "notify_url" page load it gets what PayPal sends back after transaction completes. You'll notice there is a ton of debug emails being sent back to me. This was my doing.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim vReceived As String = ""
Dim vFormValues As String = ""
Dim vResponder As String = ""
Dim strE As String = ""
Dim intAccountID As Integer = 0
Dim intCreditsPurchased As Integer = 0
Dim vWebRequest As System.Net.HttpWebRequest
Dim vSSend As Boolean = False
'vWebRequest = CType(System.Net.WebRequest.Create("https://www.sandbox.paypal.com/cgi-bin/webscr"), System.Net.HttpWebRequest)
vWebRequest = CType(System.Net.WebRequest.Create("https://www.paypal.com/cgi-bin/webscr"), System.Net.HttpWebRequest)
vWebRequest.Method = "POST"
vWebRequest.ServicePoint.Expect100Continue = False
vWebRequest.ContentType = "application/x-www-form-urlencoded"
Try
vFormValues = Encoding.ASCII.GetString(Request.BinaryRead(Request.ContentLength))
vReceived = "cmd=_notify-validate&" & vFormValues
Catch ex As Exception
sSend_Mail_From_done_aspx("Requested Form.ToString", ex.ToString)
End Try
vWebRequest.ContentLength = vReceived.Length
Dim vStreamOut As System.IO.StreamWriter = New System.IO.StreamWriter(vWebRequest.GetRequestStream(), Encoding.ASCII)
vStreamOut.Write(vReceived)
vStreamOut.Close()
Dim vStreamIn As New System.IO.StreamReader(vWebRequest.GetResponse().GetResponseStream())
vResponder = vStreamIn.ReadToEnd()
vStreamIn.Close()
Dim vFieldName As String
Dim vFieldValue As String = ""
Dim vFields As New Collection
For Each vFieldName In Request.Form
'strE = strE & Request.Form.Item(vFieldName) & " "
strE &= vFieldName & ": " & Request.Form.Item(vFieldName) & vbCrLf
'vFieldValue = Request.Form.Item(vFieldName)
'vFields.Add(Decode(vFieldValue), Decode(vFieldName).ToLower)
Next
sSend_Mail_From_done_aspx("BEFORE VERIFIED CHECK, WHAT vResponder CONTAINS", strE)
Dim transactionID As String = ""
Dim dblAmount As Double
Dim intRowID As Integer
Dim dblPayPalFee As Double
Dim strMemo As String = ""
Dim strPayerEmail As String = ""
Dim strPaymentDate As String = ""
If Trim(vResponder).ToUpper = "VERIFIED" Then
For Each vFieldName In Request.Form
strE &= vFieldName & ": " & Request.Form.Item(vFieldName) & vbCrLf
Next
sSend_Mail_From_done_aspx("VERIFIED CAME THROUGH", strE)
Try
transactionID = Request.Form.Item("txn_id").ToString()
dblAmount = CType(Request.Form.Item("payment_gross"), Double)
intRowID = CType(Request.Form.Item("custom"), Integer)
dblPayPalFee = CType(Request.Form.Item("payment_fee"), Double)
If Len(Request.Form.Item("memo") & "") <> 0 Then
strMemo = Request.Form.Item("memo").ToString.Replace("'", "")
End If
strPayerEmail = Request.Form.Item("payer_email").ToString
strPaymentDate = Request.Form.Item("payment_date").ToString
Catch ex As Exception
sSend_Mail_From_done_aspx("Request.QueryString)", ex.ToString)
End Try
Try
'==============================
'SAVE TRANSACTION INFO HERE
'==============================
Dim sb As New StringBuilder
sb.Append("UPDATE dbo.tblTransactions ")
sb.Append("SET pp_txn_id='" & transactionID & "'")
sb.Append(", pp_payment_gross=" & dblAmount)
sb.Append(", pp_mc_fee=" & dblPayPalFee)
sb.Append(", memo='" & strMemo & "'")
sb.Append(", pp_payer_email='" & strPayerEmail & "'")
sb.Append(", pp_payment_date='" & strPaymentDate & "'")
sb.Append(" WHERE RowID =" & intRowID)
'SEND SQL TO DEVELOPER
sSend_Mail_From_done_aspx("INSERT statement BEFORE action", sb.ToString)
Dim conn As New SqlConnection(f1.fUseThisConnection(Server.MachineName))
Dim cmd As New SqlCommand(sb.ToString, conn)
cmd.Connection.Open()
cmd.ExecuteNonQuery()
'=========================================================
'UPDATE ACCOUNT INFO HERE (ADD CREDITS TO CURRENT AMOUNT)
'=========================================================
Dim dr As System.Data.SqlClient.SqlDataReader
sb.Length = 0
'GET ACCOUNT ID, AND CreditsPurchased
sb.Append("SELECT AccountID, CreditsPurchased FROM dbo.tblTransactions ")
sb.Append(" WHERE RowID =" & intRowID)
cmd.CommandText = sb.ToString
dr = cmd.ExecuteReader()
If dr.Read() Then
intAccountID = dr("AccountID")
intCreditsPurchased = dr("CreditsPurchased")
End If
dr.Close()
sb.Length = 0
'AT 1.10 A CREDIT, WE DIVIDE THE AMOUNT PAYPAY CHARGES BY THIS TO GET CREDITS PURCHASED
sb.Append("UPDATE dbo.tblAL SET Credits = Credits + " & intCreditsPurchased)
sb.Append(" WHERE AccountID =" & intAccountID)
cmd.CommandText = sb.ToString
cmd.ExecuteNonQuery()
'SEND ACCOUNT UPDATE AMOUNT TO DEVELOPER
sSend_Mail_From_done_aspx(intCreditsPurchased & " CREDITS ADDED TO ", sb.ToString)
cmd.Dispose()
conn.Close()
conn = Nothing
MySession.Credits = intCreditsPurchased
Catch ex As Exception
sSend_Mail_From_done_aspx("tblTransactions NOT UPDATED with Transaction Info", ex.ToString())
End Try
Else
sSend_Mail_From_done_aspx(Trim(vResponder).ToUpper, "TRANSACTION NOT VERIFIED")
End If
End Sub
I think the request/responses are these below:
submitted form
URL = "https://www.paypal.com/cgi-bin/webscr"
sends back to this inside the "notify_url" that is submitted
Dim vWebRequest As System.Net.HttpWebRequest
Dim vSSend As Boolean = False
'vWebRequest = CType(System.Net.WebRequest.Create("https://www.sandbox.paypal.com/cgi-bin/webscr"), System.Net.HttpWebRequest)
vWebRequest = CType(System.Net.WebRequest.Create("https://www.paypal.com/cgi-bin/webscr"), System.Net.HttpWebRequest)
Sure would be nice to have a "PayPalFiddle" haha

Related

Using Coldfusion to create a REST request

Using Coldfusion I would like to create a REST service
I would like to post it to: https://www.test.co.za/ using the username "person1" and password "password1".
The data type would be: application/json
And I would like to pass the following parameters:
callbackURL (string)
amount (bigdecimal)
reference (string)
description (string)
This will then return:
reference (string)
redirectURL (string)
status (string)
This is what I have got so far:
index.cfm
<cfset restInitApplication("C:\ColdFusion10\cfusion\wwwroot\restApp","IIT")>
<cfhttp url="http://127.0.0.1:8500/rest/IIT/rest" method="get">
<cfoutput>#cfhttp.filecontent#</cfoutput>
rest.cfc
<cfcomponent rest="true" restpath="restService">
<cffunction name="sayHello" access="remote" returntype="String" httpmethod="GET">
<cfset callbackURL = "https://www.google.com">
<cfset amount = "100,50">
<cfset reference = "123456789">
<cfset description = "This is a description">
<cfreturn rest>
</cffunction>
</cfcomponent>
I would like to know if I am on the right track and how I would post my values to https://www.test.co.za/ with a username and password
I am not sure if it will look something like this:
<cfhttp
url="https://www.test.co.za/"
method="post"
port="8500"
result="res">
</cfhttp>
Thanks in advance

Invalid Signature with telesign call REST API

The API sends a verification code via a phone call that the user then enters into a website... basically verifying that there phone number is valid.
But I'm having trouble signing the request. No matter what I try it returns "Invalid Signature"
The API documentation:
http://docs.telesign.com/rest/content/verify-call.html
The authentication documentation:
http://docs.telesign.com/rest/content/rest-auth.html
The authentication examples:
http://docs.telesign.com/rest/content/auth-examples.html
The code:
<cffunction name="encryptHmacSHA1" returntype="binary" access="public" output="false">
<cfargument name="base64Key" type="string" required="true">
<cfargument name="signMessage" type="string" required="true">
<cfargument name="encoding" type="string" default="UTF-8">
<cfset var messageBytes = JavaCast("string",arguments.signMessage).getBytes(arguments.encoding)>
<cfset var keyBytes = binaryDecode(arguments.base64Key, "base64")>
<cfset var key = createObject("java","javax.crypto.spec.SecretKeySpec")>
<cfset var mac = createObject("java","javax.crypto.Mac")>
<cfset key = key.init(keyBytes,"HmacSHA1")>
<cfset mac = mac.getInstance(key.getAlgorithm())>
<cfset mac.init(key)>
<cfset mac.update(messageBytes)>
<cfreturn mac.doFinal()>
</cffunction>
<cfscript>
// PHONE NUMBER TO CALL
phoneNumberToCall = "15554565555";
// KEYS
keys = structNew();
keys.customerID = "D561FCF4-BA8D-4DFC-86D1-1A46DF47A308";
keys.apiKey = "mDzGHsMOc2g/ivkuINEFVh6fn/v4kdjvlTvtgFVOShu7hVWXS0eV2nLSw1FXgEzDSuOjhlKLXvneiq+YFG1/Vg==";
// DATES
dates = structNew();
dates.timeZoneInfo = GetTimeZoneInfo();
dates.dateToUse = DateAdd("h",dates.timeZoneInfo.utcHourOffset,now());
dates.signingDate = DateFormat(dates.dateToUse,"ddd, dd mmm yyyy") & " " & TimeFormat(dates.dateToUse,"HH:mm:ss") & " +0000";
// HEADERS
headers = [
"POST",
"application/x-www-form-urlencoded",
"#dates.signingDate#",
"phone_number=#phoneNumberToCall#&ucid=OTHR",
"/v1/verify/call"
];
headerText = arrayToList(headers, chr(10)) & chr(10);
// CREATE SIGNATURE
stringToSign = binaryEncode( encryptHmacSHA1(keys.apiKey, headerText), "base64");
// AUTHORIZE HEADER
Authorization = "TSA" & " " & keys.customerID & ":" & stringToSign;
</cfscript>
<cfhttp method="POST" url="https://rest.telesign.com/v1/verify/call" port="443" charset="UTF-8" result="verifyPhoneCall">
<cfhttpparam type="header" name="authorization" value="#Authorization#">
<cfhttpparam type="header" name="content-type" value="application/x-www-form-urlencoded">
<cfhttpparam type="header" name="date" value="#dates.signingDate#">
<cfhttpparam name="phone_number" value="#phoneNumberToCall#" type="formfield">
<cfhttpparam name="ucid" value="OTHR" type="formfield">
</cfhttp>
<cfdump var="#verifyPhoneCall#">
The headers need to be included in the signature with "new lines". And the docs also say that they need to be in the same order that the http tag is sending them in. I don't think I have the order correct... or even how I'm supposed to set an order in the cfhttp call.
Any help is appreciated. And yes the keys are real. I'll generate new ones soon.
Thanks,
Brian
Looking over their documentation on Constructing the CanonicalizedPOSTVariables Element it mentions that the POST body must match the string used when constructing the signature (emphasis mine):
... when you construct the signature string, you must use the body of
the POST request exactly as it is delivered to the service.
By default, cfhttpparam url encodes any formField values. Since you are not encoding those values when you construct the signature, the content submitted by cfhttp does not match. Hence the error.
Either disable automatic encoding for all of the form fields in the signature:
<cfhttpparam name="phone_number"
value="#phoneNumberToCall#"
type="formfield"
encoded="false">
... or use type="body" instead. Then you have complete control over the post content:
<cfhttpparam type="body"
value="phone_number=15554565555&ucid=OTHR">
Update:
Also, get rid of the final new line ie chr(10) in the "headerText". Otherwise your cfhttp content still will not match the signature. ie Use this:
headerText = arrayToList(headers, chr(10));
.. instead of:
headerText = arrayToList(headers, chr(10)) & chr(10);

How to Insert Record and Upload file using the FreeASPUpload Script

I want to Insert record and upload file at the same time, right now im using FreeASPUpload Script. When i submit the form it returns this error
Cannot use the generic Request collection after calling BinaryRead
Here is the Full Source Code of my page
<%
option explicit
Response.Expires = -1
Server.ScriptTimeout = 600
Session.CodePage = 65001
%>
<!-- #include file="UploadClass.asp" -->
<%
Dim uploadsDirVar
uploadsDirVar = server.MapPath("Files_Uploaded")
function OutputForm()
%>
<form name="frmSend" method="POST" enctype="multipart/form-data" accept-charset="utf-8" action="form.asp" onSubmit="return onSubmitForm();">
<input type="hidden" name="ApplicationForm" value="Insert" />
Name: <input type="text" name="name_insert" value="" size="30" />
<B>File names:</B><br>
File 1: <input name="attach1" type="file" size=35><br>
<br>
<input style="margin-top:4" type="submit" value="Submit">
</form>
<%
end function
function TestEnvironment()
Dim fso, fileName, testFile, streamTest
TestEnvironment = ""
Set fso = Server.CreateObject("Scripting.FileSystemObject")
if not fso.FolderExists(uploadsDirVar) then
TestEnvironment = "<B>Folder " & uploadsDirVar & " does not exist.</B><br>The value of your uploadsDirVar is incorrect. Open uploadTester.asp in an editor and change the value of uploadsDirVar to the pathname of a directory with write permissions."
exit function
end if
fileName = uploadsDirVar & "\test.txt"
on error resume next
Set testFile = fso.CreateTextFile(fileName, true)
If Err.Number<>0 then
TestEnvironment = "<B>Folder " & uploadsDirVar & " does not have write permissions.</B><br>The value of your uploadsDirVar is incorrect. Open uploadTester.asp in an editor and change the value of uploadsDirVar to the pathname of a directory with write permissions."
exit function
end if
Err.Clear
testFile.Close
fso.DeleteFile(fileName)
If Err.Number<>0 then
TestEnvironment = "<B>Folder " & uploadsDirVar & " does not have delete permissions</B>, although it does have write permissions.<br>Change the permissions for IUSR_<I>computername</I> on this folder."
exit function
end if
Err.Clear
Set streamTest = Server.CreateObject("ADODB.Stream")
If Err.Number<>0 then
TestEnvironment = "<B>The ADODB object <I>Stream</I> is not available in your server.</B><br>Check the Requirements page for information about upgrading your ADODB libraries."
exit function
end if
Set streamTest = Nothing
end function
function SaveFiles
Dim Upload, fileName, fileSize, ks, i, fileKey
Set Upload = New FreeASPUpload
Upload.Save(uploadsDirVar)
' If something fails inside the script, but the exception is handled
If Err.Number<>0 then Exit function
SaveFiles = ""
ks = Upload.UploadedFiles.keys
if (UBound(ks) <> -1) then
SaveFiles = "<B>Files uploaded:</B> "
for each fileKey in Upload.UploadedFiles.keys
SaveFiles = SaveFiles & Upload.UploadedFiles(fileKey).FileName & " (" & Upload.UploadedFiles(fileKey).Length & "B) "
next
else
SaveFiles = "No file selected for upload or the file name specified in the upload form does not correspond to a valid file in the system."
end if
SaveFiles = SaveFiles & "<br>Enter a number = " & Upload.Form("enter_a_number") & "<br>"
SaveFiles = SaveFiles & "Checkbox values = " & Upload.Form("checkbox_values") & "<br>"
SaveFiles = SaveFiles & "List values = " & Upload.Form("list_values") & "<br>"
SaveFiles = SaveFiles & "Text area = " & Upload.Form("t_area") & "<br>"
end function
%>
<HTML>
<HEAD>
<TITLE>Test Free ASP Upload 2.0</TITLE>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
BODY {background-color: white;font-family:arial; font-size:12}
</style>
<script>
function onSubmitForm() {
var formDOMObj = document.frmSend;
if (formDOMObj.attach1.value == "")
alert("Please press the Browse button and pick a file.")
else
return true;
return false;
}
</script>
</HEAD>
<BODY>
<br><br>
<div style="border-bottom: #A91905 2px solid;font-size:16">Upload files to your server</div>
<%
Dim diagnostics
if Request.ServerVariables("REQUEST_METHOD") <> "POST" then
diagnostics = TestEnvironment()
if diagnostics<>"" then
response.write "<div style=""margin-left:20; margin-top:30; margin-right:30; margin-bottom:30;"">"
response.write diagnostics
response.write "<p>After you correct this problem, reload the page."
response.write "</div>"
else
response.write "<div style=""margin-left:150"">"
OutputForm()
response.write "</div>"
end if
else
response.write "<div style=""margin-left:150"">"
OutputForm()
response.write SaveFiles()
response.write "<br><br></div>"
end if
%>
</BODY>
</HTML>
<!-- #include file="ADOVBS.inc" -->
<%
'=======================================================================================
' CONNECT DATABASE
'=======================================================================================
Dim objConn, objRs
Set objConn = CreateObject("ADODB.Connection")
Set objRs = CreateObject("ADODB.Recordset")
objConn.open"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="& server.MapPath("db/Job_database.mdb") &";Mode=ReadWrite|Share Deny None;Persist Security Info=False"
If Request("ApplicationForm") = "Insert" Then
Set InsCom=Server.CreateObject("ADODB.Command")
InsCom.ActiveConnection=objConn
InsName = Trim(request("name_insert"))
InsName = replace(InsName,"'","''")
InsCom.CommandText = "Insert into applications(aname)Values(?)"
InsCom.Parameters.Append InsCom.CreateParameter("#name_insert", adVarChar, adParamInput, 255, InsName)
InsCom.Execute
End If
%>
I have been searching for this problem, but couldn't make it work. although what i found is that i have to use the Form Collection provided by FreeASPUpload. therefore i change
If Request("ApplicationForm") = "Insert" Then
to this
If Upload.Form("ApplicationForm") = "Insert" Then
But it also returns an error, that says: Variable is undefined: 'Upload'
If i change the Request method, it only Uploads the file not inserts the record
If Request.QueryString("ApplicationForm") = "Insert" Then
What i understands is that my insert query is in wrong place or so...
Please help me solve this problem.. thanks
I haven't used AspFreeUpload much so I'm guessing a bit here.
It would appear that using the Request object isn't an option so you're stuck with having to use the Upload.Form. As your code stands, the Upload object is only defined and set within the context of your SaveFiles function.
Try moving your database insert code to within the SaveFiles function. This would mean cutting everything from the line
Dim objConn, objRs
to
InsCom.Execute
and pasting it just before 'End Function'
You may also need to move your include adovbs.inc directive to somewhere before the function was called. The most logical place would be on the line immediately below your other include directive = for uploadclass.asp

coldfusion struct in function argument

I'm trying to do server side facebook connect, but the sdk (get it here) provided gives the following error:
Invalid CFML construct found on line 523 at column 78.
ColdFusion was looking at the following text:
{
And it doesn't explain why it's throwing this error. I'm not good at cfscript, so I don't know whether the sdk uses the correct syntax, but it throws the error on this function, at the braces of the struct in the function arguments:
private String function getUrl(String path = "", Struct parameters = {})
{
var key = "";
var resultUrl = "https://www.facebook.com/" & arguments.path;
if (structCount(arguments.parameters)) {
resultUrl = resultUrl & "?" & serializeQueryString(arguments.parameters);
}
return resultUrl;
}
I had thought that using an sdk would be a no brainer, but apparently I'm missing something.
What am I doing wrong?
Part 2:
The code now comes to a halt at:
for (var propertyName in arguments.properties) {
httpService.addParam(type="formField", name=propertyName, value=arguments.properties[propertyName]);
}
Are you not allowed to use a for loop in cfscript?
Try structNew() or "#structNew()#" instead of {}
This should work for connecting to Facebook and getting an access token:
<cfset appID = ""/>
<cfset secret_key = ""/>
<cfset app_url = ""/>
<cfparam name="URL.Code" default="0">
<cfparam name="URL.state" default="0">
<cfparam name="SESSION.Redirect" default="0">
<cfset code_ = URL.Code>
<cfif code_ EQ "" OR code_ EQ 0>
<cfset SESSION.State = Hash(CreateUUID(),"MD5")>
<cfset dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" & appID & "&redirect_uri=" & app_url & "&scope=email,user_photos,publish_stream" & "&state=" & SESSION.State>
<cflocation url="#dialog_url#" addtoken="no">
</cfif>
<cfif SESSION.State EQ URL.State>
<cfset token_url = "https://graph.facebook.com/oauth/access_token?client_id=" & appID & "&redirect_uri=" & app_url & "&client_secret=" & secret_key & "&code=" & code_>
<cfhttp url="#token_url#" result="AccessToken" method="GET">
<cfelse>
<p>The state does not match. You may be a victim of CSRF.</p>
</cfif>

How to send email to recipient with umlauts in domain name?

In my app I have to send email to recipient who has umlauts in domain name.
Example:
"test#äöü.test.com"
I'm using cfmail tag and I'm getting such error:
"invalid definition for attribute to at tag mail"
"Invalid E-Mail Address definition (test#äöü.test.com)"
Is there any way to send email to such recipients in coldfusion?
There is even a easier solution! Why not use Oracles built in class:
http://download.oracle.com/javase/6/docs/api/java/net/IDN.html#toUnicode(java.lang.String)
Then you only have to do this (example shows from punycode to Unicode):
<cfset strUrl = "xn--land-poa.se" />
<!--- Create a Java URL. --->
<cfset jUrl = CreateObject( "java", "java.net.IDN" ).toUnicode(strUrl) />
<cfoutput>
#jUrl#
You don´t have to download anything!
I'm no I18N expert but I was intrigued enough to investigate and come up with the following solution.
The problem is essentially how to send mail to Internationalised Domain Names (IDN), i.e. those which contain non-ASCII characters. IDNs are valid nowadays but not recognized by many systems including Java (and therefore ColdFusion, which uses the Java validation for CFMAIL address fields - hence the error you're seeing).
For a system to recognise an IDN it needs to be converted to an ASCII form called Punycode. For example müller.org needs to be converted to xn--mller-kva.org
LibIdn is an OS java library that will do this and the following code shows how you can hook it up to CF using Mark Mandel's JavaLoader.
<cffunction name="convertIdnToAscii" returntype="string" output="false">
<cfargument name="domain" type="string" required="true">
<cfscript>
var local = {};
// these paths assume the JavaLoader folder and the libidn-1.22.jar are in the same folder as the cfm template.
local.javaLoaderPath = "javaLoader.JavaLoader";
local.idnLibPath = ExpandPath( "libidn-1.22.jar" );
// convert the IDN lib path to an array which is what JavaLoader expects
local.libPathArray = [ local.idnLibPath ];
//load the IDN Lib
loader = CreateObject( "component",local.javaLoaderPath ).init( local.libPathArray );
// create an instance of the IDN lib
local.idn = loader.create( "gnu.inet.encoding.IDNA" ).init();
// convert the domain name
return local.idn.toASCII( arguments.domain );
</cfscript>
</cffunction>
<cffunction name="convertIdnAddress" returntype="string" output="false">
<cfargument name="address" type="string" required="true">
<cfscript>
var local = {};
local.domain = GetToken( arguments.address,2,"#" );
local.converted = convertIdnToAscii( local.domain );
return Replace( arguments.address,local.domain,local.converted );
</cfscript>
</cffunction>
<!--- Loop over a list of addresses and convert them if necessary --->
<cfset processedAddresses = []>
<cfloop list="test#äöü.test.com,test#example.com" index="address">
<cfif( NOT IsValid( "email",address ) )>
<cfset address = convertIdnAddress( address )>
</cfif>
<cfmail server="0.0.0.0" from="sender#mydomain.com" to="#address#" subject="test">Message</cfmail>
<cfset ArrayAppend( processedAddresses,address )>
</cfloop>
<cfdump var="#processedAddresses#">
This will send 2 emails (to a non-existent mailserver) and dump the converted addresses:
test#xn--4ca0bs.test.com
test#example.com
Notes:
To get the libidn jar file, download and extract the tar and look for it in the Java directory
The above assumes the libidn jar and JavaLoader package are located in the same folder as the template contain the CF code
The above should work on CF8 and above, although I've only tested it on CF9.
Be aware there's no error handling for addresses that might be invalid for reasons other than it containing an IDN.