You are on page 1of 6

Proponer compras integradas

Además de las aplicaciones de pago directamente en Play Store, exite otro método para monetizar
nuestras aplicaciones: las compras integradas (in-app purchases, en inglés). Una aplicación que
propone compras integradas permite al usuario comprar directamente, desde la aplicación, elementos
suplementarios: funcionalidades, elementos de juego, etc.

Los estudios demuestran que las compras integradas son, por lo general, más apreciadas por los
usuarios, que prefieren este modo de monetización a los métodos tradicionales de las aplicaciones de
pago de Play Store. Un extracto de este estudio está disponible en la siguiente
dirección:https://www.centrodeinnovacionbbva.com/noticias/tb/32154-lo-freemium-y-la-publicidad-in-
app-modelos-lideres-en-monetizacion-de-aplicaciones

Observe que el uso del pago integrado requiere que el desarrollador de la aplicación posea una cuenta
en Google Wallet. La creación de esta cuenta puede llevarse a cabo en la siguiente
dirección:http://www.google.com/wallet/business/, y es completamente gratuita.

1. Preparación
Como con la protección de las aplicaciones de pago, es la aplicación Play Store instalada en el
dispositivo del usuario la encargada de la comunicación entre la aplicación y los servidores de Google.
Y, del mismo modo, sólo es posible implementar el pago integrado en aplicaciones publicadas en Play
Store.

La comunicación con Play Store se realiza, para el pago integrado, utilizando la


librería InAppBillingService. Esta librería la provee Google, bajo la forma de un archivo AIDL
(Android Interface Definition Language), y se distribuye mediante el Android SDK Manager.

Utilizar directamente esta librería resulta algo complicado, y exige la implementación de numerosos
elementos. Para facilitar el trabajo, Google provee un ejemplo, bien diseñado, que integra un
conjunto de clases que simplifican el uso de la librería In AppBillingService. Vamos a utilizar
estas clases para reducir la carga de trabajo.

La primera etapa consiste, entonces, en descargar el paquete Google Play Billing Library, disponible
en la sección Extras del SDK Manager.

Una vez descargada y ubicada en la carpeta < sdk>/extras/google/play_billing/, se


provee la librería IInAppBillingService.aidl(en la raíz de la carpeta) así como el ejemplo del
que vamos a extraer las clases que nos interesan, en la carpeta /samples/TrivialDrive/.
Para utilizar la librería en una aplicación, basta con crear un nuevo paquete en el proyecto. Este
paquete se llamará co m.android.vending.billing. Una vez creado el paquete, es preciso
copiar el archivo II nAppBillingService.aidl.
A continuación, copie la
carpeta Tr ivialDrive/src/com/example/android/trivialdrivesample/util en el
proyecto de la aplicación, en la carpeta /s rc. Conviene renombrar el paquete de las clases
importadas: en Eclipse, haga clic con el botón derecho sobre la carpeta utilcopiada y seleccione la
opciónRefactor y, a continuación, Rename. Indique el nombre del paquete deseado. El proyecto debe
compilar sin problemas: se genera un archivo I InAppBilling-Service.javaautomáticamente
en la carpeta /gendel proyecto.

El pago integrado requiere la autorización co m.android.vending.BILLING; es preciso, por


tanto, declararlo en el manifiesto de la aplicación.

Sintaxis

<uses-permission android:name="com.android.vending.BILLING" />

Una vez agregado el permiso al manifiesto, hay que importar el APK del proyecto en la consola de
desarrollador de Play Store: esta primera importación permite indicar a Play Store que la aplicación
poseerá pagos integrados, de modo que Play Store lo detecta automáticamente en la lectura del
manifiesto, gracias al permiso com .android.vending.BILLING. Como con cualquier aplicación
en Play Store, es necesario que el APK esté firmado (consulte el capítulo Publicar una aplicación).

Una vez importada la aplicación, manifiestamente definida como con pagos integrados, la consola del
desarrollador permite agregar productos integrados, que podrán comprarse mediante el pago
integrado: no se trata en ningún caso de productos físicos, sino de elementos que desea hacer de
pago en su aplicación.

Para agregar un producto, basta con ir a la sección Productos integrados en la aplicación en la


consola del desarrollador de la aplicación. Una vez en esta sección, haga clic en el botón Agregar un
producto: se abre una ventana que le invita a seleccionar el tipo de producto que desea agregar y un
Id de producto. La librería II nAnBillingService sólo es compatible, de momento, con los
productos gestionados. Seleccione esta opción e introduzca un identificador para el producto. Haga
clic en Continuar: el producto se ha creado, y el navegador presenta una ficha de producto, similar a
la ficha de una aplicación. Escriba un título, una descripción y un precio. Debe, obligatoriamente,
definir un precio para cada país disponible en Play Store. Como con una aplicación, existe un
botónConvertir precios automáticamente que permite automatizar esta etapa.

Una vez introducida la información obligatoria, basta con hacer clic en Habilitar, en la zona superior de
la pantalla: el producto estará activo, aunque puede existir cierto retardo antes de que esté
disponible.

La siguiente etapa consiste en recuperar, en la consola de desarrollador de Play Store, la clave


pública de la aplicación que utilizará el pago integrado. Es preciso ir a la sección Servicios y API de la
aplicación, y anotar la clave de licencia: se trata de una clave pública RSA, codificada en Base64. Esta
clave es válida para todo el tiempo de vida de la aplicación, y no se modifica cuando se publica una
actualización.

Esta clave debe almacenarse en el proyecto que utilice el pago integrado. Se recomienda no
almacenar directamente la clave, sino prever una serie de rutinas que permitan recomponerla en
tiempo de ejecución de la aplicación. Un primer enfoque sugerido por Google consiste en separar esta
clave pública en varias cadenas y reconstruir el conjunto para su uso.

Una vez realizadas estas operaciones, es posible utilizar el pago integrado en la aplicación.

2. Uso del pago integrado


Entre las clases importadas en el proyecto con el ejemplo de Google, la clase principal
es IabHelper. Esta clase se encarga de realizar las principales operaciones para las compras
integradas.

La sintaxis del constructor es la siguiente:

public IabHelper(Context context, String base64PublicKey)

La cadena ba se64PublicKeyque se pasa como parámetro del constructor corresponde a la clave


pública recuperada de la consola del desarrollador de la aplicación.

a. Iniciar la comunicación con Play Store

La primera etapa consiste en conectarse al servicio Play Store de compras integradas. Esta
operación de conexión la gestiona, completamente, la instancia de IabHelper, mediante el
método s tartSetup.
Sintaxis

public void startSetup(final OnIabSetupFinishedListener listener)

El parámetro que se pasa al método es un Listener que se invocará cuando se complete la


configuración de la conexión. Esta interfaz contiene un método onIabSetupFinished que es
preciso sobrecargar.

Ejemplo

IabHelper billingHelper = new IabHelper(this, publicKey);


billingHelper.startSetup(new OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
if(result.isSuccess())
Toast.makeText(getApplicationContext(), "La conexión al
servicio de billing está activa", Toast.LENGTH_SHORT).show();
else
Toast.makeText(getApplicationContext(), "La conexión al
servicio de billing ha fallado" , Toast.LENGTH_SHORT).show();
}
});

Cuando el proceso de solicitud se termina, o cuando la actividad se destruye, es preciso invocar al


método disposedel objeto Ia bHelper.
Ejemplo

@Override
public void onDestroy() {
super.onDestroy();
if(iabHelper!=null)
iabHelper.dispose();
}

b. Obtener la lista de productos

El método queryInventorydel objeto IabHelperpermite obtener la lista de productos que


pueden comprarse en la aplicación.

Sintaxis

public Inventory queryInventory(boolean detalleProductos, List<String>


idProductos)

El parámetro d etalleProductospermite especificar si se desea obtener los detalles acerca de


los productos (precio, descripción, etc.). El segundo parámetro es una lista de identificadores de los
productos de los que se desea obtener los detalles. Cada identificador se corresponde con el que
se ha indicado en la consola del desarrollador. Si no se indicara ningún identificador como
parámetro, el método devolverá únicamente la lista de productos que ha comprado el usuario.

Este método se ejecuta en el thread principal, lo cual puede resultar problemático, las consultas
podrían ser más o menos largas en función de la lista de productos y la calidad de la conexión de
red del terminal.

También existe una versión asíncrona del método queryInventory, que recibe como parámetro
suplementario un objeto de tipo IabH elper.QueryInventoryFinishedListener, cuyo
método onQueryInventoryFinishedse invoca cuando termina el procesamiento.
Sintaxis

public void queryInventoryAsync(final boolean detalles, final


List<String> idProductos, final QueryInventoryFinishedListener
listener)
public void onQueryInventoryFinished(IabResult resultado, Inventory
inventario)

Ejemplo
ArrayList<String> productos = new ArrayList<String>();
productos.add("producto_1");
iabHelper.queryInventoryAsync(true, productos, new Query
InventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
if(result.isFailure())
Toast.makeText(getApplicationContext(),
"Recuperación de los ítems
errónea",Toast.LENGTH_SHORT).show();
else
Toast.makeText(getApplicationContext(),
"Recuperación de los ítems
ok",Toast.LENGTH_SHORT).show();
});

El objeto de tipo Inventory devuelto por los métodos qu eryInventory contiene información
acerca de los productos disponibles y comprados: el método getSkuDetails permite obtener
información acerca de un producto, y el método getPurchasepermite obtener información acerca
de la solicitud para un producto.

Sintaxis

public SkuDetails getSkuDetails(String idProducto)


public Purchase getPurchase(String idProducto)

El objeto SkuDetails incluye información acerca del título, la descripción, así como el precio del
elemento que se ha puesto a la venta. Esta información está accesible utilizando los métodos get...
correspondientes.

Sintaxis

public String getTitle()


public String getDescription()
public String getPrice()

El objeto Purchaseincluye información relativa a la solicitud, en el caso de que el producto sehaya


pedido por parte del usuario.

Sintaxis

public String getOrderId()


public long getPurchaseTime()
public int getPurchaseState()
public String getDeveloperPayload()

c. Comprobar que un producto se ha solicitado

El objeto I nventory presenta, también, el método hasPurchase, que devuelve true si el


usuario ha pedido un producto.

Sintaxis

public boolean hasPurchase(String idProducto)

Ejemplo

iabHelper.queryInventoryAsync(true, productos, new Query


InventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
if(inventory.hasPurchase("Producto 1"))
Toast.makeText(MainActivity.this,
"El producto 1 se ha solicitado",
Toast.LENGTH_SHORT).show();
}
});

El desarrollador deberá elaborar una estrategia eficaz para la verificación de las compras: no resulta
apropiado ejecutar una verificación con cada uso de la aplicación, puesto que la verificación requiere
una conexión a Internet. Es conveniente, por tanto, implementar una caché con las compras
verificadas para el caso de que no exista ninguna conexión de red disponible, y verificar de manera
regular las compras cuando el terminal se encuentre conectado.

d. Solicitar un producto

Play Store gestiona la totalidad del proceso de solicitud de un producto. Para el desarrollador, basta
con iniciar el proceso invocando al método l aunchPurchaseFlowdel objeto IabHelper.
La sintaxis del método es la siguiente:

Sintaxis

public void launchPurchaseFlow(Activity activity, String idProducto,


int codigoSolicitud, OnIabPurchaseFinishedListener listener)

activity: actividad en curso. El proceso debe ejecutarse desde el thread principal de la actividad.

idProducto: identificador del producto, tal y como se ha especificado en la consola de


desarrollador.

CodigoSolicitud: código que ha escogido el desarrollador para identificar la petición. Este


código lo devuelve Play Store.

Listener: interfaz que expone el método o nIabPurchaseFinished, que hay que


sobrecargar. La invocación de este método es algo particular y se detalla a continuación.

A diferencia del esquema clásico que encontramos en la plataforma Android, el


objeto OnIabPurchaseFinishedListener que se pasa como parámetro del
método l aunchPurchaseFlowno se invoca directamente una vez finaliza el proceso de compra
en caso de éxito - ¡sino que se le invoca cuando se produce un error en el proceso!

Al margen de este punto, Play Store, cuando finaliza el proceso, invoca al


método o nActivityResultde la actividad que se ha pasado como parámetro. A continuación, en
el método onAc tivityResult, hay que invocar al método handleActivityResult del
objeto IabHelper para que el método onIabPurchaseFinished se invoque. El
método h andleActivityResultdevuelve truesi la petición se corresponde efectivamente con
una compra integrada, y falsesi la llamada a onActivityResultes de otro origen.
Ejemplo

private void iniciarCompra() {


IabHelper.OnIabPurchaseFinishedListener mPurchaseFinished
Listener =
new IabHelper.OnIabPurchaseFinishedListener() {
@Override
public void onIabPurchaseFinished(IabResult result,
Purchase info){
if (result.isFailure()) {
Toast.makeText(MainActivity.this,
"Se ha producido un error durante la compra",
Toast.LENGTH_LONG).show();
return;
}
else
Toast.makeText(MainActivity.this, "Compra realizada",
Toast.LENGTH_LONG).show();
}
};
iabHelper.launchPurchaseFlow(this,"Producto_1", 123,
mPurchaseFinishedListener );
}

@Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (!iabHelper.handleActivityResult(requestCode, resultCode,
data)) {
Toast.makeText(this, "La respuesta no se corresponde con
el proceso de compra", Toast.LENGTH_SHORT).show();
super.onActivityResult(requestCode, resultCode, data);
}
}

El método launc hPurchaseFlow posee una variante que permite agregar un tag arbitrario
seleccionado por el desarrollador. Este tag se devuelve en el objeto Purchase, accesible mediante
el método getDeveloperPayload.
Google recomienda utilizar este tag para verificar que la solicitud recibida se corresponde con la
solicitud enviada.

Sintaxis

public void launchPurchaseFlow(Activity act, String sku, String


itemType, int requestCode, OnIabPurchaseFinishedListener listener,
String extraData)

You might also like