Purchase flow (Google Play, Android)
-
Lua UI sends
pay.action(analytics), thenpay.before.checkwith the internal product id + detected currency. -
Server returns a fresh
selfOrderId, a server-issued correlation token, plus a confirmedproductId. -
Client calls into native code with
{skuId, itemId: selfOrderId, uid}. Billing Library’slaunchBillingFlowis built with:
Purchase object.
5. Client sends the SFS command pay: {orderId, productId, purchaseTime, signData (raw receipt JSON), signature, itemId: selfOrderId, pay_closingCurrency, pay_PriceOfClosingCurrency}, this is the actual receipt-verification call. The server independently validates signData/signature against Google’s purchase-verification API server-side; the client-submitted receipt is untrusted input from the server’s perspective and not forgeable without a genuine Google Play receipt.
6. Only after server confirmation does the client call ConsumeProduct on Google Play, making a consumable product re-purchasable.
Full command family
Non-IAP economy: no cryptography involved
Trading Center (get.r.exchange.info, money.buy.resource, resource.sell.money), the item shop (item.buy, user.shop.buy.new), and the player-to-player Storage Shop marketplace are plain request/response RPCs gated only by server-side currency balances, no receipts, no signing, directly drivable once authenticated.
Naming trap.
purchase.order.refresh/.finish/.delete is not IAP despite the name; it’s an unrelated production-queue feature (grocery store / resident orders). Only the pay*/Pay.*-namespaced commands above are real-money purchases.