Main.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. using AndroidInAppPurchasesWithCSharp.GodotGooglePlayBilling;
  2. using Godot;
  3. using System.Linq;
  4. using System;
  5. namespace AndroidInAppPurchasesWithCSharp
  6. {
  7. public partial class Main : Control
  8. {
  9. const string TestItemSku = "my_in_app_purchase_sku";
  10. private AcceptDialog _alertDialog;
  11. private Label _label;
  12. private GooglePlayBilling _payment;
  13. private string _testItemPurchaseToken;
  14. public override void _Ready()
  15. {
  16. _payment = GetNode<GooglePlayBilling>("GooglePlayBilling");
  17. _alertDialog = GetNode<AcceptDialog>("AlertDialog");
  18. _label = GetNode<Label>("Label");
  19. if (_payment.IsAvailable)
  20. {
  21. _label.Text += $"\n\n\nTest item SKU: {TestItemSku}";
  22. // No params.
  23. _payment.Connect(nameof(GooglePlayBilling.Connected), this, nameof(OnConnected));
  24. // No params.
  25. _payment.Connect(nameof(GooglePlayBilling.Disconnected), this, nameof(OnDisconnected));
  26. // Response ID (int), Debug message (string).
  27. _payment.Connect(nameof(GooglePlayBilling.ConnectError), this, nameof(OnConnectError));
  28. // Purchases (Dictionary[]).
  29. _payment.Connect(nameof(GooglePlayBilling.PurchasesUpdated), this, nameof(OnPurchasesUpdated));
  30. // Response ID (int), Debug message (string).
  31. _payment.Connect(nameof(GooglePlayBilling.PurchaseError), this, nameof(OnPurchaseError));
  32. // SKUs (Dictionary[]).
  33. _payment.Connect(nameof(GooglePlayBilling.SkuDetailsQueryCompleted), this, nameof(OnSkuDetailsQueryCompleted));
  34. // Response ID (int), Debug message (string), Queried SKUs (string[]).
  35. _payment.Connect(nameof(GooglePlayBilling.SkuDetailsQueryError), this, nameof(OnSkuDetailsQueryError));
  36. // Purchase token (string).
  37. _payment.Connect(nameof(GooglePlayBilling.PurchaseAcknowledged), this, nameof(OnPurchaseAcknowledged));
  38. // Response ID (int), Debug message (string), Purchase token (string).
  39. _payment.Connect(nameof(GooglePlayBilling.PurchaseAcknowledgementError), this, nameof(OnPurchaseAcknowledgementError));
  40. // Purchase token (string).
  41. _payment.Connect(nameof(GooglePlayBilling.PurchaseConsumed), this, nameof(OnPurchaseConsumed));
  42. // Response ID (int), Debug message (string), Purchase token (string).
  43. _payment.Connect(nameof(GooglePlayBilling.PurchaseConsumptionError), this, nameof(OnPurchaseConsumptionError));
  44. _payment.StartConnection();
  45. }
  46. else
  47. {
  48. ShowAlert("Android IAP support is not enabled. Make sure you have enabled 'Custom Build' and installed and enabled the GodotGooglePlayBilling plugin in your Android export settings! This application will not work.");
  49. }
  50. }
  51. private void ShowAlert(string text)
  52. {
  53. _alertDialog.DialogText = text;
  54. _alertDialog.PopupCentered();
  55. }
  56. private void OnConnected()
  57. {
  58. GD.Print("PurchaseManager connected");
  59. // We must acknowledge all puchases.
  60. // See https://developer.android.com/google/play/billing/integrate#process for more information
  61. var purchasesResult = _payment.QueryPurchases(PurchaseType.InApp);
  62. if (purchasesResult.Status == (int)Error.Ok)
  63. {
  64. foreach (var purchase in purchasesResult.Purchases)
  65. {
  66. if (!purchase.IsAcknowledged)
  67. {
  68. GD.Print($"Purchase {purchase.Sku} has not been acknowledged. Acknowledging...");
  69. _payment.AcknowledgePurchase(purchase.PurchaseToken);
  70. }
  71. }
  72. }
  73. else
  74. {
  75. GD.Print($"Purchase query failed: {purchasesResult.ResponseCode} - {purchasesResult.DebugMessage}");
  76. }
  77. }
  78. private async void OnDisconnected()
  79. {
  80. ShowAlert("GodotGooglePlayBilling disconnected. Will try to reconnect in 10s...");
  81. await ToSignal(GetTree().CreateTimer(10), "timeout");
  82. _payment.StartConnection();
  83. }
  84. private void OnConnectError(int code, string message)
  85. {
  86. ShowAlert("PurchaseManager connect error");
  87. }
  88. private void OnPurchasesUpdated(Godot.Collections.Array arrPurchases)
  89. {
  90. GD.Print($"Purchases updated: {JSON.Print(arrPurchases)}");
  91. // See OnConnected
  92. var purchases = GooglePlayBillingUtils.ConvertPurchaseDictionaryArray(arrPurchases);
  93. foreach (var purchase in purchases)
  94. {
  95. if (!purchase.IsAcknowledged)
  96. {
  97. GD.Print($"Purchase {purchase.Sku} has not been acknowledged. Acknowledging...");
  98. _payment.AcknowledgePurchase(purchase.PurchaseToken);
  99. }
  100. }
  101. if (purchases.Length > 0)
  102. {
  103. _testItemPurchaseToken = purchases.Last().PurchaseToken;
  104. }
  105. }
  106. private void OnPurchaseError(int code, string message)
  107. {
  108. ShowAlert($"Purchase error {code}: {message}");
  109. }
  110. private void OnSkuDetailsQueryCompleted(Godot.Collections.Array arrSkuDetails)
  111. {
  112. ShowAlert(JSON.Print(arrSkuDetails));
  113. var skuDetails = GooglePlayBillingUtils.ConvertSkuDetailsDictionaryArray(arrSkuDetails);
  114. foreach (var skuDetail in skuDetails)
  115. {
  116. GD.Print($"Sku {skuDetail.Sku}");
  117. }
  118. }
  119. private void OnSkuDetailsQueryError(int code, string message, string[] querySkuDetails)
  120. {
  121. ShowAlert($"SKU details query error {code}: {message}");
  122. }
  123. private void OnPurchaseAcknowledged(string purchaseToken)
  124. {
  125. ShowAlert($"Purchase acknowledged: {purchaseToken}");
  126. }
  127. private void OnPurchaseAcknowledgementError(int code, string message)
  128. {
  129. ShowAlert($"Purchase acknowledgement error {code}: {message}");
  130. }
  131. private void OnPurchaseConsumed(string purchaseToken)
  132. {
  133. ShowAlert($"Purchase consumed successfully: {purchaseToken}");
  134. }
  135. private void OnPurchaseConsumptionError(int code, string message, string purchaseToken)
  136. {
  137. ShowAlert($"Purchase acknowledgement error {code}: {message}");
  138. }
  139. // GUI
  140. private void OnQuerySkuDetailsButton_pressed()
  141. {
  142. _payment.QuerySkuDetails(new string[] { TestItemSku }, PurchaseType.InApp); // Use "subs" for subscriptions.
  143. }
  144. private void OnPurchaseButton_pressed()
  145. {
  146. var response = _payment.Purchase(TestItemSku);
  147. if (response != null && response.Status != (int)Error.Ok)
  148. {
  149. ShowAlert($"Purchase error {response.ResponseCode} {response.DebugMessage}");
  150. }
  151. }
  152. private void OnConsumeButton_pressed()
  153. {
  154. if (string.IsNullOrEmpty(_testItemPurchaseToken))
  155. {
  156. ShowAlert("You need to set 'test_item_purchase_token' first! (either by hand or in code)");
  157. return;
  158. }
  159. _payment.ConsumePurchase(_testItemPurchaseToken);
  160. }
  161. }
  162. }