Stripe Payment with VB - 400 Bad Request - vb.net

I'm trying to make a stripe payment work from a VB website. I know, I know, "I should use C#". I can't because the site is already in VB. Nothing I can do about it.
Anyway, I have most of it figured out:
User clicks submit button with valid info
Form submits to Stripe
Stripe sends a token back
A jQuery ajax function posts the data to donate/pay-by-stripe
I have this line of code in my Global.asax.vb
routes.MapRoute("pay-by-stripe", "donate/pay-by-stripe", New With{.controller = "Dynamic", .action = "PayByStripe"})
So my PayByStripe function in the Dynamic Controller looks like this:
Function PayByStripe()
''The Stripe Account API Token
Dim STR_Stripe_API_Token As String = "sk_test_*****"
''The Stripe API URL
Dim STR_Stripe_API_URL As [String] = "https://api.stripe.com/v1/charges"
''The Stripe Card Token
Dim token As String = HttpContext.Request.Form("token")
Dim description As String = HttpContext.Request.Form("description")
Dim amount As Single = HttpContext.Request.Form("amount")
''Creates a Web Client
Dim OBJ_Webclient As New System.Net.WebClient()
''Creates Credentials
Dim OBJ_Credentials As New System.Net.NetworkCredential(STR_Stripe_API_Token, "")
''Sets the Credentials on the Web Client
OBJ_Webclient.Credentials = OBJ_Credentials
''Creates a Transaction with Data that Will be Sent to Stripe
''Dim OBJ_Transaction As New System.Collections.Specialized.NameValueCollection()
Dim OBJ_Transaction As NameValueCollection = New NameValueCollection()
OBJ_Transaction.Add("amount", amount)
OBJ_Transaction.Add("currency", "usd")
OBJ_Transaction.Add("address-country", "US")
OBJ_Transaction.Add("description", "")
OBJ_Transaction.Add("card", token)
''The Stripe Response String
Dim STR_Response As String = Encoding.ASCII.GetString(OBJ_Webclient.UploadValues(STR_Stripe_API_URL, OBJ_Transaction))
'Response.Redirect("/donate/?transaction=success");
Return STR_Response
End Function
I'm getting a 400 bad request error on the STR_Response line:
Dim STR_Response As String = Encoding.ASCII.GetString(OBJ_Webclient.UploadValues(STR_Stripe_API_URL, OBJ_Transaction))
I'm a VB and Stripe noob, and not sure what this means. My main theory now is that it's because I don't have a /donate/pay-by-stripe/ page, but I don't know what I'd even put in there if I did create it.
Any help would be great!

That's a webservice you are calling, right?
A 400 Bad Request with a webservice means your XML request is malformed.
Example, in my request, part of it is a UTC in a certain date format. Example: <pp:utc>2013-05-24 2025</pp:utc>
So, if I were to malform my request to this <pp:utc>2013-05-24 2025</pp:utc2> it would result in:
HTTP/1.1 400 Bad Request
Cache-Control: private
Server: Microsoft-IIS/7.5
X-AspNet-Version: 2.0.5
So, check your request and make sure everything is properly formatted.
EDIT: just noticed I put the "incorrect" utc tags incorrectly.
Please notice the opening tag <pp:utc> is being closed with a </pp:utc2>, which is the reason why you see 400 bad request

I had to put my password in System.Net.NetworkCredentials, and address-country is not a usable field. The only usable fields when submitting a charge are amount, currency, description, and card (which is actually the token). This is the final, working version of my PayByStripe Function in my Dynamic Controller:
Function PayByStripe()
'' The Stripe Account API Token - change this for testing
Dim STR_Stripe_API_Token As String = ""
If (this_is_a_test) Then
' Test Secret Key
STR_Stripe_API_Token = "sk_test_***"
Else
' Prod Secret Key
STR_Stripe_API_Token = "sk_live_***"
End If
''The Stripe API URL
Dim STR_Stripe_API_URL As [String] = "https://api.stripe.com/v1/charges"
''The Stripe Card Token
Dim token As String = HttpContext.Request.Form("token")
Dim description As String = HttpContext.Request.Form("description")
Dim amount As Single = HttpContext.Request.Form("amount")
''Creates a Web Client
Dim OBJ_Webclient As New System.Net.WebClient()
''Creates Credentials
Dim OBJ_Credentials As New System.Net.NetworkCredential(STR_Stripe_API_Token, "YOUR PASSWORD FOR STRIPE")
''Sets the Credentials on the Web Client
OBJ_Webclient.Credentials = OBJ_Credentials
''Creates a Transaction with Data that Will be Sent to Stripe
Dim OBJ_Transaction As New System.Collections.Specialized.NameValueCollection()
OBJ_Transaction.Add("amount", amount)
OBJ_Transaction.Add("currency", "usd")
OBJ_Transaction.Add("description", description)
OBJ_Transaction.Add("card", token)
''The Stripe Response String
Dim STR_Response As String = Encoding.ASCII.GetString(OBJ_Webclient.UploadValues(STR_Stripe_API_URL, OBJ_Transaction))
Return STR_Response
End Function

I've never had to pass in my password when connecting to Stripe's API. Simply pass in your private API Key through an authorization header with no password. It may also help to pass in a version header as well, something Stripe recommends. The following lines of card are in C#, I know your question was in VB, but I'm sure you can easily adaptive this:
webrequest.Headers.Add("Stripe-Version", "2014-12-22");
webrequest.Headers.Add("Authorization", String.Concat("Basic ", (Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:", "sk_test_XXXXXXXXXXXXXXXXXXX"))))));
Also, it may help to know that Stripe sends a 400 Bad Request when an expired or invalid card token is sent.

Related

RestSharp call to eBay oauth2 user token

I am trying to get eBay user tokens for my users using the identity api. I finally got it to work in Postman. Converted the call from Postman to a restsharp call from a vb.net test app. The Postman call works, the VB call returns "404 Not Found". Looked at the two calls using Fiddler. The only difference I can see is that the Postman call goes to:
"POST https://api.sandbox.ebay.com/identity/v1/oauth2/token";
and the VB app call goes to
"POST https://api.sandbox.ebay.com/identity/v1/oauth2/token/1"
It would appear that somewhere the VB app is appending "/1" to the api url. Not sure where this is occurring as I can step through the code as it executes and don't see it.
Is there a property in RestSharp that might cause this value to be appended?
EDIT added code. This code is supposed to return a user token and refresh token from eBay. It is taken pretty much from Postman with mods to work with the latest version.
Async Sub RSGetCode(sCode As String)
Dim client As RestClient = New RestClient("https://api.sandbox.ebay.com/identity/v1/oauth2/token")
Dim request As RestRequest = New RestRequest(Method.Post)
sCode = WebUtility.UrlDecode(sCode)
With request
.AddHeader("Content-Type", "application/x-www-form-urlencoded")
.AddHeader("Authorization", "Basic TXVycGh5c0MtNzYxNy00ZGRmLTk5N2ItOD..........................")
.AddParameter("grant_type", "authorization_code")
.AddParameter("code", sCode)
.AddParameter("redirect_uri", "Murphys_Creativ-Mu...........")
.AddParameter("Scope", "https://api.ebay.com/oauth/api_scope/sell.inventory")
End With
Dim responce = Await client.PostAsync(request)
'Dim responce = Await client.ExecuteAsync(request)
Dim sR As String = responce.Content
End Sub```
I got it to work by slightly reformating the code. See below.
Async Sub PostRestCode(sCode As String)
Dim client As RestClient = New RestClient("https://api.sandbox.ebay.com")
Dim request As RestRequest = New RestRequest("identity/v1/oauth2/token", Method.Post)
With request
.AddHeader("Content-Type", "application/x-www-form-urlencoded")
.AddHeader("Authorization", "Basic TXVycGh5c0MtNzYxNy00ZGRmLTk5N2ItODc2OGMzZWZkYT..............................")
.AddParameter("grant_type", "authorization_code")
.AddParameter("code", sCode) '"v^1.1#i^1#I^3#p^3#f^0#r^1#t^Ul41Xzg6NEN.......................................")
.AddParameter("redirect_uri", "Murphys_Creativ-Mu......................")
.AddParameter("Scope", "https://api.ebay.com/oauth/api_scope/sell.inventory")
End With
Dim responce = Await client.PostAsync(request)
'Dim responce = Await client.ExecuteAsync(request)
Dim sR As String = responce.Content
End Sub

Please enable cookies message (httpwebrequest)

I'm trying to send a request to a website but it keeps telling me my cookies are not enabled. (But i did used a cookiecontainer in my code)
Here is the code :
Private Function does_it_asks_for_cookies() As Boolean
Dim url As String = "https://www.myhabit.com/?hash="
Dim req As Net.HttpWebRequest = Net.HttpWebRequest.Create(URL)
req.CookieContainer = New CookieContainer
req.ContentType = "application/x-www-form-urlencoded"
Dim res As Net.HttpWebResponse = req.GetResponse()
Dim strm As New IO.StreamReader(res.GetResponseStream())
Dim html As String = strm.ReadToEnd()
strm.Dispose()
res.Dispose()
If html.Contains("To continue shopping at Amazon.com, please enable cookies in") Then
Return True
Else
Return False
End If
End Function
Usage : MsgBox(does_it_asks_for_cookies)
While you have a CookieContainer the code in your example doesn't actually put anything in it. HttpWebRequest doesn't know anything about previous requests and certainly doesn't magically store the contents of any cookies in your container, you will have to do that yourself. Having a CookieContainer isn't enough. Most (especially e-commerce) websites are very specific in what they expect there to be present in the form of a cookie, often reporting that cookies aren't turned on when the cookie doesn't contain the proper values. You will have to inspect the web site in a browser to figure out what cookies are set and what values they contain. Google "inspect cookies" to learn how to view cookies in the browser of your choice.

DocuSign SOAP API Update (Correct) Envelope Expiration

I'm using vb.net (4.0) to interact with the DocuSign API. I'm trying to make a process that allows a user to add 30 days to the current expiration date instead of logging into DocuSign.net to correct the envelope. The code seems to work fine (doesn't throw any errors) but the correction doesn't happen on DocuSign's side.
Me.EnvelopeID is the Envelope's ID
DocuService is the namespace of the DocuSign API Service Reference.
Me.AuthorizationString is the Username, Password, Account# and Integrator Key to send as HTTP headers.
Private Sub UpdateExpiration()
'Get envelope details
Dim orig As DocuService.Envelope = ExecuteSoap(Function(client) client.RequestEnvelope(Me.EnvelopeID, False), Me.AuthorizationString)
Dim cor As New DocuService.Correction
cor.EnvelopeID = Me.EnvelopeID
cor.Reminders = orig.Notification.Reminders
cor.Expirations = orig.Notification.Expirations
cor.Expirations.ExpireAfter = (Integer.Parse(orig.Notification.Expirations.ExpireAfter) + 30)
'Execute Correction
Dim cord As DocuService.CorrectionStatus = Me.ExecuteSoap(Function(client) client.CorrectAndResendEnvelope(cor), Me.AuthorizationString)
'If I add a break point on the next line and check the values of cord,
'there is a returned CorrectionStatus object but every property in the object is "Nothing"
Dim check As DocuService.Envelope = ExecuteSoap(Function(client) client.RequestEnvelope(Me.EnvelopeID, False), Me.AuthorizationString)
Console.WriteLine(check.Notification.Expirations.ExpireAfter & " " & (Integer.Parse(orig.Notification.Expirations.ExpireAfter) + 30))
If check.Notification.Expirations.ExpireAfter = (Integer.Parse(orig.Notification.Expirations.ExpireAfter)) Then
'Success :)
MsgBox("success!")
Else
'Failure :(
MsgBox("failure!")
End If
End Sub
Private Function ExecuteSoap(Of TResult)(func As Func(Of DSAPIServiceSoapClient, TResult), authorizationString As String) As TResult
Using client As New DocuService.DSAPIServiceSoapClient(My.Settings.DocusignMode)
Using scope As OperationContextScope = New System.ServiceModel.OperationContextScope(client.InnerChannel)
Dim hp As HttpRequestMessageProperty = New HttpRequestMessageProperty
hp.Headers.Add("X-Docusign-Authentication", authorizationString)
OperationContext.Current.OutgoingMessageProperties(HttpRequestMessageProperty.Name) = hp
Return If(func IsNot Nothing, func(client), Nothing)
End Using
End Using
End Function
We use the same ExecuteSOAP function and AuthorizationString to create & send envelops, and do recipient updates so I know these are correct. I'm not sure whats wrong!
This is most likely 1 of 3 possibilities.
I'm surprised its not error-ing out, but you should not be putting your accountId in the http auth header. See page 19 the SOAP PDF guide:
http://www.docusign.com/sites/default/files/DocuSignAPI_Guide.pdf
There is something else not configured correctly with your SOAP API call. Inspect your raw outgoing request and ensure the xml is what you expect. Post the raw request here if not sure.
A bug with DocuSign. First rule out the other two options and if no dice still post a comment here and I can get a bug logged on DocuSign's side. Also a good test would be to make the correction call through the REST api to see if you can get that to work.

Use Api / read api return values

Im using api from SMS provider .
Dim url As String
url = "http://weburl.jsp?usr=abc&pass=def&msisdn=95786123384645&sid=ABC&msg=welcome&mt=0"
webbrowser1.navigate(url)
The url i got from provider. Is there any other better way of sending sms using api ?
there is also api for balance which returns balance. Now i want to put this balance in label. How to do this?
http://weburl/CreditCheck.jsp?usr=abc&pass=def
Copy pasting above on browser displays balance but i want this to be in label.
Im using vb.net 2008 windows app,
Thanks in advance.
You can use HttpWebRequest and HttpWebResponse, something like this...
Dim sUrl As String = "http://weburl/CreditCheck.jsp?usr=abc&pass=def"
Dim wRequest As HttpWebRequest = DirectCast(System.Net.HttpWebRequest.Create(sUrl), HttpWebRequest)
wRequest.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials 'Not always needed
wRequest.Method = "GET"
Dim wResponse As HttpWebResponse = DirectCast(wRequest.GetResponse(), HttpWebResponse)
Dim sResponse As String = ""
Using srRead As New StreamReader(wResponse.GetResponseStream())
sResponse = srRead.ReadToEnd()
End Using
You will then need to parse the result to extract your balance

vb.net problems posting to web form

I've hit a wall on POST'ing data to a webform :(
Below is the code I've adapted from many places (here most recently: http://p2p.wrox.com/asp-net-1-0-1-1-professional/34517-webrequest-webresponse-form-submit-problem-help.html )
Dim url As String = "https://student.ashford.edu/student/"
Dim data As String = "username=myusername&password=mypassword"
Dim buffer As Byte() = Encoding.UTF8.GetBytes(data)
Dim result As String = ""
Dim req As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"
req.ContentLength = buffer.Length
req.CookieContainer = New CookieContainer()
' enable cookies
Dim reqst As Stream = req.GetRequestStream()
' add form data to request stream
reqst.Write(buffer, 0, buffer.Length)
reqst.Flush()
reqst.Close()
Console.WriteLine(vbLf & "Posting data to " & url)
Dim res As HttpWebResponse = DirectCast(req.GetResponse(), HttpWebResponse)
' send request,get response
Console.WriteLine(vbLf & "Response stream is: " & vbLf)
Dim resst As Stream = res.GetResponseStream()
' display HTTP response
Dim sr2 As New StreamReader(resst)
result = sr2.ReadToEnd()
Using writer As System.IO.StreamWriter = New StreamWriter("C:\Temp\checkcheck.html")
writer.Write(result)
End Using
When I check the checkcheck.html file, it doesn't show the page I normally see when I've successfully logged into my university, but instead shows the login page again prompting for a user name and password. Since it's prompting for a user/pass in the output response, does that mean nothing is posted? Or is the login button not being hit?
As far as the field names in the source, the name of the username field is "username", and the name of the password field is "password". From what I can tell, the name of the login button itself is "submit". Below is the source of the page, am I missing something?
view-source:https://student.ashford.edu/student/
https://student.ashford.edu/student/
What I want to have happen is that in my VB.NET backend, I click a button and my username and password are automatically entered and I am automagically logged in. Once the login is done, I want to retrieve the HTML of the logged in page so I can parse it for items relating to my studies. This may be unrelated, but do I need cookies to keep my application "logged in" if I navigate to other pages?
EDIT:
I tried plugging different URL's, to no avail. I have also tried adding submit=login and login=submit (alternately of course) to the POST data. I'm still getting the original login screen HTML from the result variable at the end, instead of my university homepage that I'm expecting after I normally login by hand as a human would. Maybe there is a follow up step that I am missing?
The actual form action is at https://student.ashford.edu/login/commands/login.php. You might plug that into url instead. Also, try including the submit button - submit=login - in the values.
I found out what I needed to do. First I have to make sure that I have a cookie container. Next, I used Fiddler to find out EXACTLY what is being sent back and forth between my browser and where I want to login. I post all the login info, and I get the response back. This seems to fill up my cookie container variable with the required authentication cookies? Next I make another POST request to the page I want to go to, and voila - it works.