Flutter电话功能扩展插件phone_pe_pg的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter电话功能扩展插件phone_pe_pg的使用

简介

phone_pe_pg 是一个用于在Flutter应用中集成PhonePe支付网关的插件。当前基于PhonePe SDK Less集成,仅支持Android和iOS平台。

准备工作

  • UAT测试:需要安装名为’PhonePe Simulator’的应用,并请求PhonePe团队提供。
  • 生产环境:需编写API来调用PhonePe支付API,并分享服务器IP给PhonePe团队以进行白名单设置。

开始使用

1. 添加依赖

pubspec.yaml文件中添加依赖:

dependencies:
  phone_pe_pg: ^0.0.1

2. 导入包

在Dart文件中导入插件:

import 'package:phone_pe_pg/phone_pe_pg.dart';

3. 初始化PhonePePG

PhonePePg phonePePg = PhonePePg(
    isUAT: true,
    saltKey: Secrets.saltKey,
    saltIndex: Secrets.saltIndex,
    prodUrl: yourapi/url
);

参数说明:

  • isUAT: 布尔值,决定使用UAT或生产环境。
  • saltKey: PhonePe提供的盐密钥。
  • saltIndex: PhonePe提供的盐索引。
  • prodUrl: 生产环境下的后端API URL。

支付请求

创建PaymentRequest对象并初始化:

PaymentRequest paymentRequest = PaymentRequest(
    amount: 100, // 金额(单位为INR)
    callbackUrl: 'https://www.xyx.com',
    deviceContext: DeviceContext.getDefaultDeviceContext(merchantCallBackScheme: merchantCallBackScheme),
    merchantId: 'MerchantID',
    merchantTransactionId: 'Random Transaction Id',
    merchantUserId: 'Random User Id',
    mobileNumber: 'Mobile Number',
    paymentInstrument: UpiIntentPaymentInstrument(targetApp: Platform.isAndroid ? selectedUPIApp.packageName! : selectedUPIApp.iOSAppName!)
);

UPI Intent支付

获取设备上安装的UPI应用列表:

List<UpiAppInfo> upiApps = await PhonePePg.getUpiApps();

启动UPI交易:

final result = await phonePePg.startUpiTransaction(paymentRequest: paymentRequest);

检查交易状态:

if (result.status == UpiPaymentStatus.success) {
    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Transaction Successful")));
} else if (result.status == UpiPaymentStatus.pending) {
    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Transaction Pending")));
} else {
    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Transaction Failed")));
}

Pay Page支付

启动Pay Page交易:

Navigator.push(context, MaterialPageRoute(builder: (context) => phonePePg.startPayPageTransaction(
    paymentRequest: paypageRequestModel(),
    onPaymentComplete: (paymentStatusResponse, error) {
        if (paymentStatusResponse != null && paymentStatusResponse.code == PaymentStatus.success) {
            ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Transaction Successful")));
        } else {
            ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Transaction Failed")));
        }
    },
    appBar: YourCustomAppBar() // Optional
)));

检查交易状态

final result = await phonePePg.checkStatus(
    merchantId: 'MerchantID',
    merchantTransactionId: 'Random Transaction Id',
);

示例代码

以下是完整的示例代码:

import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:phone_pe_pg/phone_pe_pg.dart';
import 'package:phone_pe_pg_example/keys.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  PhonePePg pePg = PhonePePg(
    isUAT: true,
    saltKey: Secrets.saltKey,
    saltIndex: Secrets.saltIndex,
  );

  PaymentRequest _paymentRequest({String? merchantCallBackScheme}) {
    String generateRandomString(int len) {
      const chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
      Random rnd = Random();
      return String.fromCharCodes(Iterable.generate(len, (_) => chars.codeUnitAt(rnd.nextInt(chars.length))));
    }

    return PaymentRequest(
      amount: 100,
      callbackUrl: Secrets.callbackUrl,
      deviceContext: DeviceContext.getDefaultDeviceContext(merchantCallBackScheme: merchantCallBackScheme),
      merchantId: Secrets.merchantId,
      merchantTransactionId: generateRandomString(10).toUpperCase(),
      merchantUserId: generateRandomString(8).toUpperCase(),
      mobileNumber: Secrets.userMobileNumber,
    );
  }

  PaymentRequest upipaymentRequest(UpiAppInfo e, {String? merchantCallBackScheme}) =>
      _paymentRequest(merchantCallBackScheme: merchantCallBackScheme).copyWith(
          paymentInstrument: UpiIntentPaymentInstrument(
        targetApp: Platform.isAndroid ? e.packageName! : e.iOSAppName!,
      ));

  PaymentRequest paypageRequestModel({String? merchantCallBackScheme}) =>
      _paymentRequest(merchantCallBackScheme: merchantCallBackScheme).copyWith(
          redirectUrl: Secrets.redirectUrl,
          redirectMode: 'GET',
          paymentInstrument: PayPagePaymentInstrument());

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: const Text('Plugin example app'),
          ),
          body: FutureBuilder<List<UpiAppInfo>?>(
            future: PhonePePg.getUpiApps(iOSUpiApps: [
              UpiAppInfo(appName: "PhonePe", packageName: "ppe", appIcon: Uint8List(0), iOSAppName: "PHONEPE", iOSAppScheme: 'ppe'),
              UpiAppInfo(appName: "Google Pay", packageName: "gpay", appIcon: Uint8List(0), iOSAppName: "GPAY", iOSAppScheme: 'gpay'),
              UpiAppInfo(appName: "Paytm", packageName: "paytmmp", appIcon: Uint8List(0), iOSAppName: "PAYTM", iOSAppScheme: 'paytmmp'),
            ]),
            builder: (context, snapshot) {
              if (snapshot.hasData && snapshot.data != null) {
                return ListView(children: [
                  ...snapshot.data!.map((e) => ListTile(
                        onTap: () async {
                          pePg.startUpiTransaction(paymentRequest: upipaymentRequest(e)).then((response) {
                            if (response.status == UpiPaymentStatus.success) {
                              ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Transaction Successful")));
                            } else if (response.status == UpiPaymentStatus.pending) {
                              ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Transaction Pending")));
                            } else {
                              ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Transaction Failed")));
                            }
                          }).catchError((e) {
                            ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Transaction Failed")));
                          });
                        },
                        leading: Image.memory(e.appIcon, errorBuilder: (context, error, stackTrace) => const Icon(Icons.error)),
                        title: Text(e.appName),
                        subtitle: Text(e.packageName ?? e.iOSAppName!),
                      )).toList(),
                  ListTile(
                    title: const Text("Card/Net Banking"),
                    onTap: () {
                      Navigator.push(context, MaterialPageRoute(builder: (_) => pePg.startPayPageTransaction(
                            onPaymentComplete: (paymentResponse, paymentError) {
                              Navigator.pop(context);
                              if (paymentResponse != null && paymentResponse.code == PaymentStatus.success) {
                                ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Transaction Successful")));
                              } else {
                                ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Transaction Failed")));
                              }
                            },
                            paymentRequest: paypageRequestModel(),
                          )));
                    },
                  )
                ]);
              }
              return const Center(child: CircularProgressIndicator());
            },
          )),
    );
  }
}

以上内容详细介绍了如何在Flutter项目中使用phone_pe_pg插件实现PhonePe支付功能,包括UPI Intent支付和Pay Page支付的完整示例代码。


更多关于Flutter电话功能扩展插件phone_pe_pg的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter电话功能扩展插件phone_pe_pg的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于Flutter中的phone_pe_pg插件(这个插件名称可能是一个假设或特定项目的插件,因为常见的Flutter电话功能插件一般是url_launcher用于拨打电话等),我会提供一个假设性的使用案例代码。由于phone_pe_pg不是官方或广泛认知的插件,以下代码将基于一个假想的插件功能,即拨打电话和获取设备电话信息。

首先,确保你已经在pubspec.yaml文件中添加了该插件的依赖(假设插件名称是phone_pe_pg):

dependencies:
  flutter:
    sdk: flutter
  phone_pe_pg: ^x.y.z  # 替换为实际的版本号

然后,运行flutter pub get来安装插件。

接下来,在你的Dart代码中,你可以这样使用phone_pe_pg插件:

import 'package:flutter/material.dart';
import 'package:phone_pe_pg/phone_pe_pg.dart'; // 导入插件

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Phone PE PG Plugin Demo'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: _makePhoneCall,
                child: Text('Make Phone Call'),
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: _getDeviceInfo,
                child: Text('Get Device Phone Info'),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _makePhoneCall() async {
    try {
      // 假设插件提供了一个拨打电话的方法
      await PhonePePg.makeCall("tel:+1234567890");
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Call initiated')));
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Failed to initiate call: $e')));
    }
  }

  Future<void> _getDeviceInfo() async {
    try {
      // 假设插件提供了一个获取设备电话信息的方法
      PhoneInfo phoneInfo = await PhonePePg.getPhoneInfo();
      String infoMessage = 'Phone Number: ${phoneInfo.phoneNumber}\n'
                           'IMEI: ${phoneInfo.imei}\n'
                           'Sim Serial Number: ${phoneInfo.simSerialNumber}';
      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: Text('Device Phone Info'),
            content: Text(infoMessage),
            actions: <Widget>[
              ElevatedButton(
                onPressed: () => Navigator.of(context).pop(),
                child: Text('OK'),
              ),
            ],
          );
        },
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Failed to get phone info: $e')));
    }
  }
}

// 假设的PhoneInfo类,用于存储设备信息
class PhoneInfo {
  final String phoneNumber;
  final String imei;
  final String simSerialNumber;

  PhoneInfo({required this.phoneNumber, required this.imei, required this.simSerialNumber});
}

// 假设的PhonePePg类,用于提供插件功能
class PhonePePg {
  static Future<void> makeCall(String phoneNumber) async {
    // 插件内部实现拨打电话的逻辑
    // 这里只是模拟调用
    throw UnsupportedError('makeCall method is not implemented in this demo.');
  }

  static Future<PhoneInfo> getPhoneInfo() async {
    // 插件内部实现获取设备信息的逻辑
    // 这里只是模拟返回一些数据
    return PhoneInfo(
      phoneNumber: '123-456-7890', // 模拟电话号码
      imei: '123456789012345',    // 模拟IMEI号
      simSerialNumber: '987654321098765', // 模拟SIM卡序列号
    );
  }
}

请注意,上面的代码中的PhonePePg类和PhoneInfo类是基于假设的,因为实际的phone_pe_pg插件可能有不同的API和实现。你应该参考插件的官方文档来了解其真实的方法和属性。

此外,由于获取设备的电话号码、IMEI等信息可能涉及用户隐私,因此在实际应用中需要确保遵守相关的隐私政策和法律法规。在iOS和Android上,获取这些信息通常需要用户的明确授权。

回到顶部