#zishaansunderji - terminal

1 messages ยท Page 1 of 1 (latest)

stiff pilot
#

HI ๐Ÿ‘‹
When you say "internet reader" can you be more specific? which reader model is it?

jade bone
#

Yuppp so it's a BBPOS Wisepos E

#

And this happens about 0-1 times a day for our businesses - but the payment will go through but the reader will respond in the paymentProcess method with a response of 30 and a timeout, without the payment intent id

stiff pilot
#

There is a state machine that controls what operations are valid at any point in the operation. I suspect the waiting for the callback is necessary to ensure the state transitions to where the processPayment call can be made successfully

jade bone
#

I see - so I'm trying to simulate this by just throwing an error onSuccess and re-calling processPayment but by trying to do that I get an error message: No active Payment Intent

#

I'm wondering how I can best replicate this timeout issue using my test card and reader

stiff pilot
#

You should receive an API error about unexpected_state which is the API saying they don't expect a Payment Intent already processed to be attempted to process. As for how to spoof this... ๐Ÿค”

jade bone
#

Gotcha - yeah I'm just trying to figure out how to write the code in the way that best handles this scenario

#
Terminal.getInstance().processPayment(collectedIntent, object : PaymentIntentCallback {
  override fun onSuccess(@Nonnull collectedIntent: PaymentIntent) {
      // Success...
  }
  override fun onFailure(@Nonnull e: TerminalException) {
      val errorCode = e.errorCode.ordinal
      val paymentIntentId = e.paymentIntent?.id ?: ""
      var currency: String? = ""
      if (options != null && options.hasKey(constants.CURRENCY)) {
          currency = options.getString(constants.CURRENCY)
      }
      // If the error was error code 30 this implies we got a timeout
      // in which case we could retry the processPayment again and
      // if it has the status of succeeded or requires_capture then
      // we know the payment went through.
      if (errorCode == 30 || paymentIntentId.isEmpty()) {
        Handler(Looper.getMainLooper()).postDelayed(
            {
                processPayment(collectedIntent, currency)
            },
            10000
        )
      } else {
        val errorMap = Arguments.createMap()
        errorMap.putString(constants.ERROR, e.errorMessage)
        errorMap.putInt(constants.CODE, errorCode)
        errorMap.putString(constants.STRIPE_ID, paymentIntentId)
        sendEvent(constants.EVENT_PAYMENT_CREATION, errorMap)
      }
  }
}
stiff pilot
#

Right, that makes sense.

jade bone
#

So to the best of my knowledge - if it's one of those errors where I don't get the paymentIntent.id - I can just recall it

#

Okay cool - processPayment's implementation is actually the same - so should I expect an error or a success?

#

I can see how it can be either - where error because the payment has already succeeded or requires_capture because it's been processed, succeeded because the timeout issue is now gone and so I can send a success event to the user

stiff pilot
#

Yes I agree, you should be ready to handle errors that result from other conditions. I'm still not sure how you could simulate the timeout error without actually manipulating the network your WPE is running on. But you could test the follow-up code using some of the test-card scenarios we outline here: https://stripe.com/docs/terminal/references/testing

#

Our docs cover reader disconnects/reconnects decently but I do think we should call out handling timeouts for the various API calls and what that means for the state of the payment in the Terminal SDK.

jade bone
#

Fair enough! I think I did manage to replicate most of the card payment issues from that list

#

I guess just so I can try figure this out - do you know what error codes and messages would spawn if the process payment method was called for a second time even though a payment has already been collected?

#

I could try to work around those error codes to make sure those are being accounted for as well

stiff pilot
#

That you should be able to test pretty easily. Call process payment on a payment that has already succeeded. I think it's the unexpected_state error but I'd confirm that first.

jade bone
#

Okay gotcha!

#

Sweet! This is helpful!

#

Thanks a ton ๐Ÿ™‚

stiff pilot
#

Sure thing! And I'm working with our docs teams to understand user pain points. I've taken a note to the effect that we don't document recommendations for how to handle this edge case. Since WPEs depend on the user's network it's a situation we should cover

jade bone
#

That would be super useful! Thanks! We recently got clients whom, because their business is pretty remote, the network issues have been pretty nuanced to handle

#

For reference, another thing we added was if the error came with a paymentIntentId but we receive an error (we re-check with Stripe to see if the payment actually went through)

#

so far those two are the only circumstances we've seen - but it'd be great to safe guard against as much as we can

stiff pilot