Invalid signature error with UpgradeableApp API - google-oauth

I am trying to run a code that would allow me to migrate Google Apps Marketplace to upgrade my apps to use OAuth 2.0 authentication for subscribed domains.
Unfortunately, I receive the following error message:
{"error":{"errors":[{"domain":"global","reason":"authError","message":"Invalid OAuth signature","locationType":"header","location":"Authorization"}],"code":401,"message":"Invalid OAuth signature"}}
The code that I run is:
final String consumerKey = "xxx";
final String consumerSecret = "yyy";
final String domain = "example.com";
final String account = "admin#example.com";
OAuthParameters oauthParameters = new OAuthParameters();
oauthParameters.setOAuthConsumerKey(consumerKey);
oauthParameters.setOAuthConsumerSecret(consumerSecret);
OAuthHmacSha1Signer signer = new OAuthHmacSha1Signer();
final String marketPlaceListingId = "xxxx+xxxxxxxxxxxxxxxxxxx";
final String chromeWebStoreItemId = "yyyyyyyyyyyyyyyyyyyyyyyyyyyy";
String requestUrl = "https://www.googleapis.com/appsmarket/v2/upgradableApp/"
+ marketPlaceListingId + "/" + chromeWebStoreItemId + "/" + domain;
String oauth_nonce = OAuthUtil.getNonce();
String oauth_timestamp = OAuthUtil.getTimestamp().toString();
String signatureMethod = "HMAC-SHA1";
oauthParameters.setOAuthType(OAuthType.TWO_LEGGED_OAUTH);
oauthParameters.setOAuthNonce(oauth_nonce);
oauthParameters.setOAuthTimestamp(oauth_timestamp);
oauthParameters.setOAuthSignatureMethod(signatureMethod);
String baseString = "PUT"
+ "&" + OAuthUtil.encode(requestUrl)
+ "&" + OAuthUtil.encode("oauth_consumer_key=" + oauthParameters.getOAuthConsumerKey()
+ "&oauth_nonce=" + oauth_nonce
+ "&oauth_signature_method=" + signatureMethod
+ "&oauth_timestamp=" + oauth_timestamp
+ "&oauth_version=1.0"
+ "&xoauth_requestor_id=" + OAuthUtil.encode(account));
String oauth_signature = signer.getSignature(baseString, oauthParameters);
oauthParameters.setOAuthSignature(oauth_signature);
OAuthHelper oauthHelper = new GoogleOAuthHelper(signer);
String header = oauthHelper.getAuthorizationHeader(requestUrl + "?xoauth_requestor_id=" + OAuthUtil.encode(account), "PUT", oauthParameters);
HttpClient httpClient = new DefaultHttpClient();
HttpPut httpPut = new HttpPut(requestUrl + "?xoauth_requestor_id=" + OAuthUtil.encode(account));
httpPut.addHeader("Authorization", header);
//httpPut.addHeader("Content-Type", "application/x-www-form-urlencoded");
HttpResponse response = null;
try {
response = httpClient.execute(httpPut);
} catch (Exception e) {
System.out.println(e.getMessage());
throw new ServletException(e);
}
Please support.
Thank you,
Evgeny

Related

How do I call Pay U Money Server through WCF?

i am creating a wcf service for Pay u Money I wrote same code like asp.net c# for Pay u Money, but using HttpWebRequest I'm facing this error:
SORRY! We were unable to process your payment
Same code I tried in simple asp.net c# and there working fine. Here I don't know what goes wrong, how could I solve this?
enter code here
public PayUMoneyModel PayUMoney(PayUMoneyModel Data)
{
PayUMoneyModel objPayUMoneyModel = new PayUMoneyModel();
action1 = ConfigurationManager.AppSettings["PAYU_BASE_URL"] +
"/_payment";
try
{
string[] hashVarsSeq;
string hash_string = string.Empty;
if (string.IsNullOrEmpty(Data.txnid)) // generating txnid
{
Random rnd = new Random();
string strHash = Generatehash512(rnd.ToString() +
DateTime.Now);
txnid1 = strHash.ToString().Substring(0, 20);
}
else if(Data.txnid!=null)
{
txnid1 = Data.txnid;
}
Data.txnid = txnid1;
Data.key= ConfigurationManager.AppSettings["MERCHANT_KEY"];
string salt= ConfigurationManager.AppSettings["SALT"];
System.Collections.Hashtable data = new System.Collections.Hashtable();
data.Add("key", Data.key);
data.Add("txnid", Data.txnid);
string AmountForm = Convert.ToDecimal(Data.amount).ToString("g29");// eliminating trailing zeros
//amount.Text = AmountForm;
data.Add("amount", 1.00);
data.Add("firstname", Data.firstname);
data.Add("email", Data.email);
data.Add("phone", Data.phone);
data.Add("productinfo", Data.productinfo);
data.Add("surl", Data.surl);
data.Add("furl", Data.furl);
data.Add("lastname", Data.lastname);
data.Add("curl", Data.curl);
data.Add("address1", Data.address1);
data.Add("address2", Data.address2);
data.Add("city", Data.city);
data.Add("state", Data.state);
data.Add("country",Data.country);
data.Add("zipcode", Data.zipcode);
data.Add("udf1", Data.udf1);
data.Add("udf2", Data.udf2);
data.Add("udf3", Data.udf3);
data.Add("udf4", Data.udf4);
data.Add("udf5", Data.udf5);
data.Add("pg", Data.pg);
data.Add("service_provider", "payu_paisa");
hash_string = Data.key + "|" + Data.txnid + "|" + AmountForm + "|" + Data.productinfo+ "|" + Data.firstname + "|" + Data.email + "|||||||||||" + salt;
string hash = Generatehash512(hash_string);
data.Add("hash", hash);
data.Add("abc", hash_string);
string strForm = PreparePOSTForm(action1, data);
if (strForm != "")
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(action1);
// httpWebRequest.ContentType = "text/html";
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.Method = "POST";
httpWebRequest.ContentLength = strForm.Length;
string Json = "";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(strForm,0,strForm.Length);
streamWriter.Flush();
streamWriter.Close();
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
Json = streamReader.ReadToEnd().Replace(";", "");
}
}
HttpContext.Current.Response.Write(Json);
}
}
catch(Exception ex)
{
throw ex;
}
return objPayUMoneyModel;
}
this is my Post Form Method
private string PreparePOSTForm(string url, System.Collections.Hashtable data) // post form
{
//Set a name for the form
string formID = "PostForm";
//Build the form using the specified data to be posted.
StringBuilder strForm = new StringBuilder();
strForm.Append("<form id=\"" + formID + "\" name=\"" +
formID + "\" action=\"" + url +
"\" method=\"POST\">");
foreach (System.Collections.DictionaryEntry key in data)
{
strForm.Append("<input type=\"hidden\" name=\"" + key.Key +
"\" value=\"" + key.Value + "\">");
}
strForm.Append("</form>");
//Build the JavaScript which will do the Posting operation.
StringBuilder strScript = new StringBuilder();
strScript.Append("<script language='javascript'>");
strScript.Append("var v" + formID + " = document." +
formID + ";");
strScript.Append("v" + formID + ".submit();");
strScript.Append("</script>");
//Return the form and the script concatenated.
//(The order is important, Form then JavaScript)
return strForm.ToString() + strScript.ToString();
}
this is my key and salt provided by Payumoney website:-
Key:-rjQUPktU
Salt:-e5iIg1jwi8

CloudStack: Unable to verify user credentials and/or request signature

I am working on CloudStack API now and I have the problem about making the API request. I always got "{ "listtemplatesresponse" : {"errorcode":401,"errortext":"unable to verify user credentials and/or request signature"} }" even though I change the parameter.
This error occurs in some commands that require the parameter and this is the command that I use:
command=listTemplates&templatefilter=featured
I don't know what I did wrong since it works with others. Here is the code I use to make the API request:
try {
String encodedApiKey = URLEncoder.encode(apiKey.toLowerCase(), "UTF-8");
ArrayList<String> sortedParams = new ArrayList<String>();
sortedParams.add("apikey="+encodedApiKey);
StringTokenizer st = new StringTokenizer(apiUrl, "&");
while (st.hasMoreTokens()) {
String paramValue = st.nextToken().toLowerCase();
String param = paramValue.substring(0, paramValue.indexOf("="));
String value = URLEncoder.encode(paramValue.substring(paramValue.indexOf("=")+1, paramValue.length()), "UTF-8");
sortedParams.add(param + "=" + value);
}
Collections.sort(sortedParams);
System.out.println("Sorted Parameters: " + sortedParams);
String sortedUrl = null;
boolean first = true;
for (String param : sortedParams) {
if (first) {
sortedUrl = param;
first = false;
} else {
sortedUrl = sortedUrl + "&" + param;
}
}
sortedUrl += "&response=json";
System.out.println("sorted URL : " + sortedUrl);
String encodedSignature = signRequest(sortedUrl, secretKey);
String finalUrl = host + "?" + apiUrl + "&response=json&apiKey=" + apiKey + "&signature=" + encodedSignature;
StringBuilder str = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(finalUrl);
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) { // Status OK
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
str.append(line);
}
System.out.println("str: "+str);
result = str.toString();
System.out.println("result: "+str);
}
else
System.out.println("Error response!!");
} catch (Throwable t) {
System.out.println(t);
}
And this is signRequest function:
public static String signRequest(String request, String key) {
try {
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacSHA1");
mac.init(keySpec);
mac.update(request.getBytes());
byte[] encryptedBytes = mac.doFinal();
return URLEncoder.encode(Base64.encodeBytes(encryptedBytes), "UTF-8");
} catch (Exception ex) {
System.out.println(ex);
}
return null;
}
Please feel free to ask me if you need more information. All comments and advice are welcome!
Have you tried sorting after you've added "&response=json" to the list of parameters?
E.g.
try {
String encodedApiKey = URLEncoder.encode(apiKey.toLowerCase(), "UTF-8");
ArrayList<String> sortedParams = new ArrayList<String>();
sortedParams.add("apikey="+encodedApiKey);
sortedParams.add("response=json");
StringTokenizer st = new StringTokenizer(apiUrl, "&");
while (st.hasMoreTokens()) {
String paramValue = st.nextToken().toLowerCase();
String param = paramValue.substring(0, paramValue.indexOf("="));
String value = URLEncoder.encode(paramValue.substring(paramValue.indexOf("=")+1, paramValue.length()), "UTF-8");
sortedParams.add(param + "=" + value);
}
Collections.sort(sortedParams);
System.out.println("Sorted Parameters: " + sortedParams);
String sortedUrl = null;
boolean first = true;
for (String param : sortedParams) {
if (first) {
sortedUrl = param;
first = false;
} else {
sortedUrl = sortedUrl + "&" + param;
}
}
System.out.println("sorted URL : " + sortedUrl);
String encodedSignature = signRequest(sortedUrl, secretKey);
String finalUrl = host + "?" + apiUrl + "&response=json&apiKey=" + apiKey + "&signature=" + encodedSignature;
StringBuilder str = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(finalUrl);
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) { // Status OK
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
str.append(line);
}
System.out.println("str: "+str);
result = str.toString();
System.out.println("result: "+str);
}
else
System.out.println("Error response!!");
} catch (Throwable t) {
System.out.println(t);
}
Your API Key and Response parameters need to be part of the sorted Url used when signing, which they appear to be.
try changing
return URLEncoder.encode(Base64.encodeBytes(encryptedBytes), "UTF-8");
to
return URLEncoder.encode(Base64.encodeAsString(encryptedBytes), "UTF-8");

Paypal IPN cannot send to my MVC 4 controller action

I try to get IPN message from my MVC Controller action but IPN cannot send to my action controller
The following is my controller action :
string strLive = "https://www.paypal.com/cgi-bin/webscr";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strLive);
//Set values for the request back
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
byte[] Param = Request.BinaryRead(HttpContext.Request.ContentLength);
string strRequest = Encoding.ASCII.GetString(Param);
strRequest = strRequest + "&cmd=_notify-validate";
req.ContentLength = strRequest.Length;
//for proxy
//Dim proxy As New WebProxy(New System.Uri("http://url:port#"))
//req.Proxy = proxy
//Send the request to PayPal and get the response
StreamWriter streamOut = new StreamWriter(req.GetRequestStream(), Encoding.ASCII);
streamOut.Write(strRequest);
streamOut.Close();
StreamReader streamIn = new StreamReader(req.GetResponse().GetResponseStream());
string strResponse = streamIn.ReadToEnd();
streamIn.Close();
if (strResponse == "VERIFIED") {
//check the payment_status is Completed
//check that txn_id has not been previously processed
//check that receiver_email is your Primary PayPal email
//check that payment_amount/payment_currency are correct
//process payment
} else if (strResponse == "INVALID") {
//log for manual investigation
} else {
//Response wasn't VERIFIED or INVALID, log for manual investigation
}
The following is paypal information I used :
<add key="paypalAccount" value="abc#abc.com" />
<add key="PayPalSubmitUrl" value="https://www.paypal.com/cgi-bin/webscr"/>
<add key="PDTToken" value="asdfwlfti2Rc_Kskwsdfc7uK26FmT1pdAkhSdLb8FvS2kQ-ZQp6VoF2SqYem"/>
<add key="FromMail" value="myat#abc.com"/>
<add key="return_Url" value="http://testing/Purchase/PayPalResult"/>
<add key="cancel_return" value="http://testing/Purchase/Purchase"/>
<add key="notify_url" value="http://testing/Purchase/PayPalPaymentNotification"/>
<add key="Test_Live" value="live"/>
<add key="BCC" value="myat#abc.com"/>
But in paypal IPN message is still retrying and I didn't receive anything
I notice that HttpContext.Request.ContentLength is always 0 and response status for paypal is always is INVALID
So please advice me what should I do?
Thank you
This is my full action to get IPN message
public ActionResult PayPalPaymentNotification()
{
string strLog = "";
string currentTime = "";
currentTime = DateTime.Now.Day.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Year + "|" + DateTime.Now.TimeOfDay.Hours.ToString() + ":" + DateTime.Now.TimeOfDay.Minutes.ToString() + ":" + DateTime.Now.TimeOfDay.Seconds.ToString();
strLog = "Insert into CPLog(Log,LogTime) values('Start IPN request','" + currentTime + "')";
InsertData(strLog);
string strLive = "https://www.paypal.com/cgi-bin/webscr";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strLive);
//Set values for the request back
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
byte[] Param = Request.BinaryRead(HttpContext.Request.ContentLength);
string strRequest = Encoding.ASCII.GetString(Param);
strRequest = strRequest + "&cmd=_notify-validate";
req.ContentLength = strRequest.Length;
//for proxy
//Dim proxy As New WebProxy(New System.Uri("http://url:port#"))
//req.Proxy = proxy
//Send the request to PayPal and get the response
StreamWriter streamOut = new StreamWriter(req.GetRequestStream(), Encoding.ASCII);
streamOut.Write(strRequest);
streamOut.Close();
StreamReader streamIn = new StreamReader(req.GetResponse().GetResponseStream());
string strResponse = streamIn.ReadToEnd();
streamIn.Close();
if (strResponse == "VERIFIED")
{
//check the payment_status is Completed
//check that txn_id has not been previously processed
//check that receiver_email is your Primary PayPal email
//check that payment_amount/payment_currency are correct
//process payment
currentTime = DateTime.Now.Day.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Year + "|" + DateTime.Now.TimeOfDay.Hours.ToString() + ":" + DateTime.Now.TimeOfDay.Minutes.ToString() + ":" + DateTime.Now.TimeOfDay.Seconds.ToString();
strLog = "Insert into CPLog(Log,LogTime) values('Status - Verified','" + currentTime + "')";
InsertData(strLog);
}
else if (strResponse == "INVALID")
{
//log for manual investigation
currentTime = DateTime.Now.Day.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Year + "|" + DateTime.Now.TimeOfDay.Hours.ToString() + ":" + DateTime.Now.TimeOfDay.Minutes.ToString() + ":" + DateTime.Now.TimeOfDay.Seconds.ToString();
strLog = "Insert into CPLog(Log,LogTime) values('Status - Invalid','" + currentTime + "')";
InsertData(strLog);
}
else
{
//Response wasn't VERIFIED or INVALID, log for manual investigation
}
currentTime = DateTime.Now.Day.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Year + "|" + DateTime.Now.TimeOfDay.Hours.ToString() + ":" + DateTime.Now.TimeOfDay.Minutes.ToString() + ":" + DateTime.Now.TimeOfDay.Seconds.ToString();
strLog = "Insert into CPLog(Log,LogTime) values('Finish IPN Request','" + currentTime + "')";
InsertData(strLog);
return View();
}
Your return URL isn't right - the message can never be returned.
Add [AllowAnonymous] above the controller action.
Paypal needs to know the URL of your listener service that indicates where the IPNs need to go. You must review the IPN Notification section on your Paypal account and set the URL.
For this you can review the following section: Paypal developer and set the notifications URL.
After that you must have a payment notification to recieve.
My recomendation is first use the Paypal developer section with Sandbox whis is king of fake account that you can use for testing this application.

REST Update Recipient Email using PUT Method

I am new to REST and keep getting the Bad Request 400 Response with the code below:
I have the standard baseURL and authenticateStr from the other sample...
_recipientID, pNewEmail, pNewName and pNewRoutingOrder are passed in as parameters to the procedures.
string envDef = "<envelopeDefinition xmlns=\"http://www.docusign.com/restapi\">" +
"<signers>" +
"<signer>" +
"<recipientId>" + _recipientId + "</recipientId>" +
"<email>" + pNewEmail + "</email>" +
"<name>" + pNewName + "</name>" +
"<routingOrder>" + pNewRoutingOrder + "</routingOrder>" +
"</signer>" +
"</signers>" +
"</envelopeDefinition>";
url = baseURL + "/envelopes/" + pEnvelopeID + "/recipients";
request = (HttpWebRequest)WebRequest.Create(url);
request.Headers.Add("X-DocuSign-Authentication", authenticateStr);
request.ContentType = "application/xml";
request.Accept = "application/xml";
request.ContentLength = envDef.Length;
request.Method = "PUT";
// write the body of the request
byte[] body = System.Text.Encoding.UTF8.GetBytes(envDef);
Stream dataStream = request.GetRequestStream();
dataStream.Write(body, 0, envDef.Length);
dataStream.Close();
// read the response
webResponse = (HttpWebResponse)request.GetResponse();
sr.Close();
responseText = "";
sr = new StreamReader(webResponse.GetResponseStream());
responseText = sr.ReadToEnd();
Ok just figured out how to do this. Here's an XML request body that can be used to update the email and name of a recipient, for instance. I just verified that this works!
<recipients xmlns="http://www.docusign.com/restapi">
<signers>
<signer>
<recipientId>1</recipientId>
<email>email#docusign.com</email>
<name>Joe Mama</name>
</signer>
</signers>
</recipients>

HttpWebRequest works. WebClient.UploadFile doesn't

I thought I figured out a way to simplify my code by using WebClient.UploadFile instead of HttpWebRequest, but I end up getting a file on the server end that is a few dozen bytes too short and corrupted. Any idea where the bug lies?
Thanks
Using HttpWebRequest (works fine):
HttpWebRequest req = (HttpWebRequest)HttpWebRequest
.Create("http://" +
ConnectionManager.FileServerAddress + ":" +
ConnectionManager.FileServerPort +
"/binary/up/" + category + "/" +
Path.GetFileName(filename) + "/" + safehash);
req.Method = "POST";
req.ContentType = "binary/octet-stream";
req.AllowWriteStreamBuffering = false;
req.ContentLength = bytes.Length;
Stream reqStream = req.GetRequestStream();
int offset = 0;
while (offset < ____)
{
reqStream.Write(bytes, offset, _________);
_______
_______
_______
}
reqStream.Close();
try
{
HttpWebResponse resp = (HttpWebResponse) req.GetResponse();
}
catch (Exception e)
{
_____________
}
return safehash;
Using WebClient (corrupt file on server end):
var client = new WebClient();
client.Encoding = Encoding.UTF8;
client.Headers.Add(HttpRequestHeader.ContentType, "binary/octet-stream");
client.UploadFile(new Uri("http://" +
ConnectionManager.FileServerAddress + ":" +
ConnectionManager.FileServerPort +
"/binary/up/" + category + "/" +
Path.GetFileName(filename) + "/" + safehash), filename);
return safehash;
Server side is a WCF service:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "up/file/{fileName}/{hash}")]
void FileUpload(string fileName, string hash, Stream fileStream);
WebClient.UploadFile sends the data in a multipart/form-data format. What you want to use to have the equivalent to the code using HttpWebRequest is the WebClient.UploadData method:
var client = new WebClient();
client.Encoding = Encoding.UTF8;
client.Headers[HttpRequestHeader.ContentType] = "application/octet-stream";
byte[] fileContents = File.ReadAllBytes(filename);
client.UploadData(new Uri("http://" + ConnectionManager.FileServerAddress + ":" +
ConnectionManager.FileServerPort +
"/binary/up/" + category + "/" +
Path.GetFileName(filename) + "/" + safehash), fileContents);