Ios In-App payment (In-App Purchase, Sandbox testing, background verification)

Source: Internet
Author: User

Ios In-App payment (In-App Purchase, Sandbox testing, background verification)

 

1. Purchase Product Information in Apple iTunes Connect.

 

1) Create New, and select the type:

1. consumable Projects

For purchase items in a consumable App, you must purchase the item each time you download it. A one-time service is usually a consumable project, such as a bait in a phishing App.

2. non-consumable Projects

For a non-consumable App, you only need to purchase it once. Services that do not expire or decrease as they are used are generally non-consumable items, such as the new runway of the game App.

3. automatic subscription renewal

By automatically renewing subscriptions, you can purchase updates and dynamic content within a specified period of time. Subscription (such as magazine subscription) is automatically renewed unless you cancel the selection.

4. Free Subscription

Through free subscription, developers can add FREE subscriptions to "Newspapers and Magazines ". After a user registers for a free subscription, the subscription content will appear on all devices associated with the user's Apple ID. Please note that free subscriptions do not expire and are only available in apps that support the function of newspapers and magazines.

5. non-renewal subscription

Non-renewal subscriptions allow marketing services with limited time. You must use a non-renewal subscription for the limited-time access content of a project purchased in the App. For example, you can subscribe to a weekly subscription of the voice navigation function in the navigation App or to an online directory of archived videos or audios on an annual basis.

Be sure to select the correct one based on your application. Otherwise, it will be rejected by the App Store review team. The virtual coins in the application must adopt the consumable type. Members with fixed time limits will choose to automatically renew the subscription. You can also choose only the virtual coin to recharge your back-end purchases to solve member problems.

2) generate a shared key

The shared key is the unique code used when you contact our server to obtain the project purchase receipt in the App. If you do not have a shared key, you will not be able to test the auto-renewal in-App purchase in sandbox technology mode. In addition, the shared key cannot be used in the App Store.

Note: No matter which App you associate with, all your auto-renewal subscriptions use the same shared key.

This shared key is used by the backend server to verify the creden of the user's purchased items. If a new password is generated, the server immediately changes the verification key. The shared key is required when verifying that the subscription type item is automatically renewed.

3) Status of purchased Projects

A) Pending Developer Approval-Your in apppurchase has been created but has not been tested in a sandbox environment andapproved by you.

B) Approved By Developer-Your in apppurchase has been tested in a sandbox environment and has been approved by you.

C) Waiting For Review-You have submittedyour in app purchase to be reviewed by Apple.

D) In Review-Your in app purchase iscurrently being reviewed by Apple no edits can be made.

E) Developer Action Required-In app purchasedetail changes that you submitted have been rejected. you are required to takeaction to edit the detail information or cancel the request to change thedetail information before this in app purchase can be reviewed again. (The details page of the in-house purchase project will prompt that a problem occurs in that place. Just modify it and submit it again)

F) Ready for Sale-Apple has approved your inapp purchase to go live on the App Store with its associated application. Thein app purchase must be cleared for sale in iTunes Connect to be Ready forSale.

G) Rejected-Apple has rejected your in apppurchase during the review process. if you have not already been contacted byApple with more information about your rejection, you may inquire through theContact Us section of iTunes Connect. A rejected in app purchase cannot bereinstated. you must create a new in app purchase if you still wish for it tobe sold.

H) Developer Removed from Sale-You havemarked your in app purchase as not cleared for sale in iTunes Connect.

2. Write the app Code (the code is for reference only)

# Pragma mark-payment in the form of a single profit

+ (PurchasesObject *) SharePurchases

{

Static dispatch_once_t onceToken;

Dispatch_once (& onceToken, ^ {

If (_ purchase = nil ){

 

_ Purchase = [[super alloc] init];

[[SKPaymentQueue defaultQueue] addTransactionObserver: _ purchase];

}

});

Return _ purchase;

}

+ (Id) allocWithZone :( struct _ NSZone *) zone

{

Static dispatch_once_t onceToken;

Dispatch_once (& onceToken, ^ {

If (_ purchase = nil ){

 

_ Purchase = [[super allocWithZone: zone] init];

}

});

Return _ purchase;

}

+ (Id) alloc

{

Return _ purchase;

 

}

# Pragma mark-diamond payment member

_ Alter = [[UIAlertView alloc] initWithTitle: @ the visitor mode purchase is only available to the current device. We recommend that you log on to the purchase message: nil delegate: self cancelButtonTitle: @ cancel otherButtonTitles: @ login purchase (recommended), @ tourist mode purchase, nil];

// Visitors are very important to purchase and will be rejected by the AppStore review team.

# Pragma mark-start payment, and request product information from the AppStore based on the product id of the purchased item.

If ([SKPaymentQueue canMakePayments]) {

NSSet * set = [NSSet setWithArray: @ [ProductID];

SKProductsRequest * request = [[SKProductsRequest alloc] initWithProductIdentifiers: set];

Request. delegate = self;

[Request start];

 

}

Else

{

NSLog (@ no permission to purchase );

}

 

# Pragma mark-SKProductsRequestDelegate get appstroe Product Information

-(Void) productsRequest :( SKProductsRequest *) requestdidReceiveResponse :( SKProductsResponse *) response {

Self. mySelfView. userInteractionEnabled = NO;

[AFTools showHUD: @ get product information atView: self. mySelfView];

NSLog (@ ----------- receive Product Feedback --------------);

NSArray * myProduct = response. products;

If (myProduct. count = 0 ){

[AFTools alertWithTitle: @ failed purchase message: @ unable to obtain product information];

NSLog (@ unable to obtain product information, purchase failed .);

Return;

}

NSLog (@ Product products ==%@, myProduct );

NSLog (@ Product id =%@, response. invalidProductIdentifiers );

NSLog (@ Product Quantity ===========% lu, (unsigned long) myProduct. count );

For (SKProduct * product in myProduct ){

// SKMutablePayment

NSLog (@ SKProduct description % @, [product description]);

NSLog (@ product title % @, product. localizedTitle );

NSLog (@ product Description: % @, product. localizedDescription );

NSLog (@ price: % @, product. price );

NSLog (@ Product id: % @, product. productIdentifier );

SKMutablePayment * MpayMent = [SKMutablePayment paymentWithProduct: product];

NSLog (==%@, MpayMent. requestData );

If ([[SKPaymentQueue defaultQueue] respondsToSelector: @ selector (addPayment :)]) {

[[SKPaymentQueue defaultQueue] addPayment: MpayMent];

}

Else

{

}

}

}

# Pragmamark-SKPaymentTransactionObserver payment result

-(Void) paymentQueue :( SKPaymentQueue *) queueupdatedTransactions :( NSArray *) transactions

{

 

For (SKPaymentTransaction * transaction in transactions)

{

Switch (transaction. transactionState)

{

Case SKPaymentTransactionStatePurchased: // transaction completed

NSLog (@ transactionIdentifier =%@, transaction. transactionIdentifier );

[Self completeTransaction: transaction];

Break;

Case SKPaymentTransactionStateFailed: // transaction failed

[Self failedTransaction: transaction];

NSLog (@ transaction failed );

Break;

Case SKPaymentTransactionStateRestored: // you have purchased this product.

[Self restoreTransaction: transaction];

NSLog (@ purchased product );

Break;

Case SKPaymentTransactionStatePurchasing: // Add the item to the list

NSLog (@ add product to list );

Break;

Default:

Break;

}

}

 

}

-(Void) paymentQueue :( SKPaymentQueue *) queueremovedTransactions :( NSArray *) transactions

{

NSLog (@ --------------- remove -------------);

}

-(Void) paymentQueue :( SKPaymentQueue *) queuerestoreCompletedTransactionsFailedWithError :( NSError *) error

{

NSLog (@ --------------- repeated payment failed -------------);

}

-(Void) completeTransaction :( SKPaymentTransaction *) transaction {

NSLog (@ ------------------- payment completed --------------------);

[Self commitSeversSucceeWithTransaction: transaction];

 

}

 

-(Void) restoreTransaction: (SKPaymentTransaction *) transaction

{

NSLog (@ ---------------- pay repeatedly -----------------);

[Self commitSeversSucceeWithTransaction: transaction];

}

-(Void) commitSeversSucceeWithTransaction :( SKPaymentTransaction *) transaction

{

NSString * productIdentifier = transaction. payment. productIdentifier;

NSString * transactionReceiptString = nil;

// The method for obtaining the Payment Verification credential above IOS7.0 should be changed, and the data structure returned by the switch verification is also different.

If (IOSSystemVersion >=7.0)

{

NSURLRequest * appstoreRequest = [NSURLRequest requestWithURL: [[NSBundle mainBundle] appStoreReceiptURL];

NSError * error = nil;

NSData * receiptData = [NSURLConnection sendSynchronousRequest: appstoreRequestreturningResponse: nil error: & error];

TransactionReceiptString = [receiptdatabase64encodedstringwitexceptions: NSDataBase64EncodingEndLineWithLineFeed];

}

Else

{

NSData * receiptData = transaction. transactionreceept;

TransactionReceiptString = [receiptDatabase64EncodedString];

}

// Verify the purchase credential from your server

}

-(Void) failedTransaction :( SKPaymentTransaction *) transaction {

 

[[SKPaymentQueue defaultQueue] finishTransaction: transaction];

}

It is best to press a database on the client to track the order status to prevent the user from finding the order for secondary processing when there is a problem in a link.

When you request data from the AppStore, an error may occur. You can use connect us in iTunes connect to send them an email for feedback. But you can solve it most of the time, right. Maybe he will be fine that day.

3. backend server Verification

There are two payment modes in IOS:

1) built-in Mode

2) Server Mode

The built-in mode process can be summarized as follows:

1) The app obtains product information from the app store.

2) Select the product to be purchased

3) The app sends a payment request to the app store.

4) app store processes the payment request and returns the transaction information

5) The app displays the purchased content to the user.

The main process of the server mode is as follows:

1) The app obtains the product ID list from the server.

2) The app obtains product information from the app store.

3) Select the product to be purchased

4) The app sends a payment request to the app store.

5) the app store processes the payment request and returns the transaction information.

6) The app sends transaction receipto the server.

7) after receiving the receipt, the server sends it to the app stroe to verify the validity of the receipt.

8) app store returns the verification result of the receipt

9) determines whether the user has successfully purchased the app based on the results returned by the app store.

The difference between the two modes is mainly that: the receipt verification of the transaction, the built-in mode does not specifically verify the transaction receipt, and the server mode uses an independent server to verify the transaction receipt. The built-in mode is simple and quick, but is easy to crack. The server mode process is relatively complex, but relatively secure.

At the beginning of development, Apple was responsible for notifying us that our servers are unstable. After the development, it was found that Apple was very responsible, not only unstable, but also slow enough. It takes 3 to 6 seconds for the app store server to verify a receipt.

1. Can users endure 3-6 seconds of waiting time?

2. If the app store server goes down, how can we ensure that successful paying users can get normal services.

For the first problem, we have reason to believe that the user is totally intolerable. So we adopt Asynchronous Authentication. After the server receives a request from the client, it puts the request in MCQ for processing.

For the second problem, the apple staff was very responsible for notifying us that our server was unstable, so we did not rule out the receipt verification timeout. For the verification timeout receipt, save it to the database and mark it as verification timeout. The scheduled task goes to the app store for verification at a certain time to ensure that the verification result of the receipt can be obtained.

During the development process, you need to test whether the application can pay normally, but not the actual payment. Therefore, you need to use the sandbox Store test provided by Apple. Store Kit cannot be used in iOS simulators. Test Store must be performed on a real machine.

Verify receipt in sandbox

Https://sandbox.itunes.apple.com/verifyReceipt

Verify receipt in the production environment

Https://buy.itunes.apple.com/verifyReceipt

In the actual development process, the server uses the issandbox field to identify whether the receipt delivered by the client is in the sandbox environment or in the production environment. The Sandbox test was normal before submission to Apple for review. After submitting the ticket to Apple for review, you are notified that the purchase failed and the review failed. Query logs show that the transaction receipt sent by the client is a sandbox receipt, but the issandbox field is identified as a production environment.

Conclusion: Apple still tests the app in the sandbox environment. However, when a client colleague submits an application to Apple for review, he writes the issandbox field to death and sets it as a production environment. In this way, the sandbox receipt is sent to https://buy.itunes.apple.com/verifyreceiptfor verification.

So how can we automatically identify whether the receipt is sandbox receipt?

There are two methods to identify receipts in the sandbox environment:

1. According to the receipt field environment = sandbox.

2. Status Codes returned by the receipt verification Interface

If status = 21007, the current receipt is in the sandbox environment, and t is verified.

Status Code provided by Apple;

21000App Store cannot read the JSON data you provide
21002 invalid receipt Data Format
21003 the receipt cannot be verified
21004 the shared key you provided is inconsistent with the shared key of your account
21005 the receipt server is currently unavailable
21006 the receipt is valid, but the subscription service has expired. When this information is received, the decoded receipt information is included in the returned content.
21007 the receipt information is used for testing (sandbox), but is sent to the product environment for verification.
21008 the receipt information is used in the product environment, but is sent to the test environment for verification.

Production verification is performed first and then tested to avoid the trouble of switching back and forth interfaces. Test and verification will only be used when you test the appid you applied for. the user does not have the test appid, so it will not go to the test and verification step. Even if a production verification error occurs, shouldn't the status 21007 be returned. The user name that passes the test and verification, and the recharge amount should be recorded in the database for the convenience of checking the company's funds.

 


Related Article

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.