1. 引言

随着鸿蒙生态(HarmonyOS)的快速发展,越来越多的跨平台应用选择基于 Flutter 开发鸿蒙应用。支付功能作为移动应用商业化的核心环节,其稳定性、兼容性和安全性直接影响用户体验与业务转化。鸿蒙系统不仅支持原生华为支付(HMS Core In-App Purchases),还通过兼容层适配了微信支付、支付宝等主流第三方支付,为开发者提供了多元化的支付解决方案。

本文将从实战角度出发,详细讲解如何在鸿蒙 Flutter 应用中集成华为支付与微信 / 支付宝支付,涵盖环境搭建、权限配置、核心流程实现、订单验证、异常处理等关键环节,提供完整的代码示例、配置步骤和官方文档链接,帮助开发者快速落地支付功能,适配鸿蒙全场景设备(手机、平板、智慧屏等)。

1.1 核心价值

  • 跨平台一致性:基于 Flutter 实现一次开发,同时适配鸿蒙、Android、iOS 等平台,降低多端开发成本;
  • 生态原生支持:华为支付深度集成鸿蒙系统,无需额外兼容层,支付流程更流畅;
  • 主流支付全覆盖:同步适配微信 / 支付宝,满足不同用户的支付习惯;
  • 安全性保障:遵循鸿蒙系统安全规范与第三方支付风控要求,确保交易安全。

1.2 适用场景

  • 鸿蒙生态下的电商、订阅类、工具类 Flutter 应用;
  • 需要支持多支付方式的跨平台应用;
  • 追求支付流程稳定性与用户体验的商业应用。

1.3 前置知识

  • 熟悉 Flutter 基础开发(Widget、状态管理、异步编程);
  • 了解鸿蒙应用开发基本流程(Ability、配置文件、权限申请);
  • 掌握 HTTP 网络请求与 JSON 解析;
  • 拥有华为开发者账号、微信开放平台账号、支付宝开放平台账号。

2. 开发环境准备

2.1 基础环境配置

工具 / 依赖 版本要求 下载链接
鸿蒙 SDK 6.0 及以上(API Version 9+) 鸿蒙开发者官网
DevEco Studio 4.0 及以上 DevEco Studio 下载
Flutter 3.10 及以上 Flutter 官网
Dart 3.0 及以上 随 Flutter 自带
HMS Core SDK 6.10.0 及以上 HMS Core 开发者文档

2.2 账号与应用配置

2.2.1 华为开发者账号配置
  1. 注册并登录 华为开发者联盟
  2. 进入「应用市场」→「应用管理」,创建鸿蒙应用(需填写应用名称、包名、签名信息等);
  3. 开通「HMS Core 服务」→「应用内支付(IAP)」,并完成商户实名认证;
  4. 下载应用配置文件 agconnect-services.json(后续放入 Flutter 项目)。
2.2.2 微信开放平台配置
  1. 注册并登录 微信开放平台
  2. 创建「移动应用」,填写应用名称、包名、签名(需与鸿蒙应用签名一致);
  3. 开通「微信支付」功能,获取 AppIDMchid(商户号)、ApiKey(支付密钥)。
2.2.3 支付宝开放平台配置
  1. 注册并登录 支付宝开放平台
  2. 创建「移动应用」,完成应用签约与实名认证;
  3. 开通「手机网站支付」或「APP 支付」功能,获取 AppID私钥支付宝公钥

2.3 Flutter 项目初始化

  1. 创建 Flutter 项目(支持鸿蒙平台):

bash

运行

flutter create --platforms=harmonyos,android,ios flutter_harmony_payment
cd flutter_harmony_payment
  1. 配置鸿蒙平台支持(DevEco Studio 中):
    • 打开项目根目录的 harmonyos 文件夹,用 DevEco Studio 打开;
    • 在 build.gradle 中配置鸿蒙 SDK 版本:

groovy

ohos {
    compileSdkVersion 9
    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 9
    }
}
  1. 导入华为配置文件:将 agconnect-services.json 放入 harmonyos/app/src/main 目录。

2.4 依赖库集成

在 pubspec.yaml 中添加核心依赖库,执行 flutter pub get 安装:

yaml

dependencies:
  flutter:
    sdk: flutter

  # 华为支付(HMS Core IAP)
  huawei_iap: ^6.10.0+300  # 最新版本参考官网
  # 华为 AGConnect 核心库
  agconnect_core: ^1.6.0+300

  # 微信支付(支持鸿蒙/Android/iOS)
  fluwx: ^4.7.0  # 跨平台微信支付插件
  # 支付宝(支持鸿蒙/Android/iOS)
  flutter_alipay: ^2.2.0  # 支付宝 Flutter 插件

  # 网络请求
  dio: ^5.4.0
  # JSON 解析
  json_serializable: ^6.7.1
  build_runner: ^2.4.6
  # 加密(订单签名)
  crypto: ^3.0.3
  # 本地存储(支付状态缓存)
  shared_preferences: ^2.2.2

3. 华为支付(HMS Core IAP)集成

华为支付(IAP)是鸿蒙生态原生支付解决方案,适用于虚拟商品(如会员、道具)和实体商品支付,支持一次性购买、订阅等场景。以下是完整集成流程:

3.1 核心概念说明

  • 商品类型
    • 消耗型商品(Consumable):如游戏币,购买后可重复购买;
    • 非消耗型商品(Non-consumable):如永久解锁功能,购买后永久生效;
    • 订阅型商品(Subscription):如月度会员,定期自动续费。
  • 支付流程:应用请求商品列表 → 用户选择商品 → 发起支付 → 华为支付回调 → 验证订单 → 发放商品。

3.2 配置步骤

  1. 在 DevEco Studio 中,打开 harmonyos/app/src/main/config.json,添加华为支付权限:

json

"module": {
  "abilities": [...],
  "reqPermissions": [
    {
      "name": "ohos.permission.INTERNET"  // 网络权限(必选)
    },
    {
      "name": "com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"  // 华为应用市场权限
    }
  ]
}
  1. 配置 build.gradle(模块级),添加华为 Maven 仓库:

groovy

repositories {
    maven { url 'https://developer.huawei.com/repo/' }
}

dependencies {
    implementation 'com.huawei.hms:iap:6.10.0.300'
    implementation 'com.huawei.agconnect:agconnect-core-harmonyos:1.6.0.300'
}

3.3 核心代码实现

3.3.1 初始化华为 IAP

创建 huawei_payment_service.dart,封装支付核心逻辑:

dart

import 'package:huawei_iap/huawei_iap.dart';
import 'package:agconnect_core/agconnect_core.dart';

class HuaweiPaymentService {
  // 初始化 AGConnect 和 IAP
  Future<void> init() async {
    try {
      // 初始化 AGConnect(需传入 agconnect-services.json 配置)
      await AGConnectCore.instance.initialize();
      // 检查华为移动服务(HMS)是否可用
      final isHmsAvailable = await HuaweiIap.isHmsAvailable();
      if (!isHmsAvailable) {
        throw Exception("HMS Core 未安装或不可用");
      }
      print("华为 IAP 初始化成功");
    } catch (e) {
      print("华为 IAP 初始化失败:$e");
      rethrow;
    }
  }

  // 查询商品列表(需在华为开发者后台配置商品)
  Future<List<ProductInfo>> queryProducts(List<String> productIds) async {
    try {
      final productDetailReq = ProductDetailReq(
        productIds: productIds,
        priceType: PriceType.IN_APP_CONSUMABLE,  // 商品类型(消耗型)
      );
      final result = await HuaweiIap.queryProductDetails(productDetailReq);
      if (result.returnCode == 0 && result.productDetails != null) {
        return result.productDetails!;
      } else {
        throw Exception("查询商品失败:${result.errorMessage}");
      }
    } catch (e) {
      print("查询商品异常:$e");
      rethrow;
    }
  }

  // 发起支付请求
  Future<PurchaseResultInfo> launchPayment(String productId) async {
    try {
      // 1. 先查询商品详情
      final products = await queryProducts([productId]);
      if (products.isEmpty) {
        throw Exception("商品不存在:$productId");
      }
      final product = products.first;

      // 2. 创建订单请求
      final purchaseReq = PurchaseIntentReq(
        productId: product.productId,
        priceType: PriceType.IN_APP_CONSUMABLE,
        developerPayload: "custom_data_${DateTime.now().millisecondsSinceEpoch}",  // 自定义参数(如用户ID)
      );

      // 3. 发起支付
      final result = await HuaweiIap.createPurchaseIntent(purchaseReq);
      if (result.returnCode == 0 && result.purchaseResultInfo != null) {
        return result.purchaseResultInfo!;
      } else {
        throw Exception("支付请求失败:${result.errorMessage}");
      }
    } catch (e) {
      print("支付异常:$e");
      rethrow;
    }
  }

  // 验证订单(服务端验证,推荐)
  Future<bool> verifyOrder(PurchaseResultInfo purchaseResult) async {
    try {
      // 客户端验证(仅用于测试,生产环境需走服务端)
      final verifyReq = InAppPurchaseDataVerifyReq(
        purchaseData: purchaseResult.inAppPurchaseData,
        signature: purchaseResult.dataSignature,
      );
      final verifyResult = await HuaweiIap.verifyPurchaseIntent(verifyReq);
      if (verifyResult.returnCode == 0 && verifyResult.isSuccess) {
        print("订单验证成功:${purchaseResult.orderId}");
        return true;
      } else {
        print("订单验证失败:${verifyResult.errorMessage}");
        return false;
      }

      // 生产环境服务端验证示例(需后端对接华为 IAP 验证接口)
      // final response = await dio.post(
      //   "https://your-server.com/verify-huawei-order",
      //   data: {
      //     "purchaseData": purchaseResult.inAppPurchaseData,
      //     "signature": purchaseResult.dataSignature,
      //     "orderId": purchaseResult.orderId,
      //   },
      // );
      // return response.data["success"];
    } catch (e) {
      print("订单验证异常:$e");
      return false;
    }
  }
}
3.3.2 页面调用示例

创建 huawei_payment_page.dart,实现商品列表与支付触发:

dart

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

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

  @override
  State<HuaweiPaymentPage> createState() => _HuaweiPaymentPageState();
}

class _HuaweiPaymentPageState extends State<HuaweiPaymentPage> {
  final HuaweiPaymentService _paymentService = HuaweiPaymentService();
  List<ProductInfo> _products = [];
  bool _isLoading = false;

  @override
  void initState() {
    super.initState();
    _initPayment();
    _loadProducts();
  }

  Future<void> _initPayment() async {
    try {
      await _paymentService.init();
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("华为支付初始化失败:$e")),
      );
    }
  }

  Future<void> _loadProducts() async {
    setState(() => _isLoading = true);
    try {
      // 商品 ID 需在华为开发者后台提前配置
      final productIds = ["com.example.coins.10", "com.example.coins.100"];
      _products = await _paymentService.queryProducts(productIds);
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("加载商品失败:$e")),
      );
    } finally {
      setState(() => _isLoading = false);
    }
  }

  Future<void> _onPay(String productId) async {
    setState(() => _isLoading = true);
    try {
      final purchaseResult = await _paymentService.launchPayment(productId);
      // 验证订单
      final isVerified = await _paymentService.verifyOrder(purchaseResult);
      if (isVerified) {
        // 订单验证成功,发放商品(如增加用户余额)
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text("支付成功!订单号:${purchaseResult.orderId}")),
        );
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text("支付成功,但订单验证失败")),
        );
      }
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("支付失败:$e")),
      );
    } finally {
      setState(() => _isLoading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("华为支付")),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : ListView.builder(
              itemCount: _products.length,
              itemBuilder: (context, index) {
                final product = _products[index];
                return ListTile(
                  title: Text(product.productName),
                  subtitle: Text("价格:${product.price}"),
                  trailing: ElevatedButton(
                    onPressed: () => _onPay(product.productId),
                    child: const Text("立即购买"),
                  ),
                );
              },
            ),
    );
  }
}

3.4 关键注意事项

  1. 商品配置:需在华为开发者后台「应用内支付」→「商品管理」中创建商品,商品 ID 需与代码中一致;
  2. 订单验证:生产环境必须通过服务端验证(参考 华为 IAP 订单验证文档),客户端验证仅用于测试;
  3. 退款处理:华为支付支持用户发起退款,应用需监听退款回调(通过 HuaweiIap.observeRefund()),并同步更新用户权益;
  4. 兼容性:确保用户设备安装了最新版本的 HMS Core,否则会导致支付失败。

4. 第三方支付适配鸿蒙(微信 + 支付宝)

鸿蒙系统通过「兼容层」支持 Android 应用的第三方支付 SDK,Flutter 插件可通过调用原生能力实现微信 / 支付宝支付。以下是具体适配流程:

4.1 核心适配原理

  • 鸿蒙系统提供「Android 兼容模式」,支持运行 Android 应用与 SDK;
  • Flutter 插件(如 fluwxflutter_alipay)通过 Method Channel 调用原生(Android/HarmonyOS)支付 SDK;
  • 鸿蒙应用需配置与 Android 一致的包名、签名,确保第三方支付 SDK 识别通过。

4.2 微信支付集成

4.2.1 配置步骤
  1. 在 harmonyos/app/src/main/config.json 中添加权限与微信 Scheme:

json

"module": {
  "abilities": [
    {
      "name": "com.example.flutter_harmony_payment.WeChatPayAbility",
      "type": "page",
      "skills": [
        {
          "actions": ["action.system.home"],
          "entities": ["entity.system.home"]
        },
        // 微信支付回调 Scheme(需与微信开放平台配置一致)
        {
          "actions": ["android.intent.action.VIEW"],
          "entities": ["android.intent.category.DEFAULT"],
          "uris": [
            {
              "scheme": "weixin://wxpay/bizpayurl?pr=xxxx",  // 替换为你的微信 Scheme
              "host": "*"
            }
          ]
        }
      ]
    }
  ],
  "reqPermissions": [
    {
      "name": "ohos.permission.INTERNET"
    },
    {
      "name": "ohos.permission.ACCESS_WIFI_STATE"
    },
    {
      "name": "ohos.permission.READ_PHONE_STATE"  // 可选,用于微信支付风控
    }
  ]
}
  1. 配置 Android 兼容信息(harmonyos/app/src/main/AndroidManifest.xml):

xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.flutter_harmony_payment">
    <application>
        <!-- 微信支付配置 -->
        <activity
            android:name="com.tencent.mm.opensdk.openapi.WXEntryActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" />
        <!-- 微信支付回调 Activity -->
        <activity
            android:name="com.tencent.mm.opensdk.openapi.WXPayEntryActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" />
    </application>
</manifest>
4.2.2 核心代码实现

创建 wechat_payment_service.dart

dart

import 'package:fluwx/fluwx.dart' as fluwx;
import 'package:dio/dio.dart';
import 'package:crypto/crypto.dart';
import 'dart:convert';

class WechatPaymentService {
  final String _appId = "wx1234567890abcdef";  // 微信开放平台 AppID
  final String _mchid = "1234567890";  // 微信商户号
  final String _apiKey = "your_wechat_api_key";  // 微信支付密钥
  final Dio _dio = Dio();

  // 初始化微信支付
  Future<void> init() async {
    try {
      await fluwx.registerWxApi(
        appId: _appId,
        universalLink: "https://your-domain.com/wechat-universal-link",  // iOS 需配置,鸿蒙可选
      );
      final isWeChatInstalled = await fluwx.isWeChatInstalled;
      if (!isWeChatInstalled) {
        throw Exception("未安装微信客户端");
      }
      print("微信支付初始化成功");
    } catch (e) {
      print("微信支付初始化失败:$e");
      rethrow;
    }
  }

  // 生成微信支付签名(参考微信支付文档)
  String _generateSign(Map<String, dynamic> params) {
    // 1. 按参数名 ASCII 排序
    final sortedKeys = params.keys.toList()..sort();
    // 2. 拼接参数字符串
    String signStr = "";
    for (final key in sortedKeys) {
      if (params[key] != null && params[key].toString().isNotEmpty) {
        signStr += "$key=${params[key]}&";
      }
    }
    // 3. 拼接 API 密钥
    signStr += "key=$_apiKey";
    // 4. MD5 加密
    final md5Bytes = md5.convert(utf8.encode(signStr));
    return md5Bytes.toString().toUpperCase();
  }

  // 向服务端请求微信支付参数(生产环境需后端实现)
  Future<Map<String, dynamic>> _getWechatPayParams({
    required String orderId,
    required double amount,
    required String description,
  }) async {
    // 测试环境:本地生成支付参数(生产环境需删除)
    final timestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000;
    final nonceStr = "${timestamp}_${Random().nextInt(1000)}";
    final params = {
      "appid": _appId,
      "mch_id": _mchid,
      "nonce_str": nonceStr,
      "body": description,
      "out_trade_no": orderId,
      "total_fee": (amount * 100).toInt(),  // 微信支付金额单位为分
      "spbill_create_ip": "127.0.0.1",
      "notify_url": "https://your-server.com/wechat-pay-notify",  // 支付结果回调地址
      "trade_type": "APP",
    };
    params["sign"] = _generateSign(params);
    return params;

    // 生产环境:调用后端接口获取支付参数
    // final response = await _dio.post(
    //   "https://your-server.com/wechat-pay-params",
    //   data: {
    //     "orderId": orderId,
    //     "amount": amount,
    //     "description": description,
    //   },
    // );
    // return response.data["data"];
  }

  // 发起微信支付
  Future<void> launchPayment({
    required String orderId,
    required double amount,
    required String description,
  }) async {
    try {
      // 1. 获取支付参数
      final payParams = await _getWechatPayParams(
        orderId: orderId,
        amount: amount,
        description: description,
      );

      // 2. 发起支付
      final result = await fluwx.payWithWeChat(
        appId: payParams["appid"],
        partnerId: payParams["mch_id"],
        prepayId: payParams["prepay_id"],  // 测试环境需后端返回,本地生成需注释
        packageValue: "Sign=WXPay",
        nonceStr: payParams["nonce_str"],
        timeStamp: payParams["timestamp"].toString(),
        sign: payParams["sign"],
      );

      // 3. 监听支付结果
      result.listen((event) {
        if (event is fluwx.WeChatPaymentResponse) {
          switch (event.errCode) {
            case 0:
              // 支付成功,需验证订单
              _verifyOrder(orderId);
              break;
            case -1:
              throw Exception("支付失败:${event.errStr}");
            case -2:
              throw Exception("用户取消支付");
          }
        }
      });
    } catch (e) {
      print("微信支付异常:$e");
      rethrow;
    }
  }

  // 验证微信订单(服务端实现)
  Future<void> _verifyOrder(String orderId) async {
    try {
      final response = await _dio.post(
        "https://your-server.com/verify-wechat-order",
        data: {"orderId": orderId},
      );
      if (response.data["success"]) {
        print("微信订单验证成功:$orderId");
        // 发放商品
      } else {
        throw Exception("微信订单验证失败");
      }
    } catch (e) {
      print("微信订单验证异常:$e");
    }
  }
}
4.2.3 页面调用示例

dart

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

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

  @override
  State<WechatPaymentPage> createState() => _WechatPaymentPageState();
}

class _WechatPaymentPageState extends State<WechatPaymentPage> {
  final WechatPaymentService _paymentService = WechatPaymentService();
  bool _isLoading = false;

  @override
  void initState() {
    super.initState();
    _initPayment();
  }

  Future<void> _initPayment() async {
    try {
      await _paymentService.init();
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("微信支付初始化失败:$e")),
      );
    }
  }

  Future<void> _onPay() async {
    setState(() => _isLoading = true);
    try {
      // 生成唯一订单号(建议由服务端生成)
      final orderId = "ORDER_${DateTime.now().millisecondsSinceEpoch}";
      await _paymentService.launchPayment(
        orderId: orderId,
        amount: 0.01,  // 测试金额:0.01元
        description: "测试商品 - 10个游戏币",
      );
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("支付成功!")),
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("支付失败:$e")),
      );
    } finally {
      setState(() => _isLoading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("微信支付")),
      body: Center(
        child: _isLoading
            ? const CircularProgressIndicator()
            : ElevatedButton(
                onPressed: _onPay,
                child: const Text("微信支付 0.01元"),
              ),
      ),
    );
  }
}

4.3 支付宝集成

4.3.1 配置步骤
  1. 在 harmonyos/app/src/main/config.json 中添加支付宝 Scheme:

json

"module": {
  "abilities": [
    {
      "name": "com.example.flutter_harmony_payment.AlipayAbility",
      "type": "page",
      "skills": [
        {
          "actions": ["android.intent.action.VIEW"],
          "entities": ["android.intent.category.DEFAULT"],
          "uris": [
            {
              "scheme": "alipay://alipayclient?appId=xxxx",  // 替换为你的支付宝 Scheme
              "host": "*"
            }
          ]
        }
      ]
    }
  ]
}
  1. 配置 Android 兼容信息(AndroidManifest.xml):

xml

<activity
    android:name="com.alipay.sdk.app.H5PayActivity"
    android:configChanges="orientation|keyboardHidden|navigation|screenSize"
    android:exported="true"
    android:screenOrientation="behind"
    android:windowSoftInputMode="adjustResize|stateHidden" />
<activity
    android:name="com.alipay.sdk.app.H5AuthActivity"
    android:configChanges="orientation|keyboardHidden|navigation|screenSize"
    android:exported="true"
    android:screenOrientation="behind"
    android:windowSoftInputMode="adjustResize|stateHidden" />
4.3.2 核心代码实现

创建 alipay_payment_service.dart

dart

import 'package:flutter_alipay/flutter_alipay.dart';
import 'package:dio/dio.dart';
import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:pointycastle/pointycastle.dart';
import 'package:pointycastle/key_management.dart';
import 'package:pointycastle/signers/rsa_signer.dart';

class AlipayPaymentService {
  final String _appId = "2021000000000000";  // 支付宝 AppID
  final String _privateKey = "your_alipay_private_key";  // 支付宝私钥(PKCS8 格式)
  final String _alipayPublicKey = "your_alipay_public_key";  // 支付宝公钥
  final Dio _dio = Dio();

  // 初始化支付宝
  Future<void> init() async {
    try {
      final isAlipayInstalled = await FlutterAlipay.isAlipayInstalled();
      if (!isAlipayInstalled) {
        throw Exception("未安装支付宝客户端");
      }
      print("支付宝初始化成功");
    } catch (e) {
      print("支付宝初始化失败:$e");
      rethrow;
    }
  }

  // 生成支付宝签名(RSA2 加密)
  String _generateSign(Map<String, dynamic> params) {
    // 1. 按参数名 ASCII 排序
    final sortedKeys = params.keys.toList()..sort();
    // 2. 拼接参数字符串
    String signStr = "";
    for (final key in sortedKeys) {
      if (params[key] != null && params[key].toString().isNotEmpty) {
        signStr += "$key=${Uri.encodeComponent(params[key].toString())}&";
      }
    }
    signStr = signStr.substring(0, signStr.length - 1);

    // 3. RSA2 签名(SHA256withRSA)
    final privateKey = RSAKeyParser().parse(_privateKey) as RSAPrivateKey;
    final signer = RSASigner(SHA256Digest(), "0609608648016503040201");
    signer.init(true, PrivateKeyParameter<RSAPrivateKey>(privateKey));
    final signBytes = signer.generateSignature(utf8.encode(signStr));
    return base64.encode(signBytes.signature);
  }

  // 获取支付宝支付参数(生产环境需后端实现)
  Future<String> _getAlipayOrderInfo({
    required String orderId,
    required double amount,
    required String description,
  }) async {
    // 测试环境:本地生成订单信息
    final timestamp = DateTime.now().toString().substring(0, 19).replaceAll(RegExp(r"[-:\s]"), "");
    final params = {
      "app_id": _appId,
      "biz_content": json.encode({
        "out_trade_no": orderId,
        "total_amount": amount.toStringAsFixed(2),
        "subject": description,
        "product_code": "QUICK_MSECURITY_PAY",
      }),
      "charset": "UTF-8",
      "format": "json",
      "method": "alipay.trade.app.pay",
      "sign_type": "RSA2",
      "timestamp": timestamp,
      "version": "1.0",
    };
    params["sign"] = _generateSign(params);
    // 拼接为支付宝订单字符串
    String orderInfo = "";
    params.forEach((key, value) {
      orderInfo += "$key=${Uri.encodeComponent(value.toString())}&";
    });
    return orderInfo.substring(0, orderInfo.length - 1);

    // 生产环境:调用后端接口获取订单信息
    // final response = await _dio.post(
    //   "https://your-server.com/alipay-order-info",
    //   data: {
    //     "orderId": orderId,
    //     "amount": amount,
    //     "description": description,
    //   },
    // );
    // return response.data["orderInfo"];
  }

  // 发起支付宝支付
  Future<void> launchPayment({
    required String orderId,
    required double amount,
    required String description,
  }) async {
    try {
      // 1. 获取订单信息
      final orderInfo = await _getAlipayOrderInfo(
        orderId: orderId,
        amount: amount,
        description: description,
      );

      // 2. 发起支付
      final result = await FlutterAlipay.pay(
        orderInfo: orderInfo,
        scheme: "alipay://alipayclient",  // 支付宝 Scheme
      );

      // 3. 处理支付结果
      if (result.resultStatus == "9000") {
        // 支付成功,验证订单
        await _verifyOrder(orderId, result.result);
        print("支付宝支付成功:$orderId");
      } else if (result.resultStatus == "6001") {
        throw Exception("用户取消支付");
      } else {
        throw Exception("支付失败:${result.resultMessage}");
      }
    } catch (e) {
      print("支付宝支付异常:$e");
      rethrow;
    }
  }

  // 验证支付宝订单(服务端实现)
  Future<void> _verifyOrder(String orderId, String result) async {
    try {
      final response = await _dio.post(
        "https://your-server.com/verify-alipay-order",
        data: {
          "orderId": orderId,
          "result": result,
        },
      );
      if (response.data["success"]) {
        print("支付宝订单验证成功:$orderId");
        // 发放商品
      } else {
        throw Exception("支付宝订单验证失败");
      }
    } catch (e) {
      print("支付宝订单验证异常:$e");
    }
  }
}
4.3.4 关键注意事项
  1. 签名格式:支付宝支持 RSA 和 RSA2 签名,推荐使用 RSA2(SHA256withRSA),需确保私钥为 PKCS8 格式;
  2. Scheme 配置:支付宝回调 Scheme 需与开放平台配置一致,否则无法接收支付结果;
  3. 订单号唯一性:确保 out_trade_no 唯一,避免重复支付;
  4. 支付结果校验:支付宝客户端返回的 resultStatus 仅为参考,最终需通过服务端调用支付宝「订单查询接口」验证(参考 支付宝订单查询文档)。

5. 多支付方式整合与实战案例

5.1 支付管理类封装

创建 payment_manager.dart,统一管理华为支付、微信支付、支付宝支付,简化页面调用:

dart

import 'huawei_payment_service.dart';
import 'wechat_payment_service.dart';
import 'alipay_payment_service.dart';

enum PaymentType { huawei, wechat, alipay }

class PaymentManager {
  final HuaweiPaymentService _huaweiPayment = HuaweiPaymentService();
  final WechatPaymentService _wechatPayment = WechatPaymentService();
  final AlipayPaymentService _alipayPayment = AlipayPaymentService();

  // 初始化所有支付方式
  Future<void> initAllPayments() async {
    await Future.wait([
      _huaweiPayment.init().catchError((e) => print("华为支付初始化忽略:$e")),
      _wechatPayment.init().catchError((e) => print("微信支付初始化忽略:$e")),
      _alipayPayment.init().catchError((e) => print("支付宝初始化忽略:$e")),
    ]);
  }

  // 发起支付(根据类型选择支付方式)
  Future<void> pay({
    required PaymentType type,
    String? productId,  // 华为支付商品 ID
    required String orderId,  // 第三方支付订单号
    required double amount,  // 支付金额(第三方支付)
    required String description,  // 支付描述(第三方支付)
  }) async {
    switch (type) {
      case PaymentType.huawei:
        if (productId == null) throw Exception("华为支付需传入商品 ID");
        final purchaseResult = await _huaweiPayment.launchPayment(productId);
        await _huaweiPayment.verifyOrder(purchaseResult);
        break;
      case PaymentType.wechat:
        await _wechatPayment.launchPayment(
          orderId: orderId,
          amount: amount,
          description: description,
        );
        break;
      case PaymentType.alipay:
        await _alipayPayment.launchPayment(
          orderId: orderId,
          amount: amount,
          description: description,
        );
        break;
    }
  }
}

5.2 实战案例:支付选择页面

dart

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

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

  @override
  State<PaymentSelectionPage> createState() => _PaymentSelectionPageState();
}

class _PaymentSelectionPageState extends State<PaymentSelectionPage> {
  final PaymentManager _paymentManager = PaymentManager();
  bool _isLoading = false;
  PaymentType? _selectedType;

  @override
  void initState() {
    super.initState();
    _initPayments();
  }

  Future<void> _initPayments() async {
    setState(() => _isLoading = true);
    await _paymentManager.initAllPayments();
    setState(() => _isLoading = false);
  }

  Future<void> _confirmPayment() async {
    if (_selectedType == null) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("请选择支付方式")),
      );
      return;
    }

    setState(() => _isLoading = true);
    try {
      final orderId = "ORDER_${DateTime.now().millisecondsSinceEpoch}";
      await _paymentManager.pay(
        type: _selectedType!,
        productId: _selectedType == PaymentType.huawei ? "com.example.coins.10" : null,
        orderId: orderId,
        amount: 0.01,
        description: "测试商品 - 10个游戏币",
      );
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("支付成功!")),
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("支付失败:$e")),
      );
    } finally {
      setState(() => _isLoading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("选择支付方式")),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const Text("商品:10个游戏币", style: TextStyle(fontSize: 18)),
                  const Text("价格:0.01元", style: TextStyle(fontSize: 16, color: Colors.red)),
                  const SizedBox(height: 32),
                  _buildPaymentOption(
                    icon: Icons.payment,
                    title: "华为支付",
                    type: PaymentType.huawei,
                  ),
                  _buildPaymentOption(
                    icon: Icons.wechat,
                    title: "微信支付",
                    type: PaymentType.wechat,
                  ),
                  _buildPaymentOption(
                    icon: Icons.payment,
                    title: "支付宝",
                    type: PaymentType.alipay,
                  ),
                  const Spacer(),
                  SizedBox(
                    width: double.infinity,
                    child: ElevatedButton(
                      onPressed: _confirmPayment,
                      child: const Text("确认支付"),
                    ),
                  ),
                ],
              ),
            ),
    );
  }

  Widget _buildPaymentOption({
    required IconData icon,
    required String title,
    required PaymentType type,
  }) {
    return RadioListTile<PaymentType>(
      value: type,
      groupValue: _selectedType,
      onChanged: (value) {
        setState(() => _selectedType = value);
      },
      title: Text(title),
      secondary: Icon(icon),
    );
  }
}

5.3 全流程测试步骤

  1. 环境准备:
    • 安装鸿蒙系统设备(或 DevEco Studio 模拟器);
    • 安装 HMS Core、微信、支付宝客户端;
    • 配置好开发者账号的应用信息与商品。
  2. 功能测试:
    • 测试商品列表加载(华为支付);
    • 测试支付发起与回调(三种支付方式);
    • 测试订单验证与商品发放;
    • 测试异常场景(取消支付、网络异常、客户端未安装)。
  3. 兼容性测试:
    • 测试不同鸿蒙版本(API Version 9/10);
    • 测试不同设备类型(手机、平板);
    • 测试后台杀进程后支付结果回调。

6. 常见问题与解决方案

6.1 华为支付常见问题

问题现象 解决方案 参考链接
HMS Core 未安装 引导用户安装 HMS Core:await HuaweiIap.navigateToHmsCoreMarket() HMS Core 安装引导
商品查询失败 1. 检查商品 ID 与开发者后台一致;2. 确认应用已开通 IAP 服务;3. 检查网络权限 IAP 商品查询失败排查
订单验证失败 1. 确认 agconnect-services.json 配置正确;2. 生产环境使用服务端验证;3. 检查签名信息一致 订单验证失败排查

6.2 微信支付常见问题

问题现象 解决方案 参考链接
微信客户端未安装 引导用户安装微信,或隐藏微信支付选项 微信支付开发文档
支付回调无响应 1. 检查 Scheme 配置一致;2. 确认 WXPayEntryActivity 已注册;3. 检查包名与签名一致 微信支付回调配置
签名错误 1. 确认使用 MD5 签名(微信支付要求);2. 检查参数排序与拼接正确;3. 避免参数值包含特殊字符 微信支付签名规范

6.3 支付宝常见问题

问题现象 解决方案 参考链接
支付结果回调失败 1. 检查 Scheme 配置一致;2. 确认 H5PayActivity 已注册;3. 测试环境使用支付宝沙箱 支付宝 APP 支付回调
签名错误 1. 确认私钥为 PKCS8 格式;2. 使用 RSA2 签名;3. 检查参数编码正确(UTF-8) 支付宝签名规范
订单重复支付 1. 确保 out_trade_no 唯一;2. 支付前查询订单状态;3. 服务端处理幂等性 支付宝订单幂等性处理

6.4 鸿蒙适配常见问题

问题现象 解决方案 参考链接
第三方支付 SDK 无法调用 1. 开启 Android 兼容模式;2. 配置与 Android 一致的包名、签名;3. 检查权限配置 鸿蒙 Android 兼容模式
应用闪退 1. 检查 SDK 版本兼容性;2. 避免使用鸿蒙不支持的 Android API;3. 查看 DevEco Studio 日志 鸿蒙应用闪退排查
支付结果无法持久化 使用 shared_preferences 或鸿蒙原生存储 API 缓存支付状态,确保应用重启后可恢复 鸿蒙数据存储文档

7. 总结与展望

本文详细讲解了鸿蒙 Flutter 应用集成华为支付与微信 / 支付宝支付的完整流程,从环境准备、配置步骤、核心代码实现到实战案例与问题排查,覆盖了支付功能开发的全生命周期。通过 Flutter 的跨平台特性与鸿蒙系统的兼容性支持,开发者可以快速实现多支付方式的统一集成,适配鸿蒙全场景设备。

7.1 核心要点回顾

  1. 华为支付:原生集成鸿蒙系统,无需兼容层,适合鸿蒙生态优先的应用;
  2. 第三方支付:通过 Android 兼容模式适配,需确保包名、签名、Scheme 配置一致;
  3. 订单验证:生产环境必须通过服务端验证,确保交易安全;
  4. 异常处理:覆盖客户端未安装、网络异常、支付取消等场景,提升用户体验。

7.2 未来展望

  • 鸿蒙生态原生第三方支付:随着鸿蒙系统的发展,微信、支付宝可能推出鸿蒙原生 SDK,进一步提升支付兼容性与性能;
  • 多端统一支付:支持手机、平板、智慧屏等多设备的支付同步,实现全场景支付体验;
  • 支付安全增强:结合鸿蒙系统的分布式安全能力,提供更安全的支付环境。

7.3 参考资源

通过本文的指导,开发者可以快速落地鸿蒙 Flutter 应用的支付功能,如需进一步优化或扩展,可参考上述官方文档,或关注鸿蒙生态的最新动态。祝你开发顺利!



模板

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐