Flutter华为应用内支付插件huawei_iap的使用

Flutter华为应用内支付插件huawei_iap的使用

华为IAP Flutter插件

pub.dev版本


华为的IAP(应用内购买)服务允许你提供应用内购买并促进应用内支付。用户可以直接在你的应用中购买各种虚拟产品,包括一次性虚拟产品和订阅。

华为IAP提供了以下核心功能,使你可以快速构建可以让用户购买、消费和订阅你提供的服务的应用:

  • isEnvReady: 返回一个表示用户环境状态的响应。
  • isSandboxActivated: 返回一个表示用户账户是否已激活沙箱测试的响应。
  • obtainProductInfo: 返回产品信息列表。
  • startIapActivity: 启动一个活动来管理及编辑订阅。
  • createPurchaseIntent: 启动一个活动来购买所需的产品或订阅产品。
  • consumeOwnedPurchase: 消费所购买的产品。
  • obtainOwnedPurchases: 返回用户购买的产品列表。
  • obtainOwnedPurchaseRecord: 返回用户购买并消费的产品列表。
  • enableLogger: 此方法启用HMSLogger功能,用于发送IAP SDK方法的使用分析以改进服务质量。
  • disableLogger: 此方法禁用HMSLogger功能,用于发送IAP SDK方法的使用分析以改进服务质量。

此插件使HUAWEI IAP Kit SDK与Flutter平台之间能够通信,并暴露了HUAWEI IAP Kit SDK的所有功能。

安装

请参阅pub.devAppGallery Connect配置

文档

问题或反馈

如果你对如何使用HMS示例有疑问,可以尝试以下选项:

  • Stack Overflow 是任何编程问题的最佳去处。请务必使用标签 <strong>huawei-mobile-services</strong>
  • GitHub 是这些插件的官方仓库,你可以在其中提交问题或提出建议。
  • 华为开发者论坛 的 HMS Core 模块非常适合一般性问题,或寻求推荐和意见。
  • 华为开发者文档 是所有HMS Core Kit的官方文档所在,你可以在那里找到详细的文档。

如果你在我们的示例中遇到错误,请提交到 GitHub仓库

许可证

华为IAP Flutter插件遵循Apache 2.0许可证


示例代码

/*
 * Copyright 2020-2024. Huawei Technologies Co., Ltd. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import 'dart:developer' show log;

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

import 'package:huawei_iap_example/home_page.dart';
import 'package:huawei_iap_example/utils/custom_button.dart';

void main() => runApp(
      MaterialApp(
        theme: ThemeData(
          useMaterial3: true,
          appBarTheme: const AppBarTheme(
            backgroundColor: Colors.red,
            foregroundColor: Colors.white,
          ),
        ),
        home: const MyApp(),
      ),
    );

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String? isEnvReadyStatus;
  String? sandboxReadyStatus;
  bool hmsLoggerStatus = true;

  [@override](/user/override)
  void initState() {
    super.initState();
    enablePendingPurchase();
  }

  void enablePendingPurchase() async {
    String result = await IapClient.enablePendingPurchase();
    log(result);
  }

  void environmentCheck() async {
    isEnvReadyStatus = null;
    try {
      IsEnvReadyResult response = await IapClient.isEnvReady();
      setState(() {
        if (response.status != null) {
          isEnvReadyStatus = response.status!.statusMessage;
        }
      });
    } on PlatformException catch (e) {
      if (e.code == HmsIapResults.LOG_IN_ERROR.resultCode) {
        log(HmsIapResults.LOG_IN_ERROR.resultMessage!);
      } else {
        log(e.toString());
      }
    }
  }

  void sandboxCheck() async {
    try {
      sandboxReadyStatus = null;
      IsSandboxActivatedResult response = await IapClient.isSandboxActivated();
      setState(() {
        sandboxReadyStatus = response.isSandboxUser.toString();
      });
    } on PlatformException catch (e) {
      if (e.code == HmsIapResults.ORDER_HWID_NOT_LOGIN.resultCode) {
        log(HmsIapResults.ORDER_HWID_NOT_LOGIN.resultMessage!);
      } else {
        log(e.toString());
      }
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('华为IAP Demo'),
        centerTitle: true,
      ),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 15.0, horizontal: 8.0),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Image.asset('assets/HUAWEI_IAP_icon.png'),
                  ),
                  const Column(
                    children: [
                      Text(
                        '华为',
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                          fontSize: 20,
                        ),
                      ),
                      Text(
                        '应用内购买',
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                          fontSize: 18,
                        ),
                      ),
                      Text(
                        'Flutter插件演示',
                      )
                    ],
                  )
                ],
              ),
              const Padding(
                padding: EdgeInsets.all(8.0),
                child: Text(
                  "华为的IAP服务允许你提供应用内购买并促进应用内支付。用户可以直接在你的应用中购买各种虚拟产品,包括一次性虚拟产品和订阅。",
                  textAlign: TextAlign.center,
                ),
              ),
              SizedBox(
                width: MediaQuery.of(context).size.width / 2,
                child: const Divider(
                  color: Colors.grey,
                ),
              ),
              const Padding(
                padding: EdgeInsets.all(8.0),
                child: Text(
                  '在你的应用中使用HUAWEI IAP之前,从你的应用向HUAWEI IAP发送一个isEnvReady请求,以检查当前登录的HUAWEI ID是否位于HUAWEI IAP可用的位置。',
                  textAlign: TextAlign.center,
                ),
              ),
              CustomButton(
                onPressed: environmentCheck,
                text: '检查环境状态',
              ),
              isEnvReadyStatus == null
                  ? const SizedBox.shrink()
                  : Column(
                      children: [
                        Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: Text(
                            '环境状态: ${isEnvReadyStatus!}',
                            style: const TextStyle(fontWeight: FontWeight.bold),
                          ),
                        ),
                        CustomButton(
                          onPressed: () {
                            Navigator.push(
                              context,
                              MaterialPageRoute<dynamic>(
                                builder: (BuildContext context) => const HomePage(),
                              ),
                            );
                          },
                          text: '产品',
                        )
                      ],
                    ),
              SizedBox(
                width: MediaQuery.of(context).size.width / 2,
                child: const Divider(
                  color: Colors.grey,
                ),
              ),
              const Padding(
                padding: EdgeInsets.all(8.0),
                child: Text(
                  '沙箱测试允许你在连接到HUAWEI IAP进行联合调试时完成端到端测试而无需实际付款。你可以在AppGallery Connect中配置测试帐户,并允许这些测试者执行沙箱测试。',
                  textAlign: TextAlign.center,
                ),
              ),
              CustomButton(
                onPressed: sandboxCheck,
                text: '检查沙箱状态',
              ),
              sandboxReadyStatus == null
                  ? const SizedBox.shrink()
                  : Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text(
                        '是否沙箱用户: ${sandboxReadyStatus!}',
                        style: const TextStyle(fontWeight: FontWeight.bold),
                      ),
                    ),
              SizedBox(
                width: MediaQuery.of(context).size.width / 2,
                child: const Divider(
                  color: Colors.grey,
                ),
              ),
              const Padding(
                padding: EdgeInsets.all(8.0),
                child: Text(
                  "此方法启用/禁用HMSLogger功能,用于发送华为IAP SDK方法的使用分析以改进服务质量。",
                  textAlign: TextAlign.center,
                ),
              ),
              CustomButton(
                text: '启用/禁用Hms Logger',
                onPressed: () {
                  if (hmsLoggerStatus) {
                    IapClient.disableLogger();
                    hmsLoggerStatus = false;
                  } else {
                    IapClient.enableLogger();
                    hmsLoggerStatus = true;
                  }
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

更多关于Flutter华为应用内支付插件huawei_iap的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


当然,以下是一个关于如何在Flutter应用中使用huawei_iap插件实现华为应用内支付的代码示例。

首先,确保你已经在pubspec.yaml文件中添加了huawei_iap依赖:

dependencies:
  flutter:
    sdk: flutter
  huawei_iap: ^最新版本号  # 请替换为最新版本号

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

接下来,你需要配置华为应用内支付服务。这包括在华为开发者联盟网站上创建应用并获取必要的配置信息,如app_idclient_key

以下是Flutter代码示例,展示了如何初始化华为IAP服务、查询产品信息和发起支付请求:

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

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late IapClient iapClient;

  @override
  void initState() {
    super.initState();
    // 初始化IAP客户端
    iapClient = IapClient();
    initHuaweiIAP();
  }

  Future<void> initHuaweiIAP() async {
    try {
      await iapClient.init({
        'appId': '你的应用ID',  // 替换为你的应用ID
        'clientKey': '你的clientKey',  // 替换为你的clientKey
        'autoReportPurchases': true,
      });
      print("华为IAP初始化成功");
    } catch (e) {
      print("华为IAP初始化失败: $e");
    }
  }

  Future<void> queryProductInfo() async {
    try {
      List<String> productIds = ['your_product_id1', 'your_product_id2'];  // 替换为你的产品ID列表
      ProductInfoListResponse response = await iapClient.queryProductInfo(productIds);
      if (response.code == ResponseCode.OK) {
        response.productInfoList?.forEach((productInfo) {
          print("Product ID: ${productInfo.productId}");
          print("Product Name: ${productInfo.productName}");
          print("Price: ${productInfo.price}");
          print("Price Currency Code: ${productInfo.priceCurrencyCode}");
        });
      } else {
        print("查询产品信息失败: ${response.errMsg}");
      }
    } catch (e) {
      print("查询产品信息异常: $e");
    }
  }

  Future<void> createPurchaseIntent() async {
    try {
      String productId = 'your_product_id';  // 替换为你的产品ID
      PurchaseIntentRequest request = PurchaseIntentRequest(productId: productId);
      PurchaseIntentResult result = await iapClient.createPurchaseIntent(request);
      if (result.code == ResponseCode.OK) {
        // 启动支付页面
        String pendingIntent = result.pendingIntent;
        // 在这里使用Android的Intent来启动支付页面,通常是在原生代码部分处理
        // 例如:await MethodChannel('your_channel').invokeMethod('startPayment', pendingIntent);
        print("支付请求创建成功: $pendingIntent");
      } else {
        print("创建支付请求失败: ${result.errMsg}");
      }
    } catch (e) {
      print("创建支付请求异常: $e");
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('华为IAP示例'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: queryProductInfo,
                child: Text('查询产品信息'),
              ),
              ElevatedButton(
                onPressed: createPurchaseIntent,
                child: Text('创建支付请求'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

注意

  1. createPurchaseIntent方法中,pendingIntent的处理通常需要与原生代码进行交互。你需要创建一个MethodChannel来从Flutter端调用原生代码,并使用Android的Intent来启动支付页面。这部分代码示例中并未展示完整的原生代码实现,因为它涉及到Android平台的特定实现。

  2. 在实际应用中,你还需要处理支付结果的回调。这通常涉及到监听IAP客户端的购买更新事件,并处理购买成功的逻辑。

  3. 请确保你已经按照华为开发者文档的要求,正确配置了应用签名、包名等信息,并已经在华为开发者联盟网站上添加了你的应用信息。

  4. 由于安全和隐私的考虑,请确保不要在客户端代码中硬编码敏感信息,如clientKey。你可以考虑使用安全的存储方式来管理这些信息。

回到顶部