smarkets / react-native-paypal

React Native library that implements PayPal Checkout flow using purely native code
MIT License
118 stars 54 forks source link

Android: requestOneTimePayment appears to not be called #17

Closed dres-cifuentes closed 5 years ago

dres-cifuentes commented 5 years ago

Hello!

So I followed everything in the ReadMe. I verified everything listed in MainApplication.java, settings.gradle & build.gradle. I ran the command to link the library. Everything works as expected on iOS. Yet, when I try it on Android, it seems to keep on loading.

Here's how I'm using it:

getPaypal = async () => {
  try {
    this.setState({ isLoading: true });

    // Get Token
    const tokenResponse = await axios.get(`${API_GOES_HERE}/client_token`);
    const { client_token: token } = tokenResponse.data;

    console.log('Client Token', token);

    // Request Payment with Token
    const { nonce } = await requestOneTimePayment(token, {
      amount: '250', // required
      // any PayPal supported currency (see here: https://developer.paypal.com/docs/integration/direct/rest/currency-codes/#paypal-account-payments)
      currency: 'USD',
      // any PayPal supported locale (see here: https://braintree.github.io/braintree_ios/Classes/BTPayPalRequest.html#/c:objc(cs)BTPayPalRequest(py)localeCode)
      localeCode: 'en_US',
      shippingAddressRequired: false,
      userAction: 'commit', // display 'Pay Now' on the PayPal review page
      // one of 'authorize', 'sale', 'order'. defaults to 'authorize'. see details here: https://developer.paypal.com/docs/api/payments/v1/#payment-create-request-body
      intent: 'authorize',
    });

    console.log('Payment Nonce', nonce);

    // Create Charge
    const payload = { nonce, amount: '250' };
    const headers = { Accept: 'application/json', 'Content-Type': 'application/json' };
    const chargeResponse = await axios.post(`${API_GOES_HERE}/charge`, payload, { headers });

    console.log('Charge Response', JSON.stringify(chargeResponse.data, null, 2));

    this.setState({ paymentConfirm: 'approved' });
  } catch (error) {
    Alert.alert('Whoops! Something went wrong. Please retrace your steps and try again');
    console.log(error);
  } finally {
    this.setState({ isLoading: false });
  }
};

The token shows up in the console log. isLoading stays true, "Payment Nonce" never gets console logged, so I'm assuming that requestOneTimePayment is never finishing up.

Is there something I could be missing or any other recommendations?

Thanks!

riso commented 5 years ago

hey. your code seems fine tbh.. which version of braintree sdk are you using on android (we currently are using 2.17.0)? also, which version of android are you testing this on?

dres-cifuentes commented 5 years ago

hey @riso !

for braintree we're using 2.17.0 so implementation "com.braintreepayments.api:braintree:2.17.0"

i'm testing on my personal device, so Pixel 3a XL, Android Version 9.

we're also using react-native 0.59.8 and i see in your package.json, your react native dependency is listed as 0.41.2. not sure if that makes a difference but i feel like it's worth mentioning.

so i thought maybe i should update braintree. so i tried to update it to version 3.1.0, which requires me to update the minSdkVersion in android/build.gradle. it's currently at 16 but it requires 21. updating that has been difficult since i'm limited on experience in android studio but not sure if that's the direction i should go in...

edit: updated to react-native 0.59.9 since there were some android changes but doesn't seem to fix my issue

riso commented 5 years ago

hmm yeah we're also on RN 0.59.9, and we just tested on Android 9 as well..

dres-cifuentes commented 5 years ago

interesting! alright, the issue is probably elsewhere then. i'll keep digging but if you can think of anything else i'd appreciate the help.

thanks!

riso commented 5 years ago

out of curiosity, could you try and use intent: 'sale' instead of authorize? seems to be the only thing that we do differently.

also, could you check your merged manifest in android studio and see if you have a section that includes BraintreeBrowserSwitchActivity and inside that you should have a <data> element with your application id in it. There's some detailed instructions in this other issue https://github.com/smarkets/react-native-paypal/issues/14#issuecomment-493059370

smubarak-ali commented 5 years ago

@dres-cifuentes I am also facing the exact same issue and I have checked my dependencies and all seems correct. Did you by any chance find a solution?

dres-cifuentes commented 5 years ago

Hi @riso & @smubarak-ali , I did find a solution and it has to do with BrainTreeBrowserSwitchActivity

In the AndroidManifest.xml file, we added this:

        <activity android:name="com.braintreepayments.api.BraintreeBrowserSwitchActivity"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="${applicationId}.braintree" />
            </intent-filter>
        </activity>

and it worked. sorry about the late response, hope this helps!

mrmello commented 5 years ago

Hey, sorry for commenting on this closed issue but I happen to get the same scenario and none of the suggestions I found on the repo helped.

I have checked my merged manifest and it looks like this:

Screenshot 2019-07-22 at 11 08 57

Also tried adding to AndroidManifest.xml as mentioned by @dres-cifuentes , but no luck. Tried intent: 'sale' and other intents, but didn't work either.

To test if the library is linked, if I pass an invalid token I get Error: Tokenization Key or client token was invalid. However when I try with a valid token (for instance the one from Braintree docs) I don't get any error, but the PayPal screen won't open.

Any help is appreciated thanks!

bingbing720 commented 5 years ago

Hello. I have same issue. I was checking android studio logcat while opening requestOneTimePayment.

W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@bd4eb07 onActivityCreated Connecting to remote service Activity resumed, time: 927795

have you any advice to check this log ? Thank you.

efstathiosntonas commented 5 years ago

@mrmello

Note: The scheme you define must use all lowercase letters. If your package contains underscores, the underscores should be removed when specifying the scheme in your Android Manifest.

from braintree android sdk page https://developers.braintreepayments.com/guides/client-sdk/setup/android/v2

ElliDy commented 4 years ago

We have tested all solutions. But nothing helps. We have still the issue, that nothing happens when calling requestOneTimePayment.

ahsanihsan commented 3 years ago

@dres-cifuentes solution should be added in the documentation. As it's very necessary to add the redirection route after the payment is successful.

nzankich commented 3 years ago

@ahsanihsan this already exists in the package AndroidManifest.xml. https://github.com/smarkets/react-native-paypal/blob/9ee2024d3c557657f3f9860b8720f0167bdf602e/android/src/main/AndroidManifest.xml#L8

the example project doesn't need it to work. Is this issue on particular version of android?

nzankich commented 3 years ago

@ElliDy is your issue on ios or android? Could you provide some logs?

DangKhoi1997 commented 3 years ago

@nzankich hi Bro , i'm facing issue with android device. I 've tested many times but it still didn't work. The problem is the requestOneTimePayment or requestBillingAgreement only run 1 time and after that it does nothing. I try it in try catch but not catching anything. Any workaround guys ...

nzankich commented 3 years ago

@DangKhoi1997 could you see if you can reproduce on the example app?