This article will give you a detailed introduction of iOS in the purchase, this is my May 16 end of the development process, I hope to read this article to help people.
This article is based on the Xcodeversion 7.3 (7d175) version and the phone is the iphone 6,9.3 system.
Some places directly from the network, is basically my logic, save time and effort.
I. Create a test app
First you need to login to the app's itunesconnection, you will see the following interface
A brief introduction to these few options
1. My app is mainly used to manage my own apps, such as editing materials, shelves, racks, etc.
2. Sales and trends are mainly to see the app in each platform download volume, revenue and other aspects of data, there are graphs and other graphics and other ways to give us a reference.
3. Payment and financial reports indicate your income and payment information.
4.iAd is primarily about advertising, developers can log in to Workbench and control the app's ads through IAD.
5. Users and functions are used to generate corresponding accounts, such as the Apple Shahe test account.
6. The agreement, tax and banking is the information setting for your bank's related account.
Here we select the first option, my app, and then click the plus sign in the upper left corner to create a new app for testing.
Click New APP, the new window will appear;
Here are a few needs to fill in the place, the name of their own, platform iOS, language selected Simplified Chinese, set ID is your bundle Identifier, you need to apply on the Certificates page Bundleid,sku can be understood as the user to see the only signs , it will be reflected in the link to your app's App store.
Two. Add in-purchase
After the app is created, we open the app that we created, select the feature in the top left corner, and see the in-app purchase item on the left. We click the plus sign in the bottom right corner to add an in-app item for your apps.
After that we will see the type of options, such as
The official notes are very clear, just here to say the first two:
-Consumable items like you need to buy gold coins, buy diamonds, etc., as long as you spend money can buy unlimited times
-Non-expendable items like when you buy an app in the App Store and buy it once, you don't have to buy it for a second time, you have a permanent right to use it.
In our app, is the recharge member, so the choice is the first one, can be unlimited purchase.
Here are a few options, you need to fill in the product name, product ID and price level, simply explain
1. The product name is based on the actual meaning of your consumer props, such as "100 Jewels", "100 gold coins" and so on.
2. Product ID is more important, by the project customization, as long as the only can, because the test, I am here casually fill in 123, in the actual application, must be carefully filled.
3. The price level of the words "View price list" has a corresponding description, you can follow the table in each country's currency price and grade to choose
Next is the language selection, and the upload snapshot such as
Click Add Language, fill in the name and description, here we still choose Simplified Chinese, as follows
Audit notes, according to the actual situation, you can not fill in. And the following screenshot, is the product image, in pixels, the minimum size is 321,390, size requirements such as, upload.
So far, our in-house purchases have been added to completion. The next step is the testing phase.
Three. Apply for sandbox test account (used to test purchase items)
This account is to use the Apple Sandbox test environment to simulate the AppStore purchase process, you certainly do not want to use the real RMB to buy test it?
First we go back to itunes Connect, where we select users and functions.
Then click the plus sign in the third option sandbox technical tester above to add testers.
In the information to fill out the page simply say two sentences.
All information can be filled out at will, regardless of whether the real.
In the App Store area, be sure to choose the right one, which corresponds to the region of the app you created, your app is Chinese, and here we still choose China.
This account can only be used for testing, not on official AppStore.
Complete, click Save, we will generate a test account, of course, this account can be deleted and added at any time.
Then finally it's time to write the code, click on your Xcode to create your project!
Most of the code can be implemented in. m files.
#import "ViewController.h" #import <StoreKit/StoreKit.h> #import "SVProgressHUD.h" @interface viewcontroller () <skpaymenttransactionobserver, Skproductsrequestdelegate>@property(nonatomic, copy)NSString*currentproid;@end @implementation viewcontroller - (void) Viewdidload {[SuperViewdidload];UIButton*button = [UIButtonButtonwithtype:uibuttontypecustom]; button. Frame= CGRectMake ( -, -, -, -); button. BackgroundColor= [UicolorGreencolor]; [Button settitle:@"6 Yuan"Forstate:uicontrolstatenormal]; [Button AddTarget: SelfAction@selector(Btnclick:) Forcontrolevents:uicontroleventtouchdown]; [ Self. ViewAddsubview:button];} - (void) Btnclick: (UIButton*) button{[[Skpaymentqueue Defaultqueue] Addtransactionobserver: Self]; _currentproid = @"123";if([Skpaymentqueue canmakepayments]) { [ SelfREQUESTPRODUCTDATA:PRODUCT]; }Else{NSLog(@"Do not allow in-app payments"); }}//Go to Apple Server to request a product- (void) Requestproductdata: (NSString*) type{NSLog(@"-------------request the corresponding product information----------------"); [Svprogresshud Showwithstatus:NilMasktype:svprogresshudmasktypeblack];Nsarray*product = [[NsarrayAlloc] Initwithobjects:type,Nil]; Nsset *nsset = [Nsset setwitharray:product]; Skproductsrequest *request = [[Skproductsrequest alloc] initwithproductidentifiers:nsset]; Request. Delegate= Self; [Request start];}//Receive product return information- (void) Productsrequest: (skproductsrequest *) Request Didreceiveresponse: (Skproductsresponse *) response{NSLog(@"--------------receive a product feedback message---------------------");Nsarray*product = response. Products;if([Product count] = =0) {[Svprogresshud dismiss];NSLog(@"--------------No goods------------------");return; }NSLog(@"productid:%@", response. Invalidproductidentifiers);NSLog(@"Product paid Quantity:%lu",(unsigned Long) [Product Count]); Skproduct *p =Nil; for(Skproduct *pro in product) {NSLog(@"%@", [pro description]);NSLog(@"%@", [pro Localizedtitle]);NSLog(@"%@", [pro localizeddescription]);NSLog(@"%@", [pro price]);NSLog(@"%@", [pro Productidentifier]);if([Pro. ProductidentifierIsequaltostring:_currentproid]) {p = Pro; }} skpayment *payment = [Skpayment paymentwithproduct:p];NSLog(@"Send Purchase Request"); [[Skpaymentqueue Defaultqueue] addpayment:payment];}//Request failed- (voidRequest: (Skrequest *) Request Didfailwitherror: (Nserror*) error{[Svprogresshud showerrorwithstatus:@"Payment failed"];NSLog(@"------------------error-----------------:%@", error);} - (void) Requestdidfinish: (Skrequest *) request{[svprogresshud dismiss];NSLog(@"------------feedback end-----------------");}//Sandbox test environment validation#define SANDBOX @ "Https://sandbox.itunes.apple.com/verifyReceipt"//Formal environmental validation#define AppStore @ "Https://buy.itunes.apple.com/verifyReceipt"/** * Verify purchase, avoid jailbreak software to simulate Apple request to reach illegal purchase problem * * /-(void) verifypurchasewithpaymenttransaction{//Get the transaction voucher from the sandbox and stitch it into the request body data Nsurl*receipturl=[[NSBundleMainbundle] Appstorereceipturl]; NSData *receiptdata=[nsdata Datawithcontentsofurl:receipturl];NSString*receiptstring=[receiptdata Base64encodedstringwithoptions:nsdatabase64encodingendlinewithlinefeed];//Convert to Base64 string NSString*bodystring = [NSStringstringwithformat:@"{\" receipt-data\ ": \"%@\ "}", receiptstring];//Splicing request dataNSData *bodydata = [bodystring datausingencoding:nsutf8stringencoding];//Create request to Apple Official for purchase verification Nsurl*url=[NsurlUrlwithstring:sandbox]; Nsmutableurlrequest *requestm=[nsmutableurlrequest Requestwithurl:url]; Requestm. Httpbody=bodydata; Requestm. HttpMethod[Email protected]"POST";//Create a connection and send a sync request Nserror*error=Nil; NSData *responsedata=[nsurlconnectionSendsynchronousrequest:requestm Returningresponse:Nilerror:&error];if(Error) {NSLog(@"Verify that an error occurred during the purchase, error message:%@", error. Localizeddescription);return; }nsdictionary*dic=[nsjsonserialization jsonobjectwithdata:responsedata options:nsjsonreadingallowfragments Error:Nil];NSLog(@"%@", DIC);if([dic[@"Status"] intvalue]==0){NSLog(@"Successful purchase!" ");nsdictionary*dicreceipt= dic[@"Receipt"];nsdictionary*dicinapp=[dicreceipt[@"In_app"] Firstobject];NSString*productidentifier= dicinapp[@"product_id"];//Read product identification //If it is a consumable, record the purchase quantity, non-consumable record whether purchased Nsuserdefaults*defaults=[NsuserdefaultsStandarduserdefaults];if([Productidentifier isequaltostring:@"123"]) {intPurchasedcount=[defaults Integerforkey:productidentifier];//Purchased quantity[[NsuserdefaultsStandarduserdefaults] Setinteger: (purchasedcount+1) Forkey:productidentifier]; }Else{[Defaults Setbool:YESForkey:productidentifier]; }//Store the purchase records here, which can be stored on the server side of the developer}Else{NSLog(@"The purchase failed, did not pass the verification!" "); }}//Monitor purchase results- (void) Paymentqueue: (Skpaymentqueue *) Queue updatedtransactions: (Nsarray*) transaction{ for(Skpaymenttransaction *tran in transaction) {Switch(Tran. Transactionstate) { Caseskpaymenttransactionstatepurchased:{NSLog(@"Transaction Complete");//Send to Apple server to verify credentials[ SelfVerifypurchasewithpaymenttransaction]; [[Skpaymentqueue Defaultqueue] Finishtransaction:tran]; } Break; CaseSkpaymenttransactionstatepurchasing:NSLog(@"Add Item to List"); Break; Caseskpaymenttransactionstaterestored:{NSLog(@"already purchased goods"); [[Skpaymentqueue Defaultqueue] Finishtransaction:tran]; } Break; Caseskpaymenttransactionstatefailed:{NSLog(@"Transaction Failed"); [[Skpaymentqueue Defaultqueue] Finishtransaction:tran]; [Svprogresshud showerrorwithstatus:@"Purchase Failed"]; } Break;default: Break; } }}//End of transaction- (void) Completetransaction: (skpaymenttransaction *) transaction{NSLog(@"End of Transaction"); [[Skpaymentqueue Defaultqueue] finishtransaction:transaction];} - (void) dealloc{[[Skpaymentqueue Defaultqueue] Removetransactionobserver: Self];} - (void) Didreceivememorywarning {[SuperDidreceivememorywarning];//Dispose of any resources, can be recreated.}@end
Here are a few things to watch out for,
1. The _currentproid in the code is filled in with the ID of the purpose of your purchase, and this is the same as the ProductID of the internal purchase created in the second step; in this case, 123.
2. After listening to the purchase result, be sure to call [[Skpaymentqueue Defaultqueue] Finishtransaction:tran] to allow you to remove the transaction from the payment queue.
3. Sandbox environment test AppStore the internal purchase process, please use the device without jailbreak.
4. Be sure to test with the real machine, whichever is true.
5. The bundle identifier of the project needs to be consistent with the bundleid you fill out when you apply for AppID, otherwise you will not be able to request product information.
6. When testing the real machine, be sure to exit the original account, in order to use the sandbox test account
7. Two verification, please note that the distinction between macros, testing with sandbox verification, the APP store audit is also used in the sandbox purchase, so when verifying the purchase voucher need to determine the return status code to determine whether to go to the sandbox two verification, in order to use the online user, The order of validation must be to validate the formal environment first, and if the return value is 21007, the sandbox will need to be validated two times, as this purchase is made in a sandbox.
Attached: Apple Payment error Directory
Status Code |
Description |
21000 |
The App Store could not read the JSON object provided. |
21002 |
The data in the Receipt-data is malformed or missing. |
21003 |
The receipt could not being authenticated. |
21004 |
The shared secret you provided does does match the shared secret on file for your account. Only returned for IOS 6 style transaction receipts for auto-renewable subscriptions. |
21005 |
The receipt server is not currently available. |
2160p |
This receipt was valid but the subscription had 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 are from the test environment and it was sent to the production environment for verification. Send it to the test environment instead. |
21008 |
This receipt are from the production environment, but it's sent to the test environment for verification. Send it to the production environment instead. |
Reference:
1. iOS development within the purchase of-appstore;
2. Apple official documentation
[IOS] in-app payment (internal purchase) personal development process and pits!