Commit de8c21d1 authored by 汪林玲's avatar 汪林玲

2.2.0-nullsafety

parent a5d75a7e
## 2.2.0-nullsafety
* 同 2.2.0-nullsafety-Android-Only
## 2.2.0-nullsafety-Android-Only
* Alipay 单例
## 2.1.0-nullsafety-Android-Only
* 同 2.1.0-nullsafety
## 2.1.0-nullsafety
* nullsafety
* 不再支持 Android embedding v1
## 2.0.0
* 升级 Android/iOS SDK
......
# alipay_kit
[![Build Status](https://cloud.drone.io/api/badges/v7lin/alipay_kit/status.svg)](https://cloud.drone.io/v7lin/alipay_kit)
[![Codecov](https://codecov.io/gh/v7lin/alipay_kit/branch/master/graph/badge.svg)](https://codecov.io/gh/v7lin/alipay_kit)
[![GitHub Tag](https://img.shields.io/github/tag/v7lin/alipay_kit.svg)](https://github.com/v7lin/alipay_kit/releases)
[![Build Status](https://cloud.drone.io/api/badges/rxreader/alipay_kit/status.svg)](https://cloud.drone.io/rxreader/alipay_kit)
[![Codecov](https://codecov.io/gh/rxreader/alipay_kit/branch/master/graph/badge.svg)](https://codecov.io/gh/rxreader/alipay_kit)
[![GitHub Tag](https://img.shields.io/github/tag/rxreader/alipay_kit.svg)](https://github.com/rxreader/alipay_kit/releases)
[![Pub Package](https://img.shields.io/pub/v/alipay_kit.svg)](https://pub.dartlang.org/packages/alipay_kit)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/v7lin/alipay_kit/blob/master/LICENSE)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/rxreader/alipay_kit/blob/master/LICENSE)
flutter版支付宝SDK
## fake 系列 libraries
* [flutter版微信SDK](https://github.com/v7lin/wechat_kit)
* [flutter版腾讯(QQ)SDK](https://github.com/v7lin/tencent_kit)
* [flutter版新浪微博SDK](https://github.com/v7lin/weibo_kit)
* [flutter版支付宝SDK](https://github.com/v7lin/alipay_kit)
* [flutter版walle渠道打包工具](https://github.com/v7lin/walle_kit)
* [flutter版微信SDK](https://github.com/rxreader/wechat_kit)
* [flutter版腾讯(QQ)SDK](https://github.com/rxreader/tencent_kit)
* [flutter版新浪微博SDK](https://github.com/rxreader/weibo_kit)
* [flutter版支付宝SDK](https://github.com/rxreader/alipay_kit)
* [flutter版walle渠道打包工具](https://github.com/rxreader/walle_kit)
## dart/flutter 私服
* [simple_pub_server](https://github.com/v7lin/simple_pub_server)
* [simple_pub_server](https://github.com/rxreader/simple_pub_server)
## docs
......@@ -29,6 +29,15 @@ flutter版支付宝SDK
## android
```groovy
buildscript {
dependencies {
// Android 11兼容,需升级Gradle到3.5.4/3.6.4/4.x.y
classpath 'com.android.tools.build:gradle:3.5.4'
}
}
```
```
# 不需要做任何额外接入工作
# 混淆已打入 Library,随 Library 引用,自动添加到 apk 打包混淆
......@@ -59,13 +68,17 @@ iOS 9系统策略更新,限制了http协议的访问,此外应用需要在
## flutter
* break change
* 2.2.0: Alipay 单例
* 2.1.0: nullsafety & 不再支持 Android embedding v1
* snapshot
```
dependencies:
alipay_kit:
git:
url: https://github.com/v7lin/alipay_kit.git
url: https://github.com/rxreader/alipay_kit.git
```
* release
......
# Specify analysis options.
#
# Until there are meta linter rules, each desired lint must be explicitly enabled.
# See: https://github.com/dart-lang/linter/issues/288
#
# For a list of lints, see: http://dart-lang.github.io/linter/lints/
# See the configuration guide for more
# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer
#
# There are other similar analysis options files in the flutter repos,
# which should be kept in sync with this file:
#
# - analysis_options.yaml (this file)
# - packages/flutter/lib/analysis_options_user.yaml
# - https://github.com/flutter/plugins/blob/master/analysis_options.yaml
# - https://github.com/flutter/engine/blob/master/analysis_options.yaml
#
# This file contains the analysis options used by Flutter tools, such as IntelliJ,
# Android Studio, and the `flutter analyze` command.
analyzer:
strong-mode:
implicit-casts: false
implicit-dynamic: false
errors:
# treat missing required parameters as a warning (not a hint)
missing_required_param: warning
# treat missing returns as a warning (not a hint)
missing_return: warning
# allow having TODOs in the code
todo: ignore
# allow self-reference to deprecated members (we do this because otherwise we have
# to annotate every member in every test, assert, etc, when we deprecate something)
deprecated_member_use_from_same_package: ignore
# Ignore analyzer hints for updating pubspecs when using Future or
# Stream and not importing dart:async
# Please see https://github.com/flutter/flutter/pull/24528 for details.
sdk_version_async_exported_from_core: ignore
exclude:
- "lib/*.g.dart"
linter:
rules:
# these rules are documented on and in the same order as
# the Dart Lint rules page to make maintenance easier
# https://github.com/dart-lang/linter/blob/master/example/all.yaml
- always_declare_return_types
- always_put_control_body_on_new_line
# - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219
- always_require_non_null_named_parameters
- always_specify_types
- always_use_package_imports # we do this commonly
- annotate_overrides
# - avoid_annotating_with_dynamic # conflicts with always_specify_types
# - avoid_as # required for implicit-casts: true
- avoid_bool_literals_in_conditional_expressions
# - avoid_catches_without_on_clauses # we do this commonly
# - avoid_catching_errors # we do this commonly
- avoid_classes_with_only_static_members
# - avoid_double_and_int_checks # only useful when targeting JS runtime
- avoid_empty_else
- avoid_equals_and_hash_code_on_mutable_classes
# - avoid_escaping_inner_quotes # not yet tested
- avoid_field_initializers_in_const_classes
- avoid_function_literals_in_foreach_calls
# - avoid_implementing_value_types # not yet tested
- avoid_init_to_null
# - avoid_js_rounded_ints # only useful when targeting JS runtime
- avoid_null_checks_in_equality_operators
# - avoid_positional_boolean_parameters # not yet tested
# - avoid_print # not yet tested
# - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356)
# - avoid_redundant_argument_values # not yet tested
- avoid_relative_lib_imports
- avoid_renaming_method_parameters
- avoid_return_types_on_setters
# - avoid_returning_null # there are plenty of valid reasons to return null
# - avoid_returning_null_for_future # not yet tested
- avoid_returning_null_for_void
# - avoid_returning_this # there are plenty of valid reasons to return this
# - avoid_setters_without_getters # not yet tested
- avoid_shadowing_type_parameters
- avoid_single_cascade_in_expression_statements
- avoid_slow_async_io
# - avoid_type_to_string # we do this commonly
- avoid_types_as_parameter_names
# - avoid_types_on_closure_parameters # conflicts with always_specify_types
# - avoid_unnecessary_containers # not yet tested
- avoid_unused_constructor_parameters
- avoid_void_async
# - avoid_web_libraries_in_flutter # not yet tested
- await_only_futures
- camel_case_extensions
- camel_case_types
- cancel_subscriptions
# - cascade_invocations # not yet tested
- cast_nullable_to_non_nullable
# - close_sinks # not reliable enough
# - comment_references # blocked on https://github.com/flutter/flutter/issues/20765
# - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204
- control_flow_in_finally
# - curly_braces_in_flow_control_structures # not required by flutter style
# - diagnostic_describe_all_properties # not yet tested
- directives_ordering
# - do_not_use_environment # we do this commonly
- empty_catches
- empty_constructor_bodies
- empty_statements
- exhaustive_cases
- file_names # not yet tested
- flutter_style_todos
- hash_and_equals
- implementation_imports
# - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811
- iterable_contains_unrelated_type
# - join_return_with_assignment # not required by flutter style
- leading_newlines_in_multiline_strings
- library_names
- library_prefixes
# - lines_longer_than_80_chars # not required by flutter style
- list_remove_unrelated_type
# - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181
# - missing_whitespace_between_adjacent_strings # not yet tested
- no_adjacent_strings_in_list
# - no_default_cases # too many false positives
- no_duplicate_case_values
- no_logic_in_create_state
# - no_runtimeType_toString # ok in tests; we enable this only in packages/
- non_constant_identifier_names
- null_check_on_nullable_type_parameter
# - null_closures # not required by flutter style
# - omit_local_variable_types # opposite of always_specify_types
# - one_member_abstracts # too many false positives
# - only_throw_errors # https://github.com/flutter/flutter/issues/5792
- overridden_fields
- package_api_docs
# - package_names # non conforming packages in sdk
- package_prefixed_library_names
# - parameter_assignments # we do this commonly
- prefer_adjacent_string_concatenation
- prefer_asserts_in_initializer_lists
# - prefer_asserts_with_message # not required by flutter style
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
# - prefer_constructors_over_static_methods # far too many false positives
- prefer_contains
# - prefer_double_quotes # opposite of prefer_single_quotes
- prefer_equal_for_default_values
# - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods
- prefer_final_fields
- prefer_final_in_for_each
- prefer_final_locals
- prefer_for_elements_to_map_fromIterable
- prefer_foreach
# - prefer_function_declarations_over_variables # not yet tested
- prefer_generic_function_type_aliases
- prefer_if_elements_to_conditional_expressions
- prefer_if_null_operators
- prefer_initializing_formals
- prefer_inlined_adds
# - prefer_int_literals # not yet tested
# - prefer_interpolation_to_compose_strings # not yet tested
- prefer_is_empty
- prefer_is_not_empty
- prefer_is_not_operator
- prefer_iterable_whereType
# - prefer_mixin # https://github.com/dart-lang/language/issues/32
# - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932
# - prefer_relative_imports # not yet tested
- prefer_single_quotes
- prefer_spread_collections
- prefer_typing_uninitialized_variables
- prefer_void_to_null
# - provide_deprecation_message # not yet tested
# - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml
- recursive_getters
# - sized_box_for_whitespace # not yet tested
- slash_for_doc_comments
# - sort_child_properties_last # not yet tested
- sort_constructors_first
# - sort_pub_dependencies # prevents separating pinned transitive dependencies
- sort_unnamed_constructors_first
- test_types_in_equals
- throw_in_finally
- tighten_type_of_initializing_formals
# - type_annotate_public_apis # subset of always_specify_types
- type_init_formals
- unawaited_futures # too many false positives
# - unnecessary_await_in_return # not yet tested
- unnecessary_brace_in_string_interps
- unnecessary_const
# - unnecessary_final # conflicts with prefer_final_locals
- unnecessary_getters_setters
# - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498
- unnecessary_new
- unnecessary_null_aware_assignments
# - unnecessary_null_checks # not yet tested
- unnecessary_null_in_if_null_operators
- unnecessary_nullable_for_final_variable_declarations
- unnecessary_overrides
- unnecessary_parenthesis
# - unnecessary_raw_strings # not yet tested
- unnecessary_statements
- unnecessary_string_escapes
- unnecessary_string_interpolations
- unnecessary_this
- unrelated_type_equality_checks
# - unsafe_html # not yet tested
- use_full_hex_values_for_flutter_colors
# - use_function_type_syntax_for_parameters # not yet tested
- use_is_even_rather_than_modulo
# - use_key_in_widget_constructors # not yet tested
- use_late_for_private_fields_and_variables
- use_raw_strings
- use_rethrow_when_possible
# - use_setters_to_change_properties # not yet tested
# - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182
# - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
- valid_regexps
- void_checks
group 'io.github.v7lin.alipay_kit'
version '2.0.0'
version '2.2.0'
buildscript {
repositories {
google()
maven{
allowInsecureProtocol = true
url 'http://127.0.0.1:8081/repository/maven-public/'
}
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.4'
classpath 'com.android.tools.build:gradle:4.1.0'
}
}
rootProject.allprojects {
repositories {
google()
maven{
allowInsecureProtocol = true
url 'http://127.0.0.1:8081/repository/maven-public/'
}
google()
}
}
......@@ -56,6 +56,4 @@ android {
dependencies {
implementation 'androidx.annotation:annotation:1.0.0'
implementation 'com.qiaomeng:noutdid.alipaysdk:1.0.0@aar'
// v15.8.01
//vendorImplementation(name: 'alipaysdk-15.8.01.210112203525', ext: 'aar')
}
......@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
package io.github.v7lin.alipay_kit;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.alipay.sdk.app.AuthTask;
import com.alipay.sdk.app.PayTask;
import java.lang.ref.WeakReference;
import java.util.Map;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class AlipayKit implements MethodChannel.MethodCallHandler {
//
private static final String METHOD_ISINSTALLED = "isInstalled";
private static final String METHOD_PAY = "pay";
private static final String METHOD_AUTH = "auth";
private static final String METHOD_ONPAYRESP = "onPayResp";
private static final String METHOD_ONAUTHRESP = "onAuthResp";
private static final String ARGUMENT_KEY_ORDERINFO = "orderInfo";
private static final String ARGUMENT_KEY_AUTHINFO = "authInfo";
private static final String ARGUMENT_KEY_ISSHOWLOADING = "isShowLoading";
//
private Context applicationContext;
private Activity activity;
private MethodChannel channel;
public AlipayKit() {
super();
}
public AlipayKit(Context applicationContext, Activity activity) {
this.applicationContext = applicationContext;
this.activity = activity;
}
//
public void setApplicationContext(@Nullable Context applicationContext) {
this.applicationContext = applicationContext;
}
public void setActivity(@Nullable Activity activity) {
this.activity = activity;
}
public void startListening(@NonNull BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "v7lin.github.io/alipay_kit");
channel.setMethodCallHandler(this);
}
public void stopListening() {
channel.setMethodCallHandler(null);
channel = null;
}
// --- MethodCallHandler
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
if (METHOD_ISINSTALLED.equals(call.method)) {
boolean isInstalled = false;
try {
final PackageManager packageManager = applicationContext.getPackageManager();
PackageInfo info = packageManager.getPackageInfo("com.eg.android.AlipayGphone", PackageManager.GET_SIGNATURES);
isInstalled = info != null;
} catch (PackageManager.NameNotFoundException e) {
}
result.success(isInstalled);
} else if (METHOD_PAY.equals(call.method)) {
final String orderInfo = call.argument(ARGUMENT_KEY_ORDERINFO);
final boolean isShowLoading = call.argument(ARGUMENT_KEY_ISSHOWLOADING);
final WeakReference<Activity> activityRef = new WeakReference<>(activity);
final WeakReference<MethodChannel> channelRef = new WeakReference<>(channel);
new AsyncTask<String, String, Map<String, String>>() {
@Override
protected Map<String, String> doInBackground(String... params) {
Activity activity = activityRef.get();
if (activity != null && !activity.isFinishing()) {
PayTask task = new PayTask(activity);
return task.payV2(orderInfo, isShowLoading);
}
return null;
}
@Override
protected void onPostExecute(Map<String, String> result) {
if (result != null) {
Activity activity = activityRef.get();
MethodChannel channel = channelRef.get();
if (activity != null && !activity.isFinishing() && channel != null) {
channel.invokeMethod(METHOD_ONPAYRESP, result);
}
}
}
}.execute();
result.success(null);
} else if (METHOD_AUTH.equals(call.method)) {
final String authInfo = call.argument(ARGUMENT_KEY_AUTHINFO);
final boolean isShowLoading = call.argument(ARGUMENT_KEY_ISSHOWLOADING);
final WeakReference<Activity> activityRef = new WeakReference<>(activity);
final WeakReference<MethodChannel> channelRef = new WeakReference<>(channel);
new AsyncTask<String, String, Map<String, String>>(){
@Override
protected Map<String, String> doInBackground(String... strings) {
Activity activity = activityRef.get();
if (activity != null && !activity.isFinishing()) {
AuthTask task = new AuthTask(activity);
return task.authV2(authInfo, isShowLoading);
}
return null;
}
@Override
protected void onPostExecute(Map<String, String> result) {
if (result != null) {
Activity activity = activityRef.get();
MethodChannel channel = channelRef.get();
if (activity != null && !activity.isFinishing() && channel != null) {
channel.invokeMethod(METHOD_ONAUTHRESP, result);
}
}
}
}.execute();
result.success(null);
} else {
result.notImplemented();
}
}
}
package io.github.v7lin.alipay_kit;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import com.alipay.sdk.app.AuthTask;
import com.alipay.sdk.app.PayTask;
import java.lang.ref.WeakReference;
import java.util.Map;
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.PluginRegistry.Registrar;
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;
/**
* AlipayKitPlugin
*/
public class AlipayKitPlugin implements FlutterPlugin, ActivityAware {
// This static function is optional and equivalent to onAttachedToEngine. It supports the old
// pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
// plugin registration via this function while apps migrate to use the new Android APIs
// post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
public class AlipayKitPlugin implements FlutterPlugin, ActivityAware, MethodCallHandler {
//
// It is encouraged to share logic between onAttachedToEngine and registerWith to keep
// them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
// depending on the user's project. onAttachedToEngine or registerWith must both be defined
// in the same class.
public static void registerWith(Registrar registrar) {
AlipayKit alipayKit = new AlipayKit(registrar.context(), registrar.activity());
alipayKit.startListening(registrar.messenger());
}
// --- FlutterPlugin
private static final String METHOD_ISINSTALLED = "isInstalled";
private static final String METHOD_PAY = "pay";
private static final String METHOD_AUTH = "auth";
private final AlipayKit alipayKit;
private static final String METHOD_ONPAYRESP = "onPayResp";
private static final String METHOD_ONAUTHRESP = "onAuthResp";
public AlipayKitPlugin() {
alipayKit = new AlipayKit();
}
private static final String ARGUMENT_KEY_ORDERINFO = "orderInfo";
private static final String ARGUMENT_KEY_AUTHINFO = "authInfo";
private static final String ARGUMENT_KEY_ISSHOWLOADING = "isShowLoading";
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private MethodChannel channel;
private Context applicationContext;
private Activity activity;
// --- FlutterPlugin
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
alipayKit.setApplicationContext(binding.getApplicationContext());
alipayKit.setActivity(null);
alipayKit.startListening(binding.getBinaryMessenger());
channel = new MethodChannel(binding.getBinaryMessenger(), "v7lin.github.io/alipay_kit");
channel.setMethodCallHandler(this);
applicationContext = binding.getApplicationContext();
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
alipayKit.stopListening();
alipayKit.setActivity(null);
alipayKit.setApplicationContext(null);
channel.setMethodCallHandler(null);
channel = null;
applicationContext = null;
}
// --- ActivityAware
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
alipayKit.setActivity(binding.getActivity());
activity = binding.getActivity();
}
@Override
......@@ -66,6 +82,80 @@ public class AlipayKitPlugin implements FlutterPlugin, ActivityAware {
@Override
public void onDetachedFromActivity() {
alipayKit.setActivity(null);
activity = null;
}
// --- MethodCallHandler
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
if (METHOD_ISINSTALLED.equals(call.method)) {
boolean isInstalled = false;
try {
final PackageManager packageManager = applicationContext.getPackageManager();
PackageInfo info = packageManager.getPackageInfo("com.eg.android.AlipayGphone", PackageManager.GET_SIGNATURES);
isInstalled = info != null;
} catch (PackageManager.NameNotFoundException ignore) {
}
result.success(isInstalled);
} else if (METHOD_PAY.equals(call.method)) {
final String orderInfo = call.argument(ARGUMENT_KEY_ORDERINFO);
final boolean isShowLoading = call.argument(ARGUMENT_KEY_ISSHOWLOADING);
final WeakReference<Activity> activityRef = new WeakReference<>(activity);
final WeakReference<MethodChannel> channelRef = new WeakReference<>(channel);
new AsyncTask<String, String, Map<String, String>>() {
@Override
protected Map<String, String> doInBackground(String... params) {
Activity activity = activityRef.get();
if (activity != null && !activity.isFinishing()) {
PayTask task = new PayTask(activity);
return task.payV2(orderInfo, isShowLoading);
}
return null;
}
@Override
protected void onPostExecute(Map<String, String> result) {
if (result != null) {
Activity activity = activityRef.get();
MethodChannel channel = channelRef.get();
if (activity != null && !activity.isFinishing() && channel != null) {
channel.invokeMethod(METHOD_ONPAYRESP, result);
}
}
}
}.execute();
result.success(null);
} else if (METHOD_AUTH.equals(call.method)) {
final String authInfo = call.argument(ARGUMENT_KEY_AUTHINFO);
final boolean isShowLoading = call.argument(ARGUMENT_KEY_ISSHOWLOADING);
final WeakReference<Activity> activityRef = new WeakReference<>(activity);
final WeakReference<MethodChannel> channelRef = new WeakReference<>(channel);
new AsyncTask<String, String, Map<String, String>>(){
@Override
protected Map<String, String> doInBackground(String... strings) {
Activity activity = activityRef.get();
if (activity != null && !activity.isFinishing()) {
AuthTask task = new AuthTask(activity);
return task.authV2(authInfo, isShowLoading);
}
return null;
}
@Override
protected void onPostExecute(Map<String, String> result) {
if (result != null) {
Activity activity = activityRef.get();
MethodChannel channel = channelRef.get();
if (activity != null && !activity.isFinishing() && channel != null) {
channel.invokeMethod(METHOD_ONAUTHRESP, result);
}
}
}
}.execute();
result.success(null);
} else {
result.notImplemented();
}
}
}
......@@ -4,7 +4,7 @@
#
Pod::Spec.new do |s|
s.name = 'alipay_kit'
s.version = '2.0.0'
s.version = '2.2.0'
s.summary = 'A powerful Flutter plugin allowing developers to auth/pay with natvie Android & iOS Alipay SDKs.'
s.description = <<-DESC
A powerful Flutter plugin allowing developers to auth/pay with natvie Android & iOS Alipay SDKs.
......
......@@ -3,15 +3,16 @@ import 'dart:convert';
import 'package:alipay_kit/src/crypto/rsa.dart';
import 'package:alipay_kit/src/model/alipay_resp.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
///
class Alipay {
///
Alipay() {
_channel.setMethodCallHandler(_handleMethod);
}
Alipay._();
static Alipay get instance => _instance;
static final Alipay _instance = Alipay._();
static const String _METHOD_ISINSTALLED = 'isInstalled';
static const String _METHOD_PAY = 'pay';
......@@ -30,8 +31,9 @@ class Alipay {
static const String AUTHTYPE_AUTHACCOUNT = 'AUTHACCOUNT';
static const String AUTHTYPE_LOGIN = 'LOGIN';
final MethodChannel _channel =
const MethodChannel('v7lin.github.io/alipay_kit');
late final MethodChannel _channel =
const MethodChannel('v7lin.github.io/alipay_kit')
..setMethodCallHandler(_handleMethod);
final StreamController<AlipayResp> _payRespStreamController =
StreamController<AlipayResp>.broadcast();
......@@ -62,19 +64,17 @@ class Alipay {
}
/// 检测支付宝是否已安装 - x.y.z-Android-Only 版本下 iOS 调用会直接抛出异常 No implementation [MissingPluginException]
Future<bool> isInstalled() {
return _channel.invokeMethod<bool>(_METHOD_ISINSTALLED);
Future<bool> isInstalled() async {
return await _channel.invokeMethod<bool?>(_METHOD_ISINSTALLED) ?? false;
}
/// 支付
Future<void> payOrderJson({
@required String orderInfo,
required String orderInfo,
String signType = SIGNTYPE_RSA2,
@required String privateKey,
required String privateKey,
bool isShowLoading = true,
}) {
assert(orderInfo?.isNotEmpty ?? false);
assert(privateKey?.isNotEmpty ?? false);
return payOrderMap(
orderInfo: json.decode(orderInfo) as Map<String, dynamic>,
signType: signType,
......@@ -85,23 +85,19 @@ class Alipay {
/// 支付
Future<void> payOrderMap({
@required Map<String, dynamic> orderInfo,
required Map<String, dynamic> orderInfo,
String signType = SIGNTYPE_RSA2,
@required String privateKey,
required String privateKey,
bool isShowLoading = true,
}) {
assert(orderInfo?.isNotEmpty ?? false);
assert(privateKey?.isNotEmpty ?? false);
String charset = orderInfo['charset'] as String;
Encoding encoding =
(charset?.isNotEmpty ?? false) ? Encoding.getByName(charset) : null;
encoding ??= utf8;
Map<String, dynamic> clone = <String, dynamic>{
final String? charset = orderInfo['charset'] as String?;
final Encoding encoding = Encoding.getByName(charset) ?? utf8;
final Map<String, dynamic> clone = <String, dynamic>{
...orderInfo,
'sign_type': signType,
};
String param = _param(clone, encoding);
String sign = _sign(clone, signType, privateKey);
final String param = _param(clone, encoding);
final String sign = _sign(clone, signType, privateKey);
return payOrderSign(
orderInfo:
'$param&sign=${Uri.encodeQueryComponent(sign, encoding: encoding)}',
......@@ -111,10 +107,9 @@ class Alipay {
/// 支付 - x.y.z-Android-Only 版本下 iOS 调用会直接抛出异常 No implementation [MissingPluginException]
Future<void> payOrderSign({
@required String orderInfo,
required String orderInfo,
bool isShowLoading = true,
}) {
assert(orderInfo?.isNotEmpty ?? false);
return _channel.invokeMethod<void>(
_METHOD_PAY,
<String, dynamic>{
......@@ -126,22 +121,18 @@ class Alipay {
/// 登录
Future<void> auth({
@required String appId, // 支付宝分配给开发者的应用ID
@required String pid, // 签约的支付宝账号对应的支付宝唯一用户号,以2088开头的16位纯数字组成
@required String targetId, // 商户标识该次用户授权请求的ID,该值在商户端应保持唯一
required String appId, // 支付宝分配给开发者的应用ID
required String pid, // 签约的支付宝账号对应的支付宝唯一用户号,以2088开头的16位纯数字组成
required String targetId, // 商户标识该次用户授权请求的ID,该值在商户端应保持唯一
String authType =
AUTHTYPE_AUTHACCOUNT, // 标识授权类型,取值范围:AUTHACCOUNT 代表授权;LOGIN 代表登录
String signType =
SIGNTYPE_RSA2, // 商户生成签名字符串所使用的签名算法类型,目前支持 RSA2 和 RSA ,推荐使用 RSA2
@required String privateKey,
required String privateKey,
bool isShowLoading = true,
}) {
assert((appId?.isNotEmpty ?? false) && appId.length <= 16);
assert((pid?.isNotEmpty ?? false) && pid.length <= 16);
assert((targetId?.isNotEmpty ?? false) && targetId.length <= 32);
assert(authType == AUTHTYPE_AUTHACCOUNT || authType == AUTHTYPE_LOGIN);
assert(privateKey?.isNotEmpty ?? false);
Map<String, dynamic> authInfo = <String, dynamic>{
final Map<String, dynamic> authInfo = <String, dynamic>{
'apiname': 'com.alipay.account.auth',
'method': 'alipay.open.auth.sdk.code.get',
'app_id': appId,
......@@ -154,9 +145,9 @@ class Alipay {
'auth_type': authType,
};
authInfo['sign_type'] = signType;
Encoding encoding = utf8; // utf-8
String param = _param(authInfo, encoding);
String sign = _sign(authInfo, signType, privateKey);
final Encoding encoding = utf8; // utf-8
final String param = _param(authInfo, encoding);
final String sign = _sign(authInfo, signType, privateKey);
return authSign(
info: '$param&sign=${Uri.encodeQueryComponent(sign, encoding: encoding)}',
isShowLoading: isShowLoading,
......@@ -165,10 +156,9 @@ class Alipay {
/// 登录 - x.y.z-Android-Only 版本下 iOS 调用会直接抛出异常 No implementation [MissingPluginException]
Future<void> authSign({
@required String info,
required String info,
bool isShowLoading = true,
}) {
assert(info != null && info.isNotEmpty);
return _channel.invokeMethod<void>(
_METHOD_AUTH,
<String, dynamic>{
......@@ -187,9 +177,9 @@ class Alipay {
String _sign(Map<String, dynamic> map, String signType, String privateKey) {
// 参数排序
List<String> keys = map.keys.toList();
final List<String> keys = map.keys.toList();
keys.sort();
String content = keys.map((String e) => '$e=${map[e]}').join('&');
final String content = keys.map((String e) => '$e=${map[e]}').join('&');
String sign;
switch (signType) {
case SIGNTYPE_RSA:
......
import 'dart:convert';
import 'dart:typed_data';
import 'package:asn1lib/asn1lib.dart';
import 'package:pointycastle/pointycastle.dart';
import 'package:pointycastle/signers/rsa_signer.dart';
class RsaKeyParser {
RSAPublicKey parsePublic(String key) {
List<String> rows = key.split('\n');
String header = rows.first;
final List<String> rows = key.split('\n');
final String header = rows.first;
if (header == '-----BEGIN RSA PUBLIC KEY-----') {
return _parsePublic(_parseSequence(rows));
}
......@@ -19,8 +18,8 @@ class RsaKeyParser {
}
RSAPrivateKey parsePrivate(String key) {
List<String> rows = key.split('\n');
String header = rows.first;
final List<String> rows = key.split('\n');
final String header = rows.first;
if (header == '-----BEGIN RSA PRIVATE KEY-----') {
return _parsePrivate(_parseSequence(rows));
}
......@@ -31,41 +30,41 @@ class RsaKeyParser {
}
RSAPublicKey _parsePublic(ASN1Sequence sequence) {
BigInt modulus = (sequence.elements[0] as ASN1Integer).valueAsBigInteger;
BigInt exponent = (sequence.elements[1] as ASN1Integer).valueAsBigInteger;
final BigInt modulus = (sequence.elements![0] as ASN1Integer).integer!;
final BigInt exponent = (sequence.elements![1] as ASN1Integer).integer!;
return RSAPublicKey(modulus, exponent);
}
RSAPrivateKey _parsePrivate(ASN1Sequence sequence) {
BigInt modulus = (sequence.elements[1] as ASN1Integer).valueAsBigInteger;
BigInt exponent = (sequence.elements[3] as ASN1Integer).valueAsBigInteger;
BigInt p = (sequence.elements[4] as ASN1Integer).valueAsBigInteger;
BigInt q = (sequence.elements[5] as ASN1Integer).valueAsBigInteger;
final BigInt modulus = (sequence.elements![1] as ASN1Integer).integer!;
final BigInt exponent = (sequence.elements![3] as ASN1Integer).integer!;
final BigInt? p = (sequence.elements?[4] as ASN1Integer?)?.integer;
final BigInt? q = (sequence.elements?[5] as ASN1Integer?)?.integer;
return RSAPrivateKey(modulus, exponent, p, q);
}
ASN1Sequence _parseSequence(List<String> rows) {
String keyText = rows
final String keyText = rows
.skipWhile((String row) => row.startsWith('-----BEGIN'))
.takeWhile((String row) => !row.startsWith('-----END'))
.map((String row) => row.trim())
.join('');
Uint8List keyBytes = Uint8List.fromList(base64.decode(keyText));
ASN1Parser asn1Parser = ASN1Parser(keyBytes);
final Uint8List keyBytes = Uint8List.fromList(base64.decode(keyText));
final ASN1Parser asn1Parser = ASN1Parser(keyBytes);
return asn1Parser.nextObject() as ASN1Sequence;
}
ASN1Sequence _pkcs8PublicSequence(ASN1Sequence sequence) {
ASN1Object object = sequence.elements[1];
List<int> bytes = object.valueBytes().sublist(1);
ASN1Parser parser = ASN1Parser(Uint8List.fromList(bytes));
final ASN1Object object = sequence.elements![1];
final List<int> bytes = object.valueBytes!.sublist(1);
final ASN1Parser parser = ASN1Parser(Uint8List.fromList(bytes));
return parser.nextObject() as ASN1Sequence;
}
ASN1Sequence _pkcs8PrivateSequence(ASN1Sequence sequence) {
ASN1Object object = sequence.elements[2];
Uint8List bytes = object.valueBytes();
ASN1Parser parser = ASN1Parser(bytes);
final ASN1Object object = sequence.elements![2];
final Uint8List bytes = object.valueBytes!;
final ASN1Parser parser = ASN1Parser(bytes);
return parser.nextObject() as ASN1Sequence;
}
}
......@@ -82,7 +81,7 @@ class RsaSigner {
_rsaSigner
..reset()
..init(true, PrivateKeyParameter<RSAPrivateKey>(_privateKey));
RSASignature signature =
final RSASignature signature =
_rsaSigner.generateSignature(Uint8List.fromList(message));
return signature.bytes;
}
......
import 'package:json_annotation/json_annotation.dart';
class NullableStringToBoolConverter implements JsonConverter<bool, String?> {
const NullableStringToBoolConverter();
@override
bool fromJson(String? json) {
return json == true.toString();
}
@override
String? toJson(bool object) {
return object.toString();
}
}
class NullableStringToNullableIntConverter
implements JsonConverter<int?, String?> {
const NullableStringToNullableIntConverter();
@override
int? fromJson(String? json) {
if (json is String) {
return int.tryParse(json);
}
return null;
}
@override
String? toJson(int? object) {
return object?.toString();
}
}
int intFromString(String json) {
return (json?.isNotEmpty ?? false) ? int.parse(json) : null;
}
String intToString(int object) {
return object?.toString();
}
bool boolFromString(String json) {
return json != null ? json == true.toString() : null;
}
String boolToString(bool object) {
return object?.toString();
}
import 'package:alipay_kit/src/json/string_converter.dart';
import 'package:alipay_kit/src/json/jser_converter.dart';
import 'package:json_annotation/json_annotation.dart';
part 'alipay_auth_result.g.dart';
......@@ -9,7 +9,7 @@ part 'alipay_auth_result.g.dart';
)
class AlipayAuthResult {
AlipayAuthResult({
this.success,
required this.success,
this.resultCode,
this.authCode,
this.userId,
......@@ -18,23 +18,17 @@ class AlipayAuthResult {
factory AlipayAuthResult.fromJson(Map<String, dynamic> json) =>
_$AlipayAuthResultFromJson(json);
@JsonKey(
fromJson: boolFromString,
toJson: boolToString,
)
@NullableStringToBoolConverter()
final bool success;
/// 200 业务处理成功,会返回authCode
/// 1005 账户已冻结,如有疑问,请联系支付宝技术支持
/// 202 系统异常,请稍后再试或联系支付宝技术支持
@JsonKey(
fromJson: intFromString,
toJson: intToString,
)
final int resultCode;
@NullableStringToNullableIntConverter()
final int? resultCode;
final String authCode;
final String userId;
final String? authCode;
final String? userId;
Map<String, dynamic> toJson() => _$AlipayAuthResultToJson(this);
}
......@@ -8,17 +8,20 @@ part of 'alipay_auth_result.dart';
AlipayAuthResult _$AlipayAuthResultFromJson(Map<String, dynamic> json) {
return AlipayAuthResult(
success: boolFromString(json['success'] as String),
resultCode: intFromString(json['result_code'] as String),
authCode: json['auth_code'] as String,
userId: json['user_id'] as String,
success: const NullableStringToBoolConverter()
.fromJson(json['success'] as String?),
resultCode: const NullableStringToNullableIntConverter()
.fromJson(json['result_code'] as String?),
authCode: json['auth_code'] as String?,
userId: json['user_id'] as String?,
);
}
Map<String, dynamic> _$AlipayAuthResultToJson(AlipayAuthResult instance) =>
<String, dynamic>{
'success': boolToString(instance.success),
'result_code': intToString(instance.resultCode),
'success': const NullableStringToBoolConverter().toJson(instance.success),
'result_code': const NullableStringToNullableIntConverter()
.toJson(instance.resultCode),
'auth_code': instance.authCode,
'user_id': instance.userId,
};
import 'package:alipay_kit/src/json/string_converter.dart';
import 'package:alipay_kit/src/json/jser_converter.dart';
import 'package:alipay_kit/src/model/alipay_auth_result.dart';
import 'package:json_annotation/json_annotation.dart';
......@@ -25,21 +25,22 @@ class AlipayResp {
/// 5000——重复请求
/// 6001——用户中途取消
/// 6002——网络连接出错
@JsonKey(
fromJson: intFromString,
toJson: intToString,
)
final int resultStatus;
@NullableStringToNullableIntConverter()
final int? resultStatus;
/// 支付后结果
final String result;
final String? result;
final String memo;
final String? memo;
AlipayAuthResult parseAuthResult() {
if (resultStatus == 9000) {
if (result != null && result.isNotEmpty) {
Map<String, String> params =
bool get isSuccessful => resultStatus == 9000;
bool get isCancelled => resultStatus == 6001;
AlipayAuthResult? parseAuthResult() {
if (isSuccessful) {
if (result?.isNotEmpty ?? false) {
final Map<String, String> params =
Uri.parse('alipay://alipay?$result').queryParameters;
return AlipayAuthResult.fromJson(params);
}
......
......@@ -8,15 +8,17 @@ part of 'alipay_resp.dart';
AlipayResp _$AlipayRespFromJson(Map<String, dynamic> json) {
return AlipayResp(
resultStatus: intFromString(json['resultStatus'] as String),
result: json['result'] as String,
memo: json['memo'] as String,
resultStatus: const NullableStringToNullableIntConverter()
.fromJson(json['resultStatus'] as String?),
result: json['result'] as String?,
memo: json['memo'] as String?,
);
}
Map<String, dynamic> _$AlipayRespToJson(AlipayResp instance) =>
<String, dynamic>{
'resultStatus': intToString(instance.resultStatus),
'resultStatus': const NullableStringToNullableIntConverter()
.toJson(instance.resultStatus),
'result': instance.result,
'memo': instance.memo,
};
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
asn1lib:
dependency: "direct main"
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
url: "https://pub.flutter-io.cn"
source: hosted
version: "29.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.6.0"
args:
dependency: transitive
description:
name: args
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.0"
async:
dependency: transitive
description:
name: async
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.8.1"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
build:
dependency: transitive
description:
name: asn1lib
name: build
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.5.15"
version: "2.1.1"
build_config:
dependency: transitive
description:
name: build_config
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.0"
build_daemon:
dependency: transitive
description:
name: build_daemon
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.1"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.4"
build_runner:
dependency: "direct dev"
description:
name: build_runner
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.4"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.flutter-io.cn"
source: hosted
version: "7.2.2"
built_collection:
dependency: transitive
description:
name: built_collection
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
url: "https://pub.flutter-io.cn"
source: hosted
version: "8.1.2"
characters:
dependency: transitive
description:
......@@ -15,6 +99,41 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.1"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.1"
cli_util:
dependency: transitive
description:
name: cli_util
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.3.5"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
code_builder:
dependency: transitive
description:
name: code_builder
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.1.0"
collection:
dependency: transitive
description:
......@@ -22,18 +141,135 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.15.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.1"
dart_style:
dependency: transitive
description:
name: dart_style
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.0"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.0"
file:
dependency: transitive
description:
name: file
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.1.2"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
frontend_server_client:
dependency: transitive
description:
name: frontend_server_client
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.2"
glob:
dependency: transitive
description:
name: glob
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.2"
graphs:
dependency: transitive
description:
name: graphs
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
http_multi_server:
dependency: transitive
description:
name: http_multi_server
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.1"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.0.0"
io:
dependency: transitive
description:
name: io
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.3"
js:
dependency: transitive
description:
name: js
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.6.3"
json_annotation:
dependency: "direct main"
description:
name: json_annotation
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.1.1"
version: "4.1.0"
json_serializable:
dependency: "direct dev"
description:
name: json_serializable
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.0.2"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.2"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.12.10"
meta:
dependency: transitive
description:
......@@ -41,18 +277,151 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.7.0"
mime:
dependency: transitive
description:
name: mime
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.0"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.2"
path:
dependency: transitive
description:
name: path
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.0"
pedantic:
dependency: "direct dev"
description:
name: pedantic
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.11.1"
pointycastle:
dependency: "direct main"
description:
name: pointycastle
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.2"
version: "3.3.4"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.5.0"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
shelf:
dependency: transitive
description:
name: shelf
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.0"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.1"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_gen:
dependency: transitive
description:
name: source_gen
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.1"
source_helper:
dependency: transitive
description:
name: source_helper
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.0"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
stream_transform:
dependency: transitive
description:
name: stream_transform
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.4.2"
timing:
dependency: transitive
description:
name: timing
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.0"
typed_data:
dependency: transitive
description:
......@@ -67,6 +436,27 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.1"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.1.0"
sdks:
dart: ">=2.12.0 <3.0.0"
flutter: ">=1.10.0"
dart: ">=2.14.0 <3.0.0"
flutter: ">=1.20.0"
name: alipay_kit
description: A powerful Flutter plugin allowing developers to auth/pay with natvie Android & iOS Alipay SDKs.
version: 2.0.0
homepage: https://github.com/v7lin/fake_alipay
version: 2.2.0-nullsafety #-Android-Only
# author: v7lin <v7lin@qq.com>
homepage: https://github.com/rxreader/alipay_kit
environment:
sdk: ">=2.7.0 <3.0.0"
flutter: ">=1.10.0"
sdk: ">=2.12.0 <3.0.0"
flutter: ">=1.20.0"
dependencies:
asn1lib: ^0.5.8
pointycastle: ^1.0.0
flutter:
sdk: flutter
json_annotation: '>=2.0.0 <4.0.0'
pointycastle: ^3.0.0-nullsafety.2
json_annotation: ^4.0.0
dev_dependencies:
flutter_test:
sdk: flutter
pedantic:
build_runner:
json_serializable:
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# This section identifies this Flutter project as a plugin project.
# The 'pluginClass' and Android 'package' identifiers should not ordinarily
# be modified. They are used by the tooling to maintain consistency when
# adding or updating assets for this project.
plugin:
platforms:
android:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment