Esenthel Store.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /******************************************************************************
  2. Use 'EsenthelStore' to communicate with Esenthel Store.
  3. You can use it for example if you've developed a game which is sold through Esenthel Store,
  4. and in the game you'd like to verify if it's a licensed copy.
  5. This testing can be done for example in following way:
  6. 1. Ask the user for license key
  7. 2. Test that license key (optionally with Device ID of the user's device)
  8. 3. Allow to play the game only based on successful response from Esenthel Store
  9. 'EsenthelStore' class can also be used for making In-App purchases.
  10. /******************************************************************************/
  11. struct EsenthelStore // class allowing to communicate with Esenthel Store
  12. {
  13. enum RESULT
  14. {
  15. NONE , // nothing was ordered yet
  16. INVALID_ITEM , // 'item_id' is invalid
  17. INVALID_LICENSE_KEY_FORMAT, // 'license_key' was specified however it is not of the "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX" format
  18. INVALID_EMAIL_FORMAT , // 'email' was specified however it is not of correct format
  19. INVALID_PASSWORD , // 'password' is invalid, its length must be between 4..16 characters and may not contain unicode characters
  20. INVALID_NAME , // 'name' is invalid, its length must not exceed 32 characters
  21. INVALID_CALL , // '_purchasesRefresh' was called
  22. CONNECTING , // connecting to Esenthel Store at the moment
  23. CANT_CONNECT , // could not connect to Esenthel Store
  24. INVALID_RESPONSE , // received an invalid response from Esenthel Store
  25. DATABASE_ERROR , // Esenthel Store replied that it couldn't connect to the DataBase
  26. EMAIL_NOT_FOUND , // Esenthel Store replied that given email was not found
  27. EMAIL_ALREADY_EXISTS , // Esenthel Store replied that given email is already in use
  28. LICENSE_KEY_FAIL , // Esenthel Store replied that given license is not valid for the specified item
  29. DEVICE_ID_FAIL , // Esenthel Store replied that given license is valid for the specified item however 'DeviceID' did not match the one in the store
  30. CONFIRM_CODE_FAIL , // Esenthel Store replied that given license is valid for the specified item and 'DeviceID' matches the one in the store however confirmation code was incorrect (this may be caused by user having invalid time/date/timezone on his device)
  31. OK , // Esenthel Store replied that given license is valid for the specified item and 'DeviceID' matches the one in the store and confirmation code was correct
  32. };
  33. static void RegisterAccount(); // this function will open Esenthel Store website in a System Browser for the purpose of registering a new account there
  34. // LICENSE VERIFICATION
  35. static Str DeviceID() {return EE::DeviceID(true).asHex();} // get Device ID used in Esenthel Store, you can use this function to get the ID of current device and display it to the users, so they can set it for their products in Esenthel Store if needed
  36. // operations
  37. void licenseClear(Bool params=true); // cancel any current 'licenseTest' request and clear the 'licenseResult' to NONE, 'params'=if additionally clear the last specified parameters (such as 'licenseItemID', 'licenseKey' and 'licenseEmail')
  38. void licenseTest (Int item_id, C Str &license_key=S, C Str &email=S, Bool device_id=false); // test if license is ok for a given item in Esenthel Store, 'item_id'=ID of an item in Esenthel Store (if you're the author of the item, then you can get its ID from Esenthel Store), following parameters are optional, only one of them needs to be specified (for example you can test only license key, only email, only device id, or multiple at the same time), 'license_key'=if specified (must be of "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX" format) then the license key will be tested if it's valid for the specified item in Esenthel Store, 'email'=test if there exists a user account with specified email address which has a valid license key for specified item, 'device_id'=test if Device ID of current machine matches the one assigned to the license key, once this function is called it will try to connect to Esenthel Store on a secondary thread to verify the data, while it's running you can investigate the 'licenseResult' method to get the results
  39. // get
  40. RESULT licenseResult(); // get result of the 'licenseTest'
  41. Int licenseItemID()C {return _license_item_id;} // get item id that was specified in the last 'licenseTest' request
  42. C Str& licenseKey ()C {return _license_key ;} // get license key that was specified in the last 'licenseTest' request
  43. C Str& licenseEmail ()C {return _license_email ;} // get email that was specified in the last 'licenseTest' request
  44. // IN-APP PURCHASES
  45. enum PURCHASE_TYPE : Byte
  46. {
  47. PURCHASE_1 , // 0.99 USD In-App Purchase
  48. PURCHASE_2 , // 1.99 USD In-App Purchase
  49. PURCHASE_3 , // 2.99 USD In-App Purchase
  50. PURCHASE_5 , // 4.99 USD In-App Purchase
  51. PURCHASE_10 , // 9.99 USD In-App Purchase
  52. PURCHASE_20 , // 19.99 USD In-App Purchase
  53. PURCHASE_50 , // 49.99 USD In-App Purchase
  54. PURCHASE_100, // 99.99 USD In-App Purchase
  55. };
  56. struct Purchase
  57. {
  58. Str id ; // unique ID of this purchase
  59. PURCHASE_TYPE type; // purchase type
  60. DateTime date; // date of purchase in UTC time zone
  61. };
  62. static RESULT GetAccessKey(Int item_id); // this function will open Esenthel Store website in a System Browser and display to the user an "Access Key", which he can copy to the System Clipboard and then use it inside your Apps for the 'purchasesRefresh' method. That "Access Key" works like a password (however it is not the same as user's account password), allowing the app to operate on In-App purchases, 'item_id'=ID of an item in Esenthel Store (if you're the author of the item, then you can get its ID from Esenthel Store)
  63. static RESULT Buy(C Str &email, Int item_id, PURCHASE_TYPE purchase_type); // this function will open Esenthel Store website in a System Browser for the purpose of making a purchase, 'email'=Esenthel Store account email, 'item_id'=ID of an item in Esenthel Store (if you're the author of the item, then you can get its ID from Esenthel Store), 'purchase_type'=type of the purchase
  64. static Int PurchaseToUSD(PURCHASE_TYPE purchase_type); // convert 'purchase_type' into a USD amount rounded to the nearest integer, PURCHASE_2 -> 2, PURCHASE_3 -> 3, PURCHASE_5 -> 5, ..
  65. void purchasesClear (); // cancel any current 'purchasesRefresh' request, clear 'purchasesResult' to NONE and clear 'purchases'
  66. RESULT purchasesResult(); // get result of 'purchasesRefresh'
  67. C Memc<Purchase>& purchases (); // get all active purchases, you need to call 'purchasesRefresh' first for this to have any
  68. C Str & purchasesEmail ()C {return _purchase_email;} // get email that was specified in the last 'purchasesRefresh' request
  69. void purchasesRefresh(C Str &email, C Str &access_key, Int item_id); // refresh the list of purchases by contacting Esenthel Store, 'email'=Esenthel Store account email for the owner of the purchases, 'access_key'=access key allowing to contact Esenthel Store (THIS IS NOT Esenthel Store account password !! access key must be obtained using 'GetAccessKey' function), 'item_id'=ID of an item in Esenthel Store (if you're the author of the item, then you can get its ID from Esenthel Store), after calling this method you can monitor 'purchasesResult' for progress about the refresh, list of purchases will be available using the 'purchases' method
  70. RESULT consume (C Str &email, Int item_id, C Str &purchase_id); // consume a specific purchase, 'email'=Esenthel Store account email for the owner of the purchases, 'item_id'=ID of an item in Esenthel Store (if you're the author of the item, then you can get its ID from Esenthel Store), 'purchase_id'=unique ID of the purchase to be consumed (this is 'Purchase.id'), once this method is called, Esenthel Store will be contacted with the request of removing the purchase from its database, upon success, the purchase will be automatically removed from the 'purchases' list, this method may fail if Internet connection was lost/unavailable
  71. RESULT consume (C Str &email, Int item_id, C Purchase &purchase ) {return consume(email, item_id, purchase.id);} // consume a specific purchase, 'email'=Esenthel Store account email for the owner of the purchases, 'item_id'=ID of an item in Esenthel Store (if you're the author of the item, then you can get its ID from Esenthel Store), 'purchase_id'=unique ID of the purchase to be consumed (this is 'Purchase.id'), once this method is called, Esenthel Store will be contacted with the request of removing the purchase from its database, upon success, the purchase will be automatically removed from the 'purchases' list, this method may fail if Internet connection was lost/unavailable
  72. EsenthelStore();
  73. // DO NOT USE the following method, as IT WILL NOT WORK for your In-App purchases
  74. void _purchasesRefresh(C Str &email, C Str &password, Int item_id);
  75. #if !EE_PRIVATE
  76. private:
  77. #endif
  78. Bool _device_id;
  79. Int _license_item_id, _purchase_item_id;
  80. UInt _license_r, _purchase_r;
  81. RESULT _license_result, _purchase_result;
  82. Str _license_key, _license_email, _purchase_email;
  83. Download _license_download, _purchase_download;
  84. Memx<Download> _consume;
  85. Memc<Purchase> _purchases;
  86. #if EE_PRIVATE
  87. void updateLicense ();
  88. void updatePurchases();
  89. #endif
  90. };
  91. /******************************************************************************/