Mixpeal / flutter_paypal

A simple but powerful Paypal SDK for flutter.
MIT License
6 stars 24 forks source link

Cannot navigate to other page after payment success. #5

Open samaliftech opened 2 years ago

samaliftech commented 2 years ago

This error come out if I want to navigate to other page in onSuccess function. Only firestore update function is usable

Exception has occurred.
FlutterError (Looking up a deactivated widget's ancestor is unsafe.
At this point the state of the widget's element tree is no longer stable.
To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.)

` import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:flutter_paypal/flutter_paypal.dart'; import 'package:mps_ir4_master/screen/rechargescreen.dart';

import 'sucess.dart';

final GlobalKey _scaffoldKey = GlobalKey();

class PaymentMethodScreen extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Text', debugShowCheckedModeBanner: false, home: Scaffold( key: _scaffoldKey, appBar: AppBar( title: Text('Payment'), leading: IconButton( icon: Icon(Icons.arrow_back, color: Colors.black), onPressed: () => Navigator.of(context).pop(), ), ), body: PaymentMethodView(), ), ); } }

enum PaymentMethod { onlinebank, paypal, grabpay, cbc }

class PaymentMethodView extends StatefulWidget { @override _PaymentMethodView createState() => _PaymentMethodView(); }

class _PaymentMethodView extends State { PaymentMethod _character = PaymentMethod.cbc;

@override Widget build(BuildContext context) { return Column(children: [ Spacer(), Container( child: Padding( padding: EdgeInsets.only(top: 20, left: 60, right: 60, bottom: 20), child: Text( "Choose a payment method", textAlign: TextAlign.center, style: TextStyle( fontSize: 35.0, color: Colors.grey.shade700, ), ), )), Spacer(), RadioListTile( title: const Text('Credit / Debit Card'), value: PaymentMethod.cbc, groupValue: _character, onChanged: (PaymentMethod value) { setState(() { _character = value; print(_character); }); }, ), RadioListTile( title: const Text('FPX Online Banking'), value: PaymentMethod.onlinebank, groupValue: _character, onChanged: (PaymentMethod value) { setState(() { _character = value; print(_character); }); }, ), RadioListTile( title: const Text('GrabPay'), value: PaymentMethod.grabpay, groupValue: _character, onChanged: (PaymentMethod value) { setState(() { _character = value; print(_character); }); }, ), RadioListTile( title: const Text('PayPal'), value: PaymentMethod.paypal, groupValue: _character, onChanged: (PaymentMethod value) { setState(() { _character = value; print(_character); }); }, ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: EdgeInsets.only(top: 120, bottom: 30), child: ElevatedButton( style: ElevatedButton.styleFrom( fixedSize: const Size(380, 80), primary: Colors.lightBlue.shade900), onPressed: () async { if (_character == PaymentMethod.paypal) { print('Payment method is ready');

              Navigator.of(context).push(
                MaterialPageRoute(
                  builder: (BuildContext context) => UsePaypal(
                      sandboxMode: true,
                      clientId:
                          "Client_ID",
                      secretKey:
                          "PRIVATE_KEY",
                      returnURL: "https://samplesite.com/return",
                      cancelURL: "https://samplesite.com/cancel",
                      transactions: [
                        {
                          "amount": {
                            "total": '$globalInt',
                            "currency": "MYR",
                            "details": {
                              "subtotal": '$globalInt',
                              "shipping": '0',
                              "shipping_discount": 0
                            }
                          },
                          "description":
                              "The payment transaction description.",
                          // "payment_options": {
                          //   "allowed_payment_method":
                          //       "INSTANT_FUNDING_SOURCE"
                          // },
                          "item_list": {
                            "items": [
                              {
                                "name": "Thytron Reload RM $globalInt",
                                "quantity": 1,
                                "price": '$globalInt',
                                "currency": "MYR"
                              }
                            ],
                          }
                        }
                      ],
                      note: "Contact us for any questions on your order.",
                      onSuccess: (Map params) async {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => Success()),
                        );
                        //   print("onSuccess: $params");

                        print('Payment method is not ready yet');
                      },
                      onError: (error) {
                        print("onError: $error");
                      },
                      onCancel: (params) {
                        print('cancelled: $params');
                      }),
                ),
              );
            } else {
              showDialog(
                  context: context,
                  builder: (BuildContext context) => leadDialog1);
              print('Payment method is not ready yet');
            }
          },
          child: Text(
            "Pay Now",
            style: TextStyle(
                color: Colors.white,
                fontWeight: FontWeight.bold,
                fontSize: 20),
          ),
        ),
      )
    ],
  )
]);

} }

Dialog leadDialog1 = Dialog( child: Container( height: 300.0, width: 360.0, color: Colors.white, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: EdgeInsets.all(15.0), child: Text( 'Coming Soon', style: TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 32.0), ), ), Padding( padding: EdgeInsets.all(15.0), child: Text( "This payment method is not\nready yet to be used.", textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontSize: 22.0), ), ), ], ), ), );

Dialog leadDialog2 = Dialog( child: Container( height: 300.0, width: 360.0, color: Colors.white, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: EdgeInsets.all(15.0), child: Text( 'Payment Succesful', style: TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 32.0), ), ), Padding( padding: EdgeInsets.all(15.0), child: Text( "The amount has been added to your current balance.", textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontSize: 22.0), ), ), ], ), ), );

`

Hope you can help me as soon as possible.

TFX0019 commented 2 years ago

i have the same problem. it says payment complete and stays on that screen

TFX0019 commented 2 years ago

i have the same problem. it says payment complete and stays on that screen

onSuccess: (Map params) async { _order.paymentStatus = 1; await submitOrder(); print("onSuccess: $params"); } I am using the main context. so shouldn't have a problem

lukasmckaine22 commented 2 years ago

any solution found? having same issue

Mixpeal commented 2 years ago

It worked for me, have you tried using the parent context to navigate after the success?

Mixpeal commented 2 years ago

Let me know if you understand what I mean

lukasmckaine22 commented 2 years ago

I'm not sure what you mean. do you mind sharing a snippet?

Mixpeal commented 2 years ago

@lukasmckaine22 For example

BuildContext parentContext = context;
Navigator.of(context).push(
  MaterialPageRoute(
    builder: (BuildContext context) => UsePaypal(
        sandboxMode: true,
        clientId: ...,
        secretKey: ...,
        returnURL: "https://samplesite.com/return",
        cancelURL: "https://samplesite.com/cancel",
        transactions: ...,
        note: "Contact us for any questions on your order.",
        onSuccess: (Map params) async {
          print("onSuccess: $params");
          Navigator.push(
            parentContext,
            MaterialPageRoute(
                builder: (context) => Success()),
          );
        },
        onError: (error) {
          print("onError: $error");
        },
        onCancel: (params) {
          print('cancelled: $params');
        }),
  ),
)

You see there is another context inside the navigator that called UsePaypal Widget, don't use that, use the primary context (parent context), you catch my drift?

lukasmckaine22 commented 2 years ago

Yes i see. I made the changes and am receiving a "NEW ROUTE null" message. I am not being navigated off of the "Payment Complete" screen.

onSuccess: (Map params) async { print("onSuccess: $params"); Get.find<Prefs>().setWallet(); Navigator.push( parentContext, MaterialPageRoute( builder: (context) => WalletScreen()), ); }

onPressed: () async { BuildContext parentContext = context; Navigator.of(context).push(MaterialPageRoute( image

Mixpeal commented 2 years ago

Maybe that issue is related to GetX

mo-aro-etailer commented 1 year ago

check out https://pub.dev/packages/flutter_paypal_native

andrewkimjoseph commented 1 year ago

Was this issue resolved? I am still facing it.