23 Temmuz 2017

iOS In-App Purchase Receipt Validation with Php in Your Server

Hi,


Jailbroken iOS devices can innitiate fake in-app purchases in your application. This is a bit annoying situation, both for users as well as for an application owner. Maybe you can not stop fake in-app purchases but you can stop wrong analytic data based on fake purchases.



Today I'm going to explain in-app purchase validation with php in your server. For this aim, Apple provides a special service. To obtain the response data, you should first send your receipt data to Apple.


Apple link to obtain response data:
https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html

21000
The App Store could not read the JSON object you provided.
21002
The data in the receipt-data property was malformed or missing.
21003
The receipt could not be authenticated.
21004
The shared secret you provided does not match the shared secret on file for your account.
21005
The receipt server is not currently available.
21006
This receipt is valid but the subscription has expired. When this status code is returned to your server, the receipt data is also decoded and returned as part of the response.
Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.
21007
This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.
21008
This receipt is from the production environment, but it was sent to the test environment for verification. Send it to the production environment instead.
21010
This receipt could not be authorized. Treat this the same as if a purchase was never made.
21100-21199
Internal data access error.
There are some status codes in the bottom of the page. If your response status code is one of them, there is a problem with your receipt data or your request. If the status code is 0 (zero), your receipt-data is valid.



You can get the receipt-data from your in-app purchase by following the steps bellow:

NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL]; NSData *receipt = [NSData dataWithContentsOfURL:receiptURL]; if (receipt) { NSString *receiptEncoded = [receipt base64EncodedStringWithOptions:0]; // In addition we need to replace +(plus) sign for encoding receiptEncoded = [receiptEncoded stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"]; NSString *post = [NSString stringWithFormat:@"receipt-data=%@", receiptEncoded]; NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO]; NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[postData length]]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL:[NSURL URLWithString:@"your_server.com/verify_inapp_ios.php"]]; [request setHTTPMethod:@"POST"]; [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:postData]; NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; if (!error) { int statusCode = [[json objectForKey:@"status"] intValue]; if (statusCode == 0) { // Receipt-data is valid } } }]; [dataTask resume]; }

You can send the receipt data to your server with the above code block. You only change the your_server.com.  

NOTE: Plus sign (+) needs to be converted by utf encoding. Becuase it is a valid code in POST requests. 

We need a php page for processing this request. Apple provides 2 different URL for this aim. One for sandbox purchases and the other one for real purchases.

Sandbox: https://sandbox.itunes.apple.com/verifyReceipt
Real: https://buy.itunes.apple.com/verifyReceipt

<?php $json['receipt-data'] = $_POST['receipt-data']; $post = json_encode($json); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"https://buy.itunes.apple.com/verifyReceipt"); curl_setopt($ch, CURLOPT_POST,1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); $result=curl_exec ($ch); curl_close ($ch); ?>


Those php codes prints the response data in json format. You can deserialize the data in your objective-c or swift code.


Sample sandbox receipt-data can be found here : https://gist.github.com/sauloarruda/2559455

You can send the sandbox receipt-data to citynom.com/verify_inapp_ios.php for testing. Your json response should resemble this lines below.

object
{2}
receipt
{13}
original_purchase_date_pst
:
2012-04-30 08:05:55 America/Los_Angeles
original_transaction_id
:
1000000046178817
original_purchase_date_ms
:
1335798355868
transaction_id
:
1000000046178817
quantity
:
1
product_id
:
com.mindmobapp.download
bvrs
:
20120427
purchase_date_ms
:
1335798355868
purchase_date
:
2012-04-30 15:05:55 Etc/GMT
original_purchase_date
:
2012-04-30 15:05:55 Etc/GMT
purchase_date_pst
:
2012-04-30 08:05:55 America/Los_Angeles
bid
:
com.mindmobapp.MindMob
item_id
:
521129812
status
:
0

Bu Blogda Ara

İletişim

Ad

E-posta *

Mesaj *