Flutter移动支付插件mpesa的使用

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

Flutter移动支付插件mpesa的使用

简介

mpesa 是一个围绕 mpesa daraja api 的 Dart 包装器。当前支持的部分方法/API如下:

  • ✅ LIPA NA MPESA
  • ❌ C2BSIMULATE
  • ❌ B2B
  • ❌ C2B
  • ❌ B2C
  • ❌ TRANSACTION STATUS
  • ❌ ACCOUNT BALANCE
  • ❌ REVERSAL

准备工作

在开始开发之前,你需要从Safaricom获取以下信息:

  1. Consumer Key
  2. Consumer Secret
  3. 测试凭据(用于开发/沙箱环境)

获取这些信息的步骤:

  1. 如果你还没有,请登录或注册成为Safaricom开发者这里
  2. 在此处添加新应用这里
  3. 你会收到一个Consumer Key和Consumer Secret。这些将用于初始化Mpesa实例。
  4. 获取测试凭据这里
    • 注意:获得的测试凭据仅在沙箱/开发环境中有效。
    • 若要在生产环境中运行,你需要真实的凭据。要上线并获得真实凭据,请参考此指南

开始使用

添加依赖

pubspec.yaml 文件中添加依赖:

dependencies:
  mpesa: [ADD_LATEST_VERSION_HERE]

导入包

在你的Flutter应用程序或纯Dart应用程序中导入:

import 'package:mpesa/mpesa.dart';

class MyClass {
    Mpesa mpesa = Mpesa(
        clientKey: "YOUR_CONSUMER_KEY_HERE",
        clientSecret: "YOUR_CONSUMER_SECRET_HERE",
        passKey: "YOUR_LNM_PASS_KEY_HERE",
        environment: "sandbox", // 或者 'production'
    );
}

方法和API调用

Lipa Na Mpesa Online (LNMO)

Lipa na M-Pesa Online Payment API用于代表客户发起M-Pesa交易,使用STK Push。这是mySafaricom App用来进行支付的相同技术。

示例代码:

import 'package:mpesa/mpesa.dart';

void main() {
  final mpesa = Mpesa(
    clientKey: "YOUR_CONSUMER_KEY_HERE",
    clientSecret: "YOUR_CONSUMER_SECRET_HERE",
    passKey: "YOUR_LNM_PASS_KEY_HERE",
    environment: "sandbox",
  );

  mpesa
      .lipaNaMpesa(
        phoneNumber: "2547XXXXXXXX", // 用户手机号码
        amount: 1, // 支付金额
        businessShortCode: "短码", // 商家短码
        callbackUrl: "http://yourcallbackurl.com/callback", // 回调URL
      )
      .then((result) {
        print('Transaction result: $result');
      })
      .catchError((error) {
        print('Transaction error: $error');
      });
}

参数说明:

  • businessShortCode: 接收交易的组织短码。
  • amount: 要交易的金额。
  • phoneNumber: 发送资金的MSISDN。
  • callbackUrl: M-Pesa响应将发送到的URL。

完整示例Demo

下面是一个完整的Flutter示例项目,演示如何集成mpesa支付功能:

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Mpesa Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final Mpesa _mpesa = Mpesa(
    clientKey: "YOUR_CONSUMER_KEY_HERE",
    clientSecret: "YOUR_CONSUMER_SECRET_HERE",
    passKey: "YOUR_LNM_PASS_KEY_HERE",
    environment: "sandbox",
  );

  void _makePayment() {
    _mpesa
        .lipaNaMpesa(
          phoneNumber: "2547XXXXXXXX",
          amount: 1,
          businessShortCode: "短码",
          callbackUrl: "http://yourcallbackurl.com/callback",
        )
        .then((result) {
          ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Transaction successful: $result')));
        })
        .catchError((error) {
          ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Transaction failed: $error')));
        });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Mpesa Payment Demo'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: _makePayment,
          child: Text('Make Payment'),
        ),
      ),
    );
  }
}

这个示例展示了如何在Flutter应用中使用mpesa插件发起支付请求,并处理结果。请确保替换示例中的占位符为你自己的实际值。


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

1 回复

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


在处理Flutter应用中集成MPesa移动支付插件时,通常需要使用MPesa提供的SDK或者API接口。由于MPesa的官方SDK可能并不直接支持Flutter,你可能需要通过原生平台通道(Platform Channels)来与MPesa的Android和iOS SDK进行交互。

以下是一个简化的代码示例,展示了如何在Flutter中通过平台通道调用MPesa支付功能。注意,这只是一个概念性的示例,实际实现可能需要根据MPesa的具体SDK和API文档进行调整。

1. 设置Flutter项目

首先,确保你的Flutter项目已经创建并设置好。

2. 创建MPesa原生插件

iOS部分

ios/Runner目录下创建一个新的Objective-C/Swift类来封装MPesa的SDK调用。

MPesaPaymentHandler.swift

import Foundation
import UIKit
// 假设MPesa有一个名为MPesaSDK的框架
// import MPesaSDK

@objc(MPesaPaymentHandler)
class MPesaPaymentHandler: NSObject, FlutterPlatformView {
    
    private let methodChannel: FlutterMethodChannel
    
    init(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?, binaryMessenger messenger: FlutterBinaryMessenger) {
        methodChannel = FlutterMethodChannel(name: "mpesa_payment", binaryMessenger: messenger)
        super.init()
        
        methodChannel.setMethodCallHandler({ [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) in
            guard let strongSelf = self else {
                result(FlutterError(code: "channel_destroyed", message: "The MPesa payment channel was destroyed", details: nil))
                return
            }
            
            if call.method == "initiatePayment" {
                guard let args = call.arguments as? [String: Any],
                      let phoneNumber = args["phoneNumber"] as? String,
                      let amount = args["amount"] as? Double,
                      let callbackUrl = args["callbackUrl"] as? String else {
                    result(FlutterError(code: "invalid_arguments", message: "Invalid arguments passed to initiatePayment", details: nil))
                    return
                }
                
                // 调用MPesa SDK的支付方法
                // MPesaSDK.initiatePayment(phoneNumber: phoneNumber, amount: amount, callbackUrl: callbackUrl) { success, error in
                //     if success {
                //         result(success)
                //     } else {
                //         result(FlutterError(code: "payment_failed", message: error?.localizedDescription ?? "Payment failed", details: nil))
                //     }
                // }
                
                // 由于MPesa SDK的具体实现未知,这里用占位代码表示
                let success = true // 假设支付成功
                if success {
                    result(success)
                } else {
                    result(FlutterError(code: "payment_failed", message: "Payment failed", details: nil))
                }
                
            } else {
                result(FlutterMethodNotImplemented)
            }
        })
    }
    
    // FlutterPlatformView methods
    func view() -> UIView? {
        return nil // 因为我们不需要显示任何UI组件
    }
}

注意:上面的代码中MPesaSDK的调用部分被注释掉了,因为具体的MPesa SDK调用方式未知。你需要根据MPesa的官方文档来替换这部分代码。

Android部分

android/app/src/main/java/com/yourapp/package/目录下创建一个新的Kotlin/Java类来封装MPesa的SDK调用。

MPesaPaymentHandler.kt

package com.yourapp.package

import android.content.Context
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result

// 假设MPesa有一个名为MPesaSDK的库
// import com.mpesa.sdk.MPesaSDK

class MPesaPaymentHandler(private val context: Context) : FlutterPlugin, MethodCallHandler, ActivityAware {

    private var channel: MethodChannel? = null
    private var activity: android.app.Activity? = null

    override fun onAttachedToEngine(binding: FlutterPluginBinding) {
        channel = MethodChannel(binding.binaryMessenger, "mpesa_payment")
        channel?.setMethodCallHandler(this)
    }

    override fun onMethodCall(call: MethodCall, result: Result) {
        if (call.method == "initiatePayment") {
            val arguments = call.arguments as? Map<String, Any>
            val phoneNumber = arguments?.get("phoneNumber") as? String
            val amount = arguments?.get("amount") as? Double
            val callbackUrl = arguments?.get("callbackUrl") as? String

            arguments?.let {
                // 调用MPesa SDK的支付方法
                // MPesaSDK.initiatePayment(context, phoneNumber, amount, callbackUrl) { success, error ->
                //     if (success) {
                //         result.success(null)
                //     } else {
                //         result.error("payment_failed", error?.message ?: "Payment failed", null)
                //     }
                // }

                // 由于MPesa SDK的具体实现未知,这里用占位代码表示
                val success = true // 假设支付成功
                if (success) {
                    result.success(null)
                } else {
                    result.error("payment_failed", "Payment failed", null)
                }
            } ?: result.error("invalid_arguments", "Invalid arguments passed to initiatePayment", null)
        } else {
            result.notImplemented()
        }
    }

    override fun onDetachedFromEngine(binding: FlutterPluginBinding) {
        channel?.setMethodCallHandler(null)
        channel = null
    }

    override fun onAttachedToActivity(binding: ActivityPluginBinding) {
        activity = binding.activity
    }

    override fun onDetachedFromActivityForConfigChanges() {
        activity = null
    }

    override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
        activity = binding.activity
    }

    override fun onDetachedFromActivity() {
        activity = null
    }
}

同样,上面的代码中MPesaSDK的调用部分被注释掉了,你需要根据MPesa的官方文档来替换这部分代码。

3. 在Flutter中调用MPesa支付功能

在你的Flutter项目中,你可以通过MethodChannel来调用上面定义的MPesa支付功能。

main.dart

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

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

class MyApp extends StatelessWidget {
  static const platform = MethodChannel('mpesa_payment');

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('MPesa Payment Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: _initiatePayment,
            child: Text('Initiate Payment'),
          ),
        ),
      ),
    );
  }

  Future<void> _initiatePayment() async {
    try {
      final Map<String, dynamic> result = await platform.invokeMethod('initiatePayment', <String, dynamic>{
        'phoneNumber': '254712345678',
        'amount': 100.0,
        'callbackUrl': 'https://yourcallbackurl.com',
      });
      
      // 处理支付结果
      print('Payment result: $result');
    } on PlatformException catch (e) {
      print("Failed to initiate payment: '${e.message}'.");
    }
  }
}

总结

上面的代码示例展示了如何在Flutter项目中通过平台通道调用MPesa支付功能。由于MPesa的具体SDK和API调用方式未知,代码中的MPesa SDK调用部分被注释掉了,你需要根据MPesa的官方文档来替换这些部分。同时,确保你已经按照MPesa的要求配置了必要的权限和API密钥。

回到顶部