public static void InitCertificateValidationCallback()
{
ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback(ValidateServerCertificate);
}
static bool ValidateServerCertificate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
iOS인앱 결제 후 영수증 검증 루틴이다.
첨부된 JSON라이브러리를 c#프로젝트의 참조에 추가할 필요가 있다.
VerifyIOSReceipt 메소드의 리턴값을 판별해서
처리하면된다.
IOS_RV_SUCCESS = 영수증 검증 성공
IOS_RV_FAIL_RETRY = 영수증 검증에 실패 했다, 샌드박스모드에서 다시 검증이 필요하다.
IOS_RV_FAIL = 유효하지 않은 영수증이다.
using System.Text;
using System.Net;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
public class CIOSReceiptVerificationMng
{
public const string IOS_PRODUCT_URL = "https://buy.itunes.apple.com/verifyReceipt";
public const string IOS_SENDBOX_URL = "https://sandbox.itunes.apple.com/verifyReceipt";
public const int IOS_RV_SUCCESS = 0; //ios영수증 검증 결과 성공
public const int IOS_RV_FAIL_RETRY = 1; //샌드박스에서 재검증필요
public const int IOS_RV_FAIL = -1; //검증 실패
/*ios영수증 검증
itemID = 해당 영수증으로 결제한 아이템의 ID
receiptData = 영수증 데이터
bProduct = 프로덕트에서 검증할지 샌드박스에서 검증할지, 기본적으로 프로덕트에서 검증하고 리턴값이 IOS_RV_FAIL_RETRY 인경우에 샌드박스에서 검증한다.
*/
public static int VerifyIOSReceipt(ref string itemID, string receiptData, bool bProduct)
{
try
{
itemID = null;
// Verify the receipt with Apple
string postString = string.Format("{{ \"receipt-data\" : \"{0}\" }}", receiptData);
ASCIIEncoding ascii = new ASCIIEncoding();
byte[] postBytes = ascii.GetBytes(postString);
HttpWebRequest request;
if (bProduct)
request = WebRequest.Create(IOS_PRODUCT_URL) as HttpWebRequest;
else
request = WebRequest.Create(IOS_SENDBOX_URL) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = postBytes.Length;
Stream postStream = request.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Close();
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[8192];
Stream resStream = response.GetResponseStream();
string tempString = null;
int count = 0;
do
{
count = resStream.Read(buf, 0, buf.Length);
if (count != 0)
{
tempString = Encoding.ASCII.GetString(buf, 0, count);
sb.Append(tempString);
}
} while (count > 0);
var fd = JObject.Parse(sb.ToString());
try
{
resStream.Close();
response.Close();
}
catch
{
}
string strResult = fd["status"].ToString();
// Receipt not valid
if (strResult != "0")
{
if (strResult == "21007")
return IOS_RV_FAIL_RETRY;
// Error out
return IOS_RV_FAIL;
}
// Product ID does not match what we expected
var receipt = fd["receipt"];
/*
if (String.Compare(receipt["product_id"].ToString().Replace("\"", "").Trim(), itemID.Trim(), true) != 0)
{
// Error out
return IOS_RV_FAIL;
}
* */
//제품 ID정보를 저장함
itemID = receipt["product_id"].ToString().Replace("\"", "").Trim();
// This product was not sold by the right app
if (String.Compare(receipt["bid"].ToString().Replace("\"", "").Trim(), PACKAGE_NAME, true) != 0)
{
// Error out
return IOS_RV_FAIL;
}
/*
// This transaction didn't occur within 24 hours in either direction; somebody is reusing a receipt
DateTime transDate = DateTime.SpecifyKind(DateTime.Parse(receipt["purchase_date"].ToString().Replace("\"", "").Replace("Etc/GMT", "")), DateTimeKind.Utc);
TimeSpan delay = DateTime.UtcNow - transDate;
if (delay.TotalHours > 24 || delay.TotalHours < -24)
{
// Error out
return false;
}
*/
// Perform the purchase -- all my purchases are server-side only, which is a very secure way of doing things
// Success!
}
catch// (Exception ex)
{
// We crashed and burned -- do something intelligent
return IOS_RV_FAIL;
}
return IOS_RV_SUCCESS;
}
}
'iOS' 카테고리의 다른 글
앱스토어 가이드라인 (0) | 2015.10.10 |
---|---|
iOS사파리 브라우져를 열어서 특정 사이트로 이동 (0) | 2014.05.05 |