question

kirank avatar image
kirank asked ·

PaymentConnector.sale is not reliably launching the payment screen

Hello,
We are working on Clover Flex device. In the samples native-android-example-pos, when we go to example's Sale operation, the payment screen is correctly displayed.

Within our app which have checked is not doing any forced activity pinned. Its a fairly straight forward activity. If we call paymentConnector.sale(saleRequest);
the payment screen is not shown. We see payment.builder.pay/com.clover.payment.connector.PaymentConnectorControllerActivity
is the last paused activity and our activity is the active one.

Now, if we are debugging our app step by step at paymentConnector.sale(saleRequest) we actually see the payment screen. But if we execute the app full speed, the payment screen does not launch.

Can you please suggest few things we can try to debug this? We are leaning towards using Intents. Is this recommended?


Please also see -- https://community.clover.com/questions/15582/paymentconnectorsale-does-not-show-the-display-scr.html

This seems to be somewhat similar. But their suggested solution of intermediate screen also does not work in our case.


semi-integrationsPaymentConnector
1 comment
10 |2000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

@David Marginian - Sorry if you are not the right contact. Please help here with referring the right contact within Clover. I see many PaymentConnector related questions are unanswered on the forum leaving us with no means of support. Should we fallback to service / Intent based approach?
0 Likes 0 · ·
David Marginian avatar image
David Marginian answered ·
I took a closer look at your code. In your activity CloverPaymentActivity.onCreate you call bindServices which creates and initializes the PaymentConnector. You then immediately call CheckLaunchOperation() which initializes a sale. The problem is, you haven't waited for the PaymentConnector's connection to be initialized (IPaymentConnectorListener.onDeviceConnected). Our documentation is lacking here so I have created an internal issue to improve it.
3 comments Share
10 |2000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Thanks @David Marginian. This is definitely one part of the problem. However there still is some undocumented expectation of some other state or expectation of delay. We see that if we call the .sale() immediately after onDeviceConnected, its still unreliably launches. We could launch the payment screen with 100% success only if we introduce a roughly 800ms delay after the onDeviceConnected is called. If we call it with less than 800 ms delay, it still has the unreliable behavior (most unreliable if less than 500ms). The waiting for onDeviceConnected is a precondition otherwise its success rate is non existant.

        //Async Wait for device connected
        SystemClock.sleep(800); //800 seems to give apparent 100 % success rate.
        paymentConnector.sale(saleRequest);<br>
0 Likes 0 · ·

I can't reproduce the problem you are describing. I tried it around 20 times on both a Flex and a Mini and it worked every time. I am choosing "Read Card Data", which fires a sale (via your Activity), then I am canceling out of the sale and hitting "Read Card Data" again. My code is:

final IPaymentConnectorListener ccListener = new IPaymentConnectorListener() {
    
    ...
    
    public void onDeviceConnected() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                showMessage("SilverSky: PaymentLib Active & Ready!", Toast.LENGTH_SHORT);
                CheckLaunchOperation();
            }
        });
    }
<br>
0 Likes 0 · ·
kirank avatar image kirank David Marginian ♦♦ ·

Yes, I think this solution is good. We were waiting for it device connected flag in a postDelayed that's probably why it was somewhat timing sensitive.

0 Likes 0 · ·
kirank avatar image
kirank answered ·
@David Marginian - Yes we are trying to debug it but at this stage, we are at a dead end. We would prefer using Payment Connector. However, as described above, its not reliably launching. Our app is fairly simple. The main difference between the Clover example and our app launches 2 Activities then last activity calls the PaymentConnector.sale(). In the Clover example, most PaymentConnector operations are in a Fragment. As such I don't think there should be a dependency,but that difference is something we are not able to resolve.

During debug we observed the following:
inside the .sale() function, it checks if its connected. If its not connected, it creates async task to connect then call underlying service.sale().

The Clover Payment Screen launches all the time if it goes into the async task way. We have not seen it launch if it is already connected (in sale, paymentV3Connector.isConnected()).
The difference will in these two paths will be the state (Paused/ Running etc) of last Activity. Is there any assumption about the state of the previous Activity?

  public void sale(final SaleRequest request) {
    try {
      if (request != null) {
        request.setVersion(2); // this version supports validation
      }
      if (paymentV3Connector != null) {
        if (paymentV3Connector.isConnected()) {
          paymentV3Connector.getService().sale(request);  //***** Does not launch ****
        } else {
          this.paymentV3Connector.connect();
          waitingTask = new AsyncTask() {
            @Override
            protected Object doInBackground(Object[] params) {
              try {
                paymentV3Connector.getService().sale(request); //***** Does launch ****
              } catch (RemoteException e) {
                Log.e(this.getClass().getSimpleName(), " sale", e);
              }
              return null;
            }







6 comments Share
10 |2000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

@David Marginian - We were also able to reproduce this issue when we moved our simplified implementation to native-android-example-pos example. We have sent a patch that will reproduce this to semi-integrations@clover.com. Please let me know if you able to access the patch.

0 Likes 0 · ·

I got the patch, hopefully I can take a look next week.

0 Likes 0 · ·

I ran your example and was able to reproduce the behavior you describe. However, I also saw a warning in the logcat - "Skipped 181 frames! The application may be doing too much work on its main thread". I didn't look at your code much, but it looks like you may have a problem:


D/InputTransport(12285): Input channel constructed: name='424ab660 com.clover.example/com.clover.example.CloverPaymentActivity (client)', fd=60 I/Choreographer(12285): Skipped 181 frames! The application may be doing too much work on its main thread. D/ (12285): onServiceConnected com.clover.connector.sdk.v3.PaymentV3Connector@422e7c60 D/ (12285): appTracking = {"developerAppId":null,"applicationVersion":"1.0","sourceSDKVersion":"1.4.0","sourceSDK":"com.clover.connector.sdk.v3.PaymentConnector","applicationID":"com.clover.example"}
1 Like 1 · ·
kirank avatar image kirank David Marginian ♦♦ ·

It could be as we are connecting to payment, order, display connectors? But skipped frames itself can't block the clover payment screen right?

0 Likes 0 · ·
Show more comments
David Marginian avatar image
David Marginian answered ·
I recommend using Payment Connector - it abstracts away the complexities and details of firing raw intents. If our example app is working correctly for you can you take a closer look at the differences between that and your app?
Share
10 |2000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Welcome to the
Clover Developer Community