Click here to Skip to main content
15,867,568 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi all,

I'm trying to implement a slider that add a certain value to the initial value when checking out. But I'm not able to pass that extra value to my checkout API Call.

Here an example: https://imgur.com/a/mp5ytzW

Structure: PaymentWidget => DonateView => DonateScreen
The API call fetchStripePaymentIntent is inside the DonateScreen initState and I want the value of the Slider in DonateView to be inside the API call.

I usually know how to do it, but it's not working this time. I would really appreciate any help.

What I have tried:

PaymentWidget:
Dart
class PaymentsWidget extends StatelessWidget {
  final StripePaymentIntent stripePaymentIntent;
  final int conversationId;
 
  PaymentsWidget(this.stripePaymentIntent, this.conversationId, {Key? key}) : super(key: key) {
    isApplePaySupported();
  }
 
  isApplePaySupported() {
    print("Apple pay supported ${Stripe.instance.isApplePaySupported.value} ");
  }
 
  Future<void> checkout(BuildContext context) async {
    Stripe.stripeAccountId = stripePaymentIntent.stripeAccountId;
 
    await Stripe.instance.initPaymentSheet(
        paymentSheetParameters: SetupPaymentSheetParameters(
      applePay: true,
      googlePay: true,
      style: ThemeMode.light,
      testEnv: Config.stripeTestEnv,
      merchantCountryCode: 'DE',
      merchantDisplayName: 'TrödelSpende',
      paymentIntentClientSecret: stripePaymentIntent.client_secret,
    ));
 
    try {
      await Stripe.instance.presentPaymentSheet();
      context.router.replace(DonationSuccessfulRoute(
          itemId: stripePaymentIntent.itemId, conversationId: conversationId));
    } on Exception catch (e) {
      if (e is StripeException) {
        if (e.error.code == FailureCode.Canceled) {
          print("Stripe payment canceled");
        } else {
          print("StripeException");
          print(e.error);
        }
      } else {
        print("Error");
        print(e);
      }
    }
  }
 
  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      child: ElevatedButton(
        style: ButtonStyle(backgroundColor: MaterialStateProperty.all<Color>(MyTheme.orange)),
        onPressed: () => checkout(context),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              "PayNow".tr(),
              style: MyTheme.buttonText,
            ),
          ],
        ),
      ),
    );
  }
}

DonateView:
Dart
class DonateView extends StatefulWidget {
  final StripePaymentIntent spi;
  final Item item;
  final UserProfile? userProfile;
  final int conversationId;
  final NgoDetails ngo;
  int extra;
 
  DonateView(this.spi, this.item, this.userProfile, this.conversationId, this.ngo, this.extra,
      {Key? key})
      : super(key: key);
 
  @override
  State<DonateView> createState() => _DonateViewState();
}
 
class _DonateViewState extends State<DonateView> {
  @override
  Widget build(BuildContext context) {
    const sizedBoxSpace = SizedBox(height: 24);
    return Padding(
        padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            sizedBoxSpace,
            UserProfileWidget(widget.userProfile),
            sizedBoxSpace,
            Text(
              "donate1".tr(args: [widget.userProfile!.firstname]),
              style: MyTheme.black,
            ),
            Text("donate2".tr(), style: MyTheme.black),
            const SizedBox(height: 10),
            Text("donate3".tr(), style: MyTheme.orange600),
            sizedBoxSpace,
            RichText(
              text: TextSpan(
                style: MyTheme.mediumBlack,
                children: <TextSpan>[
                  TextSpan(text: 'donate4'.tr()),
                  TextSpan(
                      text: Utils.getDisplayPrice(widget.item.amountInCent + widget.extra),
                      style: const TextStyle(color: MyTheme.orange)),
                  TextSpan(text: 'donate5'.tr()),
                  TextSpan(text: widget.ngo.name, style: const TextStyle(color: MyTheme.primary)),
                  TextSpan(text: 'donate6'.tr()),
                ],
              ),
            ),
            sizedBoxSpace,
            getSlider(context),
            sizedBoxSpace,
            PaymentsWidget(
              widget.spi,
              widget.conversationId,
            ),
          ],
        ));
  }
 
  Widget getSlider(BuildContext context) {
    return Slider(
      min: 0,
      max: 2000,
      label: widget.extra.toString(),
      value: widget.extra.toDouble(),
      onChanged: ((value) {
        setState(() {
          widget.extra = value.toInt();
        });
      }),
    );
  }
}

DonateScreen:
Dart
class DonateScreen extends StatefulWidget {
  final int itemId;
  final int conversationId;
  final int extraInCent;
 
  DonateScreen(@pathParam this.itemId, @pathParam this.conversationId, @pathParam this.extraInCent,
      {Key? key})
      : super(key: key);
 
  @override
  _DonateScreenState createState() => _DonateScreenState();
}
 
class _DonateScreenState extends State<DonateScreen> {
  late Future<StripePaymentIntent> _stripePaymentIntent;
  @override
  void initState() {
    super.initState();
    setState(() {
      _stripePaymentIntent = Provider.of<PaymentIntentProvider>(context, listen: false)
          .fetchStripePaymentIntent(widget.itemId, widget.extraInCent);
    });
  }
 
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<ItemBloc, ItemState>(
      builder: (context, state) {
        if (state is ItemLoadedState) {
          Item item = state.item;
          return Scaffold(
            appBar: AppBar(
              title: Text(
                "Pay".tr(),
              ),
            ),
            body: SingleChildScrollView(
              child: BlocBuilder<ProfileBloc, ProfileState>(
                builder: ((context, state) {
                  if (state is ProfileLoadedState) {
                    UserProfile userProfile = state.userProfile;
                    return FutureBuilder<StripePaymentIntent>(
                        future: _stripePaymentIntent,
                        builder:
                            (BuildContext context, AsyncSnapshot<StripePaymentIntent> snapshot) {
                          List<Widget> children;
                          if (snapshot.hasData) {
                            Item theItem = item;
                            children = <Widget>[
                              BlocBuilder<NgosBloc, NgosState>(
                                builder: (context, state) {
                                  if (state is NgosLoadedState) {
                                    return Column(
                                      children: [
                                        DonateView(
                                          snapshot.data!,
                                          theItem,
                                          userProfile,
                                          widget.conversationId,
                                          state.ngos[item.ngoId]!,
                                          widget.extraInCent,
                                        ),
                                      ],
                                    );
                                  }
                                  return Container();
                                },
                              ),
                            ];
                          } else if (snapshot.hasError) {
                            children = <Widget>[
                              const Icon(
                                Icons.error_outline,
                                color: Colors.red,
                                size: 60,
                              ),
                              Padding(
                                padding: const EdgeInsets.only(top: 16),
                                child: Text('Error: $snapshot.error'),
                              ),
                            ];
                          } else {
                            children = const <Widget>[
                              SizedBox(
                                width: 60,
                                height: 60,
                                child: MyCircularProgressIndicator(),
                              )
                            ];
                          }
                          return Center(
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.center,
                              crossAxisAlignment: CrossAxisAlignment.center,
                              children: children,
                            ),
                          );
                        });
                  }
                  return Container();
                }),
              ),
            ),
          );
        }
        return Container();
      },
    );
  }
}
Posted
Updated 7-Aug-22 6:24am
Comments
Afzaal Ahmad Zeeshan 5-Aug-22 22:39pm    
The simplest way would be to use the Navigator to pass the values. But if not that, then I would recommend using a State manager to pass the state around among different UIs and pages.

Why do you think it is not working, what's the behavior?

1 solution

You can pass widget.value to PaymentsWidget like how you did for spi and conversationId.
PaymentsWidget(
             widget.spi,
             widget.conversationId,
             widget.value
 ),
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900