This can be helpful to you !
//First, you need to initializes
private void Initialize(){
billingClient = BillingClient.newBuilder(context)
.setListener(new PurchasesUpdatedListener() {
@Override
public void onPurchasesUpdated(@NonNull @NotNull BillingResult billingResult, List<Purchase> list) {
// Google Play calls this to deliver the result of the purchase operation to this listener
if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null){
for(Purchase purchase : list){
// since we have only passes a productId at LaunchPurchaseFlow
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
GotPurchase(purchase);
if(isAutoAcknowledge && !isSubscription){
HandleNonConsumable(purchase);
}
}
});
}
}else if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED){
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
PurchaseCancelled();
}
});
}else{
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
PurchaseFailed(billingResult.getResponseCode());
}
});
}
}
})
.enablePendingPurchases()
.build();
}
// To start connection
public void StartConnection(){
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingServiceDisconnected() {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
BillingServiceDisconnect();
}
});
}
@Override
public void onBillingSetupFinished(@NonNull @NotNull BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
BillingClientReady();
}
});
}
}
});
}
// To launch purchase flow use this method, productId is your product id and skuType can be subs or inapp . If you need for subs then pass skuType as subs
public void LaunchPurchaseFlow(String productId, String skuType){
String idOfProduct = isTest ? "android.test.purchased" : productId;
isSubscription = skuType.equals(BillingClient.SkuType.SUBS);
if(billingClient.isReady()){
List<String> skuList = new ArrayList<>();
skuList.add(idOfProduct);
SkuDetailsParams skuDetailsParams = SkuDetailsParams.newBuilder()
.setSkusList(skuList)
.setType(skuType)
.build();
billingClient.querySkuDetailsAsync(skuDetailsParams, new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(@NonNull @NotNull BillingResult billingResult, List<SkuDetails> list) {
if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null){
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setSkuDetails(list.get(0))
.build();
billingClient.launchBillingFlow(activity , billingFlowParams);
}else{
FailedToLaunchPurchaseFlow(billingResult.getResponseCode());
}
}
});
}else{
OnError("Billing Client is not ready");
}
}
If you are doing for InApp purchase ie, either consumable or non-conumable, you should handle the purchase like this
// Consumable
public void HandleConsumable(Object purchase){
if(purchase instanceof Purchase){
Purchase purchase1 = (Purchase) purchase;
if(purchase1.getPurchaseState() == Purchase.PurchaseState.PENDING){
PurchaseStatePending();
}else if(purchase1.getPurchaseState() == Purchase.PurchaseState.UNSPECIFIED_STATE){
PurchaseStateUnspecified();
}else{
if(!purchase1.isAcknowledged()){ // TO know if payment is acknowledged, if not it means the payment is not successful/acknowledged yet.
ConsumeParams consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase1.getPurchaseToken())
.build();
ConsumeResponseListener listener = new ConsumeResponseListener() {
@Override
public void onConsumeResponse(@NonNull @NotNull BillingResult billingResult, @NonNull @NotNull String s) {
if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK){
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
PurchaseSuccess();
}
});
}else{
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
PurchaseFailed(billingResult.getResponseCode());
}
});
}
}
};
billingClient.consumeAsync(consumeParams , listener);
}
}
}else{
OnError("purchase is not an instance of Purchase");
}
}
// Non-Consumable or Acknowledged
public void HandleNonConsumable(Object purchase){
if(purchase instanceof Purchase){
Purchase purchase1 = (Purchase) purchase;
if(purchase1.getPurchaseState() == Purchase.PurchaseState.PENDING){
PurchaseStatePending();
}else if(purchase1.getPurchaseState() == Purchase.PurchaseState.UNSPECIFIED_STATE){
PurchaseStateUnspecified();
}else if(purchase1.getPurchaseState() == Purchase.PurchaseState.PURCHASED){
if(!purchase1.isAcknowledged()){
AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchase1.getPurchaseToken())
.build();
AcknowledgePurchaseResponseListener listener = new AcknowledgePurchaseResponseListener() {
@Override
public void onAcknowledgePurchaseResponse(@NonNull @NotNull BillingResult billingResult) {
if(billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK){
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
PurchaseSuccess();
}
});
}else{
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
PurchaseFailed(billingResult.getResponseCode());
}
});
}
}
};
billingClient.acknowledgePurchase(acknowledgePurchaseParams , listener);
}
}
}else{
OnError("purchase is not an instance of Purchase");
}
}