Note with Unity IAP 2d integration to facilitate integration when needed:
Step 1: Enable Service In App Purchasing
Step 2: Create Script Purchase includes the following functions:
- InitializePurchasing: Initializes the IAP Builder, adds game products & adds the necessary callbacks to manage the purchase event.
- BuyProductID: 1 private func to buy products based on the ID of the product that we declare (config by store)
- BuyConsumable, BuyNonConsumable, BuySubscription: Public function to make purchases based on the type of product, passed in to get the exact ID of the product.
- RestorePurchases: On iOS call this function to restore a previously purchased product.
- OnInitialize: is called to check if the app can connect to the Unity IAP or not, OnInitialize is running in the background, only fails when the config fails.
- OnInitializeFailed: Call when IAP init has problem and display the log in the console
- ProcessPurchase: Check a successfully purchased product & show log in console.
- OnPurchaseFailed: Showing an error when the transaction failed in the console.
Add the following script to the source folder:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | <span class="token keyword">using</span> <span class="token namespace">System</span> <span class="token punctuation">;</span> <span class="token keyword">using</span> <span class="token namespace">System <span class="token punctuation">.</span> Collections <span class="token punctuation">.</span> Generic</span> <span class="token punctuation">;</span> <span class="token keyword">using</span> <span class="token namespace">UnityEngine</span> <span class="token punctuation">;</span> <span class="token keyword">using</span> <span class="token namespace">UnityEngine <span class="token punctuation">.</span> Purchasing</span> <span class="token punctuation">;</span> <span class="token comment">// Placing the Purchaser class in the CompleteProject namespace allows it to interact with ScoreManager, </span> <span class="token comment">// one of the existing Survival Shooter scripts.</span> <span class="token keyword">namespace</span> <span class="token namespace">CompleteProject</span> <span class="token punctuation">{</span> <span class="token comment">// Deriving the Purchaser class from IStoreListener enables it to receive messages from Unity Purchasing.</span> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Purchaser</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">MonoBehaviour</span> <span class="token punctuation">,</span> <span class="token class-name">IStoreListener</span></span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token class-name">IStoreController</span> m_StoreController <span class="token punctuation">;</span> <span class="token comment">// The Unity Purchasing system.</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token class-name">IExtensionProvider</span> m_StoreExtensionProvider <span class="token punctuation">;</span> <span class="token comment">// The store-specific Purchasing subsystems.</span> <span class="token comment">// Product identifiers for all products capable of being purchased: </span> <span class="token comment">// "convenience" general identifiers for use with Purchasing, and their store-specific identifier </span> <span class="token comment">// counterparts for use with and outside of Unity Purchasing. Define store-specific identifiers </span> <span class="token comment">// also on each platform's publisher dashboard (iTunes Connect, Google Play Developer Console, etc.)</span> <span class="token comment">// General product identifiers for the consumable, non-consumable, and subscription products.</span> <span class="token comment">// Use these handles in the code to reference which product to purchase. Also use these values </span> <span class="token comment">// when defining the Product Identifiers on the store. Except, for illustration purposes, the </span> <span class="token comment">// kProductIDSubscription - it has custom Apple and Google identifiers. We declare their store-</span> <span class="token comment">// specific mapping to Unity Purchasing's AddProduct, below.</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token class-name"><span class="token keyword">string</span></span> kProductIDConsumable <span class="token operator">=</span> <span class="token string">"consumable"</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token class-name"><span class="token keyword">string</span></span> kProductIDNonConsumable <span class="token operator">=</span> <span class="token string">"nonconsumable"</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token class-name"><span class="token keyword">string</span></span> kProductIDSubscription <span class="token operator">=</span> <span class="token string">"subscription"</span> <span class="token punctuation">;</span> <span class="token comment">// Apple App Store-specific product identifier for the subscription product.</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token class-name"><span class="token keyword">string</span></span> kProductNameAppleSubscription <span class="token operator">=</span> <span class="token string">"com.unity3d.subscription.new"</span> <span class="token punctuation">;</span> <span class="token comment">// Google Play Store-specific product identifier subscription product.</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token class-name"><span class="token keyword">string</span></span> kProductNameGooglePlaySubscription <span class="token operator">=</span> <span class="token string">"com.unity3d.subscription.original"</span> <span class="token punctuation">;</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Start</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// If we haven't set up the Unity Purchasing reference</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> m_StoreController <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Begin to configure our connection to Purchasing</span> <span class="token function">InitializePurchasing</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">InitializePurchasing</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// If we have already connected to Purchasing ...</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token function">IsInitialized</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ... we are done here.</span> <span class="token keyword">return</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Create a builder, first passing in a suite of Unity provided stores.</span> <span class="token class-name"><span class="token keyword">var</span></span> builder <span class="token operator">=</span> ConfigurationBuilder <span class="token punctuation">.</span> <span class="token function">Instance</span> <span class="token punctuation">(</span> StandardPurchasingModule <span class="token punctuation">.</span> <span class="token function">Instance</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Add a product to sell / restore by way of its identifier, associating the general identifier</span> <span class="token comment">// with its store-specific identifiers.</span> builder <span class="token punctuation">.</span> <span class="token function">AddProduct</span> <span class="token punctuation">(</span> kProductIDConsumable <span class="token punctuation">,</span> ProductType <span class="token punctuation">.</span> Consumable <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Continue adding the non-consumable product.</span> builder <span class="token punctuation">.</span> <span class="token function">AddProduct</span> <span class="token punctuation">(</span> kProductIDNonConsumable <span class="token punctuation">,</span> ProductType <span class="token punctuation">.</span> NonConsumable <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// And finish adding the subscription product. Notice this uses store-specific IDs, illustrating</span> <span class="token comment">// if the Product ID was configured differently between Apple and Google stores. Also note that</span> <span class="token comment">// one uses the general kProductIDSubscription handle inside the game - the store-specific IDs </span> <span class="token comment">// must only be referenced here. </span> builder <span class="token punctuation">.</span> <span class="token function">AddProduct</span> <span class="token punctuation">(</span> kProductIDSubscription <span class="token punctuation">,</span> ProductType <span class="token punctuation">.</span> Subscription <span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">IDs</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> kProductNameAppleSubscription <span class="token punctuation">,</span> AppleAppStore <span class="token punctuation">.</span> Name <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> kProductNameGooglePlaySubscription <span class="token punctuation">,</span> GooglePlay <span class="token punctuation">.</span> Name <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Kick off the remainder of the set-up with an asynchrounous call, passing the configuration </span> <span class="token comment">// and this class' instance. Expect a response either in OnInitialized or OnInitializeFailed.</span> UnityPurchasing <span class="token punctuation">.</span> <span class="token function">Initialize</span> <span class="token punctuation">(</span> <span class="token keyword">this</span> <span class="token punctuation">,</span> builder <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">bool</span></span> <span class="token function">IsInitialized</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Only say we are initialized if both the Purchasing references are set.</span> <span class="token keyword">return</span> m_StoreController <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> m_StoreExtensionProvider <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">BuyConsumable</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Buy the consumable product using its general identifier. Expect a response either </span> <span class="token comment">// through ProcessPurchase or OnPurchaseFailed asynchronously.</span> <span class="token function">BuyProductID</span> <span class="token punctuation">(</span> kProductIDConsumable <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">BuyNonConsumable</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Buy the non-consumable product using its general identifier. Expect a response either </span> <span class="token comment">// through ProcessPurchase or OnPurchaseFailed asynchronously.</span> <span class="token function">BuyProductID</span> <span class="token punctuation">(</span> kProductIDNonConsumable <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">BuySubscription</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Buy the subscription product using its the general identifier. Expect a response either </span> <span class="token comment">// through ProcessPurchase or OnPurchaseFailed asynchronously.</span> <span class="token comment">// Notice how we use the general product identifier in spite of this ID being mapped to</span> <span class="token comment">// custom store-specific identifiers above.</span> <span class="token function">BuyProductID</span> <span class="token punctuation">(</span> kProductIDSubscription <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">BuyProductID</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">string</span></span> productId <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// If Purchasing has been initialized ...</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token function">IsInitialized</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ... look up the Product reference with the general product identifier and the Purchasing </span> <span class="token comment">// system's products collection.</span> <span class="token class-name">Product</span> product <span class="token operator">=</span> m_StoreController <span class="token punctuation">.</span> products <span class="token punctuation">.</span> <span class="token function">WithID</span> <span class="token punctuation">(</span> productId <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// If the look up found a product for this device's store and that product is ready to be sold ... </span> <span class="token keyword">if</span> <span class="token punctuation">(</span> product <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> product <span class="token punctuation">.</span> availableToPurchase <span class="token punctuation">)</span> <span class="token punctuation">{</span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token keyword">string</span> <span class="token punctuation">.</span> <span class="token function">Format</span> <span class="token punctuation">(</span> <span class="token string">"Purchasing product asychronously: '{0}'"</span> <span class="token punctuation">,</span> product <span class="token punctuation">.</span> definition <span class="token punctuation">.</span> id <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// ... buy the product. Expect a response either through ProcessPurchase or OnPurchaseFailed </span> <span class="token comment">// asynchronously.</span> m_StoreController <span class="token punctuation">.</span> <span class="token function">InitiatePurchase</span> <span class="token punctuation">(</span> product <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Otherwise ...</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// ... report the product look-up failure situation </span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token string">"BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Otherwise ...</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// ... report the fact Purchasing has not succeeded initializing yet. Consider waiting longer or </span> <span class="token comment">// retrying initiailization.</span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token string">"BuyProductID FAIL. Not initialized."</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Restore purchases previously made by this customer. Some platforms automatically restore purchases, like Google. </span> <span class="token comment">// Apple currently requires explicit purchase restoration for IAP, conditionally displaying a password prompt.</span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">RestorePurchases</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// If Purchasing has not yet been set up ...</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span> <span class="token function">IsInitialized</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ... report the situation and stop restoring. Consider either waiting longer, or retrying initialization.</span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token string">"RestorePurchases FAIL. Not initialized."</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// If we are running on an Apple device ... </span> <span class="token keyword">if</span> <span class="token punctuation">(</span> Application <span class="token punctuation">.</span> platform <span class="token operator">==</span> RuntimePlatform <span class="token punctuation">.</span> IPhonePlayer <span class="token operator">||</span> Application <span class="token punctuation">.</span> platform <span class="token operator">==</span> RuntimePlatform <span class="token punctuation">.</span> OSXPlayer <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ... begin restoring purchases</span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token string">"RestorePurchases started ..."</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Fetch the Apple store-specific subsystem.</span> <span class="token class-name"><span class="token keyword">var</span></span> apple <span class="token operator">=</span> m_StoreExtensionProvider <span class="token punctuation">.</span> <span class="token generic-method"><span class="token function">GetExtension</span> <span class="token generic class-name"><span class="token punctuation"><</span> IAppleExtensions <span class="token punctuation">></span></span></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Begin the asynchronous process of restoring purchases. Expect a confirmation response in </span> <span class="token comment">// the Action<bool> below, and ProcessPurchase if there are previously purchased products to restore.</span> apple <span class="token punctuation">.</span> <span class="token function">RestoreTransactions</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> result <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// The first phase of restoration. If no more responses are received on ProcessPurchase then </span> <span class="token comment">// no purchases are available to be restored.</span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token string">"RestorePurchases continuing: "</span> <span class="token operator">+</span> result <span class="token operator">+</span> <span class="token string">". If no further messages, no purchases available to restore."</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Otherwise ...</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// We are not running on an Apple device. No work is necessary to restore purchases.</span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token string">"RestorePurchases FAIL. Not supported on this platform. Current = "</span> <span class="token operator">+</span> Application <span class="token punctuation">.</span> platform <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// </span> <span class="token comment">// --- IStoreListener</span> <span class="token comment">//</span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">OnInitialized</span> <span class="token punctuation">(</span> <span class="token class-name">IStoreController</span> controller <span class="token punctuation">,</span> <span class="token class-name">IExtensionProvider</span> extensions <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Purchasing has succeeded initializing. Collect our Purchasing references.</span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token string">"OnInitialized: PASS"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Overall Purchasing system, configured with products for this application.</span> m_StoreController <span class="token operator">=</span> controller <span class="token punctuation">;</span> <span class="token comment">// Store specific subsystem, for accessing device-specific store features.</span> m_StoreExtensionProvider <span class="token operator">=</span> extensions <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">OnInitializeFailed</span> <span class="token punctuation">(</span> <span class="token class-name">InitializationFailureReason</span> error <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Purchasing set-up has not succeeded. Check error for reason. Consider sharing this reason with the user.</span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token string">"OnInitializeFailed InitializationFailureReason:"</span> <span class="token operator">+</span> error <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token return-type class-name">PurchaseProcessingResult</span> <span class="token function">ProcessPurchase</span> <span class="token punctuation">(</span> <span class="token class-name">PurchaseEventArgs</span> args <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// A consumable product has been purchased by this user.</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> String <span class="token punctuation">.</span> <span class="token function">Equals</span> <span class="token punctuation">(</span> args <span class="token punctuation">.</span> purchasedProduct <span class="token punctuation">.</span> definition <span class="token punctuation">.</span> id <span class="token punctuation">,</span> kProductIDConsumable <span class="token punctuation">,</span> StringComparison <span class="token punctuation">.</span> Ordinal <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token keyword">string</span> <span class="token punctuation">.</span> <span class="token function">Format</span> <span class="token punctuation">(</span> <span class="token string">"ProcessPurchase: PASS. Product: '{0}'"</span> <span class="token punctuation">,</span> args <span class="token punctuation">.</span> purchasedProduct <span class="token punctuation">.</span> definition <span class="token punctuation">.</span> id <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// The consumable item has been successfully purchased, add 100 coins to the player's in-game score.</span> ScoreManager <span class="token punctuation">.</span> score <span class="token operator">+=</span> <span class="token number">100</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Or ... a non-consumable product has been purchased by this user.</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> String <span class="token punctuation">.</span> <span class="token function">Equals</span> <span class="token punctuation">(</span> args <span class="token punctuation">.</span> purchasedProduct <span class="token punctuation">.</span> definition <span class="token punctuation">.</span> id <span class="token punctuation">,</span> kProductIDNonConsumable <span class="token punctuation">,</span> StringComparison <span class="token punctuation">.</span> Ordinal <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token keyword">string</span> <span class="token punctuation">.</span> <span class="token function">Format</span> <span class="token punctuation">(</span> <span class="token string">"ProcessPurchase: PASS. Product: '{0}'"</span> <span class="token punctuation">,</span> args <span class="token punctuation">.</span> purchasedProduct <span class="token punctuation">.</span> definition <span class="token punctuation">.</span> id <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// TODO: The non-consumable item has been successfully purchased, grant this item to the player.</span> <span class="token punctuation">}</span> <span class="token comment">// Or ... a subscription product has been purchased by this user.</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> String <span class="token punctuation">.</span> <span class="token function">Equals</span> <span class="token punctuation">(</span> args <span class="token punctuation">.</span> purchasedProduct <span class="token punctuation">.</span> definition <span class="token punctuation">.</span> id <span class="token punctuation">,</span> kProductIDSubscription <span class="token punctuation">,</span> StringComparison <span class="token punctuation">.</span> Ordinal <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token keyword">string</span> <span class="token punctuation">.</span> <span class="token function">Format</span> <span class="token punctuation">(</span> <span class="token string">"ProcessPurchase: PASS. Product: '{0}'"</span> <span class="token punctuation">,</span> args <span class="token punctuation">.</span> purchasedProduct <span class="token punctuation">.</span> definition <span class="token punctuation">.</span> id <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// TODO: The subscription item has been successfully purchased, grant this to the player.</span> <span class="token punctuation">}</span> <span class="token comment">// Or ... an unknown product has been purchased by this user. Fill in additional products here....</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token keyword">string</span> <span class="token punctuation">.</span> <span class="token function">Format</span> <span class="token punctuation">(</span> <span class="token string">"ProcessPurchase: FAIL. Unrecognized product: '{0}'"</span> <span class="token punctuation">,</span> args <span class="token punctuation">.</span> purchasedProduct <span class="token punctuation">.</span> definition <span class="token punctuation">.</span> id <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Return a flag indicating whether this product has completely been received, or if the application needs </span> <span class="token comment">// to be reminded of this purchase at next app launch. Use PurchaseProcessingResult.Pending when still </span> <span class="token comment">// saving purchased products to the cloud, and when that save is delayed. </span> <span class="token keyword">return</span> PurchaseProcessingResult <span class="token punctuation">.</span> Complete <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">OnPurchaseFailed</span> <span class="token punctuation">(</span> <span class="token class-name">Product</span> product <span class="token punctuation">,</span> <span class="token class-name">PurchaseFailureReason</span> failureReason <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// A product purchase attempt did not succeed. Check failureReason for more detail. Consider sharing </span> <span class="token comment">// this reason with the user to guide their troubleshooting actions.</span> Debug <span class="token punctuation">.</span> <span class="token function">Log</span> <span class="token punctuation">(</span> <span class="token keyword">string</span> <span class="token punctuation">.</span> <span class="token function">Format</span> <span class="token punctuation">(</span> <span class="token string">"OnPurchaseFailed: FAIL. Product: '{0}', PurchaseFailureReason: {1}"</span> <span class="token punctuation">,</span> product <span class="token punctuation">.</span> definition <span class="token punctuation">.</span> storeSpecificId <span class="token punctuation">,</span> failureReason <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Step 3:
Drag the Purchaser script to the gameObject that you need to test / implement IAP.
Creating test to buy IAP with 1 consumable item called 100 coins. Upon successful purchase, you will be added 100 coins.
We will call the Purchase script function to purchase the IAP. Add a Button to the IAP Panel & add an event for the button that points to a Purchase script function.
Step 4: Testing:
Running the game & activating the screen containing the Purchase script will display like this in the console log:
Click on the button that implements the purchase event of the consummer product, it will display:
DONE.
To test real on iOS / Android, you must configure on account of each store. See more on youtube videos to see how to configure.