読者です 読者をやめる 読者になる 読者になる

ふるすたっくえんじにあっぽい人の日記

ASP .NET MVC (C#)、.NET Framework、iOS (Objective-c) アプリ、Androidアプリ (Java)、AWS、たまにLAMPとかプロジェクトマネジメントあたりのお話

【C#】【iOS】In-AppPurchaseレシートの検証-Consumableバージョン

あけおめにゃん。

iOS側は省略。ググればあるにゃん。
サーバーサイドはPHPだといっぱいあるんだけど、C#はあんまないから書いとくにゃん。

とりあえずデシリアライズ用のクラスさんたち。

    [DataContract]
    public class VerifyReceiptResult
    {
        [DataMember]
        public int status { get; set; }

        [DataMember]
        public string environment { get; set; }

        [DataMember]
        public virtual Receipt receipt { get; set; }
    }

    [DataContract]
    public class Receipt
    {
        [DataMember]
        public string receipt_type { get; set; }

        [DataMember]
        public int adam_id { get; set; }

        [DataMember]
        public int app_item_id { get; set; }

        [DataMember]
        public string bundle_id { get; set; }

        [DataMember]
        public string application_version { get; set; }

        [DataMember]
        public int download_id { get; set; }

        [DataMember]
        public int version_external_identifier { get; set; }

        [DataMember]
        public string request_date { get; set; }

        [DataMember]
        public long request_date_ms { get; set; }

        [DataMember]
        public string request_date_pst { get; set; }

        [DataMember]
        public string original_purchase_date { get; set; }

        [DataMember]
        public long original_purchase_date_ms { get; set; }

        [DataMember]
        public string original_purchase_date_pst { get; set; }

        [DataMember]
        public string original_application_version { get; set; }

        [DataMember]
        public virtual ICollection<Purchase> in_app { get; set; }
    }

    [DataContract]
    public class Purchase
    {
        [DataMember]
        public int quantity { get; set; }

        [DataMember]
        public string product_id { get; set; }

        [DataMember]
        public long transaction_id { get; set; }

        [DataMember]
        public long original_transaction_id { get; set; }

        [DataMember]
        public string purchase_date { get; set; }

        [DataMember]
        public long purchase_date_ms { get; set; }

        [DataMember]
        public string purchase_date_pst { get; set; }

        [DataMember]
        public string original_purchase_date { get; set; }

        [DataMember]
        public long original_purchase_date_ms { get; set; }

        [DataMember]
        public string original_purchase_date_pst { get; set; }

        [DataMember]
        public bool is_trial_period { get; set; }
    }

んで、Appleからレシート情報取得

            var serializer = new DataContractJsonSerializer(typeof(VerifyReceiptResult));
            VerifyReceiptResult verifyReceiptResult;

            using (var client = new HttpClient())
            using (var content = new StringContent(@"{""receipt-data"":""" + "クライアントから受け取ったレシートデータ" + @"""}"))
            {
                content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                var response = client.PostAsync(@"https://buy.itunes.apple.com/verifyReceipt", content).Result;
                var resultByteArray = response.Content.ReadAsByteArrayAsync().Result;
                var resultStream = new MemoryStream(resultByteArray);
                verifyReceiptResult = (VerifyReceiptResult)serializer.ReadObject(resultStream);
            }

            if (verifyReceiptResult.status == 21007)
            {
                using (var client = new HttpClient())
                using (var content = new StringContent(@"{""receipt-data"":""" + "クライアントから受け取ったレシートデータ" + @"""}"))
                {
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    var response = client.PostAsync(@"https://sandbox.itunes.apple.com/verifyReceipt", content).Result;
                    var resultByteArray = response.Content.ReadAsByteArrayAsync().Result;
                    var resultStream = new MemoryStream(resultByteArray);
                    verifyReceiptResult = (VerifyReceiptResult)serializer.ReadObject(resultStream);
                }
            }

            if (verifyReceiptResult.status == 0)
            {
                // コイン付与とか
            }

verifyReceiptResultにデシリアライズされて値が入ってるので、あとはよしなに。
transaction-idは未使用かどうか自前で管理する必要があるぉ。
StringContentはPostAsyncが終わると破棄されるらしーぉ。