블로그 이미지
래머
오늘도 열심히 개발하는 개발자입니다.

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

2014. 5. 3. 23:52 iOS


유니티에서 사용하고자 하는경우 아래 코드를 추가하시고
InitCertificateValidationCallback()을 영수증 검증 루틴 실행전 한번 호출해줄필요가 있습니다.

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;

    }


}


Newtonsoft.Json.dll


Newtonsoft.Json.xml





'iOS' 카테고리의 다른 글

앱스토어 가이드라인  (0) 2015.10.10
iOS사파리 브라우져를 열어서 특정 사이트로 이동  (0) 2014.05.05
posted by 래머