A Godot 4 addon (GDScript) for U.CASH Pay (https://pay.u.cash): in-game hosted checkout links and server-side tracked transactions. Non-custodial: the addon never holds funds, and the store Cloud Token it uses can only create checkouts that pay into your store's receive addresses.
UcashPay.hosted_checkout_url(...)builds a client-side hosted pay link forhttps://pay.u.cash/embed.php. No network call, safe to call straight from a shipped game build.UcashPay.create_checkout(...)creates a server-side tracked checkout viaPOST https://pay.u.cash/payment/ajax.php(function=create-transaction), idempotent perexternal_reference. Intended to be called from a server route, not the client.- A drop-in
PayButtonscene (UcashPayButton) that builds the hosted URL and opens it.
- Godot 4.2 or newer.
- A U.CASH Pay store and its Store Cloud Token (see setup below).
- Copy the
addons/ucash_pay/folder into your project atres://addons/ucash_pay/. - In the Godot editor: Project -> Project Settings -> Plugins, then enable UcashPay. This registers the
UcashPayautoload singleton and saves project settings. - (If you prefer not to use the plugin toggle, you can instead add the autoload manually under Project -> Project Settings -> Autoload: name
UcashPay, pathres://addons/ucash_pay/ucash_pay.gd, enabled.)
git submodule add https://github.com/UdotCASH/godot-ucashpay.git addons/ucash_payThen move the inner addons/ucash_pay up one level (the repo root is the addon source for portability), or symlink it to res://addons/ucash_pay, and enable the plugin in Godot.
UcashPay.hosted_checkout_url() performs no network I/O. Build the URL, then open it however your game prefers (system browser via OS.shell_open, or an in-game WebView).
extends Node
func _on_buy_pressed() -> void:
var url := UcashPay.hosted_checkout_url(
"st_your_store_cloud_token", # publishable store Cloud Token
4.99, # amount
"USD", # currency (default USD)
"Sword of Ucash", # title
"order_12345", # external_reference (your order id)
"" # optional redirect after payment
)
OS.shell_open(url)UcashPay.create_checkout() POSTs to the pay.u.cash ajax endpoint and is idempotent per external_reference. Because it performs a network request and yields, you can either await it or pass a callback:
extends Node
func _on_subscribe_pressed() -> void:
var result: Dictionary = await UcashPay.create_checkout(
"st_your_store_cloud_token", # store Cloud Token
9.00, # amount
"USD", # currency_code
"", # cryptocurrency_code ("" = payer chooses)
"sub_user_42_2026_07", # external_reference (idempotency key)
"UCASH Premium - 1 month", # title
"" # optional redirect
)
if result.success:
print("Pay here: ", result.url)
print("Transaction id: ", result.transaction_id)
OS.shell_open(result.url)
else:
print("Checkout failed: ", result.get("error", ""))The result Dictionary has the shape:
{
"success": bool,
"url": String, # the payment URL ("" on failure)
"transaction_id": String, # best-effort parsed id ("" if absent)
"raw": Variant # the parsed JSON body (or null)
}
You can also listen to the UcashPay.checkout_completed(result) signal, which fires for every call.
Add res://addons/ucash_pay/pay_button.tscn to your UI. Set the exported properties (cloud, amount, optional currency, title, external_reference, redirect, open_in_browser) in the inspector. When pressed it emits checkout_url_ready(url) and, if open_in_browser is on, opens the URL in the system browser.
# Wire the button's checkout_url_ready signal to handle the URL yourself:
func _on_pay_button_checkout_url_ready(url: String) -> void:
# e.g. open in your in-game WebView instead of the system browser.
MyWebView.open(url)- Sign up at pay.u.cash, then click the verification link in the email.
- Set receive addresses under Settings -> Addresses (raw address, ENS, Unstoppable Domains, or FIO).
- Create a store under Account -> Stores and copy its Store Cloud Token (use the store-level token, not the account-wide one).
- For fiat cards, connect your own Stripe under Settings -> Payment processors.
- The Store Cloud Token is a publishable, client-safe credential. Embedding it in a shipped game build is by design: it can only create checkouts that route funds into the receive addresses you configured for the store. It cannot move funds out, read balances, or change settings.
- For tracked checkouts (
create_checkout), prefer calling from your own server route when you need server-side order records and idempotency guarantees. The same publishable token is used. - The addon performs no key custody and never asks for private keys.
- Recurring crypto billing is not supported. U.CASH Pay checkouts are one-shot. For subscriptions, create a new checkout each billing cycle (e.g. drive it from your server's scheduler) and reconcile via
external_reference. create_checkoutis async (it usesHTTPRequest); it must run on a Node in the scene tree and be driven from a coroutine (await) or a callback. It is not a blocking call.- The payment URL returned by
create-transactionis parsed as "the response array element that starts withhttp(s)://". If pay.u.cash changes its response shape, update the parsing inaddons/ucash_pay/ucash_pay.gd. - The addon does not verify payment status on chain. Use the
external_referenceagainst your server and the pay.u.cash webhook to confirm settlement.
addons/ucash_pay/plugin.cfganducash_pay_plugin.gd: register theUcashPayautoload on enable.addons/ucash_pay/ucash_pay.gd: the singleton (hosted URL + tracked checkout).addons/ucash_pay/pay_button.gd/pay_button.tscn: the drop-in button.
MIT, see LICENSE.