Using Apple’s StoreKit APIs with Godot¶
This guide explains the StoreKit workflow in this addon. For Apple platform rules and App Store Connect setup, see Apple’s StoreKit documentation.
Table of Contents¶
Start StoreKit¶
Create one StoreKitManager when your app starts. Keep it alive for the life
of the app. Connect signals before you call start().
start() begins the StoreKit transaction listener. It also checks for
unfinished transactions. This lets your app recover purchases that happened
while it was not running.
var store_kit: StoreKitManager
func _ready() -> void:
store_kit = StoreKitManager.new()
store_kit.transaction_updated.connect(_on_transaction_updated)
store_kit.unverified_transaction_updated.connect(_on_unverified_transaction_updated)
store_kit.start()
func _on_unverified_transaction_updated(
transaction: StoreTransaction,
verification_error: int
) -> void:
push_warning("StoreKit could not verify transaction %s" % transaction.transaction_id)
Do not create a manager only when a user opens a store screen. StoreKit can send transactions at any time.
Handle transactions¶
transaction_updated contains verified transactions from purchases, offer
codes, subscriptions, and purchases that happen outside your app. Deliver the
product first. Then call finish().
Make delivery idempotent. A transaction can be sent again until you finish it. If delivery changes saved or server state, store the transaction ID as part of the same operation.
func _on_transaction_updated(transaction: StoreTransaction) -> void:
match transaction.product_id:
"com.example.game.coins.100":
add_coins(100)
"com.example.game.remove_ads":
unlock_remove_ads()
_:
push_warning("Unknown product: %s" % transaction.product_id)
return
transaction.finish()
fetch_current_entitlements() is useful for non-consumables and subscriptions.
It does not return consumables. Use unfinished transactions to recover a
consumable purchase that the app did not finish. start() does this
automatically. You can call fetch_unfinished_transactions() again to retry.
Redeem offer codes¶
Offer codes can apply to consumables, non-consumables, non-renewing subscriptions, and auto-renewable subscriptions. Configure the offer for the exact product in App Store Connect before you show the redemption sheet.
Use SubscriptionOfferView to show the Apple redemption sheet. Do not make a
custom code-entry screen. The success signal confirms that the code
redemption flow completed. The resulting product transaction arrives through
StoreKitManager.transaction_updated; grant the product there.
var offer_view: SubscriptionOfferView
func show_offer_code_redemption() -> void:
offer_view = SubscriptionOfferView.new()
offer_view.success.connect(func() -> void:
print("Offer code redeemed. Waiting for its transaction.")
)
offer_view.error.connect(func(message: String) -> void:
push_warning(message)
)
offer_view.present()
In-app redemption for consumables, non-consumables, and non-renewing subscriptions requires iOS or iPadOS 16.3 or later. It requires macOS 15 or later on Mac. No extra app entitlement is required.
Handle external offer-code redemptions¶
Users can redeem codes in the App Store or from a redemption URL. If your app
is running, StoreKit sends the resulting transaction through
transaction_updated. If it is not running, start() reads the unfinished
transaction on the next launch and emits the same signal.
For a consumable, do not use fetch_current_entitlements() as recovery. Apple
does not include consumables in that list. Deliver the unfinished transaction
and finish it.
If you have a server, enable App Store Server Notifications V2. Apple sends a
ONE_TIME_CHARGE notification for a consumable offer-code redemption. Use the
server notification as a second record of the event, but still handle the
device transaction to grant the item without delay.
Test offer codes¶
For Sandbox testing, create sandbox offer codes for the product in App Store Connect. Sign in with a Sandbox Apple Account on the test device. Then use the offer-code sheet in your app, or start an offer-code transaction from Sandbox Account Settings.
You can also use a StoreKit configuration file in Xcode. Add an offer code to the test product. Use Xcode’s StoreKit Transaction Manager to simulate a code redemption that happens outside the app.
Custom and one-time production codes require an approved In-App Purchase and an app that is Ready for Distribution. A new code batch can take up to one hour before customers can redeem it.