Guia de Implementação do Acompanhamento de Eventos de Assinatura
Implemente um rastreamento abrangente de assinaturas para medir a receita de assinaturas, a retenção de usuários e o desempenho da campanha em todas as plataformas usando o SDK da Singular, a integração servidor a servidor ou parceiros terceirizados.
Singular permite a atribuição precisa de eventos de assinatura - incluindo novas assinaturas, renovações, trials, cancelamentos e reembolsos - às campanhas de marketing que geraram usuários, fornecendo visibilidade completa do ciclo de vida da assinatura e da geração de receita.
Opções de implementação
Escolha o método de implementação que melhor se adapta à arquitetura da sua aplicação e aos requisitos comerciais.
| Considerações | Integração de SDK | Servidor para servidor (S2S) | Integração de terceiros |
|---|---|---|---|
| Implementação | Enviar eventos de assinatura através de métodos de receita personalizados no Singular SDK | Enviar eventos do seu backend para a API REST do Singular com as propriedades necessárias do dispositivo móvel | Configurar integrações com RevenueCat, Adapty ou outras plataformas de assinatura |
| Dependência de atividade do aplicativo | O aplicativo deve ser iniciado para que o SDK envie eventos | Eventos enviados em tempo real, independentemente do estado da aplicação | Eventos enviados em tempo real da plataforma do parceiro |
| Tempo do evento | A hora do evento pode diferir da hora real da subscrição com base no lançamento da aplicação | Acompanhamento de eventos em tempo real conforme processado no backend | Acompanhamento quase em tempo real após o processamento do parceiro |
| Complexidade | Implementação simples no lado do cliente | Requer uma infraestrutura de backend segura | Requer conta de parceiro e configuração |
Importante: A maioria dos clientes que usam S2S ou integrações de terceiros para eventos de assinatura ainda devem integrar o SDK Singular para gerenciar sessões e eventos sem assinatura para um rastreamento de atribuição completo.
Android: Integração de faturamento do Google Play
Integre a Biblioteca de Faturamento do Google Play 8.0.0 para consultar informações de assinatura e gerenciar o estado da assinatura diretamente no dispositivo para integração com o SDK Singular.
Pré-requisitos
Configurar o Google Play Console
Configure produtos in-app e itens de assinatura no Google Play Consoleantes de implementar o faturamento no seu aplicativo.
- Criar produtos de assinatura: Definir níveis de assinatura, períodos de faturamento e preços no Play Console
- Configurar ofertas: Configurar planos base, tokens de oferta e preços promocionais
- Configuração de testes: Criar contas de teste e verificar a disponibilidade do produto
Adicionar dependência da biblioteca de faturação
Atualizar build.gradle
Adicione a Biblioteca de faturamento do Google Play 8.0.0 às dependências do seu aplicativo com extensões Kotlin para suporte a corrotina.
dependencies {
val billingVersion = "8.0.0"
// Google Play Billing Library
implementation("com.android.billingclient:billing:$billingVersion")
// Kotlin extensions and coroutines support
implementation("com.android.billingclient:billing-ktx:$billingVersion")
}
Caraterísticas da versão 8.0.0: Esta versão introduz a reconexão automática de serviços com enableAutoServiceReconnection(), APIs de consulta de compras melhoradas e tratamento de transacções pendentes melhorado.
Inicializar BillingClient
Criar gestor de faturação
Configure uma classe de gestor de faturação para lidar com todas as operações de subscrição e integre com o Singular SDK para rastreio de eventos.
class SubscriptionManager(private val context: Context) {
private val purchasesUpdatedListener = PurchasesUpdatedListener { billingResult, purchases ->
when (billingResult.responseCode) {
BillingResponseCode.OK -> {
purchases?.forEach { purchase ->
handlePurchaseUpdate(purchase)
}
}
BillingResponseCode.USER_CANCELED -> {
Log.d(TAG, "User canceled the purchase")
}
else -> {
Log.e(TAG, "Purchase error: ${billingResult.debugMessage}")
}
}
}
private val billingClient = BillingClient.newBuilder(context)
.setListener(purchasesUpdatedListener)
.enablePendingPurchases() // Required for all purchases
.enableAutoServiceReconnection() // NEW in 8.0.0 - handles reconnection automatically
.build()
fun initialize() {
billingClient.startConnection(object : BillingClientStateListener {
override fun onBillingSetupFinished(billingResult: BillingResult) {
if (billingResult.responseCode == BillingResponseCode.OK) {
Log.d(TAG, "Billing client ready")
// Query existing subscriptions
queryExistingSubscriptions()
} else {
Log.e(TAG, "Billing setup failed: ${billingResult.debugMessage}")
}
}
override fun onBillingServiceDisconnected() {
// With enableAutoServiceReconnection(), SDK handles reconnection
// Manual retry is no longer required
Log.d(TAG, "Billing service disconnected - auto-reconnection enabled")
}
})
}
companion object {
private const val TAG = "SubscriptionManager"
}
}
Caraterísticas principais:
-
Auto-Reconexão: A versão 8.0.0 do
enableAutoServiceReconnection()restabelece automaticamente as ligações quando necessário - Ouvinte de compras: Recebe callbacks para todas as actualizações de compras, incluindo renovações e transacções pendentes
- Tratamento de erros: Tratamento exaustivo de cancelamentos de utilizadores e erros de faturação
Consulta de informações de assinatura
Recuperar subscrições activas
Consulta de subscrições existentes utilizando queryPurchasesAsync()para tratar renovações e subscrições compradas fora da sua aplicação.
private suspend fun queryExistingSubscriptions() {
val params = QueryPurchasesParams.newBuilder()
.setProductType(BillingClient.ProductType.SUBS)
.build()
withContext(Dispatchers.IO) {
val result = billingClient.queryPurchasesAsync(params)
if (result.billingResult.responseCode == BillingResponseCode.OK) {
result.purchasesList.forEach { purchase ->
when (purchase.purchaseState) {
Purchase.PurchaseState.PURCHASED -> {
// Active subscription - process it
handleSubscriptionPurchase(purchase)
}
Purchase.PurchaseState.PENDING -> {
// Pending payment - notify user
Log.d(TAG, "Subscription pending: ${purchase.products}")
}
}
}
} else {
Log.e(TAG, "Query failed: ${result.billingResult.debugMessage}")
}
}
}
Melhores práticas: Chame queryPurchasesAsync()em onResume() para apanhar renovações de subscrições que ocorreram enquanto a aplicação estava em segundo plano ou fechada.
Consultar detalhes do produto
Recupere os detalhes do produto de assinatura, incluindo preços, períodos de faturamento e tokens de oferta antes de exibi-los aos usuários.
private suspend fun querySubscriptionProducts() {
val productList = listOf(
QueryProductDetailsParams.Product.newBuilder()
.setProductId("premium_monthly")
.setProductType(BillingClient.ProductType.SUBS)
.build(),
QueryProductDetailsParams.Product.newBuilder()
.setProductId("premium_yearly")
.setProductType(BillingClient.ProductType.SUBS)
.build()
)
val params = QueryProductDetailsParams.newBuilder()
.setProductList(productList)
.build()
withContext(Dispatchers.IO) {
val productDetailsResult = billingClient.queryProductDetails(params)
if (productDetailsResult.billingResult.responseCode == BillingResponseCode.OK) {
// Process successfully retrieved product details
productDetailsResult.productDetailsList?.forEach { productDetails ->
// Extract subscription offers
productDetails.subscriptionOfferDetails?.forEach { offer ->
val price = offer.pricingPhases.pricingPhaseList.firstOrNull()
Log.d(TAG, "Product: ${productDetails.productId}, Price: ${price?.formattedPrice}")
}
}
// Handle unfetched products
productDetailsResult.unfetchedProductList?.forEach { unfetchedProduct ->
Log.w(TAG, "Unfetched: ${unfetchedProduct.productId}")
}
}
}
}
Processar actualizações de compra
Tratar eventos de subscrição
Processar alterações no estado da compra e enviar eventos apropriados para a Singular com base no ciclo de vida da assinatura.
private fun handlePurchaseUpdate(purchase: Purchase) {
when (purchase.purchaseState) {
Purchase.PurchaseState.PURCHASED -> {
if (!purchase.isAcknowledged) {
// Verify purchase on your backend first
verifyPurchaseOnBackend(purchase) { isValid ->
if (isValid) {
// Send subscription event to Singular
trackSubscriptionToSingular(purchase)
// Grant entitlement to user
grantSubscriptionAccess(purchase)
// Acknowledge purchase to Google
acknowledgePurchase(purchase)
}
}
}
}
Purchase.PurchaseState.PENDING -> {
// Notify user that payment is pending
Log.d(TAG, "Purchase pending approval: ${purchase.products}")
notifyUserPendingPayment(purchase)
}
}
}
private fun trackSubscriptionToSingular(purchase: Purchase) {
// Get cached product details for pricing information
val productDetails = getCachedProductDetails(purchase.products.first())
productDetails?.let { details ->
val subscriptionOffer = details.subscriptionOfferDetails?.firstOrNull()
val pricingPhase = subscriptionOffer?.pricingPhases?.pricingPhaseList?.firstOrNull()
val price = pricingPhase?.priceAmountMicros?.div(1_000_000.0) ?: 0.0
val currency = pricingPhase?.priceCurrencyCode ?: "USD"
// Determine event name based on purchase type
val eventName = if (isNewSubscription(purchase)) {
"sng_subscribe"
} else {
"subscription_renewed"
}
// Send to Singular WITHOUT receipt
Singular.customRevenue(
eventName,
currency,
price,
mapOf(
"subscription_id" to purchase.products.first(),
"order_id" to (purchase.orderId ?: ""),
"purchase_time" to purchase.purchaseTime.toString()
)
)
Log.d(TAG, "Tracked $eventName to Singular: $price $currency")
}
}
private fun acknowledgePurchase(purchase: Purchase) {
val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchase.purchaseToken)
.build()
lifecycleScope.launch {
val ackResult = withContext(Dispatchers.IO) {
billingClient.acknowledgePurchase(acknowledgePurchaseParams)
}
if (ackResult.responseCode == BillingResponseCode.OK) {
Log.d(TAG, "Purchase acknowledged successfully")
} else {
Log.e(TAG, "Acknowledgement failed: ${ackResult.debugMessage}")
}
}
}
Crítico: NÃO envie o recibo do Google Play para a Singular ao rastrear eventos de assinatura. Use o método customRevenue() sem validação de recibo. Confirme as compras dentro de 3 dias ou elas serão automaticamente reembolsadas.
iOS: Integração do StoreKit
Integre a estrutura do StoreKit da Apple para gerenciar assinaturas e enviar eventos para o Singular para aplicativos iOS.
Pré-requisitos
Configurar o App Store Connect
Configure produtos de assinatura e grupos de assinatura no App Store Connectantes de implementar o StoreKit no seu aplicativo.
- Criar grupos de subscrição: Organize as assinaturas em grupos com base nos níveis de acesso
- Definir produtos de subscrição: Configurar níveis de subscrição, durações e preços
- Configurar ofertas: Criar ofertas introdutórias, ofertas promocionais e códigos de subscrição
- Ambiente de teste: Configurar contas de teste sandbox para desenvolvimento
Implementar o StoreKit
Configurar observador de transacções
Implementar SKPaymentTransactionObserver para receber notificações de compra e renovação de subscrições.
import StoreKit
class SubscriptionManager: NSObject, SKPaymentTransactionObserver {
static let shared = SubscriptionManager()
private override init() {
super.init()
// Add transaction observer
SKPaymentQueue.default().add(self)
}
deinit {
SKPaymentQueue.default().remove(self)
}
// MARK: - SKPaymentTransactionObserver
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case .purchased:
// New subscription or renewal
handlePurchasedTransaction(transaction)
case .restored:
// Subscription restored from another device
handleRestoredTransaction(transaction)
case .failed:
// Purchase failed
handleFailedTransaction(transaction)
case .deferred:
// Purchase awaiting approval (family sharing)
print("Transaction deferred: \(transaction.payment.productIdentifier)")
case .purchasing:
// Transaction in progress
break
@unknown default:
break
}
}
}
private func handlePurchasedTransaction(_ transaction: SKPaymentTransaction) {
// Verify receipt with your backend
verifyReceipt { isValid in
if isValid {
// Send to Singular
self.trackSubscriptionToSingular(transaction)
// Grant entitlement
self.grantSubscriptionAccess(transaction)
// Finish transaction
SKPaymentQueue.default().finishTransaction(transaction)
}
}
}
private func trackSubscriptionToSingular(_ transaction: SKPaymentTransaction) {
// Get product details for pricing
let productId = transaction.payment.productIdentifier
// You should cache product details from SKProductsRequest
if let product = getCachedProduct(productId) {
let price = product.price.doubleValue
let currency = product.priceLocale.currencyCode ?? "USD"
// Determine event name
let eventName = isNewSubscription(transaction) ? "sng_subscribe" : "subscription_renewed"
// Send to Singular WITHOUT receipt
Singular.customRevenue(
eventName,
currency: currency,
amount: price,
withAttributes: [
"subscription_id": productId,
"transaction_id": transaction.transactionIdentifier ?? "",
"transaction_date": transaction.transactionDate?.timeIntervalSince1970 ?? 0
]
)
}
}
}
Consultar o estado da subscrição
Use a validação de recibo para verificar o status atual da assinatura e lidar com renovações.
func refreshSubscriptionStatus() {
let request = SKReceiptRefreshRequest()
request.delegate = self
request.start()
}
extension SubscriptionManager: SKRequestDelegate {
func requestDidFinish(_ request: SKRequest) {
// Receipt refreshed successfully
if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
// Send receipt to your backend for validation
validateReceiptOnServer()
}
}
func request(_ request: SKRequest, didFailWithError error: Error) {
print("Receipt refresh failed: \(error.localizedDescription)")
}
}
Método de integração SDK
Envie eventos de assinatura do seu aplicativo usando os métodos de receita personalizados do Singular SDK sem validação de recibo.
Métodos SDK específicos da plataforma
Use o método SDK apropriado para sua plataforma para rastrear eventos de assinatura.
SDK do Android
// Track subscription without receipt
Singular.customRevenue(
"sng_subscribe", // Event name
"USD", // Currency
9.99, // Amount
mapOf( // Additional attributes
"subscription_id" to "premium_monthly",
"billing_period" to "monthly"
)
)
Documentação: Rastreamento de receita do SDK do Android
SDK do iOS
// Track subscription without receipt
Singular.customRevenue(
"sng_subscribe", // Event name
currency: "USD", // Currency
amount: 9.99, // Amount
withAttributes: [ // Additional attributes
"subscription_id": "premium_monthly",
"billing_period": "monthly"
]
)
Documentação: Rastreamento de receita do SDK do iOS
SDK do React Native
// Track subscription without receipt
Singular.customRevenueWithArgs(
"sng_subscribe", // Event name
"USD", // Currency
9.99, // Amount
{ // Additional attributes
subscription_id: "premium_monthly",
billing_period: "monthly"
}
);
Documentação: rastreio de receitas do SDK do React Native
SDK do Unity
// Track subscription without receipt
SingularSDK.CustomRevenue(
"sng_subscribe", // Event name
"USD", // Currency
9.99, // Amount
new Dictionary<string, object> { // Additional attributes
{ "subscription_id", "premium_monthly" },
{ "billing_period", "monthly" }
}
);
Documentação: Acompanhamento de receitas do SDK do Unity
SDK do Flutter
// Track subscription without receipt
Singular.customRevenueWithAttributes(
"sng_subscribe", // Event name
"USD", // Currency
9.99, // Amount
{ // Additional attributes
"subscription_id": "premium_monthly",
"billing_period": "monthly"
}
);
Documentação: SDK do Flutter Rastreamento de receitas
SDK do Cordova
// Track subscription without receipt
cordova.plugins.SingularCordovaSdk.customRevenueWithArgs(
"sng_subscribe", // Event name
"USD", // Currency
9.99, // Amount
{ // Additional attributes
subscription_id: "premium_monthly",
billing_period: "monthly"
}
);
Documentação: Rastreamento de receita do SDK do Cordova
Crítico: NÃO use métodos IAP (In-App Purchase) ou envie valores de recibo para a Singular para rastreamento de assinatura. Use apenas os métodos customRevenue() sem recibos.
Integração de servidor para servidor
Envie eventos de assinatura em tempo real do seu backend para a API REST da Singular para rastreamento imediato, independentemente do estado do aplicativo.
Requisitos de implementação
Use o Event Endpoint do Singular para enviar eventos de subscrição com parâmetros de receita a partir do seu backend seguro.
Ponto de extremidade de evento
Envie solicitações POST para a Event API da Singular com dados de eventos de assinatura e propriedades necessárias do dispositivo móvel.
Ponto de extremidade:
POST https://api.singular.net/api/v1/evt
Parâmetros necessários:
-
Chave SDK: Sua chave SDK da Singular (parâmetro
a) -
Nome do evento: Nome do evento de assinatura (parâmetro
n) -
Receita: Valor da assinatura (parâmetro
amt) -
Moeda: Código de moeda ISO 4217 (parâmetro
cur) - Identificadores de dispositivos: IDFA (iOS) ou GAID (Android) para atribuição
-
Plataforma: Sistema operativo (parâmetro
p)
Documentação: Referência do ponto de extremidade do eventoe parâmetros de receita
Exemplo de solicitação
curl -X POST 'https://api.singular.net/api/v1/evt' \
-H 'Content-Type: application/json' \
-d '{
"a": "YOUR_SDK_KEY",
"n": "sng_subscribe",
"r": 9.99,
"pcc": "USD",
"idfa": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"p": "iOS",
"install_time": 1697000000000,
"extra": {
"subscription_id": "premium_monthly",
"order_id": "GPA.1234.5678.9012"
}
}'
SDK não necessário: Se utilizar o S2S para eventos de subscrição, não precisa de enviar estes eventos a partir do SDK. No entanto, a maioria das aplicações deve integrar o SDK para rastreio de sessões e eventos sem subscrição.
Integrações de terceiros
Configure o rastreamento de assinaturas através de plataformas de terceiros que gerenciam a infraestrutura de assinaturas e enviam eventos diretamente para a Singular.
Parceiros suportados
Integre-se com plataformas de gerenciamento de assinaturas que possuem suporte integrado ao Singular.
Integração com RevenueCat
RevenueCat gerencia a infraestrutura de assinaturas e envia automaticamente eventos de assinatura para a API REST da Singular.
Etapas de configuração:
- Criar uma conta no RevenueCat: Configurar seu aplicativo no painel do RevenueCat
- Configurar a integração do Singular: Adicione a chave SDK do Singular nas configurações de integrações do RevenueCat
- Mapear eventos: Configurar quais eventos do RevenueCat devem ser enviados para o Singular
- Testar a integração: Verificar se os eventos aparecem no painel do Singular
Documentação: Integração do RevenueCat com o Singular
Integração com Adapty
Adapty fornece análise de assinaturas e envia eventos para o Singular através de sua integração.
Etapas de configuração:
- Criar conta Adapty: Registrar e configurar seu aplicativo no Adapty
- Habilitar a integração do Singular: Navegue até as integrações e adicione credenciais do Singular
- Configurar mapeamento de eventos: Selecione quais eventos de assinatura devem ser encaminhados
- Verificar fluxo de dados: Confirme se os eventos chegam ao Singular com sucesso
Documentação: Integração do Adapty Singular
Nota: As integrações de terceiros são gerenciadas por plataformas parceiras. A configuração deve ser concluída em seus respectivos painéis. O Singular SDK ainda deve ser integrado para rastreamento de eventos de sessão e sem assinatura.
Tipos de eventos de assinatura
Acompanhe vários eventos do ciclo de vida da assinatura para medir o envolvimento, a retenção e a receita do usuário em toda a jornada da assinatura.
Nomes de eventos padrão
Use os nomes de eventos padrão do Singular para relatórios consistentes entre plataformas ou defina nomes de eventos personalizados com base em seus requisitos de rastreamento.
| Estado da subscrição | Nome do evento | Método SDK | Integração S2S |
|---|---|---|---|
| Nova Assinatura |
sng_subscribe
|
customRevenue() com o montante da receita (sem recibo) | Ponto de extremidade do evento com parâmetros de receita |
| Início do teste |
sng_start_trial
|
método event() sem receita | Ponto de extremidade de evento padrão sem receita |
| Fim do ensaio |
sng_end_trial
|
método event() sem receitas | Ponto de extremidade de evento padrão sem receita |
| Renovação da subscrição |
subscription_renewed
|
customRevenue() com montante de receitas (sem recibo) | Ponto de extremidade de evento com parâmetros de receita |
| Cancelamento |
subscription_cancelled
|
método event() sem receita | Ponto de extremidade de evento padrão sem receita |
| Reembolso |
subscription_refunded
|
customRevenue() com montante negativo (opcional) OU evento() sem receitas | Ponto de extremidade de evento com receita negativa (opcional) OU evento padrão |
Importante: Ao enviar eventos de subscrição através de customRevenue(), envie apenas eventos em que isRestored seja falso. As compras restauradas representam subscrições existentes, não novas receitas.
Exemplos de implementação de eventos
Nova assinatura
Acompanha quando os utilizadores compram uma nova subscrição pela primeira vez.
// New subscription purchase
Singular.customRevenue(
"sng_subscribe",
"USD",
9.99,
mapOf(
"subscription_tier" to "premium",
"billing_period" to "monthly",
"product_id" to "premium_monthly"
)
)
Início da avaliação
Acompanhe quando os utilizadores iniciam um período de avaliação gratuita sem receitas.
// Trial start (no revenue)
Singular.event(
"sng_start_trial",
mapOf(
"trial_duration" to "7_days",
"subscription_tier" to "premium"
)
)
Renovação de subscrição
Acompanhe as renovações automáticas de subscrição com o valor da receita.
// Subscription renewal
Singular.customRevenue(
"subscription_renewed",
"USD",
9.99,
mapOf(
"subscription_tier" to "premium",
"renewal_count" to 3,
"product_id" to "premium_monthly"
)
)
Cancelamento
Acompanhe quando os utilizadores cancelam a sua subscrição (sem evento de receitas).
// Subscription cancelled (no revenue)
Singular.event(
"subscription_cancelled",
mapOf(
"cancellation_reason" to "too_expensive",
"days_active" to 45,
"subscription_tier" to "premium"
)
)
Medição da SKAdNetwork
Medir eventos de subscrição através da SKAdNetwork da Apple para atribuição compatível com a privacidade do iOS.
Suporte de subscrição SKAN
A Singular pode medir dados de eventos de assinatura por meio de todos os métodos de integração (SDK, S2S e de terceiros). A medição de eventos pode ser limitada pelas janelas de tempo de postback do SKAN, dependendo da versão do SKAN.
Implementação híbrida de SKAN
Para aplicativos que usam o Singular SDK para eventos de ciclo de vida e integrações S2S/terceiros para assinaturas, habilite o Hybrid SKAN para combinar as duas fontes de dados.
Contactar o suporte: Entre em contato com o Gerente de sucesso do cliente (CSM) para habilitar o SKAN híbrido para seu aplicativo. Isso garante que os eventos de assinatura de fontes de back-end sejam atribuídos corretamente nos valores de conversão do SKAN.
Janelas de postback do SKAN:
- SKAN 4.0: Três janelas de postback (0-2 dias, 3-7 dias, 8-35 dias) permitem a medição de eventos de assinatura antecipada e renovações de curto prazo
- SKAN 3.0: A janela única de postback de 24 horas limita a medição apenas a subscrições imediatas
- Valores de conversão: Configure eventos de assinatura no seu esquema de valores de conversão SKAN para priorizar eventos de alto valor
Melhores práticas e validação
Siga as práticas recomendadas de implementação e verifique se o rastreamento de assinatura está funcionando corretamente antes da implantação na produção.
Práticas recomendadas de implementação
Diretrizes principais
- Sem validação de recibo: Nunca envie recibos de plataforma (Google Play, App Store) para a Singular ao rastrear assinaturas - use customRevenue() sem recibos
- Filtrar compras restauradas: Envie apenas eventos em que isRestored é falso para evitar relatórios de receita duplicados
- Verificação de backend: Sempre verifique as compras em seu backend seguro antes de enviar eventos para a Singular
- Reconhecimento oportuno: Confirme as compras no Google Play dentro de 3 dias para evitar reembolsos automáticos
- Consulta no currículo: Chame queryPurchasesAsync() em onResume() para capturar renovações que ocorreram enquanto o aplicativo estava fechado
- Nomes de eventos consistentes: Use nomes de eventos Singular padrão (sng_subscribe, subscription_renewed) para relatórios unificados
- Incluir metadados: Adicione atributos como subscription_tier, billing_period e product_id para uma análise detalhada
Teste e validação
Lista de verificação de testes
- Configuração do ambiente de teste: Usar contas sandbox/teste para o Google Play e a App Store
- Nova assinatura: Verificar se o evento sng_subscribe é enviado corretamente com o montante e a moeda adequados
- Fluxo de teste: Teste os eventos de início e fim de teste sem receita
- Tratamento de renovações: Confirme se as renovações acionam os eventos subscription_renewed com a receita correta
- Rastreamento de cancelamento: Verificar se os eventos de cancelamento são disparados quando os utilizadores cancelam as subscrições
- Filtragem de restauração: Garantir que as compras restauradas não enviem eventos duplicados
- Painel de controle do Singular: Verificar se os eventos aparecem no Singular com a atribuição correta
- Entre dispositivos: Testar a sincronização da subscrição em vários dispositivos
Problemas comuns
- Eventos ausentes: Verifique se a conexão do cliente de faturamento está ativa e se queryPurchasesAsync() é chamada na retomada do aplicativo
- Eventos duplicados: Verifique se as compras restauradas são filtradas corretamente com a verificação isRestored
- Receita incorrecta: Certifique-se de que a extração de preços de ProductDetails divide corretamente os micros por 1.000.000
- Problemas de atribuição: Confirmar se os identificadores de dispositivos (IDFA/GAID) estão corretamente incluídos nos pedidos S2S
- Falhas de confirmação: Verificar se a validação do recibo de backend é concluída antes da confirmação
Recursos de suporte: Para obter assistência na solução de problemas, entre em contato com o Suporte Singular com a versão do SDK, detalhes da plataforma, amostras de cargas de eventos e capturas de tela do painel Singular mostrando o problema.