Compras no Aplicativo Unity (Unity In-App Purchasing)
Namespace: UnityEngine.Purchasing | Segurança: UnityEngine.Purchasing.Security
Pacote: com.unity.purchasing
Unity IAP tem seu próprio caminho de inicialização via UnityIAPServices.StoreController() → store.Connect(). Ele não requer UnityServices.InitializeAsync(), mas ambos podem coexistir se seu projeto usar outros serviços UGS. Se o Analytics estiver presente e InitializeAsync() for chamado, o IAP enviará automaticamente eventos de transação.
Antes de Começar
Sempre leia references/pre-check.md primeiro. Ele escaneia o projeto em busca de pacotes IAP de terceiros, Google Billing nativo e versões existentes do Unity IAP, e então roteia para o caminho correto. Não leia nenhum outro arquivo de referência nem faça qualquer alteração até que o roteamento seja resolvido.
Referências Detalhadas
- Escaneamento do projeto e roteamento de caminho (leia primeiro): Veja references/pre-check.md
- Assinaturas de API e exemplos de código: Veja references/api-notes.md
- Extensões de plataforma (Apple, Google): Veja references/platform-notes.md
- Editando
IAPProductCatalog.json(esquema, serialização decimal, atualização): Veja references/codeless-catalog.md - Migração v4 → v5: Veja references/migration-v4-to-v5.md
- Converter Google BillingClient nativo para Unity IAP 5: Veja references/path-convert-native-google-billing.md
- Converter plugin iOS StoreKit nativo para Unity IAP 5: Veja references/path-convert-native-storekit.md
- Converter Essential Kit billing para Unity IAP 5: Veja references/convert-essentialkit.md
- UniPay (FLOBUK) — avaliação e orientação: Veja references/convert-unipay.md
- RevenueCat — avaliação e orientação de conversão: Veja references/convert-revenuecat.md
- Adapty — avaliação e orientação de conversão: Veja references/convert-adapty.md
- Adicionar Unity IAP 5 a um projeto sem IAP existente: Veja references/path-add-iap-to-new-project.md
- Implementar capacidades D2C (provedor de pagamento terceiro — Stripe/Coda, requer v5.4+): Veja references/path-implement-iap-d2c.md
Leia os arquivos de referência sob demanda — apenas quando precisar de assinaturas de API específicas, detalhes de extensão de plataforma ou mapeamentos de migração.
Fluxo de Inicialização
- Obtenha
StoreControllerviaUnityIAPServices.StoreController()(ou serviços individuais viaDefaultStore(),DefaultProduct(),DefaultPurchase()) - Inscreva-se em todos os eventos necessários (veja Inscrições de Eventos Obrigatórias abaixo) antes de chamar
Connect() await store.Connect()para conectar-se à loja da plataforma- Em
OnStoreConnected, chamestore.FetchProducts(List<ProductDefinition>)para carregar o catálogo - Em
OnProductsFetched, os produtos estão prontos para exibição e compra
Use Awake() para inicialização — garante que o IAP esteja pronto antes de outros métodos Start().
Tipos de produto: ProductType.Consumable, ProductType.NonConsumable, ProductType.Subscription.
Buscando Produtos
Defina produtos como List<ProductDefinition> e passe para store.FetchProducts(). Use StoreSpecificIds quando os IDs dos produtos diferirem entre as lojas Apple e Google. Para catálogos complexos, use CatalogProvider para gerenciar conjuntos de produtos e IDs específicos da loja.
| Método | Comportamento |
|---|---|
GetProducts() | Retorna a lista de produtos em cache (síncrono, desatualizado se FetchProducts não foi chamado) |
FetchProducts() | Consulta a loja por preços/disponibilidade atualizados e atualiza o cache |
GetProductById(id) | Retorna um único produto em cache pelo ID |
Estes NÃO são intercambiáveis. Sempre chame FetchProducts() primeiro antes de confiar em GetProducts().
Fluxo de Compra em Duas Etapas
O IAP v5 usa um fluxo obrigatório de duas etapas: Pendente → Confirmar.
store.PurchaseProduct(product)— inicia o diálogo de compra da plataformaOnPurchasePendingé disparado — você recebe umPendingOrder- Valide o recibo, conceda o conteúdo ao jogador
store.ConfirmPurchase(pendingOrder)— finaliza a transaçãoOnPurchaseConfirmedé disparado — recebe o tipo baseOrder; use pattern-match paraConfirmedOrder(sucesso) vsFailedOrder(falha na confirmação)
Você DEVE chamar ConfirmPurchase(pendingOrder) após conceder o conteúdo. Compras não confirmadas são reentregues na próxima inicialização do aplicativo para evitar perda de compras.
Desduplicação: OnPurchasePending pode ser disparado várias vezes para a mesma compra (ex.: reinicialização do aplicativo antes da confirmação). Sempre verifique se o conteúdo já foi concedido.
Consumíveis: Compras consumíveis confirmadas NÃO são retornadas por FetchPurchases. Gerencie você mesmo as concessões de consumíveis (ex.: em Cloud Save ou Economy).
Compras adiadas: OnPurchaseDeferred é disparado para compras Ask-to-Buy (iOS) e compras adiadas do Google Play. NÃO conceda conteúdo — aguarde OnPurchasePending quando aprovado.
Restaurar Transações
store.RestoreTransactions(callback) reentrega compras não consumíveis e assinaturas. Cada compra restaurada dispara OnPurchasePending.
Requerido no iOS para conformidade com a App Store da Apple — adicione um botão "Restaurar Compras".
Assinaturas não renováveis da Apple não podem ser restauradas via RestoreTransactions. Gerencie-as no lado do servidor.
Validação de Recibos
| Plataforma | Abordagem |
|---|---|
| Google Play | CrossPlatformValidator com GooglePlayTangle.Data() — validação local suportada |
| Apple (StoreKit 2) | Validação local é uma não-operação. Use order.Info.Apple?.jwsRepresentation para validação no lado do servidor |
Gere dados de tangle via Services > In-App Purchasing > Receipt Validation Obfuscator no Unity Editor.
Verificação de Direitos (Entitlement Checking)
Use quando você não tem o Order e deseja saber o status de um produto específico (substitui product.hasReceipt do v4). Se você já tem o Order, verifique seu tipo: PendingOrder mapeia para EntitledUntilConsumed (consumíveis) ou EntitledButNotFinished (não consumíveis/assinaturas), ConfirmedOrder mapeia para FullyEntitled.
Chame store.CheckEntitlement(product) e lide com store.OnCheckEntitlement. Verifique se entitlement.Status == EntitlementStatus.FullyEntitled.
Valores de EntitlementStatus: FullyEntitled, EntitledUntilConsumed, EntitledButNotFinished, NotEntitled, Unknown.
Buscar Compras Existentes
store.FetchPurchases() recupera todas as compras atuais da loja. Útil na inicialização do aplicativo.
| Método | Comportamento |
|---|---|
GetPurchases() | Retorna a lista de compras em cache |
FetchPurchases() | Consulta a loja por compras atuais e substitui a lista em cache |
FetchPurchases() substitui toda a lista em cache a cada chamada. Apenas não consumíveis e assinaturas são retornados.