khalti / checkout-sdk-flutter

BSD 3-Clause "New" or "Revised" License
1 stars 7 forks source link

Facing same issues regarding not triggered onPaymentResult call back function . #4

Closed Hritik602 closed 6 months ago

Hritik602 commented 6 months ago
          Facing same issues regarding not triggered onPaymentResult call back function .
  khalti = await Khalti.init(
      enableDebugging: true,
      payConfig: payConfig,
      onPaymentResult: (paymentResult, khalti) {
        log('Payment Result: $paymentResult');
        log(paymentResult.toString());
        setState(() {
          this.paymentResult = paymentResult;
        });
        khalti.close(context);
      },
      onMessage: (
        khalti, {
        description,
        statusCode,
        event,
        needsPaymentConfirmation,
      }) async {
        log(
          'Description: $description, Status Code: $statusCode, Event: $event, NeedsPaymentConfirmation: $needsPaymentConfirmation',
        );
        khalti.close(context);
      },
      onReturn: () => log('Successfully redirected to return_url.'),
    );
    khalti != null ? khalti?.open(context) : "";

Flutter doctor

[√] Flutter (Channel stable, 3.19.3, on Microsoft Windows [Version 10.0.22631.3447], locale en-GB)
[√] Windows Version (Installed version of Windows is version 10 or higher)
[√] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[√] Chrome - develop for the web
[X] Visual Studio - develop Windows apps
    X Visual Studio not installed; this is necessary to develop Windows apps.
      Download at https://visualstudio.microsoft.com/downloads/.
      Please install the "Desktop development with C++" workload, including all of its default components
[√] Android Studio (version 2023.1)
[√] VS Code (version 1.88.1)
[√] Connected device (4 available)
[√] Network resources

! Doctor found issues in 1 category.

And also, when any user wants to return from the Pay With Khalti View without proceeding with payment, how can I identify it? Is there anything I'm missing in the docs?

Originally posted by @Hritik602 in https://github.com/khalti/checkout-sdk-flutter/issues/3#issuecomment-2054123892

Biplab-Dutta commented 6 months ago

Hi @Hritik602 Please provide a sample code that i can just copy and paste on my end to verify to possible issue. Also, are you using the same return_url that you used when making the server side POST request?

About knowing when the user didn't proceed with the payment and navigated out of the payment page, you should receive the onMessage callback with an event property saying "kpgDisposed". Additionally, onMessage also contains a field needsPaymentConfirmation property. If needsPaymentConfirmation is true, the developer should verify the payment status on their own to be sure about the payment status. This information is all covered in the docs.

Please refer to the onMessage section in the doc under Khalti Initialization.

Hritik602 commented 6 months ago
class KhaltiSDKDemo extends StatefulWidget {
  const KhaltiSDKDemo({super.key});

  @override
  State<KhaltiSDKDemo> createState() => _KhaltiSDKDemoState();
}

class _KhaltiSDKDemoState extends State<KhaltiSDKDemo> {
  late Khalti? khalti;
  late Response? paymentResponse;

  void initialized() async {
    paymentResponse = await TestService.getPaymentResponse();

    debugPrint("paymentResponse: ${paymentResponse.toString()}");
  }

  // String pidx =
  //     'ZyzCEMLFz2QYFYfERGh8LE'; // Should be generated via a server-side POST request.

  PaymentResult? paymentResult;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    initialized();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Image.asset(
          'assets/seru.png',
          height: 200,
          width: 200,
        ),
        const SizedBox(height: 120),
        const Text(
          'Rs. 22',
          style: TextStyle(fontSize: 25),
        ),
        const Text('1 day fee'),
        OutlinedButton(
          onPressed: () {
            payWithKhalti();
          },
          child: const Text('Pay with Khalti'),
        ),
        const SizedBox(height: 120),
        paymentResult == null
            ? Text(
                'pidx: $pidx',
                style: const TextStyle(fontSize: 15),
              )
            : Column(
                children: [
                  Text(
                    'pidx: ${paymentResult!.payload?.pidx}',
                  ),
                  Text('Status: ${paymentResult!.status}'),
                  Text(
                    'Amount Paid: ${paymentResult!.payload?.amount}',
                  ),
                  Text(
                    'Transaction ID: ${paymentResult!.payload?.transactionId}',
                  ),
                ],
              ),
        const SizedBox(height: 120),
        const Text(
          'This is a demo application developed by some merchant.',
          style: TextStyle(fontSize: 12),
        )
      ],
    ));
  }

  void payWithKhalti() async {
    final payConfig = KhaltiPayConfig(
      publicKey: "live_public_key_xxxxxxxxxxxxxxxx",
      //'live_public_key_979320ffda734d8e9f7758ac39ec775f', // This is a dummy public key for example purpose
      pidx: paymentResponse?.pidx ?? "",
      returnUrl: Uri.parse('https://docs.khalti.com/khalti-epayment/'),
      environment: Environment.prod,
    );

    /// if khalti is not initialized, then initialize it.
    /// else close the current context and open a new one.

    khalti = await Khalti.init(
      enableDebugging: true,
      payConfig: payConfig,
      onPaymentResult: (paymentResult, khalti) {
        log('Payment Result: $paymentResult');
        log(paymentResult.toString());
        setState(() {
          this.paymentResult = paymentResult;
        });
        khalti.close(context);
      },
      onMessage: (
        khalti, {
        description,
        statusCode,
        event,
        needsPaymentConfirmation,
      }) async {
        log(
          'Description: $description, Status Code: $statusCode, Event: $event, NeedsPaymentConfirmation: $needsPaymentConfirmation',
        );
        khalti.close(context);
      },
      onReturn: () => log('Successfully redirected to return_url.'),
    );
    khalti != null ? khalti?.open(context) : "";
  }
}


class TestService {
  static final _dio = Dio();

  static Future<Response?> getPaymentResponse() async {
    try {
      var response = await _dio.post(
          'https://khalti.com/api/v2/epayment/initiate/',
          options: Options(headers: {
            'Authorization':
                'key live_secret_key_xxxxxxxxxxx'
          }),
          data: {
            "return_url": "http://google.com/",
            "website_url": "http://google.com/",
            "amount": "1000",
            "purchase_order_id": "Ordwer01",
            "purchase_order_name": "Test",
            "customer_info": {
              "name": "Test Bahadur",
              "email": "test@khalti.com",
              "phone": "9800000001"
            }
          });
      return Response.fromJson(response.data);
    } catch (e) {
      print(e);
      return null;
    }
  }
}
``

I have used return url as ```https://google.com```
Biplab-Dutta commented 6 months ago

Are you calling the API https://khalti.com/api/v2/epayment/initiate/ via client side?

That is to be done via a server side Post request.

Please go through the docs regarding detailed steps.

Hritik602 commented 6 months ago

Are you calling the API https://khalti.com/api/v2/epayment/initiate/ via client side?

That is to be done via a server side Post request.

Please go through the docs regarding detailed steps.

no i m using in client side .

Biplab-Dutta commented 6 months ago

@Hritik602 Please go through the official docs on how to generate pidx.

IMG-20240414-WA0007.jpg

Closing the issue as completed.