@@ -5,8 +5,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
55import '../../app_config.dart' ;
66import '../../models/isar/models/ethereum/eth_contract.dart' ;
77import '../../models/shopinbit/shopinbit_order_model.dart' ;
8+ import '../../providers/global/shopin_bit_service_provider.dart' ;
89import '../../providers/providers.dart' ;
910import '../../route_generator.dart' ;
11+ import '../../services/shopinbit/src/models/payment.dart' ;
1012import '../../services/wallets.dart' ;
1113import '../../themes/stack_colors.dart' ;
1214import '../../utilities/address_utils.dart' ;
@@ -17,7 +19,6 @@ import '../../utilities/util.dart';
1719import '../../wallets/crypto_currency/crypto_currency.dart' ;
1820import '../../widgets/background.dart' ;
1921import '../../widgets/custom_buttons/app_bar_icon_button.dart' ;
20- import '../../widgets/loading_indicator.dart' ;
2122import 'shopinbit_send_from_view.dart' ;
2223
2324final String kShopInBitUsdtContractAddress = DefaultTokens .list
@@ -223,20 +224,45 @@ Future<bool> tryNavigateToShopInBitWalletSend({
223224 return false ;
224225}
225226
227+ // Fetches the live payment info for a ticket so the caller can pass it into
228+ // the payment view as an arg (rather than loading it after the view is up).
229+ // GET first to reuse an existing invoice per the spec's "page reload
230+ // recovery" guidance; PUT (which regenerates) only when GET shows none.
231+ // Returns null on any failure so the view can fall back to polling.
232+ Future <PaymentInfo ?> fetchShopInBitPaymentInfo (
233+ WidgetRef ref,
234+ int apiTicketId,
235+ ) async {
236+ try {
237+ final client = ref.read (pShopinBitService).client;
238+ final getResp = await client.getPayment (apiTicketId);
239+ if (! getResp.hasError &&
240+ getResp.value != null &&
241+ getResp.value! .paymentLinks.isNotEmpty) {
242+ return getResp.value;
243+ }
244+ final putResp = await client.putPayment (apiTicketId);
245+ if (! putResp.hasError && putResp.value != null ) {
246+ return putResp.value;
247+ }
248+ } catch (_) {
249+ // Degrade to polling-only.
250+ }
251+ return null ;
252+ }
253+
226254// Shared mobile chrome for the two ShopInBit payment views: Background +
227255// PopScope (back goes through [onBack]) + AppBar + scrollable, intrinsic
228- // height body. Set [showLoading] to overlay a spinner.
256+ // height body.
229257class ShopInBitPaymentMobileScaffold extends StatelessWidget {
230258 const ShopInBitPaymentMobileScaffold ({
231259 super .key,
232260 required this .onBack,
233261 required this .child,
234- this .showLoading = false ,
235262 });
236263
237264 final VoidCallback onBack;
238265 final Widget child;
239- final bool showLoading;
240266
241267 @override
242268 Widget build (BuildContext context) {
@@ -259,22 +285,16 @@ class ShopInBitPaymentMobileScaffold extends StatelessWidget {
259285 body: SafeArea (
260286 child: LayoutBuilder (
261287 builder: (context, constraints) {
262- return Stack (
263- children: [
264- Padding (
265- padding: const EdgeInsets .all (16 ),
266- child: SingleChildScrollView (
267- child: ConstrainedBox (
268- constraints: BoxConstraints (
269- minHeight: constraints.maxHeight - 32 ,
270- ),
271- child: IntrinsicHeight (child: child),
272- ),
288+ return Padding (
289+ padding: const EdgeInsets .all (16 ),
290+ child: SingleChildScrollView (
291+ child: ConstrainedBox (
292+ constraints: BoxConstraints (
293+ minHeight: constraints.maxHeight - 32 ,
273294 ),
295+ child: IntrinsicHeight (child: child),
274296 ),
275- if (showLoading)
276- const LoadingIndicator (width: 24 , height: 24 ),
277- ],
297+ ),
278298 );
279299 },
280300 ),
0 commit comments