react-native-iap icon indicating copy to clipboard operation
react-native-iap copied to clipboard

{"code": "E_DEVELOPER_ERROR", "debugMessage": "Please ensure the app is signed correctly.", "message": "Google is indicating that we have some issue connecting to payment.", "responseCode": 5}

Open iasreact1 opened this issue 8 months ago • 10 comments

{"code": "E_DEVELOPER_ERROR", "debugMessage": "Please ensure the app is signed correctly.", "message": "Google is indicating that we have some issue connecting to payment.", "responseCode": 5} react-native-iap-12.10.5 i have followed every steps and add license tester at google play console , now product details are coming perfectly in all the devices but when i purchase the product android 13 below devices all are okay successfully purchase done but when use in android 13 devices it showing that error message ...not figure out what to do? please help my code is for purchase ` try { await RNIap.requestPurchase({skus: [skus]}) .then(async result => { console.log('IAP req product ===>++', result); if (Platform.OS === 'ios') {

          } else if (Platform.OS === 'android') {
           
          }
        })

        .catch(err => {
          console.log(err);
        });
    } catch (err) {
      console.log(err);
    }`

iasreact1 avatar Oct 16 '23 08:10 iasreact1

please help @andresesfm

iasreact1 avatar Oct 16 '23 11:10 iasreact1

When finishing the transaction in the case of Subscription, isConsumable: false should be passed. Please see my detailed answer here.

SufianBabri avatar Nov 08 '23 21:11 SufianBabri

I encountered the same issue, at first I thought all the code I wrote was in accordance with what was recommended, but after I looked closely at the same issue it turned out that the signingConfigs in app/build.gradle were different between debug and release.

signingConfigs {
        debug { 
             storeFile file('debug.keystore')
             storePassword 'android'
             keyAlias 'androiddebugkey'
             keyPassword 'android'  
        }
        release { 
        }
    }

This happens because the application signature is different between the initial upload on the Play Console and debug during development

cas8398 avatar Nov 19 '23 10:11 cas8398

I encountered the same issue, at first I thought all the code I wrote was in accordance with what was recommended, but after I looked closely at the same issue it turned out that the signingConfigs in app/build.gradle were different between debug and release.

signingConfigs {
        debug { 
             storeFile file('debug.keystore')
             storePassword 'android'
             keyAlias 'androiddebugkey'
             keyPassword 'android'  
        }
        release { 
        }
    }

This happens because the application signature is different between the initial upload on the Play Console and debug during development

When you change signingConfigs to release, or


 buildTypes {
        debug {
            signingConfig signingConfigs.release
        }
}

the problem should be resolved.

cas8398 avatar Nov 19 '23 10:11 cas8398

@cas8398 If i upload my app to a close test, will the google handle the sign process automatically for me to test billing?

I'm having the same issue, but my app is on expo, so i did nothing about what you mention on my graddle files other than what documentation of react-native-iap tells to modify. So i did not see at all this signingConfigs on my case.

Vittor-Javidan avatar Dec 21 '23 21:12 Vittor-Javidan

@Vittor-Javidan I've tried to do a closed test, and the IAP can work with same email tester. make sure the Log can appear on the screen to find out more.

cas8398 avatar Dec 22 '23 01:12 cas8398

@cas8398 I created a new release of my app in a closed test track that i had, to see if i get this error like i was getting during development. Just need play store to update the versions to check.

Vittor-Javidan avatar Dec 22 '23 05:12 Vittor-Javidan

Since it is working on devices running Android < 13, it may have to do something with the device. As suggest on, your (OP) StackOverflow question, try doing the following on your Android 13 device:

  1. reboot phone
  2. force stop (maybe doing clear data instead) Play Store, logout then login to Play store
  3. Try purchasing again making sure that you're logged in to Play store and you're testing those purchases that you can buy using older Android versions.

SufianBabri avatar Dec 22 '23 09:12 SufianBabri

@cas8398 @SufianBabri

I manage to upload my build to a open test (For some reason my URL for closed and open test was the same. Took a wile to realize why my app was not being updated on store).

I checked if i could buy my test premium subscription, and this time i did not had the same problem. I can now choose my payment method and confirm. But now, I'm having another issue: Transaction being refused. I know my credit card works, so i think i will need to upload another build just to stringfy the new error on this step to read the new error json message haha.

links to my open test on play store if you want to check: web: https://play.google.com/apps/testing/com.lonewispapps.earthlog android: https://play.google.com/store/apps/details?id=com.lonewispapps.earthlog

You have a delay before pops the google play billing modal, but this i will fix later adding some kind of loading feedback.

Vittor-Javidan avatar Dec 22 '23 17:12 Vittor-Javidan

probably i'm having the same problem as this guy:

https://stackoverflow.com/questions/77518008/android-react-native-iap-12-requestpurchase {"code": "E_SERVICE_ERROR", "debugMessage": "", "message": "Billing is unavailable. This may be a problem with your device, or the Play Store may be down.", "responseCode": 3}

The message i get on my app is always "Billing is unavailable. This may be a problem with your device, or the Play Store may be down."

my buy subscription method on my service class:

  private static userPlan: AppSubscribePlan = 'Free';
  private static PREMIUM_PLAN_SKU = Platform.select({
    default: 'premium_test',
  });

  static async buySubscription(o: {
    onError: (errorMessage: string) => void
  }) {
    if (this.userPlan === 'Free') {
      try {
        if (Platform.OS === 'android') {
          const subscription = (await getSubscriptions({ skus: [this.PREMIUM_PLAN_SKU ]}))[0] as SubscriptionAndroid;
          await requestSubscription({
            sku: subscription.productId,
            subscriptionOffers: [{
              sku: subscription.productId,
              offerToken: subscription.subscriptionOfferDetails[0].offerToken,
            }],
          });
        }
      } catch (error) {
        if (error instanceof Error) {
          o.onError(error.message);
        }
      }
    }
  }

How my component is defined (I made hook to connect and disconnect on parent component, so don't worry about this):

import React, { memo, useCallback, useEffect, useMemo } from 'react';
import { View } from 'react-native';
import {withIAPContext, useIAP, finishTransaction, Purchase } from 'react-native-iap';

import SubscriptionManager from '@SubscriptionManager';

import { navigate } from '@V1/Globals/NavigationControler';
import ConfigService from '@V1/Services/ConfigService';
import ThemeService from '@V1/Services/ThemeService';

import { Animation } from '@V1/Animation/index';
import { Layout } from '@V1/Layout/index';
import { Button } from '@V1/Button/index';
import { TC } from './__TC__';

export const IAPScreen = withIAPContext(memo(() => {

  const config = useMemo(() => ConfigService.config, []);
  const theme = useMemo(() => ThemeService.appThemes[config.appTheme].component, []);

  const {
    currentPurchase,
    currentPurchaseError,
  } = useIAP();

  const buySubscription = useCallback(async () => {
    await SubscriptionManager.buySubscription({
      onError: (errorMessage) => alert(errorMessage),
    });
  }, []);

  const onFinishTransaction = useCallback(async (currentPurchase: Purchase) => {
    await finishTransaction({ purchase: currentPurchase, isConsumable: false });
    navigate('RESTART APP');
  }, []);

  useEffect(() => {
    if (currentPurchaseError?.message) {
      alert(JSON.stringify(currentPurchaseError));
    }
  }, [currentPurchaseError]);

  useEffect(() => {
    if (currentPurchase) {
      onFinishTransaction(currentPurchase);
    }
  }, [currentPurchase]);

  return (
    <Layout.Screen
      screenButtons={
        <TC.ScreenButtons />
      }
    >
      <Animation.SlideFromLeft
        delay={200}
        duration={200}
      >
        <View
          style={{
            padding: 10,
          }}
        >
          <Button.TextWithIcon
            title="Buy subscription"
            iconName="wallet"
            onPress={async () => await buySubscription()}
            theme={{
              font_active: theme.font_active,
              background: theme.background_Button,
              background_active: theme.background_active,
              font: theme.font_Button,
            }}
            style={{
              borderRadius: 10,
            }}
          />
        </View>
      </Animation.SlideFromLeft>
    </Layout.Screen>
  );
}));

Vittor-Javidan avatar Dec 22 '23 19:12 Vittor-Javidan