Concepts
Payments and the pay sheet
Copy page
People pay for what your app sells in $LIA, on Lia's own pay sheet, at the price in Lia's records. Your server confirms each charge, delivers it, or refunds it.
#How a payment works
- Your page asks
Lia.pay("extra-lives")with the id of one of your products. - Lia's pay sheet opens over your appIt shows the item and its price from Lia's records (never your page's), your app and developer name, and the person's balance after.
- The person confirmsThe $LIA leaves their balance. Lia Labs holds your share for you, and the charge is recorded for your app as
paid. - Your page hears it
pay()answers{ chargeId, productId }. Acharge.paidwebhook goes to your server too. - Your server deliversIt checks the charge with Lia, gives the person what they bought, and marks the charge
delivered. Or, if it can't, refunds it.
Your page never handles money, cards or wallets, and can't change a price: the sheet only ever shows what's in Lia's records.
#Products
What your app sells is set up by the Lia team (until the developer portal arrives). Each product has:
| Field | Rules |
|---|---|
id | 1 to 64 characters: letters, digits, _, . and -, starting with a letter or digit. This is what you pass to Lia.pay(). |
name | Up to 60 characters, shown on the pay sheet and in the person's activity. |
price | In $LIA, more than 0 and up to 1,000,000, to 6 decimal places. |
active | Removing a product only hides it: its past charges stay. |
Your server can list them with GET /products.
#Charges
A charge is one payment. It has an id like ch_9b1f… and a status:
| Status | Meaning |
|---|---|
paid | The person paid. Your app hasn't delivered it yet. |
delivered | Your server said it delivered it. Delivering again changes nothing. |
refunded | The $LIA went back to the person. A refunded charge can't be delivered. |
Your server works with charges through GET /charges/:id, POST /charges/:id/deliver and POST /charges/:id/refund.
#Your share
When a live charge is paid, the full price leaves the person's balance. Your share (70% unless agreed otherwise with the Lia team) is held for you by Lia Labs, and the rest stays with Lia. A refund gives the person the full price back, out of both.
Lia Labs pays out your share monthly, into your own Lia balance. From $LIA mainnet in Q1 2028, you can withdraw it to your own wallet. See Getting paid.
#Never lose a payment
A page can reload, crash or lose its connection between the pay sheet and your server. Lia keeps every paid charge until your server delivers it, and gives your page three ways to find them:
pay()answers with{ chargeId, productId }in the normal case.Lia.onCharge(fn)hears a charge that was confirmed while nopay()was waiting, for example after the page reloaded while the sheet was open.Lia.charges()lists this player's paid, undelivered charges (oldest first, up to 50). Call it when your app opens.
And your server can rely on the charge.paid webhook instead of the page. Sell an item puts all of these together.
#When a payment doesn't happen
Lia.pay() fails with an error whose code says why:
| Code | When |
|---|---|
cancelled | The person closed the sheet without paying. The most common one: treat it as a normal "no". |
no_product | There's no active product with that id for your app. |
busy | Another of Lia's screens is already open over your app. |
bad_productId | The id isn't text up to 64 characters. |
If the person doesn't have enough $LIA, or the payment fails on the way, the pay sheet tells them itself and stays open so they can try again. Your page only hears cancelled when they close it.
#Test mode
In test mode the pay sheet says so, nobody's balance moves, and nobody needs enough $LIA. Everything else (your server's calls, webhooks, delivering and refunding) works as in live. See Test and live.