Guía de integración en la app para el programa de ofertas externas

En esta guía, se describe cómo realizar la integración con las APIs para admitir ofertas externas en las regiones y apps aptas. Para obtener más información sobre el programa de ofertas externas, incluidos los requisitos de elegibilidad y el alcance geográfico, consulta los requisitos del programa.

Configuración de la Biblioteca de Facturación Play

Para usar las APIs de ofertas externas, agrega la versión 8.2 o una posterior de la dependencia de la Biblioteca de Facturación Play a tu app para Android. Si necesitas migrar desde una versión anterior, sigue las instrucciones de la guía de migración antes de intentar implementar las ofertas externas.

Cómo conectarse a Google Play

Los primeros pasos del proceso de integración son los mismos que los descritos en la guía de integración de la facturación, excepto que debes llamar a enableBillingProgram para indicar que deseas usar ofertas externas cuando inicializas tu BillingClient:

En el siguiente ejemplo, se muestra cómo inicializar un objeto BillingClient con estas modificaciones:

Kotlin

val billingClient = BillingClient.newBuilder(context)
  .enableBillingProgram(BillingProgram.EXTERNAL_OFFER)
  .build()

Java

private BillingClient billingClient = BillingClient.newBuilder(context)
    .enableBillingProgram(BillingProgram.EXTERNAL_OFFER)
    .build();

Después de inicializar el objeto BillingClient, debes establecer una conexión con Google Play, como se describe en la guía de integración.

Comprobar disponibilidad

Para confirmar que las ofertas externas están disponibles para el usuario actual, llama a isBillingProgramAvailableAsync.

Esta API devuelve BillingResponseCode.OK si hay ofertas externas disponibles. Consulta la sección de manejo de respuestas para obtener detalles sobre cómo tu app debe responder a otros códigos de respuesta.

Kotlin


billingClient.isBillingProgramAvailableAsync(
  BillingProgram.EXTERNAL_OFFER,
  object : BillingProgramAvailabilityListener {
    override fun onBillingProgramAvailabilityResponse(
      billingResult: BillingResult,
      billingProgramAvailabilityDetails: BillingProgramAvailabilityDetails) {
        if (billingResult.responseCode !=  BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors,
            // handling external offers unavailable, etc.
            return
        }

        // External offers are available. Continue with steps in the
        // guide.
      }
  })

Java


billingClient.isBillingProgramAvailableAsync(
  BillingProgram.EXTERNAL_OFFER,
  new BillingProgramAvailabilityListener() {
    @Override
    public void onBillingProgramAvailabilityResponse(
      BillingResult billingResult,
      BillingProgramAvailabilityDetails billingProgramAvailabilityDetails) {
        if (billingResult.getResponseCode() != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors,
            // handling external offers being unavailable, etc.
            return;
        }
        // External offers are available. Continue with steps in the
        // guide.
      }
  });

Prepara un token de transacción externa

Para informar una transacción externa a Google Play, debes tener un token de transacción externa generado a partir de la Biblioteca de Play Billing. Puedes obtener este token llamando a la API de createBillingProgramReportingDetailsAsync. Se debe generar un token nuevo inmediatamente antes de dirigir al usuario fuera de la app para cada oferta externa. Los tokens no se deben almacenar en caché entre transacciones.

Kotlin

val params =
  BillingProgramReportingDetailsParams.newBuilder()
    .setBillingProgram(BillingProgram.EXTERNAL_OFFER)
    .build();

billingClient.createBillingProgramReportingDetailsAsync(
  params,
  object : BillingProgramReportingDetailsListener {
    override fun onCreateBillingProgramReportingDetailsResponse(
      billingResult: BillingResult,
      billingProgramReportingDetails: BillingProgramReportingDetails?) {
        if (billingResult.responseCode !=  BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors.
            return
        }
        val externalTransactionToken =
            billingProgramReportingDetails?.externalTransactionToken
        // Persist the transaction token in your backend. You may pass it
        // to the external website when calling the launchExternalLink API.
    }
})

Java

BillingProgramReportingDetailsParams params =
  BillingProgramReportingDetailsParams.newBuilder()
    .setBillingProgram(BillingProgram.EXTERNAL_OFFER)
    .build();

billingClient.createBillingProgramReportingDetailsAsync(
  params,
  new BillingProgramReportingDetailsListener() {
    @Override
    public void onCreateBillingProgramReportingDetailsResponse(
      BillingResult billingResult,
      @Nullable BillingProgramReportingDetails
        billingProgramReportingDetails) {
        if (billingResult.getResponseCode() != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors.
            return;
        }

        String transactionToken =
          billingProgramReportingDetails.getExternalTransactionToken();
        // Persist the transaction token in your backend. You may pass it
        // to the external website when calling the launchExternalLink API.
      }
});

También puedes consultar la función de suspensión createBillingProgramReportingDetailsAsync con extensiones de Kotlin para que no tengas que definir un objeto de escucha:

  val createBillingProgramReportingDetailsResult =
    withContext(context) {
      billingClient
        .createBillingProgramReportingDetails(params)
    }
  // Process the result

Inicia el flujo de ofertas externas

Para iniciar un flujo de ofertas externas, tu app apta debe llamar a la API de launchExternalLink() desde el subproceso principal de la app. Esta API toma como entrada un objeto LaunchExternalLinkParams. Para crear un objeto LaunchExternalLinkParams, usa la clase LaunchExternalLinkParams.Builder. Esta clase contiene los siguientes parámetros:

  • linkUri: Es el vínculo al sitio web externo en el que se ofrece el contenido digital o la descarga de la app. En el caso de las descargas de apps, este vínculo debe estar registrado y aprobado en Play Console.
  • linkType: Es el tipo de contenido que se ofrece al usuario.
  • launchMode: Especifica cómo se inicia el vínculo. En el caso de las descargas de aplicaciones, debes establecer este parámetro en LAUNCH_IN_EXTERNAL_BROWSER_OR_APP.
  • billingProgram: Configura este campo como BillingProgram.EXTERNAL_OFFER.

Cuando llamas a launchExternalLink(), es posible que se muestren diálogos de información adicional al usuario según su configuración. Según el parámetro launchMode, Play inicia el URI del vínculo en un navegador externo o devuelve el flujo a tu app para iniciar el URI. En la mayoría de los casos, puedes usar el modo LAUNCH_IN_EXTERNAL_BROWSER_OR_APP, en el que Play iniciará el URI por ti. Si deseas tener un comportamiento más personalizado, como iniciar el URI en una WebView o abrirlo en un navegador específico, puedes usar el modo CALLER_WILL_LAUNCH_LINK. Para proteger la privacidad del usuario, asegúrate de que no se pase información de identificación personal (PII) en el URI.

Kotlin


// An activity reference from which the external offers flow will be launched.
val activity = ...;

val params =
  LaunchExternalLinkParams.newBuilder()
    .setBillingProgram(BillingProgram.EXTERNAL_OFFER)
    // You can pass along the external transaction token from
    // BillingProgramReportingDetails as a URL parameter in the URI
    .setLinkUri(yourLinkUri)
    .setLinkType(LaunchExternalLinkParams.LinkType.LINK_TO_APP_DOWNLOAD)
    .setLaunchMode(
      LaunchExternalLinkParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP)
    .build()

val listener : LaunchExternalLinkResponseListener =
  LaunchExternalLinkResponseListener {
      override fun onLaunchExternalLinkResponse(billingResult: BillingResult) {
    if (billingResult.responseCode == BillingResponseCode.OK) {
      // Proceed with the rest of the external offer flow. If the user
      // purchases an item, be sure to report the transaction to Google Play.
    } else {
      // Handle failures such as retrying due to network errors.
    }
  }
}

billingClient.launchExternalLink(activity, params, listener)

Java


// An activity reference from which the external offers flow will be launched.
Activity activity = ...;

LaunchExternalLinkParams params = LaunchExternalLinkParams.newBuilder()
  .setBillingProgram(BillingProgram.EXTERNAL_OFFER)
  // You can pass along the external transaction token from  
  // BillingProgramReportingDetails as a URL parameter in the URI
  .setLinkUri(yourLinkUri)
  .setLinkType(LaunchExternalLinkParams.LinkType.LINK_TO_APP_DOWNLOAD)
  .setLaunchMode(
    LaunchExternalLinkParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP)
  .build();

LaunchExternalLinkResponseListener listener =
  new LaunchExternalLinkResponseListener() {
    @Override
    public void onLaunchExternalLinkResponse(BillingResult billingResult) {
      if (billingResult.responseCode == BillingResponseCode.OK) {
        // Proceed with the rest of the external offer flow. If the user
        // purchases an item, be sure to report the transaction to Google
        // Play.
      } else {
        // Handle failures such as retrying due to network errors.
      }
    }
  }

billingClient.launchExternalLink(activity, params, listener);

Si configuras LaunchMode como CALLER_WILL_LAUNCH_LINK, debes dirigir al usuario fuera de la app solo si onLaunchExternalLinkResponse proporciona BillingResponseCode.OK.

Cómo informar transacciones a Google Play

Debes informar todas las transacciones externas a Google Play llamando a la API de Google Play Developer desde tu backend. Cuando informes una transacción, debes proporcionar un externalTransactionToken obtenido de la API de createBillingProgramReportingDetailsAsync. Si un usuario realiza varias compras, puedes usar el mismo externalTransactionToken para informar cada compra. Si quieres obtener información para informar una transacción, consulta la guía de integración del backend.

Control de respuestas

Cuando se produce un error, los métodos isBillingProgramAvailableAsync(), createBillingProgramReportingDetailsAsync() y launchExternalLink() pueden devolver respuestas distintas de BillingResponseCode.OK. Considera controlar estos códigos de respuesta de la siguiente manera:

  • ERROR: Este es un error interno. No continúes con la transacción ni abras el sitio web externo. Vuelve a intentarlo llamando a launchExternalLink() para mostrar el diálogo de información al usuario la próxima vez que intentes dirigirlo fuera de la app.
  • FEATURE_NOT_SUPPORTED: Play Store no admite las APIs de ofertas externas en el dispositivo actual. No continúes con la transacción ni abras el sitio web externo.
  • USER_CANCELED: No continúes con la apertura del sitio web externo. Vuelve a llamar a launchExternalLink() para mostrar el diálogo de información al usuario la próxima vez que intentes dirigirlo fuera de la app.
  • BILLING_UNAVAILABLE: La transacción no es apta para ofertas externas y, por lo tanto, no debe continuar con este programa. Esto se debe a que el usuario no está en un país apto para este programa o a que tu cuenta no se inscribió correctamente en el programa. Si es la última opción, verifica el estado de inscripción en Play Console.
  • DEVELOPER_ERROR: Se produjo un error con la solicitud. Usa el mensaje de depuración para identificar y corregir el error antes de continuar.
  • NETWORK_ERROR, SERVICE_DISCONNECTED, SERVICE_UNAVAILABLE: Estos son errores transitorios que se deben controlar con una política de reintentos adecuada. En el caso de SERVICE_DISCONNECTED, restablece una conexión con Google Play antes de reintentarlo.

Prueba ofertas externas

Los verificadores de licencias se deben usar para probar la integración de tus ofertas externas. No se te facturarán las transacciones que se hayan iniciado desde cuentas de verificadores de licencias. Consulta Prueba la facturación integrada con licencias de aplicaciones para obtener más información sobre cómo configurar los verificadores con licencia.

Próximos pasos

Una vez que termines la integración en la app, tendrás todo listo para integrar tu backend.