Google a publié une toute nouvelle version pour gérer les paiements dans Android mais après une recherche assez longue, je ne trouve pas un seul exemple ou tutoriel de quelqu'un qui a réussi à l'implémenter.
La documentation est très courte et ne fournit qu'une partie du code nécessaire: https://developer.Android.com/google/play/billing/billing_library_overview
Le seul exemple fourni est réalisé avec Kotlin: https://github.com/Android/play-billing-samples
On dirait qu'ils ont oublié Java développeurs ...
Quelqu'un connaît-il un tutoriel en ligne ou a-t-il réussi à le mettre en œuvre? Mon code actuel est loin de fonctionner pour être publié.
Je débute sur Android Studio et j'implémente la bibliothèque de facturation 2.1.0. Après une semaine de lecture de Android et de nombreux tutoriels sur bibliothèque de facturation J'ai créé cette classe Java classe, mais je pense que ce n'est pas assez bon, au moins il fait ce qu'il doit faire. Si vous trouvez un moyen de l'améliorer, commentez-le. Merci:
1.- Classe Pago.Java:
package com.example.billing;
import Android.app.Activity;
import Android.content.Context;
import Android.util.Log;
import Android.widget.Toast;
import androidx.annotation.Nullable;
import com.Android.billingclient.api.BillingClient;
import com.Android.billingclient.api.BillingClientStateListener;
import com.Android.billingclient.api.BillingFlowParams;
import com.Android.billingclient.api.BillingResult;
import com.Android.billingclient.api.ConsumeParams;
import com.Android.billingclient.api.ConsumeResponseListener;
import com.Android.billingclient.api.Purchase;
import com.Android.billingclient.api.PurchasesUpdatedListener;
import com.Android.billingclient.api.SkuDetails;
import com.Android.billingclient.api.SkuDetailsParams;
import com.Android.billingclient.api.SkuDetailsResponseListener;
import com.example.R;
import static com.Android.billingclient.api.BillingClient.BillingResponseCode.SERVICE_TIMEOUT;
import static com.Android.billingclient.api.BillingClient.BillingResponseCode.OK;
import static com.Android.billingclient.api.BillingClient.BillingResponseCode.USER_CANCELED;
import static com.Android.billingclient.api.BillingClient.BillingResponseCode.BILLING_UNAVAILABLE;
import static com.Android.billingclient.api.BillingClient.BillingResponseCode.ITEM_UNAVAILABLE;
import static com.Android.billingclient.api.BillingClient.BillingResponseCode.ERROR;
import static com.Android.billingclient.api.BillingClient.SkuType.INAPP;
import Java.util.ArrayList;
import Java.util.List;
public class Pagos implements PurchasesUpdatedListener, BillingClientStateListener, SkuDetailsResponseListener, ConsumeResponseListener {
private BillingClient billingClient;
private Context contextPago;
private String skuId;
private List<SkuDetails> misProductos;
// Constructor de la clase Pagos
public Pagos(Context context) {
contextPago = context;
}
// Asigna el sku del producto que se quiere comprar
public void comprar(String skuId) {
this.skuId = skuId;
configurarBillingClient();
}
// Configura el Billing Client para iniciar la conexión con Google Play Console
private void configurarBillingClient() {
// 1. Configura el Billing Client
billingClient = BillingClient.newBuilder(contextPago)
.enablePendingPurchases()
.setListener(this)
.build();
// 2. Inicia la conexión y asigna los Listener
billingClient.startConnection(this);
}
@Override
// Evento salta al llamar billingClient.startConnection()
public void onBillingSetupFinished(BillingResult billingResult) {
// Busca compras en el Servidor de Google y las marca como consumidas
consumeCompras();
// Verifica que la versión de Play Store sea compatible con INAPP
if (!billingClient.isReady()) {
String mensaje = contextPago.getString(R.string.PAGOS_MENSAJE_VERSIÓN_NO_COMPATIBLE);
Toast.makeText(contextPago, mensaje, Toast.LENGTH_LONG).show();
return;
}
// Verifica que la versión de Play Store sea compatible con Suscripciones
// if (billingClient.isFeatureSupported(SUBSCRIPTIONS).getResponseCode() != OK) {
// String mensaje = contextPago.getString(R.string.PAGOS_MENSAJE_VERSIÓN_NO_COMPATIBLE);
// Toast.makeText(contextPago, mensaje, Toast.LENGTH_LONG).show();
// return; //GooglePlayNoSoportaComprasDeSuscripciones
// }
// Verifica que la Configuración se haya hecho bien, sino muestra mensaje de error
if (verificaResponseCode(billingResult.getResponseCode()) == OK) {
consultaProductos();
}
}
// Asigna los elemento que se consultarán a Google y los envía con querySkuDetailsAsync
private void consultaProductos() {
// Inicializa constantes
String ITEM_SKU_1 = "Android.test.item_unavailable";
String ITEM_SKU_2 = "Android.test.canceled";
String ITEM_SKU_3 = "Android.test.purchased";
String ITEM_SKU_4 = "donar";
String ITEM_SKU_5 = "prueba.1";
// Agrega los productos que se consultarán a Google
List<String> skuList = new ArrayList<>();
skuList.add(ITEM_SKU_1);
skuList.add(ITEM_SKU_2);
skuList.add(ITEM_SKU_3);
skuList.add(ITEM_SKU_4);
skuList.add(ITEM_SKU_5);
// TODO Cambiar el ingreso manual de items por una consulta a servidor propio de backend seguro.
SkuDetailsParams.Builder skuDetailsParams = SkuDetailsParams
.newBuilder()
.setSkusList(skuList)
.setType(INAPP);
// Envía consulta a Google y devuelve el listado de productos mediante onSkuDetailsResponse
billingClient.querySkuDetailsAsync(skuDetailsParams.build(), this);
}
@Override
// Evento salta cuando Google envía los detalles de los Productos en Venta
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
if (verificaResponseCode(billingResult.getResponseCode()) == OK) {
if (skuDetailsList != null) {
misProductos = skuDetailsList;
muestraDialogoCompra();
} else {
String mensaje = contextPago.getString(R.string.PAGOS_MENSAJE_NO_SKUDETAILSLIST);
Toast.makeText(contextPago, mensaje, Toast.LENGTH_LONG).show();
}
}
}
// Lanza el dialogo de compra de Google
private void muestraDialogoCompra() {
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
.setSkuDetails(getSkuIdDetails())
.build();
billingClient.launchBillingFlow((Activity) contextPago, flowParams);
}
// Obtiene el Producto que se comprará según el Sku ingresado mediante comprar(sku);
private SkuDetails getSkuIdDetails() {
if (misProductos == null) return null;
for (SkuDetails skuProducto : misProductos) {
if (skuId.equals(skuProducto.getSku())) return skuProducto;
}
return null;
}
@Override
// Evento salta cuando se finaliza el Proceso de compra
public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> list) {
if (verificaResponseCode(billingResult.getResponseCode()) == OK) {
// Validar compra con consulta a Google para evitar ingeniería inversa de hackers
if (validaCompra()) {
// Compra confirmada
Log.i("Pagos", "Compra encontrada en servidor");
} else {
// Compra no encontrada: Mensaje de error - Revocar privilegios
Log.i("Pagos", "Compra no encontrada posible hacker");
}
consumeCompras();
}
}
// Valida la compra y Devuelve True si encuentra la compra del usuario en el Servidor de Google
private boolean validaCompra() {
List<Purchase> purchasesList = billingClient.queryPurchases(INAPP).getPurchasesList();
if (purchasesList != null && !purchasesList.isEmpty()) {
for (Purchase purchase : purchasesList) {
if (purchase.getSku().equals(skuId)) {
return true;
}
}
}
return false;
}
// Busca compras en el Servidor de Google y las marca como consumidas
private void consumeCompras() {
Purchase.PurchasesResult queryPurchases = billingClient.queryPurchases(INAPP);
if (queryPurchases.getResponseCode() == OK) {
List<Purchase> purchasesList = queryPurchases.getPurchasesList();
if (purchasesList != null && !purchasesList.isEmpty()) {
for (Purchase purchase : purchasesList) {
ConsumeParams params = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
billingClient.consumeAsync(params, this);
}
}
}
}
@Override
// Evento salta cuando se ha consumido un producto, Si responseCode = 0, ya se puede volver a comprar
public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
if (billingResult.getResponseCode() == OK) {
Log.i("Pagos", "Token de Compra: " + purchaseToken + " consumida");
} else {
Log.i("Pagos", "Error al consumir compra, responseCode: " + billingResult.getResponseCode());
}
}
@Override
// Evento salta cuando se pierde la conexión durante una compra
public void onBillingServiceDisconnected() {
billingClient.startConnection(this);
}
// Verifica que el estado del responseCode sea OK, si no muestra mensaje de Error
private int verificaResponseCode(int responseCode) {
if (responseCode == OK) return OK;
if (responseCode == USER_CANCELED) return USER_CANCELED;
String mensaje = "";
switch (responseCode) {
case SERVICE_TIMEOUT:
mensaje = contextPago.getString(R.string.PAGOS_MENSAJE_SERVICE_TIMEOUT);
break;
case BILLING_UNAVAILABLE:
mensaje = contextPago.getString(R.string.PAGOS_MENSAJE_BILLING_UNAVAILABLE);
break;
case ITEM_UNAVAILABLE:
mensaje = contextPago.getString(R.string.PAGOS_MENSAJE_ITEM_UNAVAILABLE);
break;
case ERROR:
mensaje = contextPago.getString(R.string.PAGOS_MENSAJE_ERROR);
break;
default:
mensaje = contextPago.getString(R.string.PAGOS_MENSAJE_ERROR) + " código: " + responseCode;
break;
}
Toast.makeText(contextPago, mensaje, Toast.LENGTH_LONG).show();
return responseCode;
}
}
3.- Manifeste
<uses-permission Android:name="Android.permission.INTERNET" />
<uses-permission Android:name="com.Android.vending.BILLING" />
4.- build.gradle
// Google Play Billing Library
implementation 'com.Android.billingclient:billing:2.1.0'
5.- Utilisation, placez ce code là où vous souhaitez afficher le composant de facturation:
private final String SKU_UNAVAILABLE = "Android.test.item_unavailable";
private final String SKU_CANCELED = "Android.test.canceled";
private final String SKU_PURCHASED = "Android.test.purchased";
private final String SKU_DONAR = "donar";
private void donar() {
Pagos pagos = new Pagos(this);
pagos.comprar(SKU_DONAR);
cargandoDialogoCompra(true);
}
Vous pouvez changer SKU_DONAR, en SKU_UNAVAILABLE, SKU_CANCELED, SKU_PURCHASED car ce sont des éléments à des fins de test et comme je l'ai lu, il n'est pas nécessaire de les ajouter à la console de lecture
6.- Console Google Play
Presencia en Google Play Store -> Productos integrados en la aplicación -> Productos administrados:
Donación (donar) PEN 9.99
C'est tout, merci d'améliorer mon code, merci à tous.
Voici un exemple d'application pour Google Play Billing version 2 en Java: