|
1 | 1 | extends Control |
2 | 2 |
|
3 | | -onready var alert = get_node("alert") |
| 3 | +const TEST_ITEM_SKU = "my_in_app_purchase_sku" |
| 4 | + |
| 5 | +onready var alert_dialog = $AlertDialog |
| 6 | +onready var label = $Label |
| 7 | + |
| 8 | +var payment = null |
| 9 | +var test_item_purchase_token = null |
4 | 10 |
|
5 | 11 | func _ready(): |
6 | | - iap.set_auto_consume(false) |
7 | | - iap.connect("purchase_success", self, "on_purchase_success") |
8 | | - iap.connect("purchase_fail", self, "on_purchase_fail") |
9 | | - iap.connect("purchase_cancel", self, "on_purchase_cancel") |
10 | | - iap.connect("purchase_owned", self, "on_purchase_owned") |
11 | | - iap.connect("has_purchased", self, "on_has_purchased") |
12 | | - iap.connect("consume_success", self, "on_consume_success") |
13 | | - iap.connect("consume_fail", self, "on_consume_fail") |
14 | | - iap.connect("sku_details_complete", self, "on_sku_details_complete") |
| 12 | + if Engine.has_singleton("GodotPayment"): |
| 13 | + label.text += "\n\n\nTest item SKU: %s" % TEST_ITEM_SKU |
| 14 | + |
| 15 | + payment = Engine.get_singleton("GodotPayment") |
| 16 | + payment.connect("connected", self, "_on_connected") # No params |
| 17 | + payment.connect("disconnected", self, "_on_disconnected") # No params |
| 18 | + payment.connect("connect_error", self, "_on_connect_error") # Response ID (int), Debug message (string) |
| 19 | + payment.connect("purchases_updated", self, "_on_purchases_updated") # Purchases (Dictionary[]) |
| 20 | + payment.connect("purchase_error", self, "_on_purchase_error") # Response ID (int), Debug message (string) |
| 21 | + payment.connect("sku_details_query_completed", self, "_on_sku_details_query_completed") # SKUs (Dictionary[]) |
| 22 | + payment.connect("sku_details_query_error", self, "_on_sku_details_query_error") # Response ID (int), Debug message (string), Queried SKUs (string[]) |
| 23 | + payment.connect("purchase_acknowledged", self, "_on_purchase_acknowledged") # Purchase token (string) |
| 24 | + payment.connect("purchase_acknowledgement_error", self, "_on_purchase_acknowledgement_error") # Response ID (int), Debug message (string), Purchase token (string) |
| 25 | + payment.connect("purchase_consumed", self, "_on_purchase_consumed") # Purchase token (string) |
| 26 | + payment.connect("purchase_consumption_error", self, "_on_purchase_consumption_error") # Response ID (int), Debug message (string), Purchase token (string) |
| 27 | + payment.startConnection() |
| 28 | + else: |
| 29 | + show_alert("Android IAP support is not enabled. Make sure you have enabled 'Custom Build' and the GodotPayment plugin in your Android export settings! This application will not work.") |
15 | 30 |
|
16 | | - get_node("purchase").connect("pressed", self, "button_purchase") |
17 | | - get_node("consume").connect("pressed", self, "button_consume") |
18 | | - get_node("request").connect("pressed", self, "button_request") |
19 | | - get_node("query").connect("pressed", self, "button_query") |
20 | 31 |
|
| 32 | +func show_alert(text): |
| 33 | + alert_dialog.dialog_text = text |
| 34 | + alert_dialog.popup_centered() |
21 | 35 |
|
22 | | -func on_purchase_success(item_name): |
23 | | - alert.set_text("Purchase success : " + item_name) |
24 | | - alert.popup() |
25 | 36 |
|
| 37 | +func _on_connected(): |
| 38 | + print("PurchaseManager connected") |
26 | 39 |
|
27 | | -func on_purchase_fail(): |
28 | | - alert.set_text("Purchase fail") |
29 | | - alert.popup() |
| 40 | + # We must acknowledge all puchases. |
| 41 | + # See https://developer.android.com/google/play/billing/integrate#process for more information |
| 42 | + var query = payment.queryPurchases("inapp") # Use "subs" for subscriptions |
| 43 | + var purchase_token = null |
| 44 | + if query.status == OK: |
| 45 | + for purchase in query.purchases: |
| 46 | + if !purchase.is_acknowledged: |
| 47 | + print("Purchase " + str(purchase.sku) + " has not been acknowledged. Acknowledging...") |
| 48 | + payment.acknowledgePurchase(purchase.purchase_token) |
| 49 | + else: |
| 50 | + print("Purchase query failed: %d" % query.status) |
30 | 51 |
|
31 | 52 |
|
32 | | -func on_purchase_cancel(): |
33 | | - alert.set_text("Purchase cancel") |
34 | | - alert.popup() |
| 53 | +func _on_sku_details_query_completed(sku_details): |
| 54 | + for available_sku in sku_details: |
| 55 | + show_alert(to_json(available_sku)) |
35 | 56 |
|
36 | 57 |
|
37 | | -func on_purchase_owned(item_name): |
38 | | - alert.set_text("Purchase owned: " + item_name) |
39 | | - alert.popup() |
| 58 | +func _on_purchases_updated(purchases): |
| 59 | + print("Purchases updated: %s" % to_json(purchases)) |
40 | 60 |
|
| 61 | + # See _on_connected |
| 62 | + for purchase in purchases: |
| 63 | + if !purchase.is_acknowledged: |
| 64 | + print("Purchase " + str(purchase.sku) + " has not been acknowledged. Acknowledging...") |
| 65 | + payment.acknowledgePurchase(purchase.purchase_token) |
| 66 | + |
| 67 | + if purchases.size() > 0: |
| 68 | + test_item_purchase_token = purchases[purchases.size() - 1].purchase_token |
| 69 | + |
| 70 | + |
| 71 | +func _on_purchase_acknowledged(purchase_token): |
| 72 | + print("Purchase acknowledged: %s" % purchase_token) |
| 73 | + |
| 74 | + |
| 75 | +func _on_purchase_consumed(purchase_token): |
| 76 | + show_alert("Purchase consumed successfully: %s" % purchase_token) |
| 77 | + |
| 78 | + |
| 79 | +func _on_purchase_error(code, message): |
| 80 | + show_alert("Purchase error %d: %s" % [code, message]) |
41 | 81 |
|
42 | | -func on_has_purchased(item_name): |
43 | | - if item_name == null: |
44 | | - alert.set_text("Don't have purchased item") |
45 | | - else: |
46 | | - alert.set_text("Has purchased: " + item_name) |
47 | | - alert.popup() |
48 | 82 |
|
| 83 | +func _on_purchase_acknowledgement_error(code, message): |
| 84 | + show_alert("Purchase acknowledgement error %d: %s" % [code, message]) |
49 | 85 |
|
50 | | -func on_consume_success(item_name): |
51 | | - alert.set_text("Consume success: " + item_name) |
52 | | - alert.popup() |
53 | 86 |
|
| 87 | +func _on_purchase_consumption_error(code, message): |
| 88 | + show_alert("Purchase consumption error %d: %s" % [code, message]) |
54 | 89 |
|
55 | | -func on_consume_fail(): |
56 | | - alert.set_text("Try to request purchased first") |
57 | | - alert.popup() |
58 | 90 |
|
| 91 | +func _on_sku_details_query_error(code, message): |
| 92 | + show_alert("SKU details query error %d: %s" % [code, message]) |
59 | 93 |
|
60 | | -func on_sku_details_complete(): |
61 | | - alert.set_text("Got detail info: " + to_json(iap.sku_details["item_test_a"])) |
62 | | - alert.popup() |
63 | 94 |
|
| 95 | +func _on_disconnected(): |
| 96 | + show_alert("GodotPayment disconnected. Will try to reconnect in 10s...") |
| 97 | + yield(get_tree().create_timer(10), "timeout") |
| 98 | + payment.startConnection() |
64 | 99 |
|
65 | | -func button_purchase(): |
66 | | - iap.purchase("item_tess") |
67 | 100 |
|
| 101 | +# GUI |
| 102 | +func _on_QuerySkuDetailsButton_pressed(): |
| 103 | + payment.querySkuDetails([TEST_ITEM_SKU]) |
68 | 104 |
|
69 | | -func button_consume(): |
70 | | - iap.consume("item_tess") |
71 | 105 |
|
| 106 | +func _on_PurchaseButton_pressed(): |
| 107 | + var response = payment.purchase(TEST_ITEM_SKU) |
| 108 | + if response.status != OK: |
| 109 | + show_alert("Purchase error %d: %s" % [response.response_code, response.debug_message]) |
72 | 110 |
|
73 | | -func button_request(): |
74 | | - iap.request_purchased() |
75 | 111 |
|
| 112 | +func _on_ConsumeButton_pressed(): |
| 113 | + if test_item_purchase_token == null: |
| 114 | + show_alert("You need to set 'test_item_purchase_token' first! (either by hand or in code)") |
| 115 | + return |
76 | 116 |
|
77 | | -func button_query(): |
78 | | - iap.sku_details_query(["item_test_a", "item_test_b"]) |
| 117 | + payment.consumePurchase(test_item_purchase_token) |
0 commit comments