← Todas las extensiones

Extensión nativa

KlugBilling

com.klug.billing

NO NECESITAS APM. Descarga y disfruta. No puede ser más sencillo. Solo actualiza el Adobe AIR SDK. Si necesitas ayuda, aquí estamos.

Compras dentro de la app y suscripciones para apps AIR en la App Store y Google Play, con una sola API de ActionScript para ambas tiendas.

iOS Android En producción Desde €19 / año · Comprar

Resumen

KlugBilling vende productos de compra única y suscripciones desde tu app AIR. En iPhone y iPad se comunica con la App Store, en Android con Google Play, y tu código ActionScript es el mismo para ambas.

Carga tus productos con títulos y precios localizados, abre la hoja de compra de la tienda, informa de cada paso de una transacción y la cierra una vez que has entregado el producto. Incluye la restauración de compras anteriores, el recibo de la app de iOS y los datos de compra firmados de Google Play, para que tu servidor pueda verificar cada venta.

En Android, KlugBilling usa la versión actual de Google Play Billing Library 8. Se añade automáticamente al empaquetar la app y cumple los requisitos de Google Play para apps nuevas y actualizaciones.

KlugBilling vende las suscripciones de nuestras apps en iOS y Android, nuestra prueba de concepto.

Funciones

  • Autónoma: una ANE, sin biblioteca central ni ANE de dependencias que añadir
  • Una única API para la App Store y Google Play
  • Productos de compra única y suscripciones con renovación automática
  • Títulos, descripciones y precios localizados directamente de la tienda
  • Periodos de suscripción, ofertas y fases de precio
  • Cada estado de la transacción como evento: comprando, comprado, fallido, cancelado, restaurado, aplazado
  • Restaurar compras (iOS) y listar las compras realizadas (Android)
  • Datos para comprobaciones en el servidor: el recibo de la app de iOS, los datos de compra firmados de Google y la firma
  • Android: las compras se comprueban con tu clave pública de Play

Plataformas compatibles

iOS iPhone · iPad · App Store
Android teléfonos · tabletas · plegables · Google Play Billing Library 8

En otras plataformas InAppBilling.isSupported devuelve false, por lo que el mismo código puede permanecer en una app multiplataforma.

Primeros pasos

Añade la extensión al descriptor de tu aplicación:

app.xml
<extensions>
    <extensionID>com.klug.billing</extensionID>
</extensions>

No se necesitan entradas en el manifiesto ni activities. Crea tus productos en App Store Connect y en la Google Play Console con los mismos IDs de producto, y copia la clave pública base64 de tu app desde la Play Console (Configuración de monetización).

Ejemplos de código

Cuatro flujos completos, tomados de la API que funciona en nuestras apps. Cada llamada devuelve de inmediato; los resultados llegan como eventos en InAppBilling.service. Documentación completa →

1 · Conectar con la tienda
Store.as
import com.klug.billing.*;
import com.klug.billing.events.*;

var store:InAppBillingService = InAppBilling.service;

if ( InAppBilling.isSupported )   // iOS, Android
{
    store.addEventListener( InAppBillingEvent.SETUP_SUCCESS, onSetup );
    store.addEventListener( InAppBillingEvent.SETUP_FAILURE, onSetupFailed );
    store.addEventListener( PurchaseEvent.PURCHASES_UPDATED, onPurchasesUpdated );   // see 3

    var service:BillingService = new BillingService();
    if ( store.platform == "android" )
        service.setServiceType( InAppBillingServiceTypes.GOOGLE_PLAY_INAPP_BILLING )
               .setGooglePlayPublicKey( "MIIBIjANBgkqh..." );   // from the Play Console, Android only
    else
        service.setServiceType( InAppBillingServiceTypes.APPLE_INAPP_PURCHASE );
    store.setup( service );
}

function onSetup( e:InAppBillingEvent ):void
{
    store.checkAvailability( function( result:String ):void {
        if ( result == InAppBillingAvailability.AVAILABLE ) loadProducts();   // see 2
        else hideShop();   // e.g. purchases disabled by Screen Time
    });
}
2 · Mostrar productos con precios localizados
Products.as
function loadProducts():void
{
    store.addEventListener( ProductEvent.PRODUCTS_LOADED, onProducts );
    store.addEventListener( ProductEvent.PRODUCTS_FAILED, function( e:ProductEvent ):void {
        trace( "store not reachable: " + e.message );
    });
    // one-time products first, subscriptions second
    store.getProducts( [ "com.example.removeads" ],
                       [ "com.example.pro.monthly", "com.example.pro.yearly" ] );
}

function onProducts( e:ProductEvent ):void
{
    for each ( var p:Product in e.products )
    {
        // e.g. "Pro Yearly · 19,99 €" in the user's currency and language
        addShopButton( p.id, p.title + " · " + p.priceString );   // your app function
    }
}
3 · Comprar, entregar, finalizar
Purchase.as
function buy( productId:String ):void
{
    var request:PurchaseRequest = new PurchaseRequest().setProductId( productId );
    if ( store.checkPurchaseRequestValid( request ) ) store.makePurchase( request );
}

// every step of every transaction, also open ones from earlier sessions
function onPurchasesUpdated( e:PurchaseEvent ):void
{
    for each ( var p:Purchase in e.data )
    {
        switch ( p.transactionState )
        {
            case Purchase.STATE_PURCHASED:
            case Purchase.STATE_RESTORED:
                // iOS: p.transactionReceipt (app receipt)
                // Android: p.originalMessage + p.signature (Google's signed purchase data)
                verifyOnServer( p, function():void {   // your server call
                    unlock( p.productId );              // your app function
                    store.finishPurchase( p );          // close it, or the store sends it again
                });
                break;
            case Purchase.STATE_FAILED:
            case Purchase.STATE_CANCELLED:
                store.finishPurchase( p );
                break;
            case Purchase.STATE_DEFERRED:
                showHint( "Waiting for approval" );   // e.g. Ask to Buy
                break;
        }
    }
}
4 · Restaurar compras anteriores
Restore.as
function restore():void
{
    if ( store.isGetPurchasesSupported )   // Android: list what the Google account owns
    {
        store.addEventListener( PurchaseEvent.GET_PURCHASES_COMPLETE, function( e:PurchaseEvent ):void {
            for each ( var p:Purchase in e.data ) unlock( p.productId );
        });
        store.getPurchases();
    }
    else   // iOS: restored transactions arrive in onPurchasesUpdated with STATE_RESTORED
    {
        store.addEventListener( PurchaseEvent.RESTORE_PURCHASES_SUCCESS, function( e:PurchaseEvent ):void {
            showHint( "Purchases restored" );
        });
        store.restorePurchases();
    }
}

Resumen de la API

InAppBilling.isSupportedVerdadero en iOS y Android, falso en el resto.
InAppBilling.serviceEl servicio de tienda único; todas las llamadas y eventos de abajo.
setup(service)Se conecta a la tienda descrita por un BillingService. Resultado: SETUP_SUCCESS o SETUP_FAILURE.
checkAvailability(callback)AVAILABLE, NOT_AVAILABLE o STORE_UPGRADE_REQUIRED.
canMakePaymentsFalso cuando las compras están desactivadas en el dispositivo.
getProducts(productIds, subscriptionIds)Carga los datos de la tienda. Resultado: PRODUCTS_LOADED, INVALID_PRODUCT o PRODUCTS_FAILED.
getProduct(id)Un Product cargado: title, description, price, priceString, currencyCode, subscriptionPeriod, subscriptionOffers.
makePurchase(request)Abre la hoja de compra de la tienda para un PurchaseRequest; oferta de suscripción opcional.
finishPurchase(purchase)Cierra una transacción tras la entrega. Resultado: FINISH_SUCCESS o FINISH_FAILED.
getPendingPurchases()Transacciones que la tienda aún mantiene abiertas.
restorePurchases()iOS: restaura las compras anteriores del Apple ID.
getPurchases()Android: lista las compras de la cuenta de Google.
applicationReceiptiOS: el recibo de la app en base64 para tu servidor, con refresh().
dispose()Se desconecta de la tienda.

Eventos

InAppBillingEventSETUP_SUCCESS, SETUP_FAILURE, RESTORE_PURCHASES_SUCCESS, RESTORE_PURCHASES_FAILED
ProductEventPRODUCTS_LOADED (productos), INVALID_PRODUCT, PRODUCTS_FAILED
PurchaseEventPURCHASES_UPDATED (data = objetos Purchase), PURCHASE_FAILED, FINISH_SUCCESS, FINISH_FAILED, RESTORE_PURCHASES_SUCCESS, RESTORE_PURCHASES_FAILED, GET_PURCHASES_COMPLETE, GET_PURCHASES_FAILED
AvailabilityEventCOMPLETE con el resultado de disponibilidad
ApplicationReceiptEventREFRESH_SUCCESS, REFRESH_FAILED

Compra KlugBilling

Una licencia anual para una aplicación AIR, con todas las actualizaciones durante 12 meses. Tras el pago recibes la extensión, la biblioteca ActionScript y la documentación por e-mail, normalmente en un día hábil. Licencia y términos

Simple
€19 / año
  • Licencia para una aplicación AIR
  • Todas las actualizaciones durante 12 meses
  • Sin soporte
Comprar Simple
Standard
€149 / año
  • Licencia para una aplicación AIR
  • Todas las actualizaciones durante 12 meses
  • Respuesta por e-mail en un plazo de 7 días
Comprar Standard
Priority
€299 / año
  • Licencia para una aplicación AIR
  • Todas las actualizaciones durante 12 meses
  • Respuesta por e-mail en un plazo de 48 horas
Comprar Priority
Link (Stripe) calcula los impuestos al pagar. Durante el pago indicas el ID de aplicación de tu app AIR.

Requisitos

AIR SDK51.x (HARMAN)
iOSiOS 13 o posterior, productos en App Store Connect
AndroidAndroid 6.0 (API 23) o posterior, productos en la Google Play Console
Google PlayPlay Billing Library 8.3, añadida al empaquetar
Servidor (recomendado)Verifica el recibo de la app de iOS o los datos de compra firmados de Google