#cynaed_unexpected

1 messages ยท Page 1 of 1 (latest)

prisma roseBOT
#

๐Ÿ‘‹ Welcome to your new thread!

โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

๐Ÿ”— This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1446323377760501830

๐Ÿ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

grizzled mason
#

Hi there ๐Ÿ‘‹ please give me a moment to catch up, i will get back to you shortly!

waxen dagger
#

Hello @grizzled mason, sure thanks!

grizzled mason
#

Hi @waxen dagger do you have a screen recording of the reported behaviour?

waxen dagger
#

Apologies for this, it seems the person that has the video is currently unavailable, so I can't send you anything right now. but would it be possible for us to review the code or would this be on other thread?

#

I'll gladly send the snippets if it could help

waxen hill
#

Hi @waxen dagger I'm also an engineer from Stripe. Can you share with me the code snippet?

waxen dagger
#
    super.configureFlutterEngine(flutterEngine)
    Log.d("MyFloDebug", "Android Bundle ID of myFlo_Staging: ${androidBundleId}")
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger,"${androidBundleId}/nfc").setMethodCallHandler { call, result ->
      if (call.method == "stripeTapToPay") {
        println("------------------------------------------------- KOTLIN -------------------------------------------------")
        val systemId = call.argument<String>("systemId")!!
        val paymentIntentId = call.argument<String>("paymentIntentId")!!
        val locPermission = call.argument<Boolean>("locPermission")
        val jobId = call.argument<Int>("jobId")!!

        // storing result
        pendingFlutterResult = result

        // Location Id
        val locationid = call.argument<String>("locID")
        val liveMode: Boolean = call.argument<Boolean>("liveMode") ?: false
        GlobalStuff2.vGTLocID = locationid
        GlobalStuff2.vGTJobID = jobId


        initializeTerminal(paymentIntentId)
        val terminal = Terminal.getInstance()
        if (terminal.connectedReader != null) {
          Log.d("TerminalCheck", "Connected reader: ${terminal.connectedReader!!.label}")
        } else {
          onDiscoverReaders(liveMode)
        }
      } else {
        result.notImplemented()
      }
    }
  }```
#
  fun initializeTerminal(paymentIntentId: String){
    val logLevel = LogLevel.VERBOSE
    val tokenProvider = TokenProvider();
    val listener = object : TerminalListener {
      override fun onConnectionStatusChange(status: ConnectionStatus) {
        println("[CONNECTION STATUS CHANGE]: $status");
      }

      override fun onPaymentStatusChange(status: PaymentStatus) {
        println("[PAYMENT STATUS CHANGE]: $status");
        if(status == PaymentStatus.READY && !firstTime && !hasStartedTapToPay){
          firstTime = true;
          hasStartedTapToPay = true
          val intent = Intent(this@MainActivity, TapToPayActivity::class.java)
          intent.putExtra("paymentIntentId", paymentIntentId)
          startActivityForResult(intent, 1234)
        }
      }
    }

    if (!Terminal.isInitialized()) {
      Terminal.initTerminal(applicationContext, logLevel, tokenProvider, listener)
    }


    val terminal = Terminal.getInstance()
    println("STATUS IN INITIALIZATION ${terminal.paymentStatus}")
    if(terminal.paymentStatus == PaymentStatus.READY){
      val intent = Intent(this@MainActivity, TapToPayActivity::class.java)
      intent.putExtra("paymentIntentId", paymentIntentId)
      startActivityForResult(intent, 1234)
    }
  }```
#

MY suspicion falls in the initializeTerminal function which calls TapToPay Activity.

waxen hill
#

What does this TapToPayActivity do?

waxen dagger
#

TapToPayActivity.kt

    super.onCreate(savedInstanceState)
    if (isRunning) {
      Log.w("TapToPay", "TapToPayActivity already running, ignoring duplicate")
      finish()
      return
    }
    isRunning = true

    setContentView(R.layout.activity_tap_to_pay)
    val paymentIntentId = intent.getStringExtra("paymentIntentId") ?: ""

    val terminal = Terminal.getInstance()

    terminal.retrievePaymentIntent(
      paymentIntentId, // your PaymentIntent ID from backend
      object : PaymentIntentCallback {
        override fun onSuccess(paymentIntent: PaymentIntent) {
          if(paymentIntent.status ==  PaymentIntentStatus.SUCCEEDED){
            val resultIntent = Intent()
            resultIntent.putExtra("payment_intent_id", paymentIntent.id)
            setResult(Activity.RESULT_OK, resultIntent)
            finish()
            return
          }
          activePaymentIntent = paymentIntent
          collectAndConfirm(paymentIntent) // continue with collect + confirm flow
        }

        override fun onFailure(e: TerminalException) {
          Log.e("TapToPay", "Retrieve PaymentIntent failed: ${e.message}")
          setResult(Activity.RESULT_CANCELED)
          finish()
        }
      }
    )
  }```
#
  private fun collectAndConfirm(paymentIntent: PaymentIntent) {
    val terminal = Terminal.getInstance()
    terminal.collectPaymentMethod(paymentIntent, object : PaymentIntentCallback {
      override fun onSuccess(paymentIntent: PaymentIntent) {
        terminal.confirmPaymentIntent(paymentIntent, object : PaymentIntentCallback {
          override fun onSuccess(paymentIntent: PaymentIntent) {
            Log.d("TapToPay", "Payment success")
            activePaymentIntent = null
            val resultIntent = Intent()
            resultIntent.putExtra("payment_intent_id", paymentIntent.id)
            setResult(Activity.RESULT_OK, resultIntent)
            finish()
          }

          override fun onFailure(e: TerminalException) {
            Log.e("TapToPay", "Payment confirm failed: ${e.message}")
            setResult(Activity.RESULT_CANCELED)
            finish()
          }
        })
      }

      override fun onFailure(e: TerminalException) {
        Log.e("TapToPay", "Payment method failed: ${e.message}")
        setResult(Activity.RESULT_CANCELED)
        finish()
      }
    })
  }
#

it handles the collect and confirm

waxen hill
#

Ok, do you want to put some logs around initializeTerminal and see if it's invoked more than once?

#

since this is the function that launches the TapToPayActivity and evntually the Tap to Pay screen.

waxen dagger
#

The problem lies in the setup, the problem happens on Active Tab 5. The devs don't have a Active Tab 5 device on hand. It's only being used by the client. so we cannot pinpoint the problem, since the devs don't have that tablet and it's working properly for us.

waxen hill
#

Here's my suggestions: Add some logs in your application to determine if the Tap to Pay screen reapparing was caused by the initializeTerminal function, or something else.

#

Right now we don't have sufficifient information to determine the root cause and adding some logs will be helpful.

waxen dagger
#

I see, I'll find a way to create logs from it. How long will it be before this thread closes?

#

Thank you so much though @waxen hill and @grizzled mason.