PayPal WebView in Flutter doesnt work on Physical Device

711

PayPal doesn't support 'WebViews'. Only Chrome Custom Tabs (Android) or Safari View Controllers (iOS), which have an address bar. Ref: https://developer.paypal.com/docs/api/info-security-guidelines/#secure-applications


Also you are using the original REST v1/payments API, which will still work but is deprecated. The current PayPal Checkout API is v2/checkout/orders, documented here.

Share:
711
Emanuel Developer
Author by

Emanuel Developer

Updated on December 27, 2022

Comments

  • Emanuel Developer
    Emanuel Developer over 1 year

    I have built a function to give my users the ability to pay with PayPal:

    class PaypalServicesService {
    
      String domain = "https://api.sandbox.paypal.com"; // for sandbox mode
      //String domain = "https://api.paypal.com"; // for production mode
    
      // change clientId and secret with your own, provided by paypal
      String clientId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
      String secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
    
      // for getting the access token from Paypal
      Future<String> getAccessToken() async {
        try {
          var client = BasicAuthClient(clientId, secret);
          var response = await client.post('$domain/v1/oauth2/token?grant_type=client_credentials');
          if (response.statusCode == 200) {
            final body = convert.jsonDecode(response.body);
            return body["access_token"];
          }
          return null;
        } catch (e) {
          rethrow;
        }
      }
    
      // for creating the payment request with Paypal
      Future<Map<String, String>> createPaypalPayment(
          transactions, accessToken) async {
        try {
          var response = await http.post("$domain/v1/payments/payment",
              body: convert.jsonEncode(transactions),
              headers: {
                "content-type": "application/json",
                'Authorization': 'Bearer ' + accessToken
              });
    
          final body = convert.jsonDecode(response.body);
          if (response.statusCode == 201) {
            if (body["links"] != null && body["links"].length > 0) {
              List links = body["links"];
    
              String executeUrl = "";
              String approvalUrl = "";
              final item = links.firstWhere((o) => o["rel"] == "approval_url",
                  orElse: () => null);
              if (item != null) {
                approvalUrl = item["href"];
              }
              final item1 = links.firstWhere((o) => o["rel"] == "execute",
                  orElse: () => null);
              if (item1 != null) {
                executeUrl = item1["href"];
              }
              return {"executeUrl": executeUrl, "approvalUrl": approvalUrl};
            }
            return null;
          } else {
            throw Exception(body["message"]);
          }
        } catch (e) {
          rethrow;
        }
      }
    
      // for executing the payment transaction
      Future<String> executePayment(url, payerId, accessToken) async {
        try {
          var response = await http.post(url,
              body: convert.jsonEncode({"payer_id": payerId}),
              headers: {
                "content-type": "application/json",
                'Authorization': 'Bearer ' + accessToken
              });
    
          final body = convert.jsonDecode(response.body);
          if (response.statusCode == 200) {
            return body["id"];
          }
          return null;
        } catch (e) {
          rethrow;
        }
      }
    }
    

    On an emulator of Android 10 it works fine for both sandbox and live.

    However, on a physical Android 10 device (RedNote pro 9) the payment process is stuck on the PayPal screen, before loading the complete WebView:

    Image stuck

    Here is the log on RedNote device side:

    02-08 10:54:27.819 I/Perf    (17856): Connecting to perf service.
    02-08 10:54:27.839 I/FeatureParser(17856): can't find joyeuse.xml in assets/device_features/,it may be in /vendor/etc/device_features
    02-08 10:54:27.827 W/m.tortel.syslog(17856): type=1400 audit(0.0:197147): avc: denied { read } for name="u:object_r:vendor_default_prop:s0" dev="tmpfs" ino=12172 scontext=u:r:untrusted_app:s0:c253,c256,c512,c768 tcontext=u:object_r:vendor_default_prop:s0 tclass=file permissive=0
    02-08 10:54:27.840 E/libc    (17856): Access denied finding property "ro.vendor.df.effect.conflict"
    02-08 10:54:27.866 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.870 I/chatty  (17856): uid=10253(com.tortel.syslog) identical 6 lines
    02-08 10:54:27.877 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.877 D/SysLog  (17856): Fragment null, replacing
    02-08 10:54:27.879 D/SysLog  (17856): Loading settings
    02-08 10:54:27.882 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.894 I/chatty  (17856): uid=10253(com.tortel.syslog) identical 7 lines
    02-08 10:54:27.895 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.895 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.897 I/chatty  (17856): uid=10253(com.tortel.syslog) identical 3 lines
    02-08 10:54:27.898 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.899 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.900 I/chatty  (17856): uid=10253(com.tortel.syslog) identical 1 line
    02-08 10:54:27.907 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.919 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.919 I/chatty  (17856): uid=10253(com.tortel.syslog) identical 1 line
    02-08 10:54:27.919 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.925 D/SysLog  (17856): Checking for root
    02-08 10:54:27.925 D/SysLog  (17856): Setting the checkboxes
    02-08 10:54:27.925 D/SysLog  (17856): Checking if last_kmsg and radio are available
    02-08 10:54:27.952 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.953 I/chatty  (17856): uid=10253(com.tortel.syslog) identical 1 line
    02-08 10:54:27.954 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.961 I/AdrenoGLES(17856): QUALCOMM build                   : 57da73e, I82b4603a7a
    02-08 10:54:27.961 I/AdrenoGLES(17856): Build Date                       : 12/03/20
    02-08 10:54:27.961 I/AdrenoGLES(17856): OpenGL ES Shader Compiler Version: EV031.27.05.03
    02-08 10:54:27.961 I/AdrenoGLES(17856): Local Branch                     : 
    02-08 10:54:27.961 I/AdrenoGLES(17856): Remote Branch                    : refs/tags/AU_LINUX_ANDROID_LA.UM.8.9.R1.10.00.00.558.071
    02-08 10:54:27.961 I/AdrenoGLES(17856): Remote Branch                    : NONE
    02-08 10:54:27.961 I/AdrenoGLES(17856): Reconstruct Branch               : NOTHING
    02-08 10:54:27.961 I/AdrenoGLES(17856): Build Config                     : S P 8.0.12 AArch64
    02-08 10:54:27.962 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.963 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:27.963 I/AdrenoGLES(17856): PFP: 0x016ee187, ME: 0x00000000
    02-08 10:54:27.986 W/Gralloc3(17856): mapper 3.x is not supported
    02-08 10:54:27.999 D/SysLog  (17856): Root not available
    02-08 10:54:28.026 D/SysLog  (17856): Enabling log button: true
    02-08 10:54:28.031 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:28.031 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:28.032 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:28.039 I/chatty  (17856): uid=10253(com.tortel.syslog) identical 2 lines
    02-08 10:54:28.040 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:29.798 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:29.798 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:29.800 V/SysLog  (17856): Path: /data/user/0/com.tortel.syslog/cache/logs/2021-02-08_10.54/
    02-08 10:54:29.801 D/ForceDarkHelper(17856): updateByCheckExcludeList: pkg: com.tortel.syslog activity: com.tortel.syslog.FragmentMainActivity@b885376
    02-08 10:54:29.806 V/SysLog  (17856): Done grabbing logs