'PayPal callback does not trigger after login to the PayPal account

I'm stuck with the next issue.

I integrated PayPal sdk into my android app.

implementation 'com.paypal.checkout:android-sdk:0.6.1'

My app has an underscore in the package name so I have to use ‘App links’. I tested it in the test-app, all works fine like on the first screenschoot.

But in the main app when I successfully log in to a paypal account and redirect back to the app, the callback does not trigger.

I also figured out if I press on close button, callback yes triggers. Also when I returns to the app I receive Intent like this:

app.mobile.main.app.name://paypalpay?code=C21AALAqib-oCkJXmgsoDPPbpAiYza7KJgVoA_01gzzYtawIsgofw0PmCpr186xkz1OY6tSQ....

Please write if you have any suggestions. Thanks and have a nice day.

Here snippets of Manifest file and PayPalFragment.

Android Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   package="app.mobile.main_app.name">

   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
   <uses-permission
       android:name="android.permission.WRITE_EXTERNAL_STORAGE"
       android:maxSdkVersion="28" />

   <uses-permission android:name="android.permission.WAKE_LOCK" />
   <uses-permission android:name="android.permission.INTERNET" />
   <uses-permission android:name="android.permission.CAMERA" />

   <uses-feature android:name="android.hardware.camera.autofocus" />
   <uses-feature android:name="android.hardware.camera" />

   <application
       android:name=".MyApplication"
       android:allowBackup="false"
       android:hardwareAccelerated="true"
       android:icon="@mipmap/logo"
       android:label="@string/app_name"
       android:largeHeap="true"
       android:requestLegacyExternalStorage="true"
       android:roundIcon="@mipmap/logo"
       android:supportsRtl="true"
       android:theme="@style/MaterialTheme"
       android:usesCleartextTraffic="true"
       tools:replace="android:allowBackup">
     

       <activity
           android:name=".Ux.Activities.MainActivity"
           android:configChanges="keyboardHidden|orientation|screenSize"
           android:excludeFromRecents="true"
           android:exported="true"
           android:launchMode="singleTop"
           android:screenOrientation="portrait"
           android:windowSoftInputMode="stateHidden|adjustResize">

           <intent-filter >
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />   
           </intent-filter>

           <intent-filter android:autoVerify="true">
               <action android:name="android.intent.action.VIEW" />
               <category android:name="android.intent.category.DEFAULT" />
               <category android:name="android.intent.category.BROWSABLE" />

               <data
                   android:host="paypalpay"
                   android:scheme="app.mobile.main.app.name" />
           </intent-filter>
       </activity>
   </application>
</manifest>

PayPalFragment.kt

class PayPalFragment : Fragment() {

    override fun onAttach(context: Context) {
        super.onAttach(context)
        PayPalCheckout.registerCallbacks(
            onApprove = OnApprove { approval ->
                approval.orderActions.capture { captureOrderResult ->
                    Log.i("tester", "OnApprove called.")
                }
            },
            onCancel = OnCancel {
                Log.i("tester", "OnCancel called.")
            },
            onError = OnError { errorInfo ->
                Log.i("tester", "onError called.")
            },
            onShippingChange = OnShippingChange { shippingChangeData, shippingChangeActions ->
                Log.i("tester", "onShippingChange called.")
            }
        )
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val fragView = inflater.inflate(R.layout.fragment_pay_pal, container, false)

        val payPalButton = fragView.findViewById<Button>(R.id.paypal_button)
        payPalButton.setOnClickListener {
            PayPalCheckout.startCheckout(
                CreateOrder { createOrderActions ->
                    val order = Order(
                        intent = OrderIntent.CAPTURE,
                        appContext = AppContext(
                            userAction = UserAction.PAY_NOW
                        ),
                        purchaseUnitList = listOf(
                            PurchaseUnit(
                                amount = Amount(
                                    currencyCode = CurrencyCode.USD,
                                    value = "10.00"
                                )
                            )
                        )
                    )
                    createOrderActions.create(order)
                }
            )
        }
        return fragView
    }
}

enter image description here



Solution 1:[1]

So solution is to add default PayPal activity to AndroidManifest.xml

You just copy the code below and change YOUR-CUSTOM-SCHEME to what you declared in ReturnUrl in the PayPal developer account.

No need to create this activity, it comes with the PayPal SDK.

It will redirect you back into your app and trigger a PayPal payment sheet.

After the user has completed or canceled the payment, the corresponding callback will be called.

<activity
    android:name="com.paypal.openid.RedirectUriReceiverActivity"
    android:excludeFromRecents="true"
    android:theme="@style/PYPLAppTheme">
    <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:host="paypalpay"
            android:scheme="YOUR-CUSTOM-SCHEME" />
    </intent-filter>
</activity>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1