@@ -15,6 +15,7 @@ import androidx.compose.material.icons.filled.Error
1515import androidx.compose.material3.CircularProgressIndicator
1616import androidx.compose.material3.MaterialTheme
1717import androidx.compose.material3.Text
18+ import androidx.compose.runtime.Composable
1819import androidx.compose.runtime.collectAsState
1920import androidx.compose.runtime.getValue
2021import androidx.compose.ui.Alignment
@@ -28,6 +29,8 @@ import com.truelayer.demo.R
2829import com.truelayer.demo.payments.api.PaymentStatus
2930import com.truelayer.demo.utils.PrefUtils
3031import com.truelayer.payments.core.utils.extractTrueLayerRedirectParams
32+ import com.truelayer.payments.ui.screens.processor.ResultProcessor
33+ import com.truelayer.payments.ui.screens.processor.ResultProcessorContext
3134import com.truelayer.payments.ui.theme.Theme
3235import com.truelayer.payments.ui.theme.stackNavigation
3336
@@ -45,67 +48,87 @@ class PaymentStatusActivity : AppCompatActivity() {
4548 setContent {
4649 val paymentId = params[" payment_id" ]
4750 val mandateId = params[" mandate_id" ]
48- val viewModel = viewModel<PaymentStatusViewModel >(
49- factory = paymentStatusViewModel(paymentId, mandateId, PrefUtils .getQuickstartUrl(this ))
50- )
51- val status by viewModel.status.collectAsState()
52- val error by viewModel.error.collectAsState()
5351
54- // Start polling for status updates
55- if (paymentId != null ) {
56- viewModel.pollPaymentStatus()
57- } else {
58- viewModel.pollMandateStatus()
59- }
52+ val activity = this
6053
6154 Theme (
6255 navigationTransition = { current, transition, direction ->
6356 stackNavigation(current, transition, direction)
6457 }
6558 ) {
66- Box (
67- modifier = Modifier .fillMaxSize(),
68- contentAlignment = Alignment .Center
69- ) {
70- Column (
71- horizontalAlignment = Alignment .CenterHorizontally ,
72- verticalArrangement = Arrangement .spacedBy(16 .dp),
73- modifier = Modifier .padding(horizontal = 16 .dp)
74- ) {
75- Text (text = stringResource(id = R .string.status_title), style = MaterialTheme .typography.titleMedium)
76- when (status) {
77- PaymentStatus .Status .AUTHORIZING -> {
78- // If the SDK has done it's work already, it will be ok
79- // to wait for status change
80- CircularProgressIndicator ()
81- }
82- PaymentStatus .Status .AUTHORIZATION_REQUIRED -> {
83- // If you encounter this state, it's most likely that the SDK didn't
84- // get chance to do its work yet. Start the CoordinatorFlow.
85- // If the SDK has done its work, then this state would be considered
86- // an error.
87- // Because we are using this view to query the state of the payment
88- // after redirect from the bank this should never happen.
89- Image (imageVector = Icons .Filled .Error , contentDescription = null )
90- }
91- PaymentStatus .Status .AUTHORIZED ,
92- PaymentStatus .Status .SETTLED ,
93- PaymentStatus .Status .EXECUTED -> {
94- Image (
95- imageVector = Icons .Filled .CheckCircle ,
96- colorFilter = ColorFilter .tint(Color .Green ),
97- contentDescription = null
98- )
99- }
100- PaymentStatus .Status .FAILED -> {
101- Image (imageVector = Icons .Filled .Error , contentDescription = null )
102- }
59+ if (paymentId != null ) {
60+ // If this activity is launched at the end of a payment creation flow then you can use
61+ // the payment result screen to fetch and display the result
62+ ResultProcessor (
63+ resultContext = ResultProcessorContext (paymentId),
64+ onSuccess = {
65+ activity.finish()
66+ },
67+ onFailure = {
68+ activity.finish()
10369 }
70+ )
71+ } else if (mandateId != null ) {
72+ // If this activity is launched at the end of a mandate flow then you will need to manually
73+ // fetch and display the status
74+ MandateStatus (mandateId)
75+ }
76+ }
77+ }
78+ }
79+
80+ @Composable
81+ fun MandateStatus (mandateId : String ) {
82+ val viewModel = viewModel<MandateStatusViewModel >(
83+ factory = mandateStatusViewModel(mandateId, PrefUtils .getQuickstartUrl(this ))
84+ )
85+ val status by viewModel.status.collectAsState()
86+ val error by viewModel.error.collectAsState()
10487
105- Text (text = status.toString(), style = MaterialTheme .typography.bodyLarge)
106- Text (text = error, color = Color .Red )
88+ // Start polling for mandate status updates
89+ viewModel.pollMandateStatus()
90+
91+ Box (
92+ modifier = Modifier .fillMaxSize(),
93+ contentAlignment = Alignment .Center
94+ ) {
95+ Column (
96+ horizontalAlignment = Alignment .CenterHorizontally ,
97+ verticalArrangement = Arrangement .spacedBy(16 .dp),
98+ modifier = Modifier .padding(horizontal = 16 .dp)
99+ ) {
100+ Text (text = stringResource(id = R .string.status_title), style = MaterialTheme .typography.titleMedium)
101+ when (status) {
102+ PaymentStatus .Status .AUTHORIZING -> {
103+ // If the SDK has done it's work already, it will be ok
104+ // to wait for status change
105+ CircularProgressIndicator ()
106+ }
107+ PaymentStatus .Status .AUTHORIZATION_REQUIRED -> {
108+ // If you encounter this state, it's most likely that the SDK didn't
109+ // get chance to do its work yet. Start the CoordinatorFlow.
110+ // If the SDK has done its work, then this state would be considered
111+ // an error.
112+ // Because we are using this view to query the state of the payment
113+ // after redirect from the bank this should never happen.
114+ Image (imageVector = Icons .Filled .Error , contentDescription = null )
115+ }
116+ PaymentStatus .Status .AUTHORIZED ,
117+ PaymentStatus .Status .SETTLED ,
118+ PaymentStatus .Status .EXECUTED -> {
119+ Image (
120+ imageVector = Icons .Filled .CheckCircle ,
121+ colorFilter = ColorFilter .tint(Color .Green ),
122+ contentDescription = null
123+ )
124+ }
125+ PaymentStatus .Status .FAILED -> {
126+ Image (imageVector = Icons .Filled .Error , contentDescription = null )
107127 }
108128 }
129+
130+ Text (text = status.toString(), style = MaterialTheme .typography.bodyLarge)
131+ Text (text = error, color = Color .Red )
109132 }
110133 }
111134 }
0 commit comments