Vicky
Vicky

Reputation: 11

Phone_pe payment integration with flutter

Issue Description

I'm integrating the PhonePe Payment SDK into my Flutter app, and I'm encountering a MissingPluginException when trying to call the init method.

Code Snippets

Flutter Widget

import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:flutter/material.dart';
import 'package:phonepe_payment_sdk/phonepe_payment_sdk.dart';

class PhonePePaymentScreen extends StatefulWidget {
  PhonePePaymentScreen();

  @override
  State<PhonePePaymentScreen> createState() => _PhonePePaymentScreenState();
}

class _PhonePePaymentScreenState extends State<PhonePePaymentScreen> {

  @override
  void initState() {
    initiatePayment();
    body = getCheckSum().toString();
    super.initState();
  }

  String environmentValue = "SANDBOX";
  String appId = "";
  String merchantId = "PGTESTPAYUAT";
  bool enableLogging = true;
  String saltKey = "099eb0cd-02cf-4e2a-8aca-3e6c6aff0399";
  String saltIndex = "1";
  String callback = "https://webhook.site/ba843c01-f6a6-4076-8fba-24b5719b3f66";
  String apiEndPoint = "/pg/v1/pay";

  Object result;
  String body = "";
  String checksum = "";

  void initiatePayment() async {
    PhonePePaymentSdk.init(environmentValue, appId, merchantId, enableLogging)
        .then((val) => {
      setState(() {
        result = 'PhonePe SDK Initialized - $val';
      })
    })
        .catchError((error) {
      handleError(error);
      return <dynamic>{};
    });
  }

  void handleError(error) {
    setState(() {
      result = error;
    });
  }

  void startTransactions() async {
    PhonePePaymentSdk.startTransaction(body, callback, checksum, "")
        .then((response) => {
      setState(() {
        if (response != null) {
          String status = response['status'].toString();
          String error = response['error'].toString();
          if (status == 'SUCCESS') {
            result = "Flow Completed - Status: Success!";
          } else {
            result =
            "Flow Completed - Status: $status and Error: $error";
          }
        } else {
          result = "Flow Incomplete";
        }
      })
    })

        .catchError((error) {
      handleError(error);
      return <dynamic>{};
    });
  }

  String getCheckSum() {
    final reqData = {
      "merchantId": merchantId,
      "merchantTransactionId": "MT7850590068188104",
      "merchantUserId": "MUID123",
      "amount": 1000,
      "callbackUrl": callback,
      "mobileNumber": "9999999999",
      "paymentInstrument": {"type": "PAY_PAGE"}
    };
    String encoded = base64.encode(utf8.encode(json.encode(reqData)));
    checksum = '${sha256.convert(utf8.encode(encoded+apiEndPoint+saltKey))}###$saltIndex';
    return encoded;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Payment Gateway"),
        backgroundColor: Color(0xFF009db5),
      ),
      body: Column(
        children: [
          Container(
            child: ElevatedButton(
              child: Text("Pay Now"),
              onPressed: () {
                startTransactions();
              },
            ),
          ),
          Text("$result"),
        ],
      ),
    );
  }
}

I'm using Flutter version 3.0.0, Dart 2.17.0.

This is my pubspec.yaml:

environment:
  sdk: ">=2.2.0 <3.0.0"

dependencies:
  crypto: ^3.0.2
  phonepe_payment_sdk: ^2.0.1

and Added the below mentioned part in android/build.gradle

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url  "https://phonepe.mycloudrepo.io/public/repositories/phonepe-intentsdk-android"
        }
    }
}

Upvotes: 1

Views: 310

Answers (1)

Mehran
Mehran

Reputation: 355

If you put this part of your code

PhonePePaymentSdk.init(environmentValue, appId, merchantId, enableLogging)
        .then((val) => {
              setState(() {
                result = 'PhonePe SDK Initialized - $val';
              })
            })
        .catchError((error) {
      handleError(error);
      return <dynamic>{};
    });

inside a variable, lets say foo, like this:

final foo = PhonePePaymentSdk.init(environmentValue, appId, merchantId, enableLogging)
    .then((val) => {
          setState(() {
            result = 'PhonePe SDK Initialized - $val';
          })
        })
    .catchError((error) {
  handleError(error);
  return <dynamic>{};
});

you can clearly see that foo's Type: Future<Set<void>>! so let's try something like this :

import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:flutter/material.dart';
import 'package:phonepe_payment_sdk/phonepe_payment_sdk.dart';

class PhonePePaymentScreen extends StatefulWidget {
  const PhonePePaymentScreen({super.key});

  @override
  State<PhonePePaymentScreen> createState() => _PhonePePaymentScreenState();
}

class _PhonePePaymentScreenState extends State<PhonePePaymentScreen> {
  @override
  void initState() {
    initiatePayment();
    body = getCheckSum().toString();
    super.initState();
  }

  String environmentValue = "SANDBOX";
  String appId = "";
  String merchantId = "PGTESTPAYUAT";
  bool enableLogging = true;
  String saltKey = "099eb0cd-02cf-4e2a-8aca-3e6c6aff0399";
  String saltIndex = "1";
  String callback = "https://webhook.site/ba843c01-f6a6-4076-8fba-24b5719b3f66";
  String apiEndPoint = "/pg/v1/pay";

  Object? result;
  String body = "";
  String checksum = "";

  //make this function of type Future and wait on the PhonePePaymentSdk.init
  Future<void> initiatePayment() async {
    await PhonePePaymentSdk.init(
            environmentValue, appId, merchantId, enableLogging)
        .then((val) => {
              setState(() {
                result = 'PhonePe SDK Initialized - $val';
              })
            })
        .catchError((error) {
      handleError(error);
      return <dynamic>{};
    });
  }

  void handleError(error) {
    setState(() {
      result = error;
    });
  }

  void startTransactions() async {
    PhonePePaymentSdk.startTransaction(body, callback, checksum, "")
        .then((response) => {
              setState(() {
                if (response != null) {
                  String status = response['status'].toString();
                  String error = response['error'].toString();
                  if (status == 'SUCCESS') {
                    result = "Flow Completed - Status: Success!";
                  } else {
                    result =
                        "Flow Completed - Status: $status and Error: $error";
                  }
                } else {
                  result = "Flow Incomplete";
                }
              })
            })
        .catchError((error) {
      handleError(error);
      return <dynamic>{};
    });
  }

  String getCheckSum() {
    final reqData = {
      "merchantId": merchantId,
      "merchantTransactionId": "MT7850590068188104",
      "merchantUserId": "MUID123",
      "amount": 1000,
      "callbackUrl": callback,
      "mobileNumber": "9999999999",
      "paymentInstrument": {"type": "PAY_PAGE"}
    };
    String encoded = base64.encode(utf8.encode(json.encode(reqData)));
    checksum =
        '${sha256.convert(utf8.encode(encoded + apiEndPoint + saltKey))}###$saltIndex';
    return encoded;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Payment Gateway"),
        backgroundColor: Color(0xFF009db5),
      ),
      body: Column(
        children: [
          Container(
            child: ElevatedButton(
              child: Text("Pay Now"),
              onPressed: () {
                startTransactions();
              },
            ),
          ),
          Text("$result"),
        ],
      ),
    );
  }
}

Update:

Try the steps below and let me know if they solve the issue or if you need further assistance:

1- run the flutter clean command

2- delete the pubspec.lock file from the root of your project

3- run the flutter pub get command

4- run the flutter run command

Upvotes: 0

Related Questions