HTTP Signature Authentication - cybersource

I am not able to make an authenticated call against Cybersource api and apitest environments, even though my signature routine is able to generate the correct signature from their test page.
I tried different headers combination, upper and lower case, and date vs v-c-date field names.
I constructed the signature from the following headers components.
'VB, Signature Construction
Dim pHost As String = "host: apitest.cybersource.com"
Dim pMerc As String = "v-c-merchant-id: testmid"
Dim pDate As String = "v-c-date: " & Now.ToUniversalTime.ToString("r")
Dim pReq As String = "(request-target): get /reporting/v3/report-downloads?organizationId=testmid&reportDate=2018-10-27&reportName=Demo_Report"
Dim pHeader As String = pHost & Chr(10) & pDate & Chr(10) & pReq & Chr(10) & pMerc
Dim kID As String = "{secret key}"
Dim mSig As String = GenerateSignatureFromParams(pHeader, kID)
Dim pSig As String = "signature: keyid=""{key id}"", algorithm=""HmacSHA256"", headers=""host v-c-date (request-target) v-c-merchant-id"", signature=""" & mSig & """"
When added the host, v-c-merchant-id, v-c-date, and signature to the request header for a GET, I received a response of (401) Unauthorized.

The header names are:
$headerString = "host date (request-target) v-c-merchant-id"
appears your name "v-c-date" should be "date"

Related

CURL from ASP.Net (VB.Net) PayPal

https://developer.paypal.com/docs/archive/express-checkout/ht-ec-parallelPayments/
Been trying to implement this on ISS with ASP.Net & VB.Net and I am not sure how to properly build the request token so that this can work and be utilized.
This is what I have come up with, but the API request will not process getting this:
The request was aborted: Could not create SSL/TLS secure channel.
still not working
Private Sub btnSUBMIT_Click(sender As Object, e As EventArgs) Handles btnSUBMIT.Click
Dim NVP As New Dictionary(Of String, String) ''Api Name-Value-Pair parameters
''define paypal SANDBOX server
Dim paypalApiServerUrl As String = "https://api-3t.sandbox.paypal.com/nvp"
NVP.Add("USER", "fixed") ' = Caller_ID '## the PayPal User ID Of the caller account
NVP.Add("PWD", "12345678") ' PWD = Caller_Pswd '## the caller account Password
NVP.Add("SIGNATURE", "solved") ' Signature = Caller_Sig '## the caller account Signature
NVP.Add("METHOD", METHOD) ' METHOD = SetExpressCheckout '## API operation
NVP.Add("RETURNURL", RETURNURL) ' RETURNURL = https : //example.com/success.html '## URL displayed to buyer after authorizing transaction
NVP.Add("CANCELURL", CANCELURL) ' CANCELURL = https : //example.com/canceled.html '## URL displayed to buyer after canceling transaction
NVP.Add("Version", "93") ' Version = 93 '## API version
NVP.Add("PAYMENTREQUEST_0_CURRENCYCODE", PAYMENTCURRENCYCODE) ' ## Start primary level information For first payment
NVP.Add("PAYMENTREQUEST_0_AMT", "250") '
NVP.Add("PAYMENTREQUEST_0_ITEMAMT", "225") '
NVP.Add("PAYMENTREQUEST_0_TAXAMT", "25") '
NVP.Add("PAYMENTREQUEST_0_PAYMENTACTION", SALEPAYMENTACTION) '
NVP.Add("PAYMENTREQUEST_0_DESC", PaymentDescription) '
NVP.Add("PAYMENTREQUEST_0_SELLERPAYPALACCOUNTID", "email1#address.com") ' ## PayPal e-mail Of first receiver
NVP.Add("PAYMENTREQUEST_0_PAYMENTREQUESTID", "CIYP CART1") ' PAYMENTREQUEST_0_PAYMENTREQUESTID = CART1 '## unique ID Of first payment – End primary level information For first payment
NVP.Add("L_PAYMENTREQUEST_0_NAME0", "Super Sub CIYP") ' L_PAYMENTREQUEST_0_NAME0 = Super Sub '## Start secondary level information For first payment first item
NVP.Add("L_PAYMENTREQUEST_0_NUMBER0", "SS - 101") '
NVP.Add("L_PAYMENTREQUEST_0_QTY0", "1") '
NVP.Add("L_PAYMENTREQUEST_0_AMT0", "125")
NVP.Add("L_PAYMENTREQUEST_0_TAXAMT0", "15") ' ## End secondary level information For first payment first item
NVP.Add("L_PAYMENTREQUEST_0_NAME1", "Classic Wine Example") ' L_PAYMENTREQUEST_0_NAME1 = EXAMPLE Classic Wine '## Start secondary level information For first payment second item
NVP.Add("L_PAYMENTREQUEST_0_QTY1", "1") '
NVP.Add("L_PAYMENTREQUEST_0_AMT1", "100") '
NVP.Add("L_PAYMENTREQUEST_0_TAXAMT1", "10") ' ## End secondary level information For first payment second item
NVP.Add("PAYMENTREQUEST_1_CURRENCYCODE", PAYMENTCURRENCYCODE) ' ## Start primary level information For second payment
NVP.Add("PAYMENTREQUEST_1_AMT", "75") ' ## total amount Of second payment
NVP.Add("PAYMENTREQUEST_1_ITEMAMT", "65") '
NVP.Add("PAYMENTREQUEST_1_TAXAMT", "10") '
NVP.Add("PAYMENTREQUEST_1_PAYMENTACTION", SALEPAYMENTACTION) '
NVP.Add("PAYMENTREQUEST_1_DESC", "Mocktail Large") '
NVP.Add("PAYMENTREQUEST_1_SELLERPAYPALACCOUNTID", "secondpayee#address.com") ' ## PayPal e-mail Of second receiver
NVP.Add("PAYMENTREQUEST_1_PAYMENTREQUESTID", "CART2") ' ## unique ID Of second payment – End primary level information For secondary payment
NVP.Add("L_PAYMENTREQUEST_1_NAME0", "Orange crush") ' ## Start secondary level information For secondary payment first item
NVP.Add("L_PAYMENTREQUEST_1_NUMBER0", "MC - 77") '
NVP.Add("L_PAYMENTREQUEST_1_QTY0", "1") '
NVP.Add("L_PAYMENTREQUEST_1_AMT0", "65") '
NVP.Add("L_PAYMENTREQUEST_1_TAXAMT0", "10") ' ## End secondary level information For second payment first item
''build the parameter string
Dim paramBuilder As New StringBuilder
For Each kv As KeyValuePair(Of String, String) In NVP
Dim st As String
st = kv.Key & "=" & HttpUtility.UrlEncode(kv.Value) & "&"
paramBuilder.Append(st)
Next
Dim param As String
param = paramBuilder.ToString
param = param.Substring(0, param.Length - 1) ''remove the last '&'
''Create web request and web response objects, make sure you using the correct server (sandbox/live)
Dim wrWebRequest As Net.HttpWebRequest = DirectCast(Net.WebRequest.Create(paypalApiServerUrl), Net.HttpWebRequest)
wrWebRequest.Method = "POST"
Dim requestWriter As New IO.StreamWriter(wrWebRequest.GetRequestStream())
requestWriter.Write(param)
requestWriter.Close()
'' Get the responseReader
Dim responseReader As IO.StreamReader
responseReader = New IO.StreamReader(wrWebRequest.GetResponse().GetResponseStream())
''read the response
Dim responseData As String
responseData = responseReader.ReadToEnd()
responseReader.Close()
''url-decode the results
Dim result As String
result = HttpUtility.UrlDecode(responseData)
Dim formattedResult As String
formattedResult = "Request on " & paypalApiServerUrl & vbCrLf &
HttpUtility.UrlDecode(param.Replace("&", vbCrLf & " ")) & vbCrLf & vbCrLf &
"Result:" & vbCrLf & HttpUtility.UrlDecode(responseData.Replace("&", vbCrLf & " ")) & vbCrLf & vbCrLf &
"--------------------------------------" & vbCrLf
''show the results
Console.WriteLine(formattedResult)
Response.Write(formattedResult)
MSG.Text = formattedResult
End Sub
What I came up with is not working,
Message: The request was aborted: Could not create SSL/TLS secure channel.
Found these resources which helped shed some light on the subject
http://brad.w3portals.com/2008/03/paypal-nvp-api-example-for-vbnet-aspnet.html
How to create Encrypted PayNow button "on the fly" for Third-party customers, using Paypal NVP API?
https://www.paypal.com/businessprofile/mytools/apiaccess/firstparty/signature
For name value pair format, the values (right hand side) should be URL encoded, and the pairs should be separated by ampersands (&)
You can have a function that builds the request string text out of an array or dictionary
Are you using a valid USER/PWD/Signature from the profile of a Sandbox Business account at https://www.paypal.com/signin?intent=developer&returnUri=https%3A%2F%2Fdeveloper.paypal.com%2Fdeveloper%2Faccounts%2F ?
An SSL/TLS error may be due a lack of TLSv1.2 support on the server or framework environment, among other possible causes like not trusting the root CA issuer of the SSL certificate of the api-3t.paypal.com server it's connecting to

how to send an email using SendGrid V3 to multiple recipients, in a .NET app

It sends to one ok. But not to 2 or more. I've tried separating addresses by , and ; and space in the to_addr string, but failed.
What format does class EmailAddress expect for multiple addresses?
public async sub send_message( msg_subject, msg_body, from_addr_text, to_addr_text, optional commands = "")
dim apiKey = Environment.GetEnvironmentVariable("SENDGRID_API_KEY")
dim client as new SendGridClient( apiKey, , , "v3", )
dim from = new EmailAddress( from_addr_text, "INSTRUMENT")
dim subject = msg_subject
if subject = ""
subject = " " ' won't send if empty
End If
dim to_addr = new EmailAddress( to_addr_text, "INSTRUMENT")
dim plainTextContent = msg_body
dim htmlContent = "<strong>" & msg_body & "</strong>"
dim msg = MailHelper.CreateSingleEmail(from, to_addr, subject, plainTextContent, htmlContent)
dim response = await client.SendEmailAsync(msg)
if instr( commands, "SKIP POPUPS") ' TEST TEXT MSG !!!
exit sub
End If
popup_information( "MESSAGE SENDING", "Sent..." & vbcrlf & vbcrlf & "SUBJECT: " & vbcrlf & subject & vbcrlf & vbcrlf & "BODY: " & vbcrlf & msg_body )
end sub
Not sure which SDK version are you using , but if you follow the Sendgrid V3 api SDK for C# , you should find a method like below in the MailHelper class
public static SendGridMessage CreateSingleEmailToMultipleRecipients(EmailAddress from, List<EmailAddress> tos, string subject,string plainTextContent,string htmlContent)
which accepts a List<EmailAddress> to send email to multiple recipients. So instead of using the below line in your code
dim msg = MailHelper.CreateSingleEmail(from, to_addr, subject, plainTextContent, htmlContent)
you should use the below code
var to_addr = new List<EmailAddress>();
to_addr.Add(new EmailAddress( to_addr_text, "INSTRUMENT"));
to_addr.Add(new EmailAddress( "secondperson#test.com", "secondperson")); // you can add multiple email in this list
and then you can use to_addr in the code below
dim msg = MailHelper.CreateSingleEmailToMultipleRecipients(from, to_addr, subject, plainTextContent, htmlContent)
Pardon me for the example in C# but the same should be applicable for your VB.NET code
The stack overflow answer here shows how to implement SendGrid using dependency injection into a Net 6 Web API application using controllers.
The scenario of sending an email to multiple recipients is covered in the referenced example code here: https://github.com/Davidmendoza1987/dotnet-sendgrid-examples

JSON.net - Using VB.NET Unable to iterate through results

I am trying to process this json document using JSON.NET.
With the VB.NET code:
Dim o As JObject = JObject.Parse(json)
Dim results As List(Of JToken) = o.Children().ToList
Dim count As Integer = 0
For Each item As JProperty In results
Dim snippet As String = String.Empty
Dim URL As String = String.Empty
Dim source As String = String.Empty
item.CreateReader()
Select Case item.Name
Case "response"
snippet = item.Last.SelectToken("docs").First.Item("snippet").ToString
URL = item.Last.SelectToken("docs").First.Item("web_url").ToString
source = ControlChars.NewLine & "<font size='2'>" & item.First.SelectToken("docs").First.Item("source").ToString & "</font>" & ControlChars.NewLine
tbNews.Text &= "<a href=" & URL & " target='new'>" & snippet & "</a> - " & source
End Select
Next
I am only receiving the first document as a result. Can someone advise as to how I can get the 1st - Nth documents as a complete list?
The docs are 2 levels deep, you're only looping in the top level. Try this...
Dim parsedObject = JObject.Parse(json)
Dim docs = parsedObject("response")("docs")
For Each doc In docs
Dim snippet As String = doc("snippet")
Dim URL As String = doc("web_url")
Dim source As String = doc("source")
'....
Next

Backslashes in path in VB.Net

It seems I'm not lucky with backslashes in ASP.Net VB.Net.
I'm trying to output some infos about files with ffprobe and my paths are cut randomly at some backslash in every string containing backslash.
I debugged this function to return the path generated by fileToProcess:
Function ffprobe_show_format(ByVal arg As String) As String
Dim myProcess As New System.Diagnostics.Process()
Dim fileToProcess As String = MapPath(".") & "\temps\" & arg
myProcess.StartInfo.FileName = MapPath(".") & "\ffprobe.exe"
myProcess.StartInfo.Arguments = "-show_format " & fileToProcess & " >C:\inetpub\vhosts\mysite.com\httpdocs\absolutefs\ffmpegtemp.txt"
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.RedirectStandardInput = True
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.Start()
Dim myStreamWriter As StreamWriter = myProcess.StandardInput
Dim mystreamreader As StreamReader = myProcess.StandardOutput
Dim str As String = mystreamreader.ReadToEnd
Return str & ";" & "FileToProcess=" & fileToProcess & "MapPath(.) AND ffprobe.exe" & MapPath(".") & "\\ffprobe.exe"
End Function
And it returns ;FileToProcess=C:
It means that
My file is not processed because of some errors
My Path is cut at backslashes
The rest of the string is then broken
Does I need to tell asp.net to represent backslashes in another way?
[EDIT]
I can't choose an answer but will upvote since I made two mistakes:
- To debug, I was reading my value once it was put in SQL variables with limites size then
- ... fetched with Newtonsoft.Json parser that probably was refusing some chars.
I'm new on ASP.Net so I have difficulties finding a good way to debug. So I finally made as usual when I'm not able to debug on a platform: I've written my debug vars in a text file, and everything was there using this way:
Function ffprobe_show_format(ByVal file As String, ByVal app As String) As String
Dim myProcess As New System.Diagnostics.Process()
myProcess.StartInfo.FileName = app
Dim argz As String = FormatCommandLine("-show_format", file)
myProcess.StartInfo.Arguments = argz
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.Start()
Dim mystreamreader As StreamReader = myProcess.StandardOutput str As String = mystreamreader.ReadToEnd
MapPath(".") & "/ffprobe.exe"
Dim objWriter As New System.IO.StreamWriter(MapPath(".") & "\debug.txt")
objWriter.Write(str)
objWriter.Close()
Return str
End Function
I'll add an ffmpeg tag since it's also another example on how to call it and process a file.
You don't need to worry about the backslashes. The backslash is not a special character in VB like it is in C#. In fact if you do double them up you might hit errors.
It's hard to tell where the problem is occurring. Some ideas to try to narrow it down:
Try not redirecting StandardInput since you aren't passing it anything.
Read from StandardError to make sure it is empty. It may contain an error message.
I would make use of Debug.WriteLine to trace the function and try to spot where things begin to go wrong.
This may not matter, but I would place myProcess.WaitForExit after mystreamreader.ReadToEnd.
Larry's suggestion to use System.IO.Path is a good one.
Some hastily modified code based on all this:
Function ffprobe_show_format(ByVal arg As String) As String
Debug.WriteLine("arg: " & arg)
Dim fileToProcess As String = IO.Path.Combine(MapPath("."), "temps\" & arg)
Debug.WriteLine("fileToProcess = " & fileToProcess)
Debug.WriteLine("MapPath AND ffprobe.exe: " & IO.Path.Combine(MapPath(".") & "\\ffprobe.exe"))
Dim myProcess As New System.Diagnostics.Process()
myProcess.StartInfo.FileName = IO.Path.Combine(MapPath("."), "\ffprobe.exe")
myProcess.StartInfo.Arguments = "-show_format " & fileToProcess & " >C:\inetpub\vhosts\mysite.com\httpdocs\absolutefs\ffmpegtemp.txt"
myProcess.StartInfo.UseShellExecute = False
'myProcess.StartInfo.RedirectStandardOutput = True
myProcess.StartInfo.RedirectStandardError = True
myProcess.Start()
'Dim str As String = myProcess.StandardOutput.ReadToEnd
Dim errStr as string = myProcess.StandardError.ReadToEnd
myProcess.WaitForExit()
Debug.WriteLine("myProcess exit code = " & myProcess.ExitCode.ToString())
'Debug.WriteLine("stdOutput: " & str)
Debug.WriteLine("stdError: " & errStr)
Return str & ";" & "FileToProcess=" & fileToProcess
End Function
There are a few things to consider here.
First, the back-slash character is the escape character (i.e. \t \n \r ...) and should be double-escaped \\ IF you MUST embed it into strings.
However, the .NET framework contains a very good class: System.IO.Path that has several Combine method overloads that can help you to construct paths without embedding back-slash characters into strings. This also makes your code more portable in the (somewhat unlikely) event that you would ever run it on a non-Windows platform.
http://msdn.microsoft.com/en-us/library/system.io.path
Try closing the StreamReader before accessing its contents:
Dim myStreamReader As StreamReader = myProcess.StandardOutput
Dim str As String = myStreamReader.ReadToEnd
myStreamReader.Close()
Return str & ";" & "FileToProcess=" & fileToProcess & "MapPath(.) AND ffprobe.exe" & MapPath(".") & "\\ffprobe.exe"
When I run your function in my local devbox:
Function ffprobe_show_format(ByVal arg As String) As String
Dim myProcess As New System.Diagnostics.Process()
Dim fileToProcess As String = HttpContext.Current.Server.MapPath(".") & "\temps\" & arg
myProcess.StartInfo.FileName = HttpContext.Current.Server.MapPath(".") & "\ffprobe.exe"
myProcess.StartInfo.Arguments = "-show_format " & fileToProcess & " >C:\inetpub\vhosts\mysite.com\httpdocs\absolutefs\ffmpegtemp.txt"
'myProcess.StartInfo.UseShellExecute = False
'myProcess.StartInfo.RedirectStandardInput = True
'myProcess.StartInfo.RedirectStandardOutput = True
'myProcess.Start()
'Dim myStreamWriter As StreamWriter = myProcess.StandardInput
'Dim myStreamReader As StreamReader = myProcess.StandardOutput
Dim str As String = String.Empty 'myStreamReader.ReadToEnd
Return str & ";" & "FileToProcess=" & fileToProcess & "MapPath(.) AND ffprobe.exe" & HttpContext.Current.Server.MapPath(".") & "\\ffprobe.exe"
End Function
I get what I consider to be a somewhat normal string returned for ffprobe_show_format:
";FileToProcess=C:\Documents and Settings\Me\My Documents\Proj1\SubApp1\temps\testMapPath(.) AND ffprobe.exeC:\Documents and Settings\Me\My Documents\Proj1\SubApp1\\"
I commented out the System.Diagnostics.Process() as I don't have an executable called ffprobe.exe.
Given that the rest of it works, Try closing the StreamReader before accessing its contents.
You should just need to escape each backslash with another backslash.
Or, you might be able to prefix your string with the # symbol (works in C#, not sure about VB.NET).
I.E.
instead of "C:\this\that.exe"
use "C:\this\that.exe"
or #"C:\this\that.exe"

trying to send link with querystrings as email

Dim x As String
x = "http://www.domain.com/aaa/test/default2.aspx?date=" & now.Text & "&tfname=" & p1fname.Text & "&tlname=" & p1lname.Text & "&comp=" & Request.QueryString("comp")
Dim objEmail As New MailMessage()
objEmail.To = "test#email.com"
objEmail.From = "me#test.com"
objEmail.Cc = "test#email.com"
objEmail.Subject = "Test Email"
objEmail.Body = x
SmtpMail.SmtpServer = "mail.domain.com"
Try
SmtpMail.Send(objEmail)
Catch exc As Exception
Response.Write("Send failure: " + exc.ToString())
End Try
When I get the email it comes with
http://www.domain.com/aaa/test/default2.aspx?date=1/13/2011
as a link
and the rest as text
11:39:09 AM&tfname=sadasd&tlname=asd&comp=GWI
Whenever you put a parameter into a query string, you should encode it using System.Web.HttpUtility.UrlEncode to avoid invalid characters going into the URL:
x = "http://www.domain.com/aaa/test/default2.aspx?date=" & HttpUtility.UrlEncode(now.Text) &
"&tfname=" & HttpUtility.UrlEncode(p1fname.Text) &
"&tlname=" & HttpUtility.UrlEncode(p1lname.Text) &
"&comp=" & HttpUtility.UrlEncode(Request.QueryString("comp"))
You cannot have Spaces in the query string, if you need to put spaces, replace it with %20 before appending to the querystring. Although the ideal way to do this is to encrypt and decrpt the text in the querystring.

Resources