Menu
Platform
AI
App store purchases
Credits
Database
Flags
Generated Assets
Jobs and cron
Localization
Monitoring
Notifications
Payments
Sandboxes
Webhooks
Getting Started
Authentication
KV Store
Deploy & Infrastructure
Reference
Client verify on a store purchase
Verifies a store purchase for an app with no server: called with the environment's publishable key (`billing:client`), the subject is an…
Verifies a store purchase for an app with no server: called with the environment's publishable key (billing:client), the subject is an install id (inst_ and a UUID), and Money completes the purchase with the store (acknowledges or consumes it) so the app never calls the store's server API. Works only on store connections that set client_verify. Re-calling returns the same record and grant.
- Path
POST https://api.sylphx.com/v1/orgs/acme/projects/shop/envs/production/store_purchases:clientVerify - Scope
billing:client - Effect
write— a successful call changes state. - Collection store_purchases
- Publishable key callable
#Request
| Field | Type | What it is |
|---|---|---|
parent | string | The environment the purchase is verified in. Required. |
subject | Subject | Who bought it: end_user of inst_ and a lower-case UUID. Required. |
store | string | app_store or google_play. Required. |
signed_transaction | string | App Store: the StoreKit 2 signed transaction (jwsRepresentation). |
purchase_token | string | Google Play: the purchase token. |
product_id | string | Google Play: the store product id (for a subscription, its id). |
package_name | string | Google Play: the package name, when the connection covers several. |
account_token | string | The account token the app set at purchase (Play obfuscatedAccountId, App Store appAccountToken). A consistency check only: it must match the subject's derivation and the store's copy. |
#Subject
| Field | Type | What it is |
|---|---|---|
end_user | string | An end user's id (Sylphx Auth, or the app's own OIDC issuer). One of the kind group. |
customer_organization | string | A customer organization's id. One of the kind group. |
#Response
| Field | Type | What it is |
|---|---|---|
store_purchase | StorePurchase | The verified purchase. |
grant_token | string | A compact EdDSA JWS (typ money-grant+jwt) the app's server or client verifies offline against Money's published keys; it names the subject, the store product, the transaction, the quantity, and the catalog grants. |
already_verified | bool | Whether this transaction was verified before; the record and grant are the same. |
customer_subscription | CustomerSubscription | The subscription, for a subscription purchase. |
grant_claims | struct | With validate_only, the claims the grant would carry (the same JSON a signed grant_token holds); empty otherwise. |
store_completion | string | ClientVerifyStorePurchase only: what Money did to finish the purchase with the store: acknowledged, consumed, or retry (the store call failed; call again later). Empty on VerifyStorePurchase. |
transferred | bool | ClientVerifyStorePurchase only: the purchase moved from another install to the caller (restore). Always false until restore transfer is served. |
#StorePurchase
| Field | Type | What it is |
|---|---|---|
name | string | orgs/{org}/projects/{project}/envs/{env}/store_purchases/{store_purchase}. |
uid | string | spu_<cell><ulid>; never reused. Output only. |
meta | ResourceMeta | Resource metadata. |
subject | Subject | Who it belongs to. Output only. |
store | string | app_store or google_play. Output only. |
product_id | string | The store product id. Output only. |
product | string | The catalog product it sells, when the catalog maps the store product. Output only. |
bundle_or_package | string | The bundle id or package name. Output only. |
transaction_id | string | The store's transaction id (App Store transaction id, Play order id). Output only. |
original_transaction_id | string | The first transaction of a subscription or restored purchase. Output only. |
quantity | int32 | Units bought. Output only. |
environment | string | production or sandbox. Output only. |
state | string | purchased, pending, or revoked. Output only. |
purchase_time | timestamp | When the store says it was bought. Output only. |
revoke_time | timestamp | When the store refunded or revoked it. Output only. |
price | string | The price the store charged, in minor units of currency, when the store reports it. Output only. |
currency_code | string | ISO 4217 currency of price. Output only. |
customer_subscription | string | The subscription it belongs to, for a subscription purchase. Output only. |
region_code | string | ISO 3166-1 alpha-2 country of the buyer's storefront, upper case; empty when the store did not report one. Output only. |
original_purchase_time | timestamp | When the store says the first purchase of this subscription or restored purchase was made; unset when it did not report one. Output only. |
claw_back | bool | Revoked after it was delivered, and its goods come back: its entitlements ended, and the app takes back the assets its grant credited, up to what the subject still holds. False while it stands, and for a refund the catalog's refund_claw_back lets the subject keep. Output only. |
#CustomerSubscription
| Field | Type | What it is |
|---|---|---|
name | string | orgs/{org}/projects/{project}/envs/{env}/customer_subscriptions/{customer_subscription}. |
uid | string | csb_<cell><ulid>; never reused. Output only. |
meta | ResourceMeta | Resource metadata. |
subject | Subject | Who holds it. Output only. |
source | string | stripe, app_store, or google_play. Output only. |
processor_subscription_id | string | The processor's subscription id. Output only. |
status | string | trialing, active, past_due, paused, canceled, unpaid, incomplete, or incomplete_expired, as the processor reports it. Output only. |
items | LineItem[] | The prices, by lookup key, and their quantities. Output only. |
current_period_end_time | timestamp | The end of the paid period. Output only. |
cancel_at_period_end | bool | Whether it ends at current_period_end_time instead of renewing. Output only. |
trial_end_time | timestamp | The end of the trial, when there is one. Output only. |
metadata | struct | The checkout's metadata. Output only. |
#ResourceMeta
| Field | Type | What it is |
|---|---|---|
generation | int64 | Increases by one on every change to spec. Output only. |
etag | string | Strong ETag (AIP-154): changes on any change to spec, status, or metadata. Send it back as If-Match or etag to make Update and Delete conditional; a mismatch fails with ABORTED / 409 ETAG_MISMATCH. Output only. |
create_time | timestamp | When the Resource was created. Output only. |
update_time | timestamp | When the Resource last changed. Output only. |
delete_time | timestamp | Set while the Resource is being deleted. Output only. |
labels | map<string, string> | Caller-writable, indexed labels (AIP-122 label rules). |
annotations | map<string, string> | Caller-writable, unindexed annotations. |
display_name | string | Caller-writable human-readable name. |
creator | string | The principal that created the Resource. Output only. |
#Subject
| Field | Type | What it is |
|---|---|---|
end_user | string | An end user's id (Sylphx Auth, or the app's own OIDC issuer). One of the kind group. |
customer_organization | string | A customer organization's id. One of the kind group. |
#LineItem
| Field | Type | What it is |
|---|---|---|
price | string | The price's lookup key. Required. |
quantity | int32 | How many; default 1. Seats for a per-seat or family price. |
#Errors
UNAUTHENTICATED— No valid key or token was presented.PERMISSION_DENIED— The key lacks the method's permission.INVALID_FIELD— A field failed validation.INVALID_STATE— The Resource is in a state that forbids the call.RESOURCE_IN_USE— The Resource is attached to or held by another Resource, for example a volume attached to a running lease.RATE_LIMITED— The rate limit is reached; see Retry-After.UNAVAILABLE— The Resource store, the owning service's backend, or the key verifier's snapshot is unavailable; retry after Retry-After.
Every error arrives in the body Errors describes.
#Examples
curl -X POST "https://api.sylphx.com/v1/orgs/acme/projects/shop/envs/production/store_purchases:clientVerify" \
-H "Authorization: Bearer $SYLPHX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"store":"…","subject":{}}'