fix razorpay qr credit log

This commit is contained in:
androidlover5842
2026-02-01 14:03:19 +05:30
parent 43ee7311e8
commit 8f62459d5e
3 changed files with 52 additions and 8 deletions

View File

@@ -73,10 +73,19 @@ fun RazorpayQrScreen(
LaunchedEffect(propertyId, bookingId) {
viewModel.loadQrList(propertyId, bookingId)
}
LaunchedEffect(state.isCredited) {
if (state.isCredited) {
onBack()
}
}
val isViewingQr = state.isClosed || !state.imageUrl.isNullOrBlank()
BackHandler(enabled = isViewingQr) {
val exitAndRefresh: () -> Unit = {
viewModel.exitQrView()
viewModel.loadQrList(propertyId, bookingId)
}
BackHandler(enabled = isViewingQr) {
exitAndRefresh()
}
Scaffold(
@@ -86,7 +95,7 @@ fun RazorpayQrScreen(
navigationIcon = {
IconButton(onClick = {
if (isViewingQr) {
viewModel.exitQrView()
exitAndRefresh()
} else {
onBack()
}
@@ -98,7 +107,20 @@ fun RazorpayQrScreen(
)
}
) { padding ->
if (state.isClosed) {
if (state.isCredited) {
Box(
modifier = Modifier
.fillMaxSize()
.padding(padding),
contentAlignment = Alignment.Center
) {
Text(
text = "Payment received",
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.primary
)
}
} else if (state.isClosed) {
Box(
modifier = Modifier
.fillMaxSize()

View File

@@ -10,6 +10,7 @@ data class RazorpayQrState(
val currency: String? = null,
val imageUrl: String? = null,
val isClosed: Boolean = false,
val isCredited: Boolean = false,
val paymentLink: String? = null,
val qrList: List<com.android.trisolarispms.data.api.model.RazorpayQrListItemDto> = emptyList()
)

View File

@@ -37,12 +37,14 @@ class RazorpayQrViewModel : ViewModel() {
}
fun exitQrView() {
stopQrEventStream()
stopQrEventPolling()
_state.update {
it.copy(
qrId = null,
imageUrl = null,
isClosed = false,
isCredited = false,
error = null
)
}
@@ -121,6 +123,7 @@ class RazorpayQrViewModel : ViewModel() {
if (qrId.isNullOrBlank()) return
if (lastQrId == qrId && qrEventSource != null) return
stopQrEventStream()
stopQrEventPolling()
lastQrId = qrId
val client = ApiClient.createOkHttpClient(readTimeoutSeconds = 0)
val url = "${ApiConstants.BASE_URL}properties/$propertyId/bookings/$bookingId/payments/razorpay/qr/$qrId/events/stream"
@@ -138,10 +141,17 @@ class RazorpayQrViewModel : ViewModel() {
val event = runCatching {
gson.fromJson(data, RazorpayQrEventDto::class.java)
}.getOrNull() ?: return
if (isClosedStatus(event.status)) {
_state.update { it.copy(isClosed = true, imageUrl = null) }
val status = event.status?.lowercase()
val eventName = event.event?.lowercase()
if (eventName == "qr_code.credited" || status == "credited") {
_state.update { it.copy(isCredited = true, imageUrl = null) }
stopQrEventStream()
stopQrEventPolling()
return
}
if (isClosedStatus(status)) {
_state.update { it.copy(isClosed = true, imageUrl = null) }
stopQrEventStream()
}
}
@@ -151,13 +161,16 @@ class RazorpayQrViewModel : ViewModel() {
response: okhttp3.Response?
) {
stopQrEventStream()
startQrEventPolling(propertyId, bookingId, qrId)
}
override fun onClosed(eventSource: EventSource) {
stopQrEventStream()
startQrEventPolling(propertyId, bookingId, qrId)
}
}
)
// Keep polling as a fallback in case SSE is buffered or never delivers events.
startQrEventPolling(propertyId, bookingId, qrId)
}
@@ -170,6 +183,7 @@ class RazorpayQrViewModel : ViewModel() {
private fun startQrEventPolling(propertyId: String, bookingId: String, qrId: String) {
if (qrPollJob?.isActive == true) return
qrPollJob = viewModelScope.launch {
var delayMs = 4000L
while (true) {
val currentQrId = state.value.qrId
if (currentQrId.isNullOrBlank() || currentQrId != qrId || state.value.isClosed) {
@@ -183,16 +197,22 @@ class RazorpayQrViewModel : ViewModel() {
)
val body = response.body()
if (response.isSuccessful && body != null) {
if (body.any { it.event?.lowercase() == "qr_code.credited" || it.status?.lowercase() == "credited" }) {
_state.update { it.copy(isCredited = true, imageUrl = null) }
stopQrEventStream()
break
}
if (body.any { isClosedStatus(it.status) }) {
_state.update { it.copy(isClosed = true, imageUrl = null) }
stopQrEventStream()
break
}
}
} catch (_: Exception) {
// ignore polling errors
delayMs = 4000L
} catch (e: Exception) {
delayMs = (delayMs * 1.5).toLong().coerceAtMost(15000L)
}
delay(5000)
delay(delayMs)
}
}
}
@@ -258,6 +278,7 @@ class RazorpayQrViewModel : ViewModel() {
currency = item.currency,
imageUrl = item.imageUrl,
isClosed = status == "closed" || status == "expired" || status == "credited",
isCredited = status == "credited",
error = null
)
}