stripe / stripe-android

Stripe Android SDK
https://stripe.com/docs/mobile/android
MIT License
1.29k stars 645 forks source link

[BUG] React Native Android Paymentsheet initialization crash #6679

Closed jaksonfact closed 1 year ago

jaksonfact commented 1 year ago

Summary

I have used stripe payment sheet for last one year for reactnative mobile application. it was working perfectly but now in ios working fine as expected but in android, whenever i trigger initpaymentsheet function my application get crashing

Code to reproduce

import React, {useState, useEffect} from 'react'; import { StyleSheet, TouchableOpacity, Text, Button, View, Alert, } from 'react-native'; import { CardField, CardFieldInput, useStripe, useGooglePay, } from '@stripe/stripe-react-native'; import AsyncStorage from '@react-native-async-storage/async-storage'; import {useDispatch} from 'react-redux'; import {useNavigation} from '@react-navigation/native'; import LinearGradient from 'react-native-linear-gradient'; import AppConfig from '../../../../navigation/appConfig'; import {Colors} from '../../../../Constants/Colors'; import {commonStyleForContainer} from '../../../../Constants/CommonStyles'; const PaymentInit = ({ totalPay = '', doc_id = '', patient_id = '', appointment_id = '', otp = '', tenantId = '', customerIds, emphemeral_key, secret_intent, }) => { const navigation = useNavigation(); const dispatch = useDispatch(); const [card, setCard] = useState(CardFieldInput.Details | null); // const {confirmPayment, handleCardAction} = useStripe(); const {initPaymentSheet, presentPaymentSheet} = useStripe(); const [loading, setLoading] = useState(false); const {isGooglePaySupported, initGooglePay} = useGooglePay();

const initializePaymentSheet = async () => { console.log('ooooo'); // const logic = await fetchPaymentSheetParams();

console.log('lllll', 'oooo');
const {error} = await initPaymentSheet({
  merchantDisplayName: 'Medosys',
  customerId: customerIds,
  customerEphemeralKeySecret: emphemeral_key,
  paymentIntentClientSecret: secret_intent,
});
console.log('llllloooo');
if (error) {
  console.log(`Error initializing Payment Sheet:  ${JSON.stringify(error)}`);
  setLoading(true);
} else {
  console.log(error);
}

}; const openPaymentSheet = async () => { const {error} = await presentPaymentSheet(); console.log('paymentResponse', error); if (error) { Alert.alert(Error code: ${error.code}, error.message); } else { Alert.alert('Success', 'Your order is confirmed!', [ { text: 'OK', onPress: () => { navigation.navigate(AppConfig.SCREEN.QUESTIONS_SCREEN, { appointmentId: appointment_id, patientId: patient_id, tenant_Id: tenantId, }); }, }, ]); } }; useEffect(() => { console.log('initializePaymentSheet', 'initializePaymentSheet'); initializePaymentSheet(); }, []); return (

Pay $ {totalPay}

); }; export default PaymentInit; const styles = StyleSheet.create({ ...commonStyleForContainer, container: { flex: 1, width: '100%', }, button: { backgroundColor: '#00aeef', borderColor: 'red', borderWidth: 5, borderRadius: 15, }, });

Android version

Platform OS: android Platform Version: 33 old version : 31

Impacted devices

Mobile Application got crashing in only ANDROID

Installation method

yarn add @stripe/stripe-react-native

Dependency Versions

apply plugin: "com.android.application" apply plugin: 'com.google.gms.google-services'

import com.android.build.OutputFile

project.ext.react = [ enableHermes: true, // clean and rebuild if changing ]

apply from: "../../node_modules/react-native/react.gradle"

def enableSeparateBuildPerCPUArchitecture = false

def enableProguardInReleaseBuilds = false

def jscFlavor = 'org.webkit:android-jsc:+'

def enableHermes = project.ext.react.get("enableHermes", false);

def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures")

android { ndkVersion rootProject.ext.ndkVersion

compileSdkVersion rootProject.ext.compileSdkVersion
 compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

defaultConfig {
    applicationId "com.medosys"
    minSdkVersion rootProject.ext.minSdkVersion
    vectorDrawables.useSupportLibrary = true
    targetSdkVersion rootProject.ext.targetSdkVersion
    versionCode 1
    versionName "1.0"
}
splits {
    abi {
        reset()
        enable enableSeparateBuildPerCPUArchitecture
        universalApk false  // If true, also generate a universal APK
        include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
    }
}
  signingConfigs {
release {
  storeFile file('Medo123.keystore')
  storePassword 'Medosys312'
  keyAlias 'Medo123'
  keyPassword 'Medosys312'
}

} signingConfigs { debug { storeFile file('debug.keystore') storePassword 'android' keyAlias 'androiddebugkey' keyPassword 'android' } } buildTypes { debug { signingConfig signingConfigs.debug if (nativeArchitectures) { ndk { abiFilters nativeArchitectures.split(',') } } } release { // Caution! In production, you need to generate your own keystore file. // see https://reactnative.dev/docs/signed-apk-android.

        signingConfig signingConfigs.release
        signingConfig signingConfigs.debug
        minifyEnabled enableProguardInReleaseBuilds;
        proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"

    }
}

// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
    variant.outputs.each { output ->
        // For each separate APK per architecture, set a unique version code as described here:
        // https://developer.android.com/studio/build/configure-apk-splits.html
        // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
        def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
        def abi = output.getFilter(OutputFile.ABI)
        if (abi != null) {  // null for the universal-debug, universal-release variants
            output.versionCodeOverride =
                    defaultConfig.versionCode * 1000 + versionCodes.get(abi)
        }

    }
}

}

dependencies {

implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDynamicVersion

// implementation(project(':stripe_stripe-react-native')) { exclude module: 'appcompat' }
constraints { implementation('com.stripe:stripe-android') { version { strictly '20.11.0' } } }
constraints { implementation('com.stripe:financial-connections') { version { strictly '20.11.0' } } }
implementation "com.facebook.react:react-native:+" // From node_modules
implementation 'com.google.android.material:material:1.6.1'
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
implementation ("androidx.appcompat:appcompat:1.3.1") {
version {
    strictly '1.3.1'
}

}

implementation 'com.facebook.fresco:animated-base-support:1.3.0'

// For animated GIF support implementation 'com.facebook.fresco:animated-gif:1.3.0'

// For WebP support, including animated WebP implementation 'com.facebook.fresco:animated-webp:1.3.0' implementation 'com.facebook.fresco:webpsupport:1.3.0'

// For WebP support, without animations implementation 'com.facebook.fresco:webpsupport:1.3.0'

   implementation platform('com.google.firebase:firebase-bom:29.0.3')
implementation 'com.google.firebase:firebase-analytics' 

implementation platform('com.google.firebase:firebase-bom:30.3.2')
implementation 'com.google.firebase:firebase-analytics'
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
    exclude group:'com.facebook.fbjni'
}
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
    exclude group:'com.facebook.flipper'
    exclude group:'com.squareup.okhttp3', module:'okhttp'
}

debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
    exclude group:'com.facebook.flipper'
}

if (enableHermes) {
    def hermesPath = "../../node_modules/hermes-engine/android/";
    debugImplementation files(hermesPath + "hermes-debug.aar")
    releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
    implementation jscFlavor
}

}

task copyDownloadableDepsToLibs(type: Copy) { from configurations.implementation into 'libs' }

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

For kotlin: ./gradlew :dependencies | grep kotlin

For stripe-android: ./gradlew :dependencies | grep com.android.tools.build

For Android Gradle Plugin: ./gradlew :dependencies | grep com.stripe:stripe-android

For Gradle version:

Gradle 7.2

Build time: 2021-08-17 09:59:03 UTC Revision: a773786b58bb28710e3dc96c4d1a7063628952ad

Kotlin: 1.5.21 Groovy: 3.0.8 Ant: Apache Ant(TM) version 1.10.9 compiled on September 27 2020 JVM: 11.0.11 (AdoptOpenJDK 11.0.11+9) OS: Mac OS X 11.3 x86_64

kotlin: stripe-android: Android Gradle Plugin: Gradle:

SDK classes

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

ext {
    androidXCore = "1.6.0"
    buildToolsVersion = "30.0.2"
    minSdkVersion = 21
    compileSdkVersion = 33
    targetSdkVersion = 33
    ndkVersion = "21.4.7075529"
    supportLibVersion   = "30.0.2"
    kotlinVersion = "1.5.31"
playServicesVersion = "17.0.0" // or find latest version
}
repositories {
    google()
    mavenCentral()
}
dependencies {
    classpath("com.android.tools.build:gradle:7.0.0")
    classpath 'com.google.gms:google-services:4.3.13'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31"
    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}

}

allprojects { repositories { exclusiveContent { filter { includeGroup "com.facebook.react" } forRepository { maven { url "$rootDir/../node_modules/react-native/android" } } } maven { // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm url("$rootDir/../node_modules/react-native/android") } maven { // Android JSC is installed from npm url("$rootDir/../node_modules/jsc-android/dist") } mavenCentral { // We don't want to fetch react-native from Maven Central as there are // older versions over there. content { excludeGroup "com.facebook.react" } } google() maven { url 'https://maven.google.com' } maven { url 'https://www.jitpack.io' }

}

}

My reactnative version: "react-native": "0.67.3",

Other information

I have updated latest version of react native and got this issue i hope i have problem with SDK installation version in build.gradle so please help me to get out from this issue. Thanks In Advance

seanzhang-stripe commented 1 year ago

@jaksonfact It'll be helpful if you can share the relevant crash logcat here.

You might also want to delete the yarn.lock file and node_modules folder, then run yarn install to install the Stripe Android SDK that is shipped with the latest Stripe react-native SDK.

jaksonfact commented 1 year ago

I did this multiple time bro but it din't work. i think i have a problem with my build.gradle. for this scenario i cannot print any log inside the initipaymentsheet. after entering this function my application got crash

seanzhang-stripe commented 1 year ago

Can you run adb logcat -b crash and see if there are crash logs related to your application? You can learn more about adb logcat here

jaksonfact commented 1 year ago

@seanzhang-stripe This is my logcat :

05-07 19:04:28.698 14268 14268 E AndroidRuntime: FATAL EXCEPTION: main 05-07 19:04:28.698 14268 14268 E AndroidRuntime: Process: com.medosys, PID: 14268 05-07 19:04:28.698 14268 14268 E AndroidRuntime: java.lang.NoSuchMethodError: No direct method (Ljava/lang/String;Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration;Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration;Landroid/content/res/ColorStateList;Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails;ZLcom/stripe/android/paymentsheet/PaymentSheet$Appearance;ILkotlin/jvm/internal/DefaultConstructorMarker;)V in class Lcom/stripe/android/paymentsheet/PaymentSheet$Configuration; or its super classes (declaration of 'com.stripe.android.paymentsheet.PaymentSheet$Configuration' appears in /data/app/~~Th0Vef7L3WBvPKWxAtHykQ==/com.medosys-ic2UMFf6znjcsNxSwYeo4A==/base.apk!classes7.dex) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at com.reactnativestripesdk.PaymentSheetFragment.onViewCreated(PaymentSheetFragment.kt:120) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3128) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:552) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1890) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1808) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1751) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:538) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:942) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:201) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at android.os.Looper.loop(Looper.java:288) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7872) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 05-07 19:04:28.698 14268 14268 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

seanzhang-stripe commented 1 year ago

I noticed that you applied a dependency constraints in your gradle file, so there's a possibility that the Stripe Android SDK version that stripe-react-native SDK uses is incompatible with the version that your constraint specifies (i.e., 20.11.0), and therefore cause the NoSuchMethodError during runtime.

I'd suggest you to remove the dependency constraint, and let Gradle automatically pick the Stripe Android SDK version that shipped with the stripe-react-native SDK.