Store.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /******************************************************************************
  2. Use 'PlatformStore' to communicate with the Platform Store, like:
  3. Microsoft Windows Store
  4. Google Play Store for Android
  5. Apple App Store for iOS
  6. In Google Play in addition to your own item ID's, you can use the following:
  7. "android.test.purchased" - test purchase that will always succeed
  8. "android.test.canceled" - test purchase that will always fail
  9. "android.test.item_unavailable" - test purchase that will always fail due to item unavailability
  10. "android.test.refunded" - test purchase that will trigger item refund
  11. In Google Play to test your custom item ID's, make sure to run the Application:
  12. -in Release mode (which will force signing of the APK file)
  13. -on actual device (not on emulator)
  14. -with the same Package Name as in the store
  15. Otherwise testing purchases will fail with following message:
  16. "This version of the application is not configured for billing through Google Play"
  17. In Apple Store to test your custom item ID's, make sure to run the Application:
  18. -on actual device (not on simulator)
  19. -with the same Package Name as in the store
  20. -have your bank account details setup on iTunes Connect
  21. -sometimes you may need to wait a few hours after creating new items in iTunes Connect until they become available
  22. -make sure that the items in iTunes Connect are "Cleared for Sale"
  23. /******************************************************************************/
  24. #define STORE (WINDOWS_NEW || ANDROID || APPLE) // if Store is supported on this platform
  25. /******************************************************************************/
  26. struct PlatformStore // class allowing to communicate with Platform Store
  27. {
  28. #if EE_PRIVATE
  29. // !! These enums must be equal to "EsenthelActivity.java" !!
  30. #endif
  31. enum RESULT
  32. {
  33. PURCHASED , // item was purchased successfully, 'purchases' container will now include it
  34. CONSUMED , // item was consumed successfully, 'purchases' container will now not include it
  35. REFUND , // item was refunded by the store
  36. WAITING , // result is not yet known as the command was forwarded further, the result will be passed to the 'callback' function (if specified) at a later time
  37. USER_CANCELED , // user canceled purchase
  38. SERVICE_CANCELED , // service canceled purchase, possibly due to lack of funds or other payment failure
  39. SERVICE_UNAVAILABLE, // service is unavailable
  40. ITEM_UNAVAILABLE , // item was not found in the store
  41. ALREADY_OWNED , // item is already owned and can't be purchased again
  42. NOT_OWNED , // item is not owned and can't be consumed
  43. VERIFICATION_FAIL , // item purchase didn't pass the verification test based on the key provided in "Application Android License Key"
  44. UNKNOWN , // unknown error
  45. REFRESHED_ITEMS , // 'items' were refreshed, this can occur after calling the 'refreshItems' method
  46. REFRESHED_PURCHASES, // 'purchases' were refreshed, this can occur after calling the 'refreshPurchases' method
  47. };
  48. struct Item
  49. {
  50. Bool subscription; // if this is a subscription or a regular item (valid only in Google Play)
  51. Str id , // ID
  52. name , // name
  53. desc , // description
  54. price; // price
  55. };
  56. struct Purchase
  57. {
  58. Str id, // ID of the item
  59. data, // custom string that was specified in 'buy' method (valid only in Google Play)
  60. token; // token of purchase, you can use it to consume this purchase
  61. DateTime date; // date of purchase in UTC time zone
  62. };
  63. void (*callback)(RESULT result, C Purchase *purchase); // pointer to a custom function that will be called with processed events, 'result'=message received at the moment, 'purchase'=purchase data related to this message (it may be null if not available, also some of its members may be empty)
  64. // get
  65. Bool supportsItems ()C {return _supports_items;} // if store supports purchasing regular items
  66. Bool supportsSubscriptions()C {return _supports_subs ;} // if store supports purchasing subscriptions
  67. C Memc<Item >& items ()C {return _items ;} // get all known item details that were requested using 'refreshItems'
  68. C Memc<Purchase>& purchases()C {return _purchases;} // get all active purchases, you need to call 'refreshPurchases' first for this to have any
  69. C Item * findItem (C Str &item_id)C; // find item from the 'items' container by its ID, null on fail
  70. C Purchase* findPurchase(C Str &item_id)C; // find purchase from the 'purchases' container by item ID, null on fail
  71. #if EE_PRIVATE
  72. C Purchase* findPurchaseByToken(C Str &token)C; // find purchase from the 'purchases' container by its token, null on fail
  73. void update();
  74. Bool backgroundUpdate();
  75. #endif
  76. // operations
  77. Bool refreshItems (C MemPtr<Str> &item_ids); // refresh 'items' container for selected items, once the latest data has been received, 'callback' function will be called with REFRESHED_ITEMS result, false on fail, 'item_ids'=item ID's for which you want to refresh the details
  78. Bool refreshPurchases( ); // refresh 'purchases' container , once the latest data has been received, 'callback' function will be called with REFRESHED_PURCHASES result, false on fail
  79. RESULT buy(C Str &id, Bool subscription=false, C Str &data=S); // purchase an item, 'id'=ID of the item, 'subscription'=if it's a subscription or regular item (this is required only for Google Play, for Apple Store it's ignored), 'data'=custom string that will be attached to the purchase and later accessible through 'Purchase.data' (used only in Google Play, in Apple Store this is ignored)
  80. RESULT buy(C Item &item, C Str &data=S) {return buy(item.id, item.subscription, data);}
  81. RESULT consume(C Str &token); // consume purchase, 'token'=item purchase token ('Purchase.token' which can be obtained from the 'purchases' container)
  82. RESULT consume(C Purchase &purchase) {return consume(purchase.token);}
  83. PlatformStore& restorePurchases(); // this function is usable only for Apple, it will call "[[SKPaymentQueue defaultQueue] restoreCompletedTransactions]"
  84. #if !EE_PRIVATE
  85. private:
  86. #endif
  87. struct Processed : Purchase {RESULT result;};
  88. Bool _supports_items, _supports_subs, _has_new_purchases, _refresh_purchases;
  89. Memc<Item > _items, _new_items;
  90. Memc<Purchase > _purchases, _new_purchases;
  91. Memc<Processed> _processed;
  92. Thread _thread;
  93. SyncLock _lock;
  94. Memc<Str > _get_item_details, _consume;
  95. PlatformStore();
  96. ~PlatformStore();
  97. }extern
  98. Store; // access 'PlatformStore' through this singleton object
  99. /******************************************************************************/