Flutter Plugin for Square In-App Payments SDK

Overview

Flutter plugin for In-App Payments SDK

Build Status Pub

The Flutter plugin for Square In-App Payments SDK is a wrapper for the native Android and iOS SDKs and supports the following native In-App Payments SDK versions:

  • iOS: 1.4.0
  • Android: 1.4.0

Additional documentation

In addition to this README, the following is available in the flutter plugin GitHub repo:

Build requirements

Flutter

A version of Flutter greater than 1.12 is required for v2 embedding support. Any application that uses v1 embeddings for android will still be backwards compatible and supported.

Android

  • Android minSdkVersion is API 21 (Lollipop, 5.0) or higher.
  • Android Target SDK version: API 27 (Oreo, 8.1).
  • Android SDK build tools: 26.0.3
  • Android Gradle Plugin: 3.0.0 or greater.
  • Support library: 27.1.1
  • Google Play Services: 16.0.1
  • Google APIs Intel x86 Atom_64 System Image

iOS

  • Xcode version: 9.1 or greater.
  • iOS Base SDK: 11.1 or greater.
  • Deployment target: iOS 11.0 or greater.

In-App Payments SDK requirements and limitations

  • In-App Payments SDK cannot issue refunds. Refunds can be issued programmatically using the Refunds API or manually in the Square Dashboard.

Sample applications

License

Copyright 2019 Square Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • SDK uses legacy v1 or v2 Square API?

    SDK uses legacy v1 or v2 Square API?

    Describe your question

    I'm trying to understand if this SDK uses legacy v1 or v2 Square API

    When I enter my v2 sandbox APPLICATION_ID I get this response on the client mobile application Screen Shot 2019-09-13 at 4 36 00 PM

    When I enter the Legacy Sandbox Application ID the request goes from the client to the server. I do get another error on the server but that is a different issue: Screen Shot 2019-09-13 at 5 16 00 PM

    The only place I enter my application ID is in the following function

      Future<void> _initSquarePayment() async {
         await InAppPayments.setSquareApplicationId('APPLICATION_ID');
      }
    
    question 
    opened by tonydiaz 21
  • Can't build apk

    Can't build apk

    I cannot build apk, but i can debug. please help..

    thnx

    Execution failed for task ':square_in_app_payments:verifyReleaseResources'.

    java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.v2.Aapt2Exception: Android resource linking failed D:\Client\Grocerr\grocerr\build\square_in_app_payments\intermediates\res\merged\release\values-v28\values-v28.xml:7: error: resource android:attr/dialogCornerRadius not found. D:\Client\Grocerr\grocerr\build\square_in_app_payments\intermediates\res\merged\release\values-v28\values-v28.xml:11: error: resource android:attr/dialogCornerRadius not found. D:\Client\Grocerr\grocerr\build\square_in_app_payments\intermediates\res\merged\release\values\values.xml:2949: error: resource android:attr/fontVariationSettings not found. D:\Client\Grocerr\grocerr\build\square_in_app_payments\intermediates\res\merged\release\values\values.xml:2950: error: resource android:attr/ttcIndex not found. error: failed linking references.

    opened by tegab 18
  • Exception: sqip.internal.event.LogEventsResponse not present

    Exception: sqip.internal.event.LogEventsResponse not present

    We started getting a hard crash/exception only on Android phones only when the user is trying add a new card and either backs out (by clicking the back arrow) or successfully adds a card and we call InAppPayments.completeCardEntry(...) to complete the entry and dismiss sqip screen (it crashes as sqip card screen is being dismissed).

    This issue doesn't happen on iOS - only Android. This issue also doesn't happen when running in debug mode. It seems to occur 100% of the time when running a released build on a device. This issue got introduced with one of the recent upgrades of the various libraries we're using, though doesn't seem like going from sqip 1.2.2 to 1.2.3 is the root cause (tried both sqip versions as well as Flutter up to 1.9.1 hotfix 6).

    Hopefully the following exception will be sufficient to track this, though let me know if you need any more info. Thank you!

    EXCEPTION

    Fatal Exception: java.lang.TypeNotPresentException: 
    Type sqip.internal.event.LogEventsResponse not present
           at libcore.reflect.ParameterizedTypeImpl.getRawType(ParameterizedTypeImpl.java:67)
           at libcore.reflect.ParameterizedTypeImpl.getResolvedType(ParameterizedTypeImpl.java:76)
           at libcore.reflect.ListOfTypes.resolveTypes(ListOfTypes.java:70)
           at libcore.reflect.ListOfTypes.getResolvedTypes(ListOfTypes.java:55)
           at libcore.reflect.ParameterizedTypeImpl.getResolvedType(ParameterizedTypeImpl.java:75)
           at libcore.reflect.Types.getType(Types.java:56)
           at java.lang.reflect.Method.getGenericReturnType(Method.java:177)
           at j.M.a(:2)
           at j.L.a(:8)
           at j.K.invoke(:5)
           at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
           at $Proxy3.a()
           at sqip.internal.b.c$a.a(:59)
           at sqip.internal.b.c$a.a(:1)
           at sqip.internal.b.d.run(:1)
           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
           at java.lang.Thread.run(Thread.java:919)
    

    ENVIRONMENT

    [✓] Flutter (Channel unknown, v1.7.10, on Mac OS X 10.14.6 18G95, locale en-US) [✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3) [✓] Xcode - develop for iOS and macOS (Xcode 11.1) [✓] Android Studio (version 3.5) [✓] VS Code (version 1.39.2)

    square_in_app_payments: ^1.2.3

    bug 
    opened by d3vtoolsmith 16
  • Lost connection to device on back button tap

    Lost connection to device on back button tap

    I having a problem with the plugin when tapping the back button on a new flutter project with Android X support. The app launches the card entry form but when tapping the back button it loses connection and the app ends.

    [√] Flutter (Channel stable, v1.12.13+hotfix.5, on Microsoft Windows [Version 10.0.18362.535], [√] Android toolchain - develop for Android devices (Android SDK version 28.0.3) [√] Android Studio (version 3.5) [√] VS Code, 64-bit edition (version 1.41.0) [√] Connected device (1 available)

    Also how can I modify error messages that say 'Something went wrong. Please contact the developer of this application and provide them with this error code:'?

    Thanks

    bug 
    opened by PizzaLober 15
  • App crash after card entry complete

    App crash after card entry complete

    Hi Square team,

    I am trying to use this plugin to process in app payments in my flutter app. I enter the test card details i.e. 411111111111 ... and then hit the save button once all card details are entered. The check mark appears and then the app crashes with the following error:

    2020-01-02 21:39:06.053 7470-7470/com.phrasing.grocery_bullet E/AndroidRuntime: FATAL EXCEPTION: main Process: com.phrasing.grocery_bullet, PID: 7470 java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=51789, result=-1, data=Intent { (has extras) }} to activity {com.phrasing.grocery_bullet/com.phrasing.grocery_bullet.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.app.Activity.getResources()' on a null object reference at android.app.ActivityThread.deliverResults(ActivityThread.java:4845) at android.app.ActivityThread.handleSendResult(ActivityThread.java:4886) at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7356) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.app.Activity.getResources()' on a null object reference at sqip.flutter.internal.CardEntryModule.readCardEntryCloseExitAnimationDurationMs(CardEntryModule.java:215) at sqip.flutter.internal.CardEntryModule.access$500(CardEntryModule.java:52) at sqip.flutter.internal.CardEntryModule$1$1.onResult(CardEntryModule.java:86) at sqip.flutter.internal.CardEntryModule$1$1.onResult(CardEntryModule.java:73) at sqip.internal.CardEntryActivity$Companion.onActivityResult(CardEntryActivity.kt:596) at sqip.CardEntry.handleActivityResult(CardEntry.kt:58) at sqip.flutter.internal.CardEntryModule$1.onActivityResult(CardEntryModule.java:73) at io.flutter.embedding.engine.FlutterEnginePluginRegistry$FlutterEngineActivityPluginBinding.onActivityResult(FlutterEnginePluginRegistry.java:634) at io.flutter.embedding.engine.FlutterEnginePluginRegistry.onActivityResult(FlutterEnginePluginRegistry.java:367) at io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.onActivityResult(FlutterActivityAndFragmentDelegate.java:546) at io.flutter.embedding.android.FlutterActivity.onActivityResult(FlutterActivity.java:594) at android.app.Activity.dispatchActivityResult(Activity.java:8110) at android.app.ActivityThread.deliverResults(ActivityThread.java:4838) at android.app.ActivityThread.handleSendResult(ActivityThread.java:4886)  at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)  at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)  at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)  at android.os.Handler.dispatchMessage(Handler.java:107)  at android.os.Looper.loop(Looper.java:214)  at android.app.ActivityThread.main(ActivityThread.java:7356)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) ### Describe your question

    question 
    opened by scottynoshotty 13
  • Please help

    Please help

    I am at the last stage of my app. I have this major issue that i have been ignoring for awhile.

    I can never get canUseGooglePay to true. My setting is on google_pay_constants.environmentTest. I have tried on device and simulator, it doesn't matter. When i run your git, it will come up true. The difference on mine is, I am on androidx. This is the last stage to my project. My squareLocationId and squareApplicationId is set correctly.

    await InAppPayments.initializeGooglePay( squareLocationId, google_pay_constants.environmentTest); canUseGooglePay = await InAppPayments.canUseGooglePay;

    opened by tegab 13
  • Crash on clicking SAVE button

    Crash on clicking SAVE button

    Initially it was working perfectly but after i tried to add firebase notification to my project this is getting crash in android side only.

    I added "apply plugin: 'com.google.gms.google-services'" in app/build.gradle and classpath 'com.google.gms:google-services:4.3.3' in android/build.gradle file and run in android.

    In Card Entry Page after i enter the card details when i click SAVE button, the indicator animates and the after 1 2 seconds it crashes.

    this is the error

    E/AndroidRuntime(24359): FATAL EXCEPTION: CardResultHandler
    E/AndroidRuntime(24359): Process: com.possibility.algo, PID: 24359
    E/AndroidRuntime(24359): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.Activity.runOnUiThread(java.lang.Runnable)' on a null object reference
    E/AndroidRuntime(24359): 	at sqip.flutter.internal.CardEntryModule$1.handleEnteredCardInBackground(CardEntryModule.java:96)
    E/AndroidRuntime(24359): 	at sqip.internal.CardEntryActivityController$onCardNonceSuccess$1.run(CardEntryActivityController.kt:151)
    E/AndroidRuntime(24359): 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    E/AndroidRuntime(24359): 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    E/AndroidRuntime(24359): 	at java.lang.Thread.run(Thread.java:919)
    

    Please help me with this issue.

    bug 
    opened by ankitpanwar8979 10
  • card_entry_sandbox_not_supported

    card_entry_sandbox_not_supported

    Hi everyone.

    I am having an issue when entering real card details. I get the error : card_entry_sandbox_not_supported. I have checked the application ID is the new production ID and not the sandbox one in the InAppPayments.setSquareApplicationId call.

    I have looked and cannot see the sandbox Id in any other locations !

    This message appears when pressing save after entering the card details. I get the spinning padlock, then the dialog with the error!

    If I enter the sandbox card (4111 111 1111 1111) I get a successful card nonce

    I assume that by this point, the app would not have connected to my transaction server?

    Any thoughts to point me in the right direction, please.

    question 
    opened by exgonline 10
  • FormatException when decoding the json.

    FormatException when decoding the json.

    Describe the issue

    I was following the documentation on setting up the payment processing. Everything looks good except when the user saves the valid card, I get a FormatException when decoding the json. It looks just like the documentation so I am confused if I am missing something.

    Here is the log:

    E/flutter ( 7392): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: FormatException: Unexpected character (at character 1)
    E/flutter ( 7392): <!DOCTYPE html>
    E/flutter ( 7392): ^
    E/flutter ( 7392):
    E/flutter ( 7392): #0      _ChunkedJsonParser.fail  (dart:convert-patch/convert_patch.dart:1392:5)
    E/flutter ( 7392): #1      _ChunkedJsonParser.parseNumber  (dart:convert-patch/convert_patch.dart:1259:9)
    E/flutter ( 7392): #2      _ChunkedJsonParser.parse  (dart:convert-patch/convert_patch.dart:924:22)
    E/flutter ( 7392): #3      _parseJson  (dart:convert-patch/convert_patch.dart:29:10)
    E/flutter ( 7392): #4      JsonDecoder.convert  (dart:convert/json.dart:493:36)
    E/flutter ( 7392): #5      JsonCodec.decode  (dart:convert/json.dart:151:41)
    E/flutter ( 7392): #6      _EventLayoutState.chargeCard 
    package:link/…/events_list/list_page.dart:422
    E/flutter ( 7392): <asynchronous suspension>
    E/flutter ( 7392): #7      _EventLayoutState._makeCharge 
    package:link/…/events_list/list_page.dart:436
    E/flutter ( 7392): <asynchronous suspension>
    E/flutter ( 7392): #8      _EventLayoutState._cardNonceRequestSuccess 
    package:link/…/events_list/list_page.dart:403
    E/flutter ( 7392): #9      InAppPayments._nativeCallHandler 
    package:square_in_app_payments/in_app_payments.dart:77
    E/flutter ( 7392): <asynchronous suspension>
    E/flutter ( 7392): #10     MethodChannel._handleAsMethodCall 
    package:flutter/…/services/platform_channel.dart:397
    E/flutter ( 7392): <asynchronous suspension>
    E/flutter ( 7392): #11     MethodChannel.setMethodCallHandler.<anonymous closure> 
    package:flutter/…/services/platform_channel.dart:365
    E/flutter ( 7392): #12     _DefaultBinaryMessenger.handlePlatformMessage 
    package:flutter/…/services/binary_messenger.dart:110
    E/flutter ( 7392): <asynchronous suspension>
    E/flutter ( 7392): #13     _invoke3.<anonymous closure>  (dart:ui/hooks.dart:280:15)
    E/flutter ( 7392): #14     _rootRun  (dart:async/zone.dart:1124:13)
    E/flutter ( 7392): #15     _CustomZone.run  (dart:async/zone.dart:1021:19)
    E/flutter ( 7392): #16     _CustomZone.runGuarded  (dart:async/zone.dart:923:7)
    E/flutter ( 7392): #17     _invoke3  (dart:ui/hooks.dart:279:10)
    
    

    -->

    To Reproduce

    Steps to reproduce the issue.

    1. Read the documentation https://github.com/square/in-app-payments-flutter-plugin/blob/master/example/take_a_payment.md
    2. Call the function InAppPayments.startCardEntryFlow()
    3. Complete form and get a nonce
    4. Make the charge (which I still don't know how to set a PRICE to the transaction using Heroku)
    5. Pass in the CardDetails result and the chargeUrl string.

    Here the piece of code that reproduce the issue.

      Future<void> chargeCard(CardDetails result, String chargeUrl) async {
      var body = jsonEncode({"nonce": result.nonce});
      http.Response response;
      try {
        response = await http.post(chargeUrl, body: body, headers: {
          "Accept": "application/json",
          "content-type": "application/json"
        });
      } on SocketException catch (ex) {
        throw ChargeException(ex.message);
      }
    
      var responseBody = json.decode(response.body); // FormatException occurs 
      if (response.statusCode == 200) {
        return;
      } else {
        throw ChargeException(responseBody["errorMessage"]);
      }
    }
    

    Expected behavior

    To make a transaction and NOT break the app. Also want to pass in a PRICE variable but don't know how to do it.

    Environment (please complete the following information):

    • platform: Android
    • OnePlus 6T OxygenOS version 9.0.16
    • Windows
    • square_in_app_payments: ^1.2.2
    Doctor summary (to see all details, run flutter doctor -v):
    [√] Flutter (Channel stable, v1.7.8+hotfix.4, on Microsoft Windows [Version 10.0.17763.678], locale en-US)
    
    [√] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    [!] Android Studio (version 3.4)
      X Flutter plugin not installed; this adds Flutter specific functionality.
      X Dart plugin not installed; this adds Dart specific functionality.
    [√] VS Code (version 1.37.1)
    [√] Connected device (1 available)
    
    ! Doctor found issues in 1 category.
    

    Screenshots

    Json Decoder

    Additional context

    I should note that a transaction of $0.01 did occur but not fully. It has been refunded.

    bug 
    opened by mike-gallego 10
  • Build error in Xcode 14 with square_in_app_payments-sqip_flutter_resource

    Build error in Xcode 14 with square_in_app_payments-sqip_flutter_resource

    With Xcode 14, it seems that the sqip_flutter_resource pod needs signing when building to a device, resulting in the follow error:

    Signing for "square_in_app_payments-sqip_flutter_resource" requires a development team. Select a development team in the Signing & Capabilities editor.  
    

    Not sure if this is an issue that can/should be fixed within the Square SDK or if there is another way to deal with this. Never encountered this issue in Xcode 13.

    I'm using the latest version of the Flutter plugin (1.7.5) in Xcode 14.0 (14A309)

    bug 
    opened by jannisnikoy 9
  • square_in_app_payments App Crash on Android release mode

    square_in_app_payments App Crash on Android release mode

    Describe the issue

    App is working fine on android debug mode and also in iOS but crashing on android release mode

    ** My Implementation ** Future onStartCardEntryFlow(String? appID) async { // this.amountPayable = amountPayable; await InAppPayments.setSquareApplicationId(appID ?? squareApplicationId); if (Platform.isIOS) { await _setIOSCardEntryTheme(); } await InAppPayments.startCardEntryFlow( onCardNonceRequestSuccess: _onCardEntryCardNonceRequestSuccess, onCardEntryCancel: () {}, collectPostalCode: false); }

    Environment (please complete the following information):