Search Unity

How To Use Prime 31 Storekit

Discussion in 'iOS and tvOS' started by dlhilemanjr, Jun 6, 2012.

  1. dlhilemanjr

    dlhilemanjr

    Joined:
    Jun 6, 2012
    Posts:
    30
    Hello everyone. I purchased Prime 31's Storekit Plugin and I'm not sure how to use it. I understand that the plugin requests and recieves information from ITC. I tested the test scene that comes with it and I was successfully able to connect to ITC with it. In the XCode Console I saw that it received how many In App Purchases that are available and it allowed me to go through the purchase cycle but I'm not sure exactly how to setup a store and use that information to unlock items. I am creating an interactive touch reader for children and want them to be able to download addition scenes or what they will think is books.

    I apologize for the newbie questions. Below are the things I'm confused about:

    1. Should the Get Product Information be automatically loaded when the store scene is loaded or does the user have to manually press a button to get Product Info from ITC? I know that Apple requires product data to be received before purchases can be made but where I'm confused is does this have to be a manual action by the user or does it automatically do this when the store containing my items opens.

    2. Once the Product Info is loaded, should it generate the products on the page such as show descriptions and generate product images or are those items already showi g on the page. What I mean is, do I create all the buttons and images and have them always visible or should they be unlocked when the plugin gets the Product Info from ITC.

    3. Finally, from what I read, I should use PlayerPrefs on locked items and once purchased, the PlayerPref changes to a value that unlocks it. How do I do that?

    Once again I apologize for the newbie questions. I have spent the last two days reading everything I could include the documentation on Prime 31's site as well as the links in that documentation but I am still lost and not sure how to implement the PlugIn into my app. I was only able o find a few tutorials online and the Prime 31 documentation doesn't go into much detail on how to use this plugin or maybe I'm just missing it. I have also checked YouTube but haven't come up with much other than for doing this in XCode itself.
     
    Last edited: Jun 6, 2012
  2. andymads

    andymads

    Joined:
    Jun 16, 2011
    Posts:
    1,614
    My short answer is that you should decide what you want it to do.

    I have some experience with consumables in our game, i.e. IAP of in-game currency like coins for example. Your products will likely be non-consumables. If you've read the Apple docs then you know about these.

    My preference would be to have a store retrieves the product data automatically. Perhaps it could be done quietly in the background before the user even gets to open the store page? Failing that, do it on opening the store page but obviously deal with the fact that the retrieval takes time and may also fail. So just let it take place without blocking and deal with the results accordingly. Maybe you need placeholders in your store that get filled in when the products are retrieved, perhaps with progress spinners so that the user understands what is happening? Perhaps inform the user with a message while the retrieval takes place. Once you have the product data you can update the store to reflect the data and enable/show purchase buttons, etc.

    Clearly you will have to save something internally to say that the user has purchased a 'book' so that they have it the next time the app is run. You can use the PlayerPrefs for saving this, although if the app is removed then you'll lose this save date. I believe you can retreive a list of product previously purchased by the user, which would allow you to reinstate any purchases.
     
  3. dlhilemanjr

    dlhilemanjr

    Joined:
    Jun 6, 2012
    Posts:
    30
    Hi andym. Thank you for taking the time to respond to my post. Everything you said makes sense, I just need to figure out how to use the plugin to make all that happen. That is where I'm lost. I got the sample scene to successfully connect to ITC and pull info, just need how to take that info and change the Playerprefs to something hat unlocks the In App Purchases after they are bought. The more I play with it, the more it makes sense, I'm just not far enough along to make it happen yet.
     
  4. laserlars

    laserlars

    Joined:
    Nov 17, 2011
    Posts:
    255
    Have you read the API docs from Prime?
    I haven't usedthe StoreKit plugin, but some other prime-plugins and they are pretty much the same in use.

    public static event Action<StoreKitTransaction> purchaseSuccessful; in StoreKitManager.cs will fire when the player has successfully purchased an item. This is a good spot to change your PlayerPrefs value.
     
  5. foemoe

    foemoe

    Joined:
    Jun 13, 2012
    Posts:
    7
    I'm still learning myself so take what i say with a grain of salt:

    You can use PlayerPrefs.SetBool and PlayerPrefs.GetBool to store whether or not something is unlocked, you'll definitely want to do that so they can instantly access previous purchases regardless of internet connection.

    To restore previous transactions (in case the app is deleted or loading onto another ios device):
    Code (csharp):
    1. StoreKitBinding.restoreCompletedTransactions();
    This will 're-fire' purchase_completed actions. You'll need to create a function to 'grab' the purchase completed action when it fires, something like this in the Start() function:

    Code (csharp):
    1. StoreKitManager.purchaseSuccessful += purchase_sucessful;
    Once you've done that you create a 'purchase_sucessful' function that you named above :

    Code (csharp):
    1. public void purchase_sucessful(StoreKitTransaction transaction)
    2.     {  
    3.         if(transaction.productIdentifier == "world_2") //this is the id you setup in itunes connect
    4.             { dataCore.unlock_world_2(); }  //dataCore is my data save handler (playerprefs wrapper)
    5.  
    6.         Debug.Log("Sucessful Purchase ");  
    7.     }
    8.  
    You can take a look at StoreKitEventListener to see how it grabs events/actions from StoreKitManager.
     
  6. dlhilemanjr

    dlhilemanjr

    Joined:
    Jun 6, 2012
    Posts:
    30
    Thank you foemoe. That helped a lot. It is all starting to make sense to me. I think where I'm going wrong is I'm over thinking everything. I have been staring at that code for 5 days. May be time to walk away for a day so i can put a fresh set of eyes on it.
     
  7. Daniel FF

    Daniel FF

    Joined:
    Mar 23, 2009
    Posts:
    70
    And about validateReceipt ? How should it be used?
     
  8. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @daniel, neither Apple nor us recommend doing receipt validation on the device. The only secure way to do it is on an external server. The validate method is in the plugin only for legacy purposes.
     
  9. madpoet0204

    madpoet0204

    Joined:
    Sep 10, 2012
    Posts:
    98
    What's the easiest way to print the product identifier info. Xcode reports it in the console but I
    don't know how to get those strings and pass to a gui text. Also, when product is purchased, what is the
    best way to confirm the purchase... BIG THX to any tips...

    <StoreKitProduct>
    ID: com.thecompany etc.
    Title:
    Description: trex description ROAR!
    Price: 0.99
    Currency Symbol: $
    Formatted Price: $0.99
    Currency Code: CAD
     
  10. andymads

    andymads

    Joined:
    Jun 16, 2011
    Posts:
    1,614
    @madpoet2004, you use the StoreKitManager events, e.g. productListReceivedEvent, which will give you a list of products. You can then do what you want with these products.

    See the docs here.
     
  11. madpoet0204

    madpoet0204

    Joined:
    Sep 10, 2012
    Posts:
    98
    Can I get a code example:

    Something like
    var product price = theproduct[0];

    Much appreciated andymads..:)
     
  12. madpoet0204

    madpoet0204

    Joined:
    Sep 10, 2012
    Posts:
    98
    I've tried this but it doesn't seem to work. I don't think it's
    firing. I was expecting it to fire after the
    StoreKitBinding.requestProductData( productIdentifiers );
    is invoked.
    Code below:

    void productListReceivedEvent( List<StoreKitProduct> productList )

    {


    Debug.Log ("my products " + productList);

    }
     
  13. andymads

    andymads

    Joined:
    Jun 16, 2011
    Posts:
    1,614
    I think you need to start with learning about actions.

    See Prime31's tutorial video.

    This will help you understand the documentation I linked to before.
     
  14. madpoet0204

    madpoet0204

    Joined:
    Sep 10, 2012
    Posts:
    98
    For anyone having a problem with accessing the product info...:)

    StoreKitManager.productListReceivedEvent += allProducts =>
    {

    _products = allProducts;

    print("We have the products here!!!!"+_products[0] );
    print("The price is here!!!!!"+_products[0].price );
    print("description"+_products[0].description );

    }
     
  15. liven410

    liven410

    Joined:
    Dec 23, 2010
    Posts:
    36
    Hi all,

    I want to setup IAP for a non-consumable product. When i press on buy it takes some time to get product details and then buy the product. So, what i want is to have an activity indicator or progress indicator or please wait indicator like the Maze+ game on appstore has wile product information is received.

    Means When i press on buy, the time it takes between getting the product details and showing the final alert "Do you want to buy xyz product?". And for that timegap i would like show an UIAlert kind of thing on screen, with the activity indicator spinning before the confirmation to purhase alert comes.

    I thing, I have detailed my query, but sorry if anybody finds it hard to get. You can simply check the Maze+ game for that (even temple run has the same kind of thing)

    thanks everyone.. ;)
     
  16. CazicThule

    CazicThule

    Joined:
    Nov 29, 2012
    Posts:
    95
    StoreKitManager.productListReceivedEvent += allProducts => is returning 0 products for me even though I have two products set up in ITC. Have I missed something? The IAPs will be on the latest version of an existing app.
     
  17. jugnu

    jugnu

    Joined:
    Jul 17, 2012
    Posts:
    28
    Hi i am using Plain StoreKitTestScene canMakePayment always returning false on the device. i have created the Test User Acc.

    1) Do i have to log-in with test user acc to test it.
    2) Where should i verify the Product Identifier.
    3) youtube video is quite old with the New Plug-in which is released in Jan on the Unity Asset store i am facing problem. I haven't done IAP earlier, so need little help over here.
     
  18. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @cazic, ensure you bundle ID is properly setup and that you are using the matching provisioning profile along with test uesrs created in iTunes Connect. Apple will not recognize your app until everything matches correctly.


    @jugnu, the docs (http://prime31.com/docs#iosStoreKit ) have bulleted list of requirements and link to Apple's docs and other tutorials explaining the process. Per our docs and Apple's, you should log out of the Store via the Settings.app. I have no idea what you mean you you say "verify the Product Identifier". There is no such process via Apple's API. It is up to you to properly copy/paste the identifier from iTunes Connect as you set it up.
     
  19. games-james

    games-james

    Joined:
    Jan 17, 2013
    Posts:
    7
    Hi , I need to validate my ios in app reciept with my own server ..... where is the provision imade to put my server link (url ) for verification....
    as now in the new storekit plugin there is only libStoreKit.a file present ....
     
  20. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @games, visit Apples docs to learn how to validate receipts on your own server. They have a guide showing what you need to do.
     
  21. Banderous

    Banderous

    Joined:
    Dec 25, 2011
    Posts:
    669
    To anyone else I recommend upgrading to Unibill. It will retrieve your product data for you, and it also maintains a local PlayerPrefs database of purchases, not to mention equally seamless integration with Google Play and the Amazon App store.
     
  22. games-james

    games-james

    Joined:
    Jan 17, 2013
    Posts:
    7
    @prime[31] : Thanks for your reply. My Concern was that where to write my server URL ...earlier i use to write the my server url in StoreKitReceiptRequest.m file now there is lib file present instead of that file...
     
  23. games-james

    games-james

    Joined:
    Jan 17, 2013
    Posts:
    7
    @prime[31] : Thanks for your reply. My Concern was that where to write my server URL ...earlier i use to write the my server url in StoreKitReceiptRequest.m file now there is lib file present instead of that file...
     
  24. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @james, when your purchase is complete you would just use the normal Unity WWW class to validate the receipt.
     
  25. francksitbon

    francksitbon

    Joined:
    Jan 22, 2010
    Posts:
    268
    Any idea how I can do this in java script ?
    Thanks
     
  26. francksitbon

    francksitbon

    Joined:
    Jan 22, 2010
    Posts:
    268
    How can I get this in JavaScript ?
    Thks

     
  27. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @franck, please do not SPAM multiple support outlets with the same question. You will have to soft through the Unity docs to learn the UnityScript syntax for generic Lists. We do not use UnityScript at all due to its missing features, lack of code complete, poor documentation, etc.
     
  28. francksitbon

    francksitbon

    Joined:
    Jan 22, 2010
    Posts:
    268
    Yea Sorry I'm stuck for a couple days on it, and I didn't get any answer, I almost forgot I asked 3 days ago
     
  29. francksitbon

    francksitbon

    Joined:
    Jan 22, 2010
    Posts:
    268
    Actually really weird! something Alzheimer
     
  30. francksitbon

    francksitbon

    Joined:
    Jan 22, 2010
    Posts:
    268
    In case, it might help for finding an answer, I used this tutorial : http://gordonroberts.net/blog/

    Here is my code :

    (sorry I only know Javascript)



    I got these errors :

    BCE0032: The event 'StoreKitManager.productListReceivedEvent' expects a function reference compatible with 'function(System.Collections.Generic.List.<StoreKitProduct>): void'.

    BCE0019: 'formattedPrice' is not a member of 'T'.
     
  31. GordonRoberts

    GordonRoberts

    Joined:
    Dec 14, 2012
    Posts:
    8
    blog editor ate some of the text, I'll fix the blog post, sorry for the problems

    var listProducts = new String[3];

    function Start()

    listProducts[0] = "abc.gordonrobert.puzzletwox";
    listProducts[1] = "abc.gordonrobert.puzzletenxx";
    listProducts[2] = "abc.gordonrobert.puzzleunlimitedxxx";
    //Listen for product list
    StoreKitManager.productListReceivedEvent += productListReceived;
    //listen for purchase
    StoreKitManager.purchaseSuccessfulEvent += purchaseSuccessful;
    //Request product list
    StoreKitBinding.requestProductData(listProducts);

    function productListReceived(aProducts : System.Collections.Generic.List.<StoreKitProduct>){

    for (var i = 0; i < 3; i++) {
    print (aProducts.formattedPrice);
    }

    }
     
    Last edited: Feb 14, 2013
  32. francksitbon

    francksitbon

    Joined:
    Jan 22, 2010
    Posts:
    268
    Thanks a lot Gordon!
     
  33. rbarbosa

    rbarbosa

    Joined:
    Jun 20, 2012
    Posts:
    61
    I'm having a problem that is not related to Prime[31] but I'm hoping the StoreKit plugin has a solution for it.

    I want an identifier of some kind that indicates a cash exchange. I have a multi-platform game project that allows a player to login on any device. But once they have upgraded to a premium account...they become premium on all platforms.

    The mechanics of this are mostly functional. The only gap is that I keep getting a unique transaction ID each time the store transaction goes through. Which is fine because I don't want to charge the person again...but I would like to be able to identify a specific payment transaction and have it stick. That way if the player downloads the update several times...they will always have the same payment ID. Then I can reconcile money in with actual payments.

    Right now, if the same player downloaded the upgrade 10 times...I'd only get paid for 1 of those transactions, but they would each have their own transaction ID. I'm hoping that Prime[31]'s StoreKit plugin allows me to gain access to the ID for the payment (which only happens once).

    Any thoughts?
    --RB
     
  34. rbarbosa

    rbarbosa

    Joined:
    Jun 20, 2012
    Posts:
    61
    I think what I want to do might require me to go through the transaction restoration process. So I can refer back to the original transaction. But I'm having a hard time understanding how Prime[31] implements that in Storekit.
     
  35. rbarbosa

    rbarbosa

    Joined:
    Jun 20, 2012
    Posts:
    61
    If anyone else is having this problem, I've managed a solution. As I indicated in my original post, this was not indicative of a bug or failure in prime[31]'s plugin.

    The Apple docs account for the transaction restoration process and suggest that within each restored transaction there will be an "originalTransaction" property. I was not able to find an analog to this in the prime[31] plugin. More info about transaction restoration can be found here:

    Apple docs...

    That being said, if you are selling a non-consumable, one-time-per-Apple-ID purchase (like a premium upgrade in my case), then you do not actually need to go through the transaction restoration process. You can simply use the exact same purchase process.

    In my case, I'm taking the base64 encoded receipt string (it's available in the prime[31] transaction object), and posting it to my game's server before I process the upgrade in my game's database. On the server, I take the string and add it to a JSON packet (DO NOT BASE64 DECODE IT...SEND IT AS-IS) under the key "receipt-data" as described here.

    Post that JSON packet to Apple's receipt verification process:

    For test purchases: https://sandbox.itunes.apple.com/verifyReceipt
    For production purchases: https://buy.itunes.apple.com/verifyReceipt

    If all goes well, you'll get a JSON packet back. Check the packet for an error (a non-zero value in the "status" of the JSON object). If there is no error, then you will have a "transaction_id" property. If this is a re-purchase, you will ALSO have an "original_transaction_id" property. Use that one if you want to reconcile the transaction back to a cash exchange.

    I use this to ensure that people can't log in with an Apple ID that's paid for a premium upgrade and use it to upgrade their friend's account on my game server. Without being to track an ID back to a cash exchange, it would be theoretically possible for someone to game the system and upgrade multiple accounts to premium status while only paying once.

    Hope this helps someone...
    --RB
     
    Last edited: Feb 19, 2013
  36. DannyB

    DannyB

    Joined:
    Jun 20, 2012
    Posts:
    214
    Hello everybody,

    How do I properly use restoreCompletedTransactions()?
    A post on page 1 of this thread claims that this method is triggering the purchaseSuccessfulEvent but it doen't happen for me.

    I know that restoreCompletedTransactions did something, since I get a trigger from the restoreTransactionsFinishedEvent event.

    I am able to make purchases successfully in my code, but I can't figure out how to restore transactions.

    Thanks.

    EDIT:
    Sorry - I believe it is my bad. I tested on a user that purchased only consumable products. After testing on another user, which also had a non consumable purchase, it seems to be working as advertised.
     
    Last edited: Mar 1, 2013
  37. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @danny, restoreCompletedTransactions will trigger a purchaseSuccessfulEvent for each and every transaction that it restores.
     
  38. DannyB

    DannyB

    Joined:
    Jun 20, 2012
    Posts:
    214
    Thanks Mike - just to make sure I got it all right: It will NOT trigger any event for consumable products, correct? At least this is the behavior I see, which makes sense to me.
     
  39. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @danny, per Apples docs a consumable cannot be restored.
     
  40. echoic

    echoic

    Joined:
    Apr 29, 2011
    Posts:
    91
    This may be a C related question (I've only used Javascript), but how can I save PlayerPrefs immediately after the StoreKitBinding.purchaseProduct event? I'm able to make a purchase and save PlayerPrefs, but I'd like to save immediately once the purchase has been confirmed. I wish there were more java examples ><

    Anyway, thanks in advance!
     
  41. laserlars

    laserlars

    Joined:
    Nov 17, 2011
    Posts:
    255
    PlayerPrefs.Save ?
     
  42. echoic

    echoic

    Joined:
    Apr 29, 2011
    Posts:
    91
    If I edit PlayerPrefs right after StoreKitBinding.purchaseProduct, the PlayerPrefs will change even if the purchase has not completed successfully. I know how to check that the purchase has completed successfully, but the check doesn't work within the same if statement that holds the purchaseProduct event. I have to click two buttons to get both results.
     
    Last edited: Apr 3, 2013
  43. laserlars

    laserlars

    Joined:
    Nov 17, 2011
    Posts:
    255
    Wait for the listener to trigger, as seen in the storekit docs:
    public static event Action<StoreKitTransaction> purchaseSuccessfulEvent;

    There's a good spot to write your prefs.
     
  44. madpoet0204

    madpoet0204

    Joined:
    Sep 10, 2012
    Posts:
    98
    I'm trying to implement restore transactions on an existing app that has IAP.

    When I test w/test account, it doesn't keep the transaction history when deleting and
    re-installing on device.

    My code is:
    on a button touch I call this:
    StoreKitBinding.restoreCompletedTransactions();

    Then I retrieve the array of transactions with the following
    after a few seconds with Invoke("gettrans",5);

    void gettrans()
    {

    List<StoreKitTransaction> transactionList = StoreKitBinding.getAllSavedTransactions();
    foreach( var t in transactionList )
    {

    print("T: " + t.productIdentifier);
    // Unlock if t.productIdentifier == "some condition";
    }

    }
     
  45. laserlars

    laserlars

    Joined:
    Nov 17, 2011
    Posts:
    255
    public static event Action restoreTransactionsFinishedEvent;
    public static event Action<string> restoreTransactionsFailedEvent;
     
  46. madpoet0204

    madpoet0204

    Joined:
    Sep 10, 2012
    Posts:
    98
    Something like:
    void restoreTransactionsFinished ( transaction , ???? ){
    // Unlock transaction
    }



    Can you provide the syntax?
     
  47. madpoet0204

    madpoet0204

    Joined:
    Sep 10, 2012
    Posts:
    98
    restore transaction does not seem to work with the version of my store kit so I updated it and
    get this:

    when I update my storekit plugin and try and build I get this in xcode 4.2 and 4.4.1
    using unity3.5. I have set armv7 in build settings and minimum iOS to 4.2



    Undefined symbols for architecture armv7:
    "__storeKitFinishPendingTransactions", referenced from:
    RegisterMonoModules() in RegisterMonoModules.o
    ld: symbol(s) not found for architecture armv7

    I really need some help. Please someone help me out.
    Thx
     
  48. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,426
    @madpoet, When having issues with the build system you should visit our troubleshooting guide here: http://prime31.com/docs#iosTroubleshooter

    If the troubleshooting guide does not solve your problem please send us the plugin logs referenced in the guide.
     
  49. Gamieon

    Gamieon

    Joined:
    Mar 20, 2010
    Posts:
    38
    Quick question using the 2013-08-20 IAPCombo Plugin:

    I have a game on both Google Play and the App Store. I have an in-app for $1.99 on both stores with the same product identifier. The IAPProduct value for price is "$1.99" when I fetch from Google Play, and "1.99" from the App Store (note the missing currency symbol). I noticed the StoreKitProduct has a separate formatted price field, but the IAPProduct object fetches from price instead.

    I can work around this by adding my own handler for fetching the product list, but I wondered if you've come across this before, and could tell me if I'm doing something wrong that would result in the $ not appearing in the iOS version of my app?
     
  50. danms

    danms

    Joined:
    Jan 11, 2013
    Posts:
    3
    If anyone's still having this issue:

    In Assets/Plugins/IAPCombo/IAPProduct.cs:

    Add this under the #if UNITY_IPHONE || UNITY_ANDROID section at the top:
    public class IAPProduct
    {
    public string formattedPrice { get; private set; }
    }


    And add this under the #if UNITY_IPHONE section:

    public IAPProduct( StoreKitProduct prod )
    {
    formattedPrice = prod.formattedPrice;
    }

    You should be able to see the patterns in those section to identify which ones to change. The StoreKitProduct class is storing all of the StoreKit variables, the plugin just exposes the ones that are universal to both Android and iOS. Probably would be better for "price" to refer to "formattedPrice" in iOS's case, but as of the 2014-11-05 version, you'll need to add this.