#AC-terminal

1 messages ยท Page 1 of 1 (latest)

unborn drum
#

Hi there, seems like your android application can't connect to stripe API endpoint. Do you use SSL Pinning in your android app?

scenic kestrel
#

I do not think so?

#

When I am using this new node.js endpoint I made it doesn't work

#

However when I just use the default heroku library you guys provide it works fine

#

Sorry that wasn't clear. When I run the default vanilla endpoint that uses ruby on a heroku server as you guys suggest. It works fine. However using my endpoint it fails.

#

Not sure why

unborn drum
#

When you say failed, is it about token creation or connection to Stripe?

scenic kestrel
#

It's always the connect to stripe

unborn drum
#

OK, your android app doesn't have the Couldn't connect to Stripe error when using the example code?

scenic kestrel
#

yeah

#

but it's only getting the token so I'm confused

#

eitherway I'm running:

callback.onSuccess(token)

unborn drum
#

Can you share with me your merchant ID? you can find it from the Stripe Dashboard -> Settings ->Account Details

icy plover
#

Pasting for context:

Wanted to say that my merchant id is the following: acct_1KdIhIIJZpIjm1tz

scenic kestrel
#

Here is my merchant id: acct_1KdIhIIJZpIjm1tz

icy plover
#

Hi ๐Ÿ‘‹ so can you recap your concern?

scenic kestrel
#

So I made my own token provider that points to my own backend. For some reason I am constantly getting the following error:
com.stripe.stripeterminal.external.models.TerminalException: Could not connect to Stripe. Please retry.

However looking at my stripe logs and my run time logs, I am providing the token fine.

When I do not have this issue when I used the supplied example methods that point to a heroku endpoint that is running the also supplied backend

#

One second I'll send a screen shot of it working

icy plover
#

And what function is executing that is returning the "Could not connect to Stripe" error?

scenic kestrel
#

It's my readerCallback.onFailure

#

Terminal.getInstance().connectBluetoothReader(reader,
connectionConfig,
TerminalBluetoothReaderListener(),
readerCallback
)

icy plover
#

Hm, thank you . Please bear with me while I think on this.

scenic kestrel
#

Thank you

icy plover
#

And when you use the Heroku backend, everything works as expected? With the same bluetooth reader?

scenic kestrel
#

yes

#

At the end of the day both my token providers are running:
callback.onSuccess(token)

#

and I am just logging the token before they execute in both cases

icy plover
#

Is that logging done where the tokens are generated, or back in your app to ensure the tokens make it back there?

scenic kestrel
#

I am doing the logging in the android app

#

I am logging it right before I call the callback.onSuccess(token) method

spare tulip
#

Interesting. And it has the same form as the other tokens you are sending, is being created by the same API key, and all that?

scenic kestrel
#

Yes

#

One is just being generated with node.js and the other with ruby I think

spare tulip
#

Can you send me a request ID (req_123) from a time you created this token from your own backend?

scenic kestrel
#

node.js: const connectionToken = await stripe.terminal.connectionTokens.create();

spare tulip
scenic kestrel
#

Here is a working one:
req_vdORAvyKvmHNm3

#

Sorry I have to hop on a call. I'll be back in 20 minutes

spare tulip
#

Thank you. Checking these requests out

scenic kestrel
spare tulip
#

Those look the same. Looking at the code again to see what might be the difference there.

#

What does your fetchConnectionToken function look like?

#

Just for testing purposes: can you try hard coding that function to directly returns that token "pst_test_YWNjdF8xS2RJaElJSlpwSWptMXR6LHRxVHRnc2Rnc3FMMjc5Rnpqd1ZZU3VYbGdzNmlXNjI_00EIRoQ4AX"?

scenic kestrel
#

val jsonO = object : JsonObjectRequest(Method.POST, BuildConfig.BASE_API_URL + Request.Method.STRIPE_TERMINAL_TOKEN_REQ, jsonObject, {
response -> callback.onsuccess(token)
error-> callback.onFailure(ConnectionTokenException("failed to generate token"))

#

hard coded value works

spare tulip
#

Awesome! So maybe your actual version of fetchConnectionToken method isn't returning the string as you would expect? I do know I saw a similar issue a day or two back where the user was accidentally returning their entire json instead of just the token string.

#

Oh wait or is it completely working now?

scenic kestrel
#

no it's not totally working

#

just the hard coded

spare tulip
#

Can you see any difference in the hard coded string vs what your fetchConnectionToken function returns normally?

scenic kestrel
#

I think they are returning the same thing

balmy river
#

Hi ๐Ÿ‘‹ I'm stepping in for @spare tulip
The fact that you see different behavior when you hardcode vs use the function suggests they are not. Could you log the value returned and ensure it is exactly what you are hard-coding?

scenic kestrel
#

Okay here is something that I generated with my code:
2022-03-29 09:49:47.238 15127-15127/beam.live.ride V/StripeTerminalActivity: Stripe Token: "pst_test_YWNjdF8xS2RJaElJSlpwSWptMXR6LGJqSlVmNVN1VDB1NHh3VmxFa1VMbnhZU2ZOUzhSYng_00aGOqucwG"
2022-03-29 09:50:06.699 15127-15127/beam.live.ride V/StripeTerminalActivity: Running Discovery
2022-03-29 09:50:11.741 15127-15858/beam.live.ride V/StripeTerminalActivity: onUpdateDiscoveredReadersCB
2022-03-29 09:50:11.741 15127-15858/beam.live.ride V/StripeTerminalActivity: STRM26138029907
2022-03-29 09:50:11.741 15127-15858/beam.live.ride V/StripeTerminalActivity: Trying to connect to reader
2022-03-29 09:50:11.748 15127-15849/beam.live.ride V/StripeTerminalActivity: Discovery Success Callback
2022-03-29 09:50:15.765 15127-15127/beam.live.ride V/StripeTerminalActivity: Stripe Token: "pst_test_YWNjdF8xS2RJaElJSlpwSWptMXR6LDV4Z2hLcEtjS1ROREVvOWZYRjNHTWNxd0RRa2VtdGI_00oIZwqvOw"
2022-03-29 09:50:17.905 15127-15849/beam.live.ride V/StripeTerminalActivity: fail reader connection
2022-03-29 09:50:17.906 15127-15849/beam.live.ride V/StripeTerminalActivity: com.stripe.stripeterminal.external.models.TerminalException: Could not connect to Stripe. Please retry.

#

These two lines:
Log.v("StripeTerminalActivity", "Stripe Token: " + token)
callback.onSuccess(token)

Here is log resulting log line showing what the token parameter is

V/StripeTerminalActivity: Stripe Token: "pst_test_YWNjdF8xS2RJaElJSlpwSWptMXR6LDV4Z2hLcEtjS1ROREVvOWZYRjNHTWNxd0RRa2VtdGI_00oIZwqvOw"

balmy river
#

Okay. And this is the exact same token as what you were hard-coding?

scenic kestrel
#

No this is a token I'm generating

#

It is made with this id: req_torxGIU2dHw0ii

#

pst_test_YWNjdF8xS2RJaElJSlpwSWptMXR6LDV4Z2hLcEtjS1ROREVvOWZYRjNHTWNxd0RRa2VtdGI_00oIZwqvOw

balmy river
#

Okay and when you use this one it doesn't work, correct?

scenic kestrel
#

yes

balmy river
#

NVM, found it

#

And what SDK are you using to integrate your Terminal reader?

scenic kestrel
#

Implementation('com.stripe:stripe-android:19.2.2')
Implementation("com.stripe:stripeterminal:2.7.0")

balmy river
#

Specifically I'm interested in the TokenProvider class

scenic kestrel
#

Would it be possible to do a quick call with someone to resolve this?

balmy river
#

We don't offer calls at this time.

scenic kestrel
#

Also if you look at my fail logs from earlier you can see that the sdk is getting the token:
2022-03-29 08:03:08.190 6278-6278/beam.live.ride V/StripeTerminalActivity: Stripe Token: "pst_test_YWNjdF8xS2RJaElJSlpwSWptMXR6LExLbEc5ZWZpdlh4WjlSTDFtQ3A2WVRaaVZEbDFKS0w_00WdtSFV4L"

#

2022-03-29 08:03:08.191 6278-6278/beam.live.ride D/StripeTerminal: class=ConnectionTokenManager message=fetchConnectionToken.onSuccess

balmy river
#

Yes I saw that. So you've getting the token, now we need to make sure it's getting passed to the Terminal SDK

#

Since the SDK expects to be provided with a Provider, not the actual token, that is why I'm asking if you created the ToeknProvider class and are using it when initializing the Terminal SDK

scenic kestrel
#

Yes I did create the clas

balmy river
#

Like this code snippet here:

// Create your listener object. Override any methods that you want to be notified about
TerminalListener listener = new TerminalListener() {};

// Choose the level of messages that should be logged to your console
LogLevel logLevel = LogLevel.VERBOSE;

// Create your token provider.
TokenProvider tokenProvider = new TokenProvider();

// Pass in the current application context, your desired logging level, your token provider, and the listener you created
if (!Terminal.isInitialized()) {
    Terminal.initTerminal(getApplicationContext(), logLevel, tokenProvider, listener);
}

// Since the Terminal is a singleton, you can call getInstance whenever you need it
Terminal.getInstance();

#

Or like this (if you use Kotlin)

// Create your listener object. Override any methods that you want to be notified about
val listener = object : TerminalListener {
}

// Choose the level of messages that should be logged to your console
val logLevel = LogLevel.VERBOSE

// Create your token provider.
val tokenProvider = TokenProvider()

// Pass in the current application context, your desired logging level, your token provider, and the listener you created
if (!Terminal.isInitialized()) {
    Terminal.initTerminal(applicationContext, logLevel, tokenProvider, listener)
}

// Since the Terminal is a singleton, you can call getInstance whenever you need it
Terminal.getInstance()
scenic kestrel
#

Terminal.initTerminal(
applicationContext, LogLevel.VERBOSE, TokenProvider(this), TerminalEventListener()
)

#

I had to change my tokenProvider to accept a context

#

I'm sorry this is taking up so much time, I really appreciate your help

balmy river
#

Sure thing! So when you say you needed to change you tokenProvider to accept a context, what did that do to the fetchConnectionToken function?

scenic kestrel
#

I did not change any of the parameters of the function it is still:
override fun fetchConnectionToken(callback: ConnectionTokenCallback) {

But inside the function I need to access some local parameters for my servers authentication using the auth

balmy river
#

Okay so, sorry to harp on this, but can you assign your TokenProvider(this) to a value and log that? I may be paranoid but I always like to check the value is the same inside the function as out.

scenic kestrel
#

class TokenProvider(context: Context) : ConnectionTokenProvider {
private val contextRef = WeakReference(context)

#

Yes I'm saving the paramter

balmy river
#

Right, I'm just looking at this snippet you provided:

Terminal.initTerminal(
                applicationContext, LogLevel.VERBOSE, TokenProvider(this), TerminalEventListener()
            )

And asking if you can do something like

val tP = TokenProvider(this)
Log.d("TerminalTest", tP)
scenic kestrel
#

okay will do

balmy river
#

I admit it's probably overly cautious but I just want to make we aren't missing something simple

scenic kestrel
#

good idea

#

So this is what I'm going to run

#

2022-03-29 10:59:46.629 15127-15127/beam.live.ride D/TerminalTest: TokenProvider@84f4cde

#

What were you hoping to see?

balmy river
#

Wait sorry, I think I know what I'm looking for. Can you try

val tP = TokenProvider(this)
Log.d("TerminalTest", tP.fetchConnectionToken())
scenic kestrel
#

what should the callback be?

balmy river
#

Sorry I've got a working integration that uses the JavaScript SDK. Under the hood they all use the same APIs but sometimes working with the different objects can be tricky

#

the callback is what returns the connection token string, if successful, or the error message if not

scenic kestrel
#

``
val discoveryCallback = object : Callback {
override fun onSuccess() {
Log.v("TerminalTest", " Success Callback")
}

        override fun onFailure(e: TerminalException) {
            Log.d("TerminalTest", "Fail Callback")

        }
    }

``

balmy river
#

Are we still talking about the callback that is the parameter for the fetchConnectionToken function?

class TokenProvider : ConnectionTokenProvider {
  override fun fetchConnectionToken(callback: ConnectionTokenCallback) {
    try {
      // Your backend should call /v1/terminal/connection_tokens and return the
      // JSON response from Stripe. When the request to your backend succeeds,
      // return the `secret` from the response to the SDK.
      callback.onSuccess(secret)
    } catch (e: Exception) {
      callback.onFailure(
        ConnectionTokenException("Failed to fetch connection token", e)
      )
    }
  }
}
#

As far as I can tell, the callback is used here to allow for listening to the onSuccess and onFailure events by the SDK while allowing you to define how your application handles those events

#

So if the code you shared is what the callback in the Token provider is doing, then it isn't returning the token secret when initializing the Terminal SDK.....I think

scenic kestrel
#

I am wondering what callback you want me to provide for the test

#

I haven't gotten anything to work yet

balmy river
#

Right...event driven. I'm just trying to figure out how we test, before we initialize the Terminal, whether the onSuccess callback is actually returning the Connection Token secret.

#

Which is another thing, can you log out the response from your server?

scenic kestrel
#

I'm going to try and run this

#

It should just print out the token

scenic kestrel
#

The test just keeps crashing :/

balmy river
#

I'm still a little curious why you appear to be abstracting/customizing the callback here. I do not know enough about Android programming to say whether it's a better approach or not, but I know that the TokenProvider.fetchConnectionToken definition above does work.

#

I haven't been able to dig through the entire thing but you should be able to clone this and get the example app running with a few configuration steps. Personally I found the TokenProvider and ApiClient definitions rather interesting.