IAP Buy-In

Source: Internet
Author: User

IAPHelper.h

iaphelper.h//airplay////Created by Apple on 13-10-23.//Copyright (c) 2013 itcast. All rights reserved.//#import <foundation/foundation.h>typedef Void (^myblock) (); typedef void (^ Buycompletionblock) (NSString *identifier); typedef void (^restorecompletionblock) (Nsarray *products); typedef void (^ Failedblock) (NSString *reason); typedef void (^requestproductscompletionhandler) (BOOL success, Nsarray * products); Interface Iaphelper:nsobject {nsuserdefaults *defaults;} /** packaging After the use of the Iaphelper Method 1. Call Requestproducts to go to the server to verify the list of available items 2. Call the Buyproduct method, pass in the product label to be purchased, and do the subsequent processing in the completion block code 3. Call the Restorepurchase method, and in the completion block code to do the subsequent processing can be called follow-up, is based on the purchase situation, adjust UI UI or set user properties hint: In the use of iaphelper, you need to import Base64 two classification methods. */@property (nonatomic,assign) int money;//Recharge amount @property (strong,nonatomic) myblock block;+ (Iaphelper *) Sharediaphelper; #pragma mark request a valid product (use a custom product collection to go to the itunes server to confirm which items are available for sale)-(void) Requestproducts: (Nsset *) products;# pragma mark purchases (purchase goods using the specified product identifier)-(void) Buyproduct: (NSString *) identifier        Completion: (Buycompletionblock) Completion failed: (Failedblock) failed; #pragma mark Recovery purchase (available for non-consumable only)-(voi d) Restorepurchase: (restorecompletionblock) Completion failed: (Failedblock) failed;-(void) Buyproduct: (NSStri ng *) identifier; @end

Iaphelper.m

  iaphelper.m//airplay////Created by Apple on 13-10-23.//Copyright (c) 2013 itcast. All rights reserved.//#import "IAPHelper.h" #import <StoreKit/StoreKit.h> #import "nsdata+base64.h" static Iaphelper *sharedinstance;/** in order to prevent jailbreak mobile phone plug-in interception, after the completion of the purchase, you need to do a purchase verification! *///server address for true machine authentication # Itms_prod_verify_receipt_url @ "Https://buy.itunes.apple.com/verifyReceipt"//Authentication service used by the development simulator Service address # Itms_sandbox_verify_receipt_url @ "Https://sandbox.itunes.apple.com/verifyReceipt" @interface iaphelper     () <skproductsrequestdelegate, skpaymenttransactionobserver>{//A valid commodity dictionary returned from the server for the user to purchase is to use Nsmutabledictionary        *_productdict;    Callback block code Buycompletionblock _buycompletion;    Restorecompletionblock _restorecompletion; Failedblock _failedblock;}    @end @implementation Iaphelper#pragma Mark-Single-case method + (ID) Allocwithzone: (Nszone *) zone{static dispatch_once_t Oncetoken; Dispatch_once (&oncetoken, ^{sharedinstance = [Super Allocwithzone:zone];    Adding a trading observer object to a shared instance [[Skpaymentqueue defaultqueue]addtransactionobserver:sharedinstance];        }); return sharedinstance;}    + (Iaphelper *) sharediaphelper{static dispatch_once_t Oncetoken;    Dispatch_once (&oncetoken, ^{sharedinstance = [[Iaphelper alloc]init];        }); return sharedinstance;} #pragma mark-Inside method #pragma mark request a valid product (use a custom product collection to go to the itunes server to confirm which items are available for sale)-(void) Requestproducts: (Nsset *) products{//instantiation    Request Skproductsrequest *request = [[Skproductsrequest alloc]initwithproductidentifiers:products];    NSLog (@ "%@", products);        Set agent [Request Setdelegate:self]; Launch request [request start];} #pragma mark requests error message-(void) Request: (Skrequest *) Request Didfailwitherror: (Nserror *) error{NSLog (@ "Request error message:%@", error);}    #pragma mark request Success-(void) Requestdidfinish: (Skrequest *) request{//[activityview stopanimating]; NSLog (@ "Success request =%@", request); #pragma mark Purchase (purchase goods using the specified product identifier)-(void) Buyproduct: (NSString *) IdentiFier//completion: (Buycompletionblock) completion//failed: (failedblock) failed{//Record callback block code//_buycomp        Letion = completion;//_failedblock = failed;        Extract the Product object from the commodity dictionary, if there is only buy//if not, Prompt user skproduct *product = _productdict[identifier];                if (product) {//purchase//1. Instantiate the Payment object skpayment *payment = [Skpayment paymentwithproduct:product]; 2.    The payment object is added to the payment queue, the payment is started, the purchase request is submitted to the itunes server, and the server waits for the appropriate [[Skpaymentqueue defaultqueue]addpayment:payment];                 } else {//This situation will define the purchase, but Apple does not approve it, or the Apple server is unavailable when the NSLog (@ "The current item is not available for purchase, please try again later");                                                                Uialertview *alterview = [[Uialertview alloc] initwithtitle:@ "Reload failed! Please try again later!"                                                      Message:nil delegate:self Cancelbuttontitle:nil Otherbutton titles:@ "OK, nil];                [Alterview show]; }} #pragma mark verifies the purchase/verification purchase, after each purchase is completed, the purchase transaction needs to be verified//so-called authentication, is the voucher of the transaction "encrypted", the post request to Apple's server, the Apple server to "encrypt" the data after authentication,// Will return a JSON data for the developer to determine whether the credentials are valid//some "in-purchase assistant" will also intercept the authentication credentials, return a fake verification results//So in development, the verification of credentials to be extra careful-(void) Verifypurchase: ( Skpaymenttransaction *) transaction{//Use base64 encryption algorithm to encrypt the credentials//1. Use Base64 to encrypt trading credentials nsstring *ENCODESTR = [Transa        Ction.transactionreceipt base64encodedstring]; 2.    Build authentication request//1) test URL itms_prod_verify_receipt_url Nsurl *url = [Nsurl Urlwithstring:itms_prod_verify_receipt_url]; 2) Build request Nsmutableurlrequest *request = [Nsmutableurlrequest requestwithurl:url Cachepolicy:nsurlrequestuseprotoco        Lcachepolicy timeoutinterval:10.0f];    1> Request Data Body nsstring *payload = [NSString stringwithformat:@ "{\" receipt-data\ ": \"%@\ "}", Encodestr];    NSData *payloaddata = [payload datausingencoding:nsutf8stringencoding];    2> setting the data body [request Sethttpbody:payloaddata]; 3> Set Request method [REquest sethttpmethod:@ "POST"];    3) Make a connection and send a sync request! Cannot send asynchronous request!    Follow up also to the server return results to do further confirmation, to ensure that the user is really in the purchase!        The so-called real purchase, not the plug-in simulation of the calibration data nsurlresponse *response = nil; This request returns a JSON result nsdata *data = [nsurlconnection sendsynchronousrequest:request returningresponse:&response Erro        R:nil];    Deserializes the data into a data dictionary if (= = nil) {return; } nsdictionary *jsondict = [nsjsonserialization jsonobjectwithdata:data options:nsjsonreadingallowfragments Error:nil    ]; if (jsondict! = nil) {[[Nsnotificationcenter Defaultcenter]postnotificationname:kjoinmembernotificationcen            TER Object:nil]; ///For the server to return data to verify//usually need to verify: bid,product_id,purchase_date,status//if ([jsondict[@ "status"]integer Value] = = 0) {//_buycompletion (Transaction.payment.productIdentifier);/} else {//_buycompletion (@ "Validation missing Fail, check if your machine is jailbroken ");/}} #pragma mark recovery purchase (non consumable only)//recover purchased Application scenario//1) User recovery of non-consumable purchases on other devices//2) User's phone factory reset, or reinstall soft, you can use the recovery purchase//Hint: Restore the purchase is essentially the same as the purchase, for non-consumable, even if the purchase again, will not allow users to pay//recovery purchase is relatively more humane, so in the actual development, two buttons one can not be less//use to restore the purchase, You can recover all non-consumable type items that the user has purchased-(void) Restorepurchase: (restorecompletionblock) Completion failed: (Failedblock) Faile    d{//Record callback block code _restorecompletion = completion;        _failedblock = failed; Restore how the purchase works, connect to the itunes server using the user's AppleID, check all the items that the user has purchased//return the collection of items to the user [[Skpaymentqueue Defaultqueue]restorecompletedtra Nsactions];} #pragma mark Skproductsrequest delegate-(void) Productsrequest: (skproductsrequest *) Request Didreceiveresponse: ( Skproductsresponse *) response{//Lazy Load Product dictionary if (_productdict = = nil) {_productdict = [nsmutabledictionary dict    IonaryWithCapacity:response.products.count];    } else {[_productdict removeallobjects];    } NSLog (@ "Valid product List%@", response.products);            NSLog (@ "Invalid product:%@", response.invalidproductidentifiers); The list of products returned by the Traversal server for (skproduct *product in response.products) {//Output valid products (products currently available for purchase) uniquely marked//NSLog (@ "////%@", product.productidentifier);        You need to record the valid items returned by the server for subsequent purchases//tips: Do not use custom product identifiers to start the purchase, before purchasing, be sure to check the available goods from the server//To avoid server adjustment or other reasons, the user can not normally purchase, but also caused the loss of money    [_productdict setobject:product ForKey:product.productIdentifier]; }} #pragma mark-trading Observer Method//callback method for transaction changes in the payment queue-(void) Paymentqueue: (Skpaymentqueue *) queue updatedtransactions: (Nsarray *) transactions{//For recovery operations, define a temporary array//nsmutablearray *restorearray = [Nsmutablearray ArrayWithCapacity:transactions.cou    NT];        Determine if the operation is resumed//bool isrestore = NO; For (Skpaymenttransaction *transaction in Transactions) {//nslog (@ "transaction.        State =%@ ", transaction);                            Switch (transaction.transactionstate) {case skpaymenttransactionstatepurchased://transaction completed            Break                Case skpaymenttransactionstatefailed://transaction Failure//[self Failedtransaction:transaction];            Break Case skpaymenttransactionstaterestored://Already purchased the product//[self restoretransaction:transaction];            Break                Case skpaymenttransactionstatepurchasing://Product added to list NSLog (@ "Item added to list");            Break        Default:break; }} for (Skpaymenttransaction *transction in transactions) {//If the status of the transaction is completed, the product is purchased successfully if (skpaymen ttransactionstatepurchased = = transction.transactionstate) {NSLog (@ "Purchase success%@", TRANSCTION.PAYMENT.P                                    Roductidentifier);            Verify credentials if (currentsystemversion >= 7) {[Self verifyPruchaseIOS7];            }else {[Self verifypurchase:transction];                        }//[self Verifyfinishedtransaction:transction];        Notification queue end Transaction [queue finishtransaction:transction]; }//else if (skpaymenttransactionstaterestored = = Transction.traNsactionstate) {//Isrestore = yes;//////restore purchase//[Restorearray Addobject:tra nsction.payment.productidentifier];//////Notification queue end TRADE//[queue Finishtransaction:transctio n];//} else if (skpaymenttransactionstatefailed = = transction.transactionstate) {////To determine if a user clicks Cancel, the resulting Request failed//if (skerrorpaymentcancelled! = Transction.error.code) {/////Error block code callback, before calling callback method, you need to determine whether the callback method is set Set////After this setting, you can set the callback method to nil, or you will get an error!                if (_failedblock) {//_failedblock (transction.error.localizedDescription);// }//}//}}//If the transaction is resumed//if (Isrestore) {/////Call block code callback the entire restored product identifier array//_ Restorecompletion (Restorearray);//}}-(void) verifyPruchaseIOS7 {//Verify credentials, get the trading credentials returned to Apple//Appstorereceipturl  IOS7.0 added, after the purchase transaction is completed, the credentials will be stored at the address nsurl *receipturl = [[NSBundle mainbundle] appstorereceipturl];  Obtain the purchase credential from the sandbox nsdata *receiptdata = [NSData Datawithcontentsofurl:receipturl];    Send a network POST request to verify the purchase credentials Nsurl *url = [Nsurl Urlwithstring:itms_prod_verify_receipt_url]; Domestic visit to the Apple server is slow, timeoutinterval need a little longer nsmutableurlrequest *request = [Nsmutableurlrequest requestwithurl:url        Cachepolicy:nsurlrequestuseprotocolcachepolicy timeoutinterval:10.0f]; Request.        HttpMethod = @ "POST";     Transmission of data in the network, in most cases is the transmission of strings rather than binary data//transmission is BASE64 encoded string/** BASE64 commonly used encoding scheme, usually for data transmission, as well as the basic algorithm of encryption algorithm, transmission process can guarantee the stability of data transmission BASE64 can be encoded and decoded */nsstring *ENCODESTR = [Receiptdata base64encodedstringwithoptions:nsdatabase64encodingendline        Withlinefeed];    NSString *payload = [NSString stringwithformat:@ "{\" receipt-data\ ": \"%@\ "}", Encodestr];        NSData *payloaddata = [payload datausingencoding:nsutf8stringencoding]; Request.        Httpbody = Payloaddata; Submit a validation request and get the official validation json result nsdata *result = [Nsurlconnection sendsynchronousrequest:request returningresponsE:nil Error:nil];    The official validation result is null if (result = = nil) {NSLog (@ "validation failed"); } nsdictionary *dict = [nsjsonserialization jsonobjectwithdata:result options:nsjsonreadingallowfragments Error:nil        ];        NSLog (@ "%@", dict); if (dict! = nil) {//Compare the following information in the dictionary to basically guarantee data security//BUNDLE_ID&AMP;APPLICATION_VERSION&AMP;PRODUCT_ID&AMP;TRANSACTI        on_id [[Nsnotificationcenter defaultcenter]postnotificationname:kjoinmembernotificationcenter Object:nil];    NSLog (@ "verify success"); }} @end

IAP Buy-In

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.