Flutter支付集成插件phonepe_pg_htkc的使用

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

Flutter支付集成插件phonepe_pg_htkc的使用

PhonePe PG HTKC 是一个可重用的 Flutter 包,用于在任何 Flutter 项目中集成 PhonePe 支付网关。

特性

PhonePe 支付网关完整的流程集成到 Flutter 应用中,并包含支付状态。

其他特性 Laravel 响应逻辑

public function response(Request $request)
{
    $input = $request->all();
    $saltKey = '099eb0cd-02cf-4e2a-8aca-3e6c6aff0399';
    $saltIndex = 1;

    $finalXHeader = hash('sha256','/pg/v1/status/'.$input['merchantId'].'/'.$input['transactionId'].$saltKey).'###'.$saltIndex;

    $response = Curl::to('https://api.phonepe.com/apis/hermes/pg/v1/status/'.$input['merchantId'].'/'.$input['transactionId'])
            ->withHeader('Content-Type:application/json')
            ->withHeader('accept:application/json')
            ->withHeader('X-VERIFY:'.$finalXHeader)
            ->withHeader('X-MERCHANT-ID:'.$input['merchantId'])
            ->get();

    return $response;
}

Laravel 发起支付逻辑

public function phonePe()
{
    $data = array (
      'merchantId' => 'PGTESTPAYUAT',
      'merchantTransactionId' => uniqid(),
      'merchantUserId' => 'MERCHANTUSERID1',
      'amount' => 100,
      'redirectUrl' => route('response'),
      'redirectMode' => 'POST',
      'callbackUrl' => route('response'),
      'mobileNumber' => '9999999999',
      'paymentInstrument' =>
      array (
        'type' => 'PAY_PAGE',
      ),
    );

    $encode = base64_encode(json_encode($data));

    $saltKey = '099eb0cd-02cf-4e2a-8aca-3e6c6aff0399';
    $saltIndex = 1;

    $string = $encode.'/pg/v1/pay'.$saltKey;
    $sha256 = hash('sha256',$string);

    $finalXHeader = $sha256.'###'.$saltIndex;

    $response = Curl::to('https://api.phonepe.com/apis/hermes/pg/v1/pay')
            ->withHeader('Content-Type:application/json')
            ->withHeader('X-VERIFY:'.$finalXHeader)
            ->withData(json_encode(['request' => $encode]))
            ->post();

    $rData = json_decode($response);

    return redirect()->to($rData->data->instrumentResponse->redirectInfo->url);
}

开始使用

创建你的项目并遵循以下说明。

使用方法

示例

要使用此包:

  • pubspec.yaml 文件中添加依赖项:
dependencies:
  flutter:
    sdk: flutter
  phonepe_pg_htkc: 

添加到 Dart 文件

import 'package:example/controllers/pg_payment_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:nb_utils/nb_utils.dart';

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo PhonePe',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo PhonePe PG'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final controller = Get.put(PGPaymentController());
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Obx(() => Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'PhonePe Payment Gateway Integration',
            ),
            MaterialButton(
              onPressed: () {
                controller.initPayment(customerMobile: '+919876543210', amount: 100);
              },
              color: greenColor,
              child: Text(
                'Pay Now',
                style: boldTextStyle(color: white),
              ),
            ),
            50.height,
            Visibility(
              visible: !controller.isVisible.value,
              child: MaterialButton(
                onPressed: () {
                  controller.checkPaymentStatus();
                },
                color: greenColor,
                child: Text(
                  'Check Status',
                  style: boldTextStyle(color: white),
                ),
              ),
            ),
          ],
        ),
      ),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

控制器逻辑

import 'package:get/get.dart';
import 'package:nb_utils/nb_utils.dart';
import 'package:phonepe_pg_htkc/models/pg_payment_status_model.dart';
import 'package:phonepe_pg_htkc/phonepe_pg_htkc.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:uuid/uuid.dart';

class PGPaymentController extends GetxController {
  var isLoading = false.obs;
  var isVisible = true.obs;
  var errorMsg = ''.obs;
  var merchantTransactionId = ''.obs;
  var paymentStatusResponse = List<PGPaymentStatusResponse>.empty().obs;
  Uuid uuid = const Uuid();

  void checkPaymentStatus() async {
    try {
      isLoading(true);
      var data = await PhonePeApiServices.checkTransactionStatus(merchantTransactionId.value);
      if (data != null) {
        if(data.code=='PAYMENT_SUCCESS'){
          toast('Payment Success!!');
        } else if(data.code=='PAYMENT_PENDING'){
          toast('Please complete payment process!!!');
        }  else if(data.code=='PAYMENT_ERROR'){
          isVisible(true);
          toast('Payment failed! Please try again!');
        }
      } else {
        isVisible(true);
        toast('Transaction failed! Please try again!');
      }
    } finally {
      isLoading(false);
    }
  }

  Future<bool> initPayment({
    required String customerMobile,
    required double amount}) async {
    merchantTransactionId.value = uuid.v1();
    try {
      isLoading(true);
      var paymentResponse = await PhonePeApiServices.initTransaction(merchantTransactionId.value, customerMobile, amount);
      if (paymentResponse != null) {
        await launchUrl(Uri.parse(paymentResponse.data.instrumentResponse.redirectInfo.url),mode: LaunchMode.externalNonBrowserApplication);
        isVisible(false);
        return true;
      } else {
        toast('Something went wrong! Please try again later');
        return true;
      }
    } finally {
      isLoading(false);
    }
  }
}

更多关于Flutter支付集成插件phonepe_pg_htkc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter支付集成插件phonepe_pg_htkc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中集成并使用phonepe_pg_htkc插件的示例代码。这个插件通常用于集成PhonePe支付网关。请注意,由于我无法直接访问外部库或实时环境,以下代码示例是基于假设的API和插件使用方法。在实际项目中,你需要参考插件的官方文档和API说明进行调整。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加phonepe_pg_htkc依赖:

dependencies:
  flutter:
    sdk: flutter
  phonepe_pg_htkc: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来安装依赖。

2. 配置Android和iOS

根据你使用的平台,你可能需要在AndroidManifest.xmlInfo.plist中添加一些必要的配置。具体配置请参考插件的官方文档。

3. 初始化插件并进行支付

在你的Flutter应用中,你可以这样初始化并使用phonepe_pg_htkc插件:

import 'package:flutter/material.dart';
import 'package:phonepe_pg_htkc/phonepe_pg_htkc.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('PhonePe Payment Integration'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              // 替换为实际的配置参数
              String merchantId = '你的商户ID';
              String transactionId = '你的交易ID';
              String amount = '交易金额'; // 注意格式,例如 "100.00"
              String currencyCode = 'INR';
              String callbackUrl = '你的回调URL';
              Map<String, String> additionalData = {
                'key1': 'value1',
                // 添加其他需要的附加数据
              };

              try {
                // 初始化插件
                PhonepePgHtkc phonepePgHtkc = PhonepePgHtkc();

                // 发起支付请求
                bool result = await phonepePgHtkc.initiatePayment(
                  merchantId: merchantId,
                  transactionId: transactionId,
                  amount: amount,
                  currencyCode: currencyCode,
                  callbackUrl: callbackUrl,
                  additionalData: additionalData,
                );

                if (result) {
                  // 支付成功处理
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('支付成功')),
                  );
                } else {
                  // 支付失败处理
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('支付失败')),
                  );
                }
              } catch (e) {
                // 异常处理
                print('支付过程中发生错误: $e');
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('支付过程中发生错误')),
                );
              }
            },
            child: Text('发起支付'),
          ),
        ),
      ),
    );
  }
}

注意事项

  1. 安全性:确保你的商户ID、交易ID等敏感信息不会硬编码在客户端代码中,而是通过安全的后端服务提供。
  2. 错误处理:在实际应用中,你应该有更详细的错误处理和用户反馈机制。
  3. 测试:在发布前,务必在沙箱或测试环境中充分测试支付流程。
  4. 更新:定期检查并更新插件到最新版本,以确保安全性和功能的最新性。

请根据你的具体需求和插件的官方文档调整上述代码。

回到顶部