In this hands-on presentation, Amazon Technology Evangelist Mario Viviani will deep dive into how easily add IAP and Subscriptions to Android Apps using the Amazon In-App Purchasing and Subscriptions APIs.
The In-App Purchasing and Subscriptions APIs makes it easy for you to offer subscriptions and digital content such as in-game currency, expansion packs, upgrades, magazine issues, consumables, and more for purchase within your app.
In this presentation we will:
• Understand why is important to add IAP and Subscriptions to your App
• How to Submit In-App Items and Subscription periods on Amazon Developer Portal
• How to Test In-App Items on-device using the Amazon App Tester
• How to Add IAP SDK & APIs to your Android App in just a few minutes
Handwritten Text Recognition for manuscripts and early printed texts
Why and How to Add In-App Purchasing and Subscriptions to your Apps - Mario Viviani
1. MARIO VIVIANI
T E C H N O L O G Y E V A N G E L I S T, A M A Z O N A P P S T O R E E U
@mariuxtheone marioviviani
W H Y A N D H O W TO A D D
I N - A P P P U R C H A S I N G A N D
S U B S C R I P T I O N S TO Y O U R A P P S
2. I T ’ S A - M E !
Ma r io V ivia n i
Technology Evangelist, Amazon Appstore EU
@mariuxtheone
Android Developer since 2010
95+ apps published
12,000,000+ downloads
Google Developer Expert 2013-15
Startup Founder, Co-Worker
Speaker at: Droidcon,
Casual Connect, Big Android BBQ,
Google I/O
7. A M A Z O N S U B S C R I P T I O N S
Amazon Appstore UK Data: Jan – May 2017
96% OF SUBSCRIPTIONS COME FROM
AMAZON DEVICES
8. A M A Z O N S U B S C R I P T I O N S O N F I R E T V
+150% YoY
Amazon Fire TV
Subscription
Revenue
Amazon Appstore UK Data: Jan – May 2017
9. A M A Z O N S U B S C R I P T I O N S O N F I R E T V
+1400% YoY
Fire TV
On-Demand
Movie Streaming
Category Revenue
Amazon Appstore UK Data: Jan – May 2017
+125% YoY
Fire TV
Sports
Category Revenue
10. TO P 1 0 G R O S S I N G A P P C AT E G O R I E S U S I N G S U B S C R I P T I O N S
Amazon Appstore UK Data: Jan – May 2017
1. Newspapers and Magazines
2. On-Demand Movie Streaming
3. Magazines
4. Novelty
5. Sports
6. Education
7. News
8. Adventure
9. Trivia
10.Document Editing
(AGGREGATE OF AMAZON DEVICES AND NON-AMAZON ANDROID)
11. TO P 1 0 G R O S S I N G A P P C AT E G O R I E S U S I N G S U B S C R I P T I O N S
Amazon Appstore UK Data: Jan – May 2017
1. On-Demand Movie Streaming
2. Sports
3. Novelty
4. Newspapers
5. Magazines
6. Workout Guides
7. Concert Finders
8. News
9. Outdoors & Nature
10. News, Politics and Opinion
1. Newspapers
2. Magazines
3. Education
4. News
5. Adventure
6. Trivia
7. Document Editing
8. On-Demand Movie Streaming
9. News, Politics and Opinion
10. Music & Rhythm
AMAZON FIRE TV AMAZON FIRE TABLETS
13. A P P M O N E T I S AT I O N M O D E L S
Paid
Apps
In-App
Items
Subscriptions
AD
Advertisement
Amazon In-App Purchase API
14. W H Y A M A Z O N I A P & S U B S C R I P T I O N A P I
A D VA N TA G E S
Provide IAP Items,
Entitlements & Subscriptions
Handles purchase flow, payment
processing, receipts, and rights
management.
Amazon 1-Click Settings
18. I N - A P P I T E M S : A B R E A K D O W N
T Y P E O F I N - A P P I T E M IN-APP ITEMS INFO
Consumables
Entitlements
Subscriptions
• Title
• SKU
• Content delivery
• Availability & Pricing
• Subscription Periods
(subscriptions only)
• Free Trial (subscriptions only)
• Description
• Images
19. T E S T I A P I T E M S & S U B S C R I P T I O N S O N - D E V I C E
CONFIGURE IAP ITEMS
ON DEV PORTAL
LAUNCH AND TEST
IAP & SUBSCRIPTION
INSTALL
AMAZON APP TESTER
ON YOUR TEST DEVICE
RETRIEVE JSON OF IAP
ITEMS
JSON
24. 5 ) F I N A L I S E & D O W N L O A D J S O N
amazon.sdktester.json
25. A M A Z O N . S D K T E S T E R . J S O N
{
"com.amazon.sample.iap.subscription.mymagazine.month": {
"description":"Monthly Subscription to My Magazine",
"title":"My Magazine",
"itemType":"SUBSCRIPTION",
"price":5.0,
"subscriptionParent":"com.amazon.sample.iap.subscription.mymagazine"
}
}
Child SKU – Subscription Period
Parent SKU
26. A M A Z O N . S D K T E S T E R . J S O N
{
"com.amazon.sample.iap.subscription.mymagazine.month": {
"description":"Monthly Subscription to My Magazine",
"title":"My Magazine",
"itemType":"SUBSCRIPTION",
"price":5.0,
"subscriptionParent":"com.amazon.sample.iap.subscription.mymagazine"
},
"com.amazon.sample.iap.subscription.mymagazine.quarter": {
"description":"Quarterly Subscription to My Magazine",
"title":"My Magazine",
"itemType":"SUBSCRIPTION",
"price":12.0,
"subscriptionParent":"com.amazon.sample.iap.subscription.mymagazine"
}
}
27. I N S TA L L A M A Z O N A P P T E S T E R F R O M A P P S TO R E
28. I N S TA L L A M A Z O N A P P T E S T E R F R O M A P P S TO R E
29. I N S TA L L A M A Z O N A P P T E S T E R F R O M A P P S TO R E
36. T H E M A I N C O M P O N E N T S O F T H E I A P S D K
PurchasingListener
PurchasingService
ResponseReceiver
37. A D D R E S P O N S E R E C E I V E R TO A N D R O I D M A N I F E S T
<application>
...
<receiver android:name = "com.amazon.device.iap.ResponseReceiver" >
<intent-filter>
<action android:name = "com.amazon.inapp.purchasing.NOTIFY"
android:permission = "com.amazon.inapp.purchasing.Permission.NOTIFY" />
</intent-filter>
</receiver>
...
</application> Response
Receiver
38. F E T C H T H E U S E R & R E C E I P T S D ATA
String parentSKU = "com.amazon.sample.iap.subscription.mymagazine";
@Override
protected void onResume() {
super.onResume();
PurchasingService.getUserData();
PurchasingService.getPurchaseUpdates(true);
final Set<String> productSkus = new HashSet<String>();
productSkus.add(parentSKU);
PurchasingService.getProductData(productSkus);
}
Purchasing
Service
39. I N I T I A L I Z E P U R C H A S I N G L I S T E N E R
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PurchasingService.registerListener(this, purchasingListener);
...
40. T H E P U R C H A S I N G L I S T E N E R
PurchasingListener purchasingListener = new PurchasingListener() {
@Override
public void onUserDataResponse(UserDataResponse userDataResponse) {...}
@Override
public void onProductDataResponse(ProductDataResponse productDataResponse) {...}
@Override
public void onPurchaseResponse(PurchaseResponse purchaseResponse) {...}
@Override
public void onPurchaseUpdatesResponse(PurchaseUpdatesResponse purchaseUpdatesResponse) {…}
};
Purchasing
Listener
41. @Override
public void onUserDataResponse(UserDataResponse response) {
final UserDataResponse.RequestStatus status = response.getRequestStatus();
switch (status) {
case SUCCESSFUL:
currentUserId = response.getUserData().getUserId();
currentMarketplace = response.getUserData().getMarketplace();
break ;
case FAILED:
case NOT_SUPPORTED:
// Fail gracefully.
break ;
}
}
U S E R D ATA R E S P O N S E
Purchasing
Listener
Response
Receiver
42. P R O D U C T D ATA R E S P O N S E
Purchasing
Listener
Response
Receiver
@Override
public void onProductDataResponse(ProductDataResponse response) {
switch (response.getRequestStatus()) {
case SUCCESSFUL:
for ( final String s : response.getUnavailableSkus()) {
//perform action to hide/display unavailable SKUs
}
break ;
case FAILED:
break ;
}
}
43. Button button = (Button) findViewById(R.id.subscriptionButton);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
PurchasingService.purchase(parentSKU);
}
});
P E R F O R M I N G P U R C H A S E
Purchasing
Service
44. @Override
public void onPurchaseResponse(PurchaseResponse purchaseResponse) {
logthis("onPurchaseResponse");
logthis("Response: "+purchaseResponse.getRequestStatus().name());
logthis("SKU Purchased:"+purchaseResponse.getReceipt().getSku());
switch (purchaseResponse.getRequestStatus()) {
case SUCCESSFUL:
//notify fulfillment of the transaction
PurchasingService.notifyFulfillment(purchaseResponse.getReceipt().getReceiptId(),
FulfillmentResult.FULFILLED);
break ;
case FAILED:
break ;
}
}
@Override
public void onPurchaseResponse(PurchaseResponse purchaseResponse) {
logthis("onPurchaseResponse");
logthis("Response: "+purchaseResponse.getRequestStatus().name());
logthis("SKU Purchased:"+purchaseResponse.getReceipt().getSku());
switch (purchaseResponse.getRequestStatus()) {
case SUCCESSFUL:
//notify fulfillment of the transaction
PurchasingService.notifyFulfillment(purchaseResponse.getReceipt().getReceiptId(),
FulfillmentResult.FULFILLED);
break ;
case FAILED:
break ;
}
}
P U R C H A S E R E S P O N S E
Purchasing
Listener
Purchasing
Service
Response
Receiver
45. P U R C H A S E U P D AT E S R E S P O N S E & G R A N T I N G I A P I T E M
@Override
public void onPurchaseUpdatesResponse(PurchaseUpdatesResponse response) {
switch (response.getRequestStatus()) {
case SUCCESSFUL:
for ( final Receipt receipt : response.getReceipts()) {
// Process receipts
if (!receipt.isCanceled()){
// GRANT THE ITEMS TO THE USER
}
}
if (response.hasMore()) {
PurchasingService.getPurchaseUpdates(true);
}
break ;
case FAILED:
Log.d("FAILED","FAILED");
break ;
}
}
};
Purchasing
Listener
Purchasing
Service
Response
Receiver