Gplay Iap Setup logo

Gplay Iap Setup

Community
hanamizuki
gplay-iap-setup

In-app products, subscriptions, base plans, and offers setup for Google Play monetization, including bulk-localizing subscription display names, descriptions, and benefits across all locales. Use when configuring in-app purchases or subscription products.

Overview

Publisherhanamizuki
Repositorysolopreneur
Skill namegplay-iap-setup
Stars
150
Forks
9
Bundled files
1
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 1 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by hanamizuki on GitHub. Read the source before you install it.

Installation

Install the Gplay Iap Setup AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/hanamizuki/solopreneur.git /tmp/solopreneur
mkdir -p .claude/skills
cp -r /tmp/solopreneur/plugins/claude/android-dev/skills/gplay-iap-setup .claude/skills/gplay-iap-setup
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Gplay Iap Setup in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Gplay Iap Setup on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Gplay Iap Setup is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

In-App Purchase Setup for Google Play

Use this skill when you need to set up monetization for your Android app.

Two APIs: Legacy vs New Monetization

Google Play has two APIs for one-time products:

Legacy (gplay iap)New Monetization (gplay onetimeproducts)
APIinappproductsmonetization.onetimeproducts
Price formatpriceMicros/currencyunits/nanos/currencyCode
StructureFlat prices mappurchaseOptions with regionalPricingAndAvailabilityConfigs
Statesactive/inactiveDRAFTACTIVE (requires explicit activation)
Regional pricing--auto-convert-prices flag--regions-version required

Prefer the new monetization API (gplay onetimeproducts) for new products. It supports purchase options, better regional pricing control, and is the actively developed API.

Use the legacy API (gplay iap) only for managing existing legacy products.

Never mix the two APIs for the same product. A product created via gplay iap create cannot be managed via gplay onetimeproducts and vice versa.

Critical: Product IDs Are Permanent

Google Play permanently reserves product IDs after deletion. If you create premium_unlock and later delete it, the ID premium_unlock can never be reused — not even with a different API. Choose product IDs carefully.

This means:

  • Do NOT create a "test" product with a good ID and then delete it
  • Do NOT create via the legacy API and then try to recreate via the new API
  • If you burn an ID, you must choose a new one (e.g., premium_unlock_v2)

One-Time Products (New Monetization API)

List products

bash
gplay onetimeproducts list --package com.example.app

Create product

--regions-version is required — the create command uses PATCH with allowMissing=true internally:

bash
gplay onetimeproducts create \
  --package com.example.app \
  --product-id premium_unlock \
  --json @product.json \
  --regions-version "2025/03"

product.json (new monetization format)

json
{
  "productId": "premium_unlock",
  "listings": [
    { "languageCode": "en-US", "title": "Premium Unlock", "description": "Unlock all premium features" },
    { "languageCode": "es-ES", "title": "Desbloqueo Premium", "description": "Desbloquea todas las funciones premium" }
  ],
  "purchaseOptions": [
    {
      "buyOption": { "legacyCompatible": true },
      "newRegionsConfig": {
        "availability": "AVAILABLE",
        "usdPrice": { "currencyCode": "USD", "units": "9", "nanos": 990000000 },
        "eurPrice": { "currencyCode": "EUR", "units": "9", "nanos": 990000000 }
      },
      "regionalPricingAndAvailabilityConfigs": [
        { "regionCode": "US", "availability": "AVAILABLE", "price": { "currencyCode": "USD", "units": "9", "nanos": 990000000 } },
        { "regionCode": "GB", "availability": "AVAILABLE", "price": { "currencyCode": "GBP", "units": "7", "nanos": 990000000 } },
        { "regionCode": "IN", "availability": "AVAILABLE", "price": { "currencyCode": "INR", "units": "249", "nanos": 990000000 } }
      ]
    }
  ]
}

Activate the purchase option

New products start in DRAFT state. You must activate before users can purchase:

bash
gplay purchase-options batch-update-states \
  --package com.example.app \
  --product-id premium_unlock \
  --json '{"requests":[{"activatePurchaseOptionRequest":{"packageName":"com.example.app","productId":"premium_unlock","purchaseOptionId":"default"}}]}'

Update product

bash
gplay onetimeproducts patch \
  --package com.example.app \
  --product-id premium_unlock \
  --json @product-updated.json \
  --regions-version "2025/03" \
  --update-mask "purchaseOptions"

Get product

bash
gplay onetimeproducts get --package com.example.app --product-id premium_unlock

Delete product

bash
gplay onetimeproducts delete \
  --package com.example.app \
  --product-id premium_unlock \
  --confirm

Batch operations

bash
# Get multiple products
gplay onetimeproducts batch-get \
  --package com.example.app \
  --product-ids "premium_unlock,coins_100"

# Update multiple products (regionsVersion goes inside JSON)
gplay onetimeproducts batch-update \
  --package com.example.app \
  --json @products-batch.json

Legacy In-App Products (IAP)

Use only for managing existing legacy products.

List products

bash
gplay iap list --package com.example.app

Create product

iap create has no --sku flag — the SKU/productId lives in the JSON body:

bash
gplay iap create \
  --package com.example.app \
  --json @product.json

product.json (legacy format)

json
{
  "sku": "premium_upgrade",
  "status": "active",
  "purchaseType": "managedUser",
  "defaultPrice": {
    "priceMicros": "990000",
    "currency": "USD"
  },
  "prices": {
    "US": { "priceMicros": "990000", "currency": "USD" },
    "GB": { "priceMicros": "799000", "currency": "GBP" }
  },
  "listings": {
    "en-US": { "title": "Premium Upgrade", "description": "Unlock all premium features" },
    "es-ES": { "title": "Actualización Premium", "description": "Desbloquea todas las funciones premium" }
  }
}

Update / Batch / Delete

bash
# Update
gplay iap update --package com.example.app --sku premium_upgrade --json @product-updated.json

# Batch update
gplay iap batch-update --package com.example.app --json @products.json

# Batch get
gplay iap batch-get --package com.example.app --skus "premium,coins_100,coins_500"

# Delete (permanent — ID cannot be reused)
gplay iap delete --package com.example.app --sku premium_upgrade --confirm

Subscriptions

List subscriptions

bash
gplay subscriptions list --package com.example.app

Create subscription

bash
gplay subscriptions create \
  --package com.example.app \
  --json @subscription.json

subscription.json

Subscriptions use the units/nanos/currencyCode price format:

json
{
  "productId": "premium_monthly",
  "basePlans": [
    {
      "basePlanId": "monthly",
      "state": "ACTIVE",
      "regionalConfigs": [
        {
          "regionCode": "US",
          "newSubscriberAvailability": true,
          "price": { "currencyCode": "USD", "units": "4", "nanos": 990000000 }
        }
      ],
      "autoRenewingBasePlanType": {
        "billingPeriodDuration": "P1M"
      }
    },
    {
      "basePlanId": "yearly",
      "state": "ACTIVE",
      "regionalConfigs": [
        {
          "regionCode": "US",
          "newSubscriberAvailability": true,
          "price": { "currencyCode": "USD", "units": "49", "nanos": 990000000 }
        }
      ],
      "autoRenewingBasePlanType": {
        "billingPeriodDuration": "P1Y"
      }
    }
  ],
  "listings": [
    { "languageCode": "en-US", "title": "Premium Subscription", "description": "Get all premium features" }
  ]
}

Bulk-localize subscriptions across locales

Subscription listings are an array of per-locale objects (not an object keyed by locale). Each entry uses languageCode, title, benefits (array, max 4), and description. One subscriptions update call sets every locale atomically — use --update-mask listings so base plans and pricing are left untouched.

1. Discover the locales your app already ships (cover at least these):

bash
EDIT_ID=$(gplay edits create --package com.example.app | jq -r '.id')
gplay listings list --package com.example.app --edit "$EDIT_ID" --output table

2. Build a listings-only JSON file (subscription-listings.json):

json
{
  "listings": [
    { "languageCode": "en-US", "title": "Premium Monthly", "benefits": ["Unlimited access", "No ads"], "description": "Premium access to all features." },
    { "languageCode": "de-DE", "title": "Premium Monatlich", "benefits": ["Unbegrenzter Zugang", "Keine Werbung"], "description": "Premium-Zugang zu allen Funktionen." },
    { "languageCode": "es-ES", "title": "Premium Mensual", "benefits": ["Acceso ilimitado", "Sin anuncios"], "description": "Acceso premium a todas las funciones." },
    { "languageCode": "ja-JP", "title": "プレミアム月額", "benefits": ["無制限アクセス", "広告なし"], "description": "すべての機能にプレミアムアクセス。" }
  ]
}

3. Apply to one subscription:

bash
gplay subscriptions update \
  --package com.example.app \
  --product-id premium_monthly \
  --json @subscription-listings.json \
  --update-mask listings

4. Loop over every subscription in the app:

bash
PACKAGE="com.example.app"
gplay subscriptions list --package "$PACKAGE" --paginate \
  | jq -r '.[].productId' \
  | while read -r PRODUCT_ID; do
      gplay subscriptions update \
        --package "$PACKAGE" \
        --product-id "$PRODUCT_ID" \
        --json @subscription-listings.json \
        --update-mask listings
    done

Verify with gplay subscriptions get --package com.example.app --product-id premium_monthly --pretty and confirm every languageCode appears in the listings array. Constraints: title max 55 chars, description max 80 chars, benefits max 4 items. When the user gives a single display name, reuse it for all locales; when they give per-locale translations, use each locale's own text.

Base Plans

Base plans define the billing period and price for subscriptions.

Activate base plan

bash
gplay baseplans activate \
  --package com.example.app \
  --product-id premium_monthly \
  --base-plan-id monthly

Deactivate base plan

bash
gplay baseplans deactivate \
  --package com.example.app \
  --product-id premium_monthly \
  --base-plan-id monthly

Migrate prices

bash
gplay baseplans migrate-prices \
  --package com.example.app \
  --product-id premium_monthly \
  --base-plan-id monthly \
  --json @migration.json

Subscription Offers

Offers provide discounts, free trials, or introductory pricing.

List offers

bash
gplay offers list \
  --package com.example.app \
  --product-id premium_monthly \
  --base-plan-id monthly

Create offer

bash
gplay offers create \
  --package com.example.app \
  --product-id premium_monthly \
  --base-plan-id monthly \
  --json @offer.json

offer.json (Free trial)

json
{
  "offerId": "trial_7day",
  "state": "ACTIVE",
  "phases": [
    {
      "duration": "P7D",
      "pricingType": "FREE_TRIAL"
    }
  ],
  "regionalConfigs": [
    {
      "regionCode": "US"
    }
  ]
}

offer.json (Introductory price)

json
{
  "offerId": "intro_50_off",
  "state": "ACTIVE",
  "phases": [
    {
      "duration": "P1M",
      "pricingType": "SINGLE_PAYMENT",
      "price": {
        "priceMicros": "2490000",
        "currency": "USD"
      }
    }
  ]
}

Activate/Deactivate offer

bash
# Activate
gplay offers activate \
  --package com.example.app \
  --product-id premium_monthly \
  --base-plan-id monthly \
  --offer-id trial_7day

# Deactivate
gplay offers deactivate \
  --package com.example.app \
  --product-id premium_monthly \
  --base-plan-id monthly \
  --offer-id trial_7day

OTP Purchase Option Offers

Manage offers on one-time product purchase options:

bash
# List offers
gplay otp-offers list --package com.example.app --product-id premium_unlock --purchase-option-id default

# Activate offer
gplay otp-offers activate --package com.example.app --product-id premium_unlock --purchase-option-id default --offer-id promo_50off

# Deactivate offer
gplay otp-offers deactivate --package com.example.app --product-id premium_unlock --purchase-option-id default --offer-id promo_50off

Regional Pricing

Convert prices

bash
gplay pricing convert \
  --package com.example.app \
  --json @price-request.json

price-request.json (ConvertRegionPricesRequest)

The body is a single base price as Money — units is the whole-currency amount as a string, nanos is the fractional part (990000000 = .99):

json
{
  "price": {
    "currencyCode": "USD",
    "units": "9",
    "nanos": 990000000
  }
}

The response returns converted prices for all supported regions plus a regionVersion you can pass as --regions-version to subscriptions, base plans, offers, and one-time product commands.

Common Monetization Patterns

Pattern 1: New One-Time Product (recommended)

bash
# 1. Create product
gplay onetimeproducts create \
  --package com.example.app \
  --product-id premium_unlock \
  --json @premium.json \
  --regions-version "2025/03"

# 2. Activate purchase option
gplay purchase-options batch-update-states \
  --package com.example.app \
  --product-id premium_unlock \
  --json '{"requests":[{"activatePurchaseOptionRequest":{"packageName":"com.example.app","productId":"premium_unlock","purchaseOptionId":"default"}}]}'

# 3. Verify
gplay onetimeproducts get --package com.example.app --product-id premium_unlock

Pattern 2: Subscription with Free Trial

bash
# 1. Create subscription
gplay subscriptions create \
  --package com.example.app \
  --json @sub.json

# 2. Create free trial offer
gplay offers create \
  --package com.example.app \
  --product-id premium \
  --base-plan-id monthly \
  --json @trial.json

Pattern 3: Multi-Tier Subscription

json
{
  "productId": "premium",
  "basePlans": [
    {
      "basePlanId": "basic_monthly",
      "regionalConfigs": [{ "regionCode": "US", "newSubscriberAvailability": true, "price": { "currencyCode": "USD", "units": "2", "nanos": 990000000 } }],
      "autoRenewingBasePlanType": { "billingPeriodDuration": "P1M" }
    },
    {
      "basePlanId": "premium_monthly",
      "regionalConfigs": [{ "regionCode": "US", "newSubscriberAvailability": true, "price": { "currencyCode": "USD", "units": "4", "nanos": 990000000 } }],
      "autoRenewingBasePlanType": { "billingPeriodDuration": "P1M" }
    },
    {
      "basePlanId": "premium_yearly",
      "regionalConfigs": [{ "regionCode": "US", "newSubscriberAvailability": true, "price": { "currencyCode": "USD", "units": "49", "nanos": 990000000 } }],
      "autoRenewingBasePlanType": { "billingPeriodDuration": "P1Y" }
    }
  ]
}

Testing

Use test purchases

In your app code, use test product IDs:

  • android.test.purchased
  • android.test.canceled
  • android.test.refunded
  • android.test.item_unavailable

License testing

Add test accounts in Play Console: Settings → License Testing → Add license testers

Best Practices

  1. Use clear product IDs - e.g., premium_monthly, not prod_001. IDs are permanent and cannot be reused after deletion.
  2. Prefer the new monetization API - Use gplay onetimeproducts for new products, not gplay iap.
  3. Localize descriptions - Provide listings for all supported languages.
  4. Set up regional pricing - Use PPP pricing (see gplay-ppp-pricing skill) instead of same price everywhere.
  5. Activate after creation - New OTP products start in DRAFT. Use gplay purchase-options batch-update-states to activate.
  6. Discover commands - Run gplay --help to see all command groups. Purchase option management is under gplay purchase-options, not under gplay onetimeproducts.
  7. Test thoroughly - Use test accounts and test product IDs.
  8. Monitor conversions - Track which products/offers perform best.
  9. Update prices carefully - Price changes affect existing subscribers.

Billing Periods

  • P1W - 1 week
  • P1M - 1 month
  • P3M - 3 months
  • P6M - 6 months
  • P1Y - 1 year

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Gplay Iap Setup AI skill do?

In-app products, subscriptions, base plans, and offers setup for Google Play monetization, including bulk-localizing subscription display names, descriptions, and benefits across all locales. Use when configuring in-app purchases or subscription products.

Why use Gplay Iap Setup on TypingMind?

Because you install it once and use it with any model. Gplay Iap Setup is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Gplay Iap Setup in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/hanamizuki/solopreneur/tree/main/plugins/claude/android-dev/skills/gplay-iap-setup. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Gplay Iap Setup?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Gplay Iap Setup?

As many as you like. As long as a model supports skills, you can use Gplay Iap Setup with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Gplay Iap Setup AI skill free?

Yes. It is published on GitHub by hanamizuki under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇