Strange Status Code From Apple Receipt Verification Sandbox - iphone

I make a post request of base64 encoded data to the receipt verification address as follows (this is in C#):
var postSerializer = new JavaScriptSerializer();
byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(Receipt);
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
var temp = new Dictionary<string, string>();
temp.Add("receipt-data", returnValue);
string jsonReceipt = postSerializer.Serialize(temp);
request.Method = "POST";
request.ContentType = "application/json";
byte[] postBytes = System.Text.Encoding.ASCII.GetBytes(jsonReceipt);
request.ContentLength = postBytes.Length;
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(postBytes, 0, postBytes.Length);
// Close the Stream object.
dataStream.Close();
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
I'm pretty sure things are in the right format because I'm not getting any exceptions back
from the apple receipt verification endpoint. The entirety of the response I get back is
{status : -42352}
And I can't find out what this error means anywhere. Does anyone know what this means or if there's an error in my code?

Just solved the same problem. Got the solution from here: Verify receipt for in App purchase
The problem was in post encoding. When I encoded post on my server using
$receipt = json_encode(array("receipt-data" => base64_encode($receiptdata)));
I had the same -42352 status. When I used my own function for encoding on iPhone - everything worked! Magic...

Related

StreamReader reads \u00fc but Postman reads OK

Probably duplicate question but I couldn't find an answer for my problem. I have this code to call a web service:
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://172.21.122.1:5001/autocomplete");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
//tried this too: httpWebRequest.Accept = "gzip, deflate";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write("{ \"message\" : \"mü\" }");
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
response = "";
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
response = streamReader.ReadToEnd();
}
But no matter what Encoding I tried with StreamReader() c'tor, I get this response or worse: {"words":["m\u00fc\u015fteri","m\u00fc\u015fterisiyim""]}
When I use Postman or SoapUI to call the same service with the same request: {"message": "mü"},
response looks ok: {"words": ["müşteri","müşterisiyim"]}
Strange thing is: The same code works OK with many other services. It is only this specific service that the reponse is not correctly encoded. We believe there is a programming error with the service, but what I wonder is how Postman or SoapUI handles this. There should be a control in their code and if the response contains "\uxxxx", then Postman or SoapUI decodes it again.
I've checked all request / response headers in Postman and SoapUI with no luck. What can be the reason?
You have to make sure that your request is encoded correctly:
Set the Content Type to:
httpWebRequest.ContentType = "application/json;charset=UTF-8";
Check if request body is also UTF-8 encoded. Set the StreamWriter encoding to UTF-8 as well:
...
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream(), Encoding.UTF8))
...
If you are getting the request content from other source, make sure to read it also using UTF-8 encoding.
Regex.Unescape(response) worked like a charm, thanks JosefZ!

Get SOAP Reply in ASP.NET Webservice

I created a SOAP WebService to receive a request. I want to log the SOAP messages with envelope.
I discovered how get the request message, but I don't discovered how can I get the reply message.
To get the XML Request, I use the code below.
// Create array for holding request in bytes
byte[] inputStream = new byte[HttpContext.Current.Request.ContentLength];
// Read the entire request input stream
HttpContext.Current.Request.InputStream.Read(inputStream, 0, inputStream.Length);
// Set stream position back to beginning
HttpContext.Current.Request.InputStream.Position = 0;
// Get the XML request
string xmlRequestString = Encoding.UTF8.GetString(inputStream);
To get the reply, I tried do this into the Dispose method, but I couldn't make it work.
The InputStream works fine.
The Request SOAP XML I get propertelly. I need a way to get de SOAP XML that my web method replay to the caller. Into the WebMethod the Response is not complet. So I tried use the Dispose Method, but I have the same problem. The dispose method is call before .Net Framework return the reply to caller.
I need a way to log the SOAP XML Request abd the SOAP XML Replay.
The code below get XML Request fine:
[WebMethod]
public ActivityCCPResponseOutput Request(ActivityCCPRequestInput ActivityCCPRequestInput)
{
XmlDocument xmlSoapRequest = new XmlDocument();
Stream receiveStream = HttpContext.Current.Request.InputStream;
receiveStream.Position = 0;
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
xmlSoapRequest.Load(readStream);
string xmlSOAPRequest = xmlSoapRequest.InnerXml;
...
}
In the code below, I couldn't get the reply. Probably, there is a different way to do this.
void IDisposable.Dispose()
{
XmlDocument xmlSoapResponse = new XmlDocument();
// In this point HttpContext.Current.Response.OutputStream is empty
Stream responseStream = HttpContext.Current.Response.OutputStream;
responseStream.Position = 0;
StreamReader readStream = new StreamReader(responseStream, Encoding.UTF8);
xmlSoapResponse.Load(readStream);
string xmlSOAPReply = xmlSoapResponse.InnerXml;
}

Azure REST WebClient PUT Blob

I'm trying to simply upload a new blob to an Azure Storage countainer using WebClient like this :
var sas = "[a new generated sas with Read, Write, List & Delete permissions]";
var sData = "This is a test!";
var sEndPoint = "http://myaccount.blob.core.windows.net/mycontainer/MyTest.txt" + sas;
var clt = new WebClient();
var res = await clt.UploadStringTaskAsync(sEndPoint, "PUT", sData);
This is giving me a "(400) Bad Request." error. Am I doing anything wrong here?
Thanks
(By the way, I need to use REST instead of Client API since I'm in a Silverlight project)
You would need to define a request header (x-ms-blob-type) for blob type and set it's value to BlockBlob. Also for Put requests you would need to define the Content-Length request header as well. I wrote a blog post on Shared Access Signatures and performing some blob operations using that (with both REST API and Storage Client library) which you can read here: http://gauravmantri.com/2013/02/13/revisiting-windows-azure-shared-access-signature/.
and here's the code from that post on uploading blob. It uses HttpWebRequest/HttpWebResponse instead of WebClient:
static void UploadBlobWithRestAPISasPermissionOnBlobContainer(string blobContainerSasUri)
{
string blobName = "sample.txt";
string sampleContent = "This is sample text.";
int contentLength = Encoding.UTF8.GetByteCount(sampleContent);
string queryString = (new Uri(blobContainerSasUri)).Query;
string blobContainerUri = blobContainerSasUri.Substring(0, blobContainerSasUri.Length - queryString.Length);
string requestUri = string.Format(CultureInfo.InvariantCulture, "{0}/{1}{2}", blobContainerUri, blobName, queryString);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
request.Method = "PUT";
request.Headers.Add("x-ms-blob-type", "BlockBlob");
request.ContentLength = contentLength;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(Encoding.UTF8.GetBytes(sampleContent), 0, contentLength);
}
using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
}
}
When testing against the blob emulator this is the code I need to get it working:
var connection = ConfigurationManager.AppSettings["AzureStorageConnectionString"];
var storageAccount = CloudStorageAccount.Parse(connection);
var client = new WebClient();
client.Headers.Add("x-ms-blob-type", "BlockBlob");
client.Headers.Add("x-ms-version", "2012-02-12");
client.UploadData(string.Format(#"{0}/$root/{1}{2}", storageAccount.BlobEndpoint, myFileName, sharedAccessSignature), "PUT", _content);

Set Express Checkout method returning an failure in the ack

I want to do the express checkout process in the paypal for the customers without redirecting the browser. I have written the code like
string sAPIUser = apiuser;
string sAPIPassword = password;
string sAPISignature = "signature";
string sAPIEndpoint = "https://api-3t.sandbox.paypal.com/nvp";
string sAppID = "APP-80W284485P519543T";
StringBuilder sRequest = new StringBuilder();
ASCIIEncoding encoding = new ASCIIEncoding();
string postData = ("&METHOD=SetExpressCheckout");
postData += ("&VERSION=63.0");
postData += ("&PAYMENTREQUEST_0_AMT=10.00");
postData += ("&PAYMENTREQUEST_0_CURRENCYCODE=USD");
postData += ("&PAYMENTREQUEST_0_PAYMENTACTION=Sale");
postData += ("CANCELURL=http://www.google.com");
postData += ("RETURNURL=http://www.google.com");
byte[] data = encoding.GetBytes(postData);
// Prepare web request...
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(sAPIEndpoint);
myRequest.Method = "POST";
myRequest.Headers.Add("X-PAYPAL-SECURITY-USERID", sAPIUser);
myRequest.Headers.Add("X-PAYPAL-SECURITY-PASSWORD", sAPIPassword);
myRequest.Headers.Add("X-PAYPAL-SECURITY-SIGNATURE", sAPISignature);
myRequest.Headers.Add("X-PAYPAL-SERVICE-VERSION", "1.3.0");
myRequest.Headers.Add("X-PAYPAL-REQUEST-DATA-FORMAT", "NV");
myRequest.Headers.Add("X-PAYPAL-RESPONSE-DATA-FORMAT", "NV");
myRequest.Headers.Add("X-PAYPAL-APPLICATION-ID", sAppID);
myRequest.ContentType = "application/x-www-form-urlencoded";
myRequest.ContentLength = data.Length;
// Send the request, read the response
Stream newStream = myRequest.GetRequestStream();
newStream.Write(data, 0, data.Length);
newStream.Close();
HttpWebResponse response = (HttpWebResponse)myRequest.GetResponse();
Stream responseStream = response.GetResponseStream();
Encoding encoding2 = Encoding.GetEncoding("utf-8");
StreamReader reader = new StreamReader(responseStream, encoding2);
string theResponse = reader.ReadToEnd();
theResponse = HttpUtility.HtmlDecode(theResponse);
But i am getting the failure message in the theResponse variable. What error i am doing. The error is like
TIMESTAMP=2013%2d03%2d05T05%3a55%3a38Z&CORRELATIONID=5c10035aca937&ACK=Failure&VERSION=63%2e0&BUILD=5331358&L_ERRORCODE0=10002&L_SHORTMESSAGE0=Authentication%2fAuthorization%20Failed&L_LONGMESSAGE0=You%20do%20not%20have%20permissions%20to%20make%20this%20API%20call&L_SEVERITYCODE0=Error
How can i rectify this.
Make sure that the credentials you are using are for your sandbox account and not your live account. Your code looks like it is pointing to the sandbox, so you would need to use your sandbox credentials. Also, if this is not all of your code, make sure you are not passing across a variable called "SUBJECT" and populating it with an email address.

How To URLEncode Facebook Post Data in C#

I am rewriting code from http://blog.blackballsoftware.com/2010/11/03/making-a-facebook-wall-post-using-the-new-graph-api-and-c/ to create a class to post to Facebook. The code works as long as I do not URLEncode the post data. For example: If the post data is "message=Test,please ignore" then it works. If I URLEncode the same data into "message%3dTest%2cplease+ignore" then I get the error {"error":{"message":"(#100) Missing message or attachment","type":"OAuthException","code":100}}.
Should the Post data be URLEncoded? I think it should because if I post a message like this, "Test&Message", then only the word Test appears.
Relevant code is below. If postParams = HttpUtility.UrlEncode(postParams); is commented out, then the code works. If not, Facebook returns the error that the message is missing.
postParams = HttpUtility.UrlEncode(postParams);
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(postParams);
webRequest.ContentLength = bytes.Length;
System.IO.Stream os = webRequest.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
try
{
var webResponse = webRequest.GetResponse();
}
catch (WebException ex)
{
StreamReader errorStream = null;
errorStream = new StreamReader(ex.Response.GetResponseStream());
error = errorStream.ReadToEnd() + postParams;
}
The answer can be found on Stackoverflow at C# Escape Plus Sign (+) in POST using HttpWebRequest. Use Uri.EscapeDataString and not URLEncode. Encode the parameter value only and not the equals sign after the parameter name. Example: message=Test%2Cplease%26%20ignore works but message%3dTest%2Cplease%26%20ignore does not work because the equals after the parameter name is encoded as %3d.