[IOS] in-app payment (internal purchase) personal development process and pits!

Source: Internet
Author: User

This article is based on the Xcodeversion 7.3 (7d175) version and the phone is the iphone 6,9.3 system.

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"@interfaceViewcontroller () <Skpaymenttransactionobserver,Skproductsrequestdelegate>@property (Nonatomic,copy)NSString *currentproid;@end@implementationviewcontroller-(void) Viewdidload {[Super Viewdidload];UIButton *button = [UIButton Buttonwithtype:uibuttontypecustom]; button. frame = CGRectMake (100,100,100,100); button. backgroundcolor = [Uicolor Greencolor]; [Button settitle:@"6 Yuan" forstate:uicontrolstatenormal]; [Button AddTarget:Self action:@selector (Btnclick:) Forcontrolevents:uicontroleventtouchdown]; [Self. View Addsubview:button];} - (void) Btnclick: (UIButton *) button{[[Skpaymentqueue Defaultqueue] Addtransactionobserver:Self]; _currentproid = @"123";if ([Skpaymentqueue canmakepayments]) {[Self requestproductdata:product]; }else{NSLog (@"Do not allow in-program payment"); }}Go to Apple Server request product-(void) Requestproductdata: (NSString *) type{NSLog (@"-------------request the corresponding product information----------------"); [Svprogresshud Showwithstatus:Nil Masktype:svprogresshudmasktypeblack];Nsarray *product = [[Nsarray Alloc] 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 the 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", (UnsignedLong) [Product Count]); Skproduct *p =NilFor (skproduct *pro in product) {NSLog (@"%@", [pro description]);NSLog (@"%@", [pro Localizedtitle]);NSLog (@"%@", [pro localizeddescription]);NSLog (@"%@", [pro price]);NSLog (@"%@", [pro Productidentifier]);if ([Pro. Productidentifier Isequaltostring:_currentproid]) {p = Pro;}} Skpayment *payment = [Skpayment paymentwithproduct:p];NSLog (@"Send purchase Request"); [[Skpaymentqueue Defaultqueue] addpayment:payment];}Request Failed-(void) Request: (Skrequest *) Request Didfailwitherror: (Nserror *) error{[Svprogresshud showerrorwithstatus:@"Payment failure"];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 dataNsurl *receipturl=[[NSBundle Mainbundle] Appstorereceipturl]; NSData *receiptdata=[nsdata Datawithcontentsofurl:receipturl];NSString *receiptstring=[receiptdata Base64encodedstringwithoptions:nsdatabase64encodingendlinewithlinefeed];Convert to Base64 stringNSString *bodystring = [NSString stringwithformat:@"{\" receipt-data\ ": \"%@\ "}", receiptstring];Stitching request Data NSData *bodydata = [bodystring datausingencoding:nsutf8stringencoding];Create a request to Apple official for purchase verificationNsurl *url=[Nsurl Urlwithstring:sandbox]; Nsmutableurlrequest *requestm=[nsmutableurlrequest Requestwithurl:url]; Requestm. Httpbody=bodydata; Requestm[Email protected]"POST";Create a connection and send a sync requestNserror *error=Nil NSData *responsedata=[Nsurlconnection sendsynchronousrequest:requestm Returningresponse:Nil error:&error];if (Error) {NSLog (@"Validation error occurred during purchase, error message:%@". 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 identificationIf it is a consumable, record the purchase quantity, non-consumable then record whether purchasedNsuserdefaults *defaults=[Nsuserdefaults Standarduserdefaults];if ([Productidentifier isequaltostring:@"123"]) {int Purchasedcount=[defaults Integerforkey:productidentifier];Purchased quantity [[Nsuserdefaults Standarduserdefaults] Setinteger: (purchasedcount+1) Forkey:productidentifier]; }else{[Defaults Setbool:YES Forkey: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) {Case skpaymenttransactionstatepurchased:{NSLog (@"Transaction completion");Send to Apple server to verify credentials [Self verifypurchasewithpaymenttransaction]; [[Skpaymentqueue Defaultqueue] Finishtransaction:tran]; }BreakCase skpaymenttransactionstatepurchasing:NSLog (@"Add Product to List");BreakCase skpaymenttransactionstaterestored:{NSLog (@"Already purchased goods"); [[Skpaymentqueue Defaultqueue] Finishtransaction:tran]; }BreakCase skpaymenttransactionstatefailed:{NSLog (@ "trading failed"); [[Skpaymentqueue Defaultqueue] Finishtransaction:tran]; [Svprogresshud showerrorwithstatus:@ "purchase Failure"];} break; default: break;}} //Trading End-(void) completetransaction: (Skpaymenttransaction *) transaction{nslog (@ "trading End"); [[Skpaymentqueue Defaultqueue] finishtransaction:transaction];} -(void) dealloc{[[Skpaymentqueue defaultqueue] Removetransactionobserver:self";} -(void) didreceivememorywarning {[super Didreceivememorywarning]; //Dispose of any of the resources that 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.

Excerpt from: http://blog.csdn.net/darling_shadow/article/details/51538267

Reference:
1. iOS development within the purchase of-appstore;
2. Apple official documentation

[IOS] in-app payment (internal purchase) personal development process and pits!

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.