#cynaed_code
1 messages ¡ Page 1 of 1 (latest)
đ 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/1451004618426548305
đ Have more to share? Add more details, code, screenshots, videos, etc. below.
hi there, give me a moment to catch up
Alright for the mean time, I'll paste snippets here
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
// Ensure logging runs sequentially on IO
CoroutineScope(Dispatchers.IO).launch {
postLoggingSequential("MyFloOffline | TapToPay", "First Time Payment")
// Switch back to Main thread for UI action
withContext(Dispatchers.Main) {
val intent = Intent(this@MainActivity, TapToPayActivity::class.java)
intent.putExtra("paymentIntentId", paymentIntentId)
startActivityForResult(intent, 1234)
}
}
}
}
}
CoroutineScope(Dispatchers.IO).launch {
postLoggingSequential("MyFloOffline | TapToPay", "Initialize Terminal")
}
// Initialize Terminal (this is OK on IO)
if (!Terminal.isInitialized()) {
Terminal.initTerminal(applicationContext, logLevel, tokenProvider, listener)
}
val terminal = Terminal.getInstance()
println("STATUS IN INITIALIZATION ${terminal.paymentStatus}")
if (terminal.paymentStatus == PaymentStatus.READY) {
CoroutineScope(Dispatchers.IO).launch {
postLoggingSequential("MyFloOffline | TapToPay", "2nd Condition Block")
}
val intent = Intent(this@MainActivity, TapToPayActivity::class.java)
intent.putExtra("paymentIntentId", paymentIntentId)
startActivityForResult(intent, 1234)
}
}```
postLoggingSequential is my way to create logs on this because only client have the Samsung Active Tab 5.
the logs is here
2025-12-18 10:58:31.9526|Info||[MyFloOffline | TapToPay : 12/18/2025 10:58:31 AM] : Started Payment |
2025-12-18 10:58:32.0297|Info||[MyFloOffline | TapToPay : 12/18/2025 10:58:32 AM] : 2nd Condition Block |
2025-12-18 10:58:32.0297|Info||[MyFloOffline | TapToPay : 12/18/2025 10:58:32 AM] : Initialize Terminal |
2025-12-18 10:58:32.0764|Info||[MyFloOffline | TapToPay : 12/18/2025 10:58:32 AM] : TapToPayActivity : pi_3SfUbwDFGfQzmzjw1Q81y7us |
2025-12-18 10:58:32.3670|Info||[MyFloOffline | TapToPay : 12/18/2025 10:58:32 AM] : TapToPayActivity : pi_3SfUbwDFGfQzmzjw1Q81y7us REQUIRES_PAYMENT_METHOD |
2025-12-18 10:58:56.0882|Info||[MyFloOffline | TapToPay : 12/18/2025 10:58:56 AM] : TapToPayActivity : pi_3SfUbwDFGfQzmzjw1Q81y7us |
2025-12-18 10:58:56.3885|Info||[MyFloOffline | TapToPay : 12/18/2025 10:58:56 AM] : TapToPayActivity : pi_3SfUbwDFGfQzmzjw1Q81y7us |
2025-12-18 10:58:56.4102|Info||[MyFloOffline | TapToPay : 12/18/2025 10:58:56 AM] : TapToPayActivity : pi_3SfUbwDFGfQzmzjw1Q81y7us REQUIRES_PAYMENT_METHOD |
2025-12-18 10:58:57.6190|Info||[MyFloOffline | TapToPay : 12/18/2025 10:58:57 AM] : Payment Successful |
TapToPayActivity onCreate
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") ?: ""
postLoggingSequential("MyFloOffline | TapToPay", "TapToPayActivity : " + 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) {
postLoggingSequential(
"MyFloOffline | TapToPay",
"TapToPayActivity : ${paymentIntentId} ${paymentIntent.status}"
)
val resultIntent = Intent()
resultIntent.putExtra("payment_intent_id", paymentIntent.id)
setResult(Activity.RESULT_OK, resultIntent)
finish()
return
}
activePaymentIntent = paymentIntent
postLoggingSequential(
"MyFloOffline | TapToPay",
"TapToPayActivity : ${paymentIntentId} ${paymentIntent.status}"
)
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()
}
}
)```
Could you share how you declared isRunning?
companion object {
private var isRunning = false
private var activePaymentIntent: PaymentIntent? = null
}
override fun onDestroy() {
super.onDestroy()
Log.d("TapToPay", "Destroyed Activity")
isRunning = false
}
what I firgured just now is that upon changing of orientation it recreates the Activity again. since i'm using a tab it automatically do the collection of payment in landscape but my application is on portrait
do you think this is a possible reason?
Could you reproduce the same behavior on an Android phone device? If yes then it likely is it. When you mentioned orientation, I looked up Android docs [0] and it does say
*The system recreates an Activity when a configuration change occurs. To do this, the system calls onDestroy() and destroys the existing Activity instance. It then creates a new instance using onCreate(), and this new Activity instance is initialized with the new, updated configuration. This also means that the system also recreates the UI with the new configuration.
*
[0] https://developer.android.com/guide/topics/resources/runtime-changes
I recreated the issue on phone by rotating my phone while the collection of payment is happening. and it reappears, so it recreates the activity upon changing of orientation this is confirmed since I did side by side testing just now with the client. and we run the application on landscape and it didn't re appear.
but the problem is we locked the device into portrait now but the collection of payment is still turning in landscape
is there a way in stripe to lock the collection in portrait orientation in tablet?
when I say client they're testing it on Samsung Active Tab 5
paymentIntentId, // your PaymentIntent ID from backend
object : PaymentIntentCallback {
override fun onSuccess(paymentIntent: PaymentIntent) {
if (paymentIntent.status == PaymentIntentStatus.SUCCEEDED) {
postLoggingSequential(
"MyFloOffline | TapToPay",
"TapToPayActivity : ${paymentIntentId} ${paymentIntent.status}"
)
val resultIntent = Intent()
resultIntent.putExtra("payment_intent_id", paymentIntent.id)
setResult(Activity.RESULT_OK, resultIntent)
finish()
return
}
activePaymentIntent = paymentIntent
postLoggingSequential(
"MyFloOffline | TapToPay",
"TapToPayActivity : ${paymentIntentId} ${paymentIntent.status}"
)
collectAndConfirm(paymentIntent) // continue with collect + confirm flow
}```
```collectAndConfirm(paymentIntent) // continue with collect + confirm flow```
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()
}
})
}```
which Stripe SDK version are you currently on?
and what is the Android version on the Samsung Tab 5 device?
implementation("com.stripe:stripeterminal-taptopay:4.3.1")
implementation("com.stripe:stripeterminal-core:4.3.1")
Androind Version 16
It looks like we fixed the orientation issue on our SDK version 4.6.0: https://github.com/stripe/stripe-terminal-android/issues/537
See the latest comment on Jul 10 by chr-stripe
you're welcome. feel free to reach out again if the same issue persist after the upgrade
alright.