La version de la bibliothèque est passée de 1.0 à 2.0, j'ai donc réécrit le contenu. Vous trouverez ci-dessous le code de l'essai d'essai.
Je vais vous montrer un exemple de code qui fonctionne d'une manière ou d'une autre, mais à vos risques et périls. C'est une histoire qui implique de l'argent, il est donc fortement recommandé de vérifier les informations du chef de famille. https://developer.android.com/google/play/billing/billing_library_overview?hl=ja
À la recherche d'échantillons de traitement des achats via une application sur Android, beaucoup étaient anciens et complexes. Avec la nouvelle bibliothèque de facturation Google Play, c'était relativement facile à réaliser, donc je m'en souviendrai.
Cette procédure ne nécessite pas de paramètres tels que «IInAppBillingService.aidl» ou «AndroidManifest.xml». Vous pouvez également le tester avant de télécharger l'application sur Google Play.
Ici, j'ai sélectionné une simple "Activité Employeur" comme activité et j'ai écrit tout le code dans MainActivity. Le nom du projet était "Exemple de facturation".
build.gradle
    dependencies {
		....
		implementation 'com.android.billingclient:billing:2.0.1'
    }
MainActivity.java
  package xx.xx.xx.xx.billingsample;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import com.android.billingclient.api.AcknowledgePurchaseParams;
import com.android.billingclient.api.AcknowledgePurchaseResponseListener;
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.Purchase;
import com.android.billingclient.api.PurchaseHistoryRecord;
import com.android.billingclient.api.PurchaseHistoryResponseListener;
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 java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity
        implements View.OnClickListener, PurchasesUpdatedListener, AcknowledgePurchaseResponseListener {
    TextView textView1;
    private BillingClient billingClient;
    List<SkuDetails> mySkuDetailsList;
    //Appelé au démarrage de l'application
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //Préparer les boutons de commande et le champ de sortie des résultats
        textView1 = findViewById(R.id.text_view1);
        findViewById(R.id.button_get_skus).setOnClickListener(this);
        findViewById(R.id.button_query_owned).setOnClickListener(this);
        findViewById(R.id.button_purchase).setOnClickListener(this);
        findViewById(R.id.button_purchase_history).setOnClickListener(this);
        //Préparer le client de facturation
        billingClient = BillingClient.newBuilder(this)
                .setListener(this).enablePendingPurchases().build();
        billingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(BillingResult billingResult) {
                int responseCode = billingResult.getResponseCode();
                if (responseCode == BillingClient.BillingResponseCode.OK) {
                    // The BillingClient is ready. You can query purchases here.
                    textView1.setText("Billing Setup OK");
                } else {
                    showResponseCode(responseCode);
                }
            }
            @Override
            public void onBillingServiceDisconnected() {
                // Try to restart the connection on the next request to
                // Google Play by calling the startConnection() method.
                textView1.setText("Billing Servise Disconnected. Retry");
            }
        });
    }
    //Appelé lorsque le bouton est cliqué
    @Override
    public void onClick(View v) {
        if (v != null) {
            switch (v.getId()) {
                case R.id.button_get_skus:
                    querySkuList();
                    break;
                case R.id.button_query_owned:
                    queryOwned();
                    break;
                case R.id.button_purchase:
                    startPurchase("android.test.purchased");
                    break;
                case R.id.button_purchase_history:
                    queryPurchaseHistory();
                    break;
                default:
                    break;
            }
        }
    }
    //Appelé lorsque l'application est fermée
    @Override
    protected void onDestroy() {
        billingClient.endConnection();
        super.onDestroy();
    }
    //Renseignez-vous sur l'article que vous souhaitez acheter
    void querySkuList() {
        List skuList = new ArrayList<>();
        skuList.add("android.test.purchased");  // prepared by Google
        skuList.add("android.test.canceled");
        skuList.add("android.test.refunded");
        skuList.add("android.test.item_unavailable");
        SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
        params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
        billingClient.querySkuDetailsAsync(params.build(),
                new SkuDetailsResponseListener() {
                    @Override
                    public void onSkuDetailsResponse(BillingResult billingResult,
                                                     List<SkuDetails> skuDetailsList) {
                        // Process the result.
                        StringBuffer resultStr = new StringBuffer("");
                        int responseCode = billingResult.getResponseCode();
                        if (responseCode == BillingClient.BillingResponseCode.OK) {
                            //Conservez les détails du Sku pour le processus d'achat ultérieur
                            mySkuDetailsList = skuDetailsList;
                            //Afficher la liste
                            if (skuDetailsList != null) {
                                for (Object item : skuDetailsList) {
                                    SkuDetails skuDetails = (SkuDetails) item;
                                    String sku = skuDetails.getSku();
                                    String price = skuDetails.getPrice();
                                    resultStr.append("Sku=" + sku + " Price=" + price + "\n");
                                }
                            } else {
                                resultStr.append("No Sku");
                            }
                            textView1.setText(resultStr);
                        } else {
                            showResponseCode(responseCode);
                        }
                    }
                });
    }
    //Lancer le processus d'achat
    void startPurchase(String sku) {
        SkuDetails skuDetails = getSkuDetails(sku);
        if (skuDetails != null) {
            BillingFlowParams params = BillingFlowParams.newBuilder()
                    .setSkuDetails(skuDetails)
                    .build();
            BillingResult billingResult = billingClient.launchBillingFlow(this, params);
            showResponseCode(billingResult.getResponseCode());
        }
    }
    //Obtenir les détails de la référence SKU spécifiée dans la liste
    SkuDetails getSkuDetails(String sku) {
        SkuDetails skuDetails = null;
        if(mySkuDetailsList==null){
            textView1.setText("Exec [Get Skus] first");
        }else {
            for (SkuDetails sd : mySkuDetailsList) {
                if (sd.getSku().equals(sku)) skuDetails = sd;
            }
            if (skuDetails == null) {
                textView1.setText(sku + " is not found");
            }
        }
        return skuDetails;
    }
    //Appelé lors de la mise à jour des résultats d'achat
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        StringBuffer resultStr = new StringBuffer("");
        int billingResultCode = billingResult.getResponseCode();
        if (billingResultCode == BillingClient.BillingResponseCode.OK
                && purchases != null) {
            for (Purchase purchase : purchases) {
                //Approuver l'achat
                String state = handlePurchase(purchase);
                //Afficher la chaîne Sku achetée et le résultat d'approbation
                String sku = purchase.getSku();
                resultStr.append(sku).append("\n");
                resultStr.append(" State=").append(state).append("\n");
            }
            textView1.setText(resultStr);
        } else {
            // Handle error codes.
            showResponseCode(billingResultCode);
        }
    }
    //Approuver l'achat
    String handlePurchase(Purchase purchase) {
        String stateStr = "error";
        int purchaseState = purchase.getPurchaseState();
        if (purchaseState == Purchase.PurchaseState.PURCHASED) {
            // Grant entitlement to the user.
            stateStr = "purchased";
            // Acknowledge the purchase if it hasn't already been acknowledged.
            if (!purchase.isAcknowledged()) {
                AcknowledgePurchaseParams acknowledgePurchaseParams =
                        AcknowledgePurchaseParams.newBuilder()
                                .setPurchaseToken(purchase.getPurchaseToken())
                                .build();
                billingClient.acknowledgePurchase(acknowledgePurchaseParams, this);
            }
        }else if(purchaseState == Purchase.PurchaseState.PENDING){
            stateStr = "pending";
        }else if(purchaseState == Purchase.PurchaseState.UNSPECIFIED_STATE){
            stateStr = "unspecified state";
        }
        return stateStr;
    }
    //Résultats d'approbation d'achat renvoyés
    @Override
    public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
        int responseCode = billingResult.getResponseCode();
        if(responseCode != BillingClient.BillingResponseCode.OK) {
            showResponseCode(responseCode);
        }
    }
    //Renseignez-vous sur les articles achetés (traitement des espèces)
    void queryOwned(){
        StringBuffer resultStr = new StringBuffer("");
        Purchase.PurchasesResult purchasesResult
                = billingClient.queryPurchases(BillingClient.SkuType.INAPP);
        int responseCode = purchasesResult.getResponseCode ();
        if(responseCode== BillingClient.BillingResponseCode.OK){
            resultStr.append("Query Success\n");
            List<Purchase> purchases = purchasesResult.getPurchasesList();
            if(purchases.isEmpty()){
                resultStr.append("Owned Nothing");
            } else {
                for (Purchase purchase : purchases) {
                    resultStr.append(purchase.getSku()).append("\n");
                }
            }
            textView1.setText(resultStr);
        }else{
            showResponseCode(responseCode);
        }
    }
    //Demander l'historique des achats (traitement de l'accès au réseau)
    void queryPurchaseHistory() {
        billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP,
                new PurchaseHistoryResponseListener() {
                    @Override
                    public void onPurchaseHistoryResponse(BillingResult billingResult,
                                                          List<PurchaseHistoryRecord> purchasesList) {
                        int responseCode = billingResult.getResponseCode();
                        if (responseCode == BillingClient.BillingResponseCode.OK) {
                            if (purchasesList == null || purchasesList.size() == 0) {
                                textView1.setText("No History");
                            } else {
                                for (PurchaseHistoryRecord purchase : purchasesList) {
                                    // Process the result.
                                    textView1.setText("Purchase History="
                                            + purchase.toString() + "\n");
                                }
                            }
                        } else {
                            showResponseCode(responseCode);
                        }
                    }
        });
    }
    //Afficher la réponse du serveur
    void showResponseCode(int responseCode){
        switch(responseCode){
            case BillingClient.BillingResponseCode.OK:
                textView1.setText("OK");break;
            case BillingClient.BillingResponseCode.USER_CANCELED:
                textView1.setText("USER_CANCELED");break;
            case BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE:
                textView1.setText("SERVICE_UNAVAILABLE");break;
            case BillingClient.BillingResponseCode.BILLING_UNAVAILABLE:
                textView1.setText("BILLING_UNAVAILABLE");break;
            case BillingClient.BillingResponseCode.ITEM_UNAVAILABLE:
                textView1.setText("ITEM_UNAVAILABLE");break;
            case BillingClient.BillingResponseCode.DEVELOPER_ERROR:
                textView1.setText("DEVELOPER_ERROR");break;
            case BillingClient.BillingResponseCode.ERROR:
                textView1.setText("ERROR");break;
            case BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED:
                textView1.setText("ITEM_ALREADY_OWNED");break;
            case BillingClient.BillingResponseCode.ITEM_NOT_OWNED:
                textView1.setText("ITEM_NOT_OWNED");break;
            case BillingClient.BillingResponseCode.SERVICE_DISCONNECTED:
                textView1.setText("SERVICE_DISCONNECTED");break;
            case BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED:
                textView1.setText("FEATURE_NOT_SUPPORTED");break;
        }
    }
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
        <Button
            android:id="@+id/button_get_skus"
            android:text="Get Skus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/button_query_owned"
            android:text="Query Owned"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/button_purchase"
            android:text="Purchase"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/button_purchase_history"
            android:text="Purchase History"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/text_view1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</android.support.constraint.ConstraintLayout>
 
Ouvrez Build Valiants dans l'onglet le plus à gauche d'Android Studio et remplacez Build Valiant de Debug en Release.
Error: The apk for your currently selected variant (app-release-unsigned.apk) is not signed.
Cliquez sur "Corriger" affiché sur le côté droit de l'affichage des erreurs et entrez la clé enregistrée dans Google Play. Si vous n'êtes pas inscrit, vous devez vous inscrire. La procédure de saisie par clé est la suivante.