iap auto renewable in practice

Post on 16-Apr-2017

909 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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