IAP auto-renewable in practice
Cocoaheads Taipei ,2016.12
2
3
In App Purchase
Users use their Apple ID purchase virtual product(s)
Developer use receipt(s) to implement business logic
Financial receive simple report
4
step 1~7 get products user can purchase
5
6
NSSet *productsIDSet = ["product_identifiers1","product_identifiers2"]
self.productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productsIDSet];
productRequest.delegate = self;
[productRequest start];
7
SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { NSLog(@"receive products %@", response.products); NSLog(@"invalidProductIdentifiers %@", response.invalidProductIdentifiers); self.products = response.products; …… }
[SKProduct] from productsIDSet
8
step 8 user select product to buy
9
step 8 user select product to buy
- (void)purchaseProduct:(SKProduct *)inProduct { SKPayment *p = [SKPayment paymentWithProduct:inProduct]; [[SKPaymentQueue defaultQueue] addPayment:p]; }
10
step 9 ~11 validate user AppleID/password
11
step 12 ~14 receive receipt
12
SKPaymentTransactionObserver
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { NSMutableArray *purchasedTransactions = [NSMutableArray array]; for (SKPaymentTransaction *t in transactions) {
switch (t.transactionState) { case SKPaymentTransactionStatePurchased:
[purchasedTransactions addObject:t]; [[SKPaymentQueue defaultQueue] finishTransaction:t]; break; //ignore other case in sample code
} } if ([purchasedTransactions count] > 0) { //handle receipts here,continue step 15 } }
13
step 15~19 verify receipt with Apple server / Your server
14
How server validate a receipt
1.Apple API receipt product_id receipt bid receipt duration(auto-renewable) https://sandbox.itunes.apple.com/verifyReceipt https://buy.itunes.apple.com/verifyReceipt 2.DB ensure receipt transaction_id not used
15
step 20 Deliver purchased content
16
Overview (bad side)3.1.1 In-App Purchase, 3.1.2 Subscriptions:
If you want to unlock features or functionality within your app,you must use in-app purchase
only verify API, no webhook
When user cancel on iTunes ,Server will not get cancel request.
Can not know which Apple ID user use
Can not know purchase condition until receive receipt
17
A lot of problems we met
18
Receive sandbox receipt on production environment
production validate API -> receive 21007 status code -> try sandbox API
Solution:
18
Receive sandbox receipt on production environment
production validate API -> receive 21007 status code -> try sandbox API
Solution:
Look like workaround,but it’s spec
19
Critical:Network condition bad When Upload receipt to server
19
Critical:Network condition bad When Upload receipt to server
Business logicPurchase Manager
Purchase Manager StoreKitPurchase
ViewController
SKProductsRequestDelegateSKPaymentTransactionObserverdelegatedelegate
Solution: cache receipts , remove cache after ensure receipt is uploaded
19
Critical:Network condition bad When Upload receipt to server
Business logicPurchase Manager
Purchase Manager StoreKitPurchase
ViewController
SKProductsRequestDelegateSKPaymentTransactionObserverdelegatedelegate
cache receipts
Solution: cache receipts , remove cache after ensure receipt is uploaded
19
Critical:Network condition bad When Upload receipt to server
Business logicPurchase Manager
Purchase Manager StoreKitPurchase
ViewController
SKProductsRequestDelegateSKPaymentTransactionObserverdelegatedelegate
cache receiptstrigger API
remove receipts
Solution: cache receipts , remove cache after ensure receipt is uploaded
19
Critical:Network condition bad When Upload receipt to server
Business logicPurchase Manager
Purchase Manager StoreKitPurchase
ViewController
SKProductsRequestDelegateSKPaymentTransactionObserverdelegatedelegate
cache receiptstrigger API
remove receiptsUI
Solution: cache receipts , remove cache after ensure receipt is uploaded
20
User purchase on iTunes instead of app
case 1
1.touch purchase product on App
2.when validate AppleID, type wrong password more than 3 times
3.StoreKit ask user to change password
4.redirect to iTunes
5.type correct password and user can purchase on iTunes
21
User purchase on iTunes instead of app
touch this
itms-apps://buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/manageSubscriptionscase 2
22
User purchase on iTunes instead of appcase 2 https://buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/manageSubscriptions
touch this
23
User purchase on iTunes instead of app
Business logicPurchase Manager
Purchase Manager StoreKitPurchase
ViewController
SKProductsRequestDelegateSKPaymentTransactionObserverdelegate
delegate
Solution: init purchase manager at app launch
23
User purchase on iTunes instead of app
Business logicPurchase Manager
Purchase Manager StoreKit
Purchase ViewController
SKProductsRequestDelegateSKPaymentTransactionObserverdelegate
delegate
Solution: init purchase manager at app launch
AppDelegate init at app launch
24
What is receipt (app side)SKPaymentTransaction@property(nonatomic, readonly, nullable) NSData *transactionReceipt
/* base64 encode string */NSString *receiptString = [receipt base64EncodedStringWithOptions:0];
24
What is receipt (app side)SKPaymentTransaction@property(nonatomic, readonly, nullable) NSData *transactionReceipt
/* base64 encode string */NSString *receiptString = [receipt base64EncodedStringWithOptions:0];
25
What is receipt (server side)
25
What is receipt (server side)
25
What is receipt (server side)
26
Critical: Auto-renew fail but user receive charge mail
26
Critical: Auto-renew fail but user receive charge mailSolution: Trigger Verify API at Next day of expire_date
Not the same day
27
When switch from objC to swift
28
When switch from objC to swift
28
When switch from objC to swift
transactionReceipt property missing can only use iOS 7 style receipt
29
iOS 7 receipt
29
iOS 7 receipt
29
iOS 7 receipt
30
iOS 7 receipt
30
iOS 7 receipt
31
iOS 6 vs iOS 7 style transaction receipts• each transaction has unique iOS 6 style receipt
• iOS 7 style receipt get all receipt data in one query
• base64 encode iOS 7 style receipt is much larger than iOS 6 style
32
Will original_transaction_id change?
purchase cancel purchase again
A C
renew
a long time
B
32
Will original_transaction_id change?
purchase cancel purchase again
A C
original_transaction_id in receipt A , B and C keep the same
renew
a long time
B
33
Can I manage auto-renewable subscription in Sandbox ?
No.In addition,sandbox will auto-renew 5 times. in the end will get 6 receipt
34
What will user see in iTune Connect If my app have multiple auto-renewable products( A & B)?
34
What will user see in iTune Connect If my app have multiple auto-renewable products( A & B)?
https://buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/manageSubscriptions This URL will only work for production accounts to display existing auto-renewing subscriptions for management
35
purchase product A in app
cancel auto-renew A
in iTune
purchase product B in app
product A expire
What will user see in iTune Connect If my app have multiple auto-renewable products( A & B)?
35
purchase product A in app
cancel auto-renew A
in iTune
purchase product B in app
product A expire
What will user see in iTune Connect If my app have multiple auto-renewable products( A & B)?
iTune display product A product B
36
You can not do anything If
You have a auto renewable product,also set trial period(Eq:1 month)
But Apple receipt trial period is more than your setting
KKTV happen this few times
37
if your service has
account system + multiple platform + multiple payment
37
if your service has
account system + multiple platform + multiple payment
email facebook
phone number
iOS Android
Web PS4 …
IAP credit card
mobile payment POSA card
redeem code convenient store code
38
Example:User Apple ID KKTV
iTunesKKTV
Result:StoreKit
39
Example:User Apple ID KKTV
iTunesKKTV
Result:receipt server
KKTV
Solution:receipt Alert
39
Example:User Apple ID KKTV
iTunesKKTV
Result:receipt server
KKTV
Solution:receipt Alert
40
Example: user IAP
iTunes IAP
40
Example: user IAP
iTunes IAP
Result IAP user
40
Example: user IAP
iTunes IAP
Result IAP user
Solutionapp/server side user iTunes
41
Example:user
IAP
..... KKTV KKTV IAP
41
Example:user
IAP
ResultAppleID user
..... KKTV KKTV IAP
42
Financial
• report daily
• report user ID transactionID
• user cancel / refund
•
43
Conclusion
• IAP is unfriendly to Developer. But super easy for user.
• Tracking IAP log help find unexpected problems
• Raise IAP price could be an option
44
Reference
TN2387:In-App Purchase Best Practices TN2413: In-App Purchase FAQ In-App Purchase Programming Guide Receipt Validation Programming Guide
WWDC 2016: Using StoreKit for In-App Purchases with Swift 3 WWDC 2014: Optimizing In-App Purchases WWDC 2012: Selling Products with Store Kit WWDC 2013: Using Store Kit for In-App Purchases WWDC 2012: Managing Subscriptions with In-App Purchase TN2259: Adding In-App Purchase to your iOS and macOS Applications
https://forums.developer.apple.com/community/system-frameworks/in-app-purchase
Top Related