Open-source project
OpenFlutter/tobias avatar
OpenFlutter/tobias

Tobias: an Alipay SDK plugin for Flutter across iOS, Android and OpenHarmony

AliPay For Flutter.支付宝Flutter插件

749 stars139 forksObjective-CApache-2.0

At a glance

What is it?
Tobias wraps the AlipaySDK for Flutter apps and covers three platforms, but its 6.0.0 release moved all iOS configuration out of the plugin and into the developer's own Xcode project. It is a reasonable choice for a Chinese payment flow that needs a native SDK, and the manual iOS setup is the part to plan for.
Who is it for?
Tobias fits a Flutter team that needs the native Alipay SDK for an in-app payment or auth flow and is prepared to configure the iOS target by hand, including Info.plist keys, associated domains and a universal link. It does not fit a team that wants the plugin to write its own iOS configuration, since 6.0.0 deliberately removed that behaviour.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 39 days ago.
What is it written in?
Mainly Objective-C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A thin Flutter wrapper over the native Alipay SDK

Tobias is a Flutter plugin for AliPaySDK, and it works on iOS, Android and OpenHarmony. That is the whole product: a Dart class that forwards calls to the vendor's native SDK and hands the results back as a map.

The three-platform coverage is the part that distinguishes it. Most payment plugins in the Flutter ecosystem cover the two mobile platforms, and OpenHarmony support means the plugin ships an ohos/ directory alongside android/ and ios/. The repository layout matches that, with android/, ios/ and ohos/ at the top level next to lib/, test/ and example/.

The primary language of the repository is listed as Objective-C, which is a sign of how the iOS side is built: the plugin wraps the vendor's Objective-C SDK rather than reimplementing anything.

The audience is a Flutter developer building a Chinese-market payment flow. The readme recommends reading the official Alipay documentation before using Tobias, which is the right instruction: the plugin moves you across the platform channel, it does not explain Alipay's own product, and the merchant setup, signing and order parameters are still Alipay's problem.

The project is Apache-2.0 licensed, and the copyright line in the licence file reads Copyright 2018 OpenFlutter Project, so the plugin itself has been around long enough to have accumulated platform-specific configuration baggage.

6.0.0 stopped touching your Xcode project

The most consequential line in the readme is a breaking change notice, and it is worth reading before anything else.

Tobias no longer modifies your Xcode project during pod install. The tobias: section in pubspec.yaml, with its url_scheme, no_utdid, ios.ignore_security and ios.universal_link keys, is obsolete and ignored. Everything has to be configured by hand.

The reason is not stated, but the effect is clear: the plugin used to write configuration into the host app's Xcode project as a side effect of pod install, and that behaviour is gone. For a team that upgrades from 5.x, this is a day of work, not an afternoon, because you have to add keys to Info.plist, add an entitlements file, and set up a universal link that used to be generated for you.

The benefit is real too, and it is the usual one: a plugin that mutates your project file behind your back is a plugin that will eventually conflict with your own configuration. A plugin that leaves your Xcode project alone is a plugin you can reason about.

The current release line is still in preview. The recent tags are v6.0.0-preview.4 from 2026-09-16, v6.0.0-preview.3 from 2026-08-27 and v6.0.0-preview.2 from 2026-08-03, so the 6.x line is still settling. The repository is not archived, and the last push was on 2026-09-16.

Manual iOS configuration: Info.plist, query schemes and transport security

The iOS section is a checklist, and it is the bulk of what you need to get right.

First, your own URL scheme, which is a unique string used to resume your app, and the readme notes that an underscore is not allowed. That goes into Info.plist as a CFBundleURLTypes array. Then, so that your app can query the Alipay app, LSApplicationQueriesSchemes has to list alipays.

Both are plain plist fragments:

xml
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>alipays</string>
</array>

The third fragment is the one most people would hesitate to add. Because Alipay still serves some content over HTTP, the readme says that unless you know what you are doing, you should add NSAppTransportSecurity with NSAllowsArbitraryLoads and NSAllowsArbitraryLoadsInWebContent both set to true.

That advice is worth pausing on. Disabling App Transport Security wholesale is a real security decision, and the plugin author is explicit that the default position should be to add it only if you do not have a reason not to. On a payment flow, the sensible move is to find out why Alipay is still serving HTTP content on that path and scope the exemption as narrowly as you can, which may not be possible with these two global keys.

Universal links and associated domains are mandatory for Alipay

Universal link is required by Alipay, so the associated domains capability has to be enabled and the host of your universal link added to Runner.entitlements:

xml
<key>com.apple.developer.associated-domains</key>
<array>
    <string>applinks:your.domain.com</string>
</array>

The readme points at example/ios/Runner in the repository for a working setup, which is the fastest way to see the whole configuration in one place rather than assembling it from the readme's fragments.

Two things follow from universal links being mandatory. First, you need a domain you control, with an apple-app-site-association file served over HTTPS, which is a piece of server-side work that has nothing to do with Flutter. Second, on iOS you have to pass the universal link into the plugin when you make a payment, and the readme says so explicitly.

That is a meaningful amount of infrastructure for what looks like a one-line API call in Dart. A team that already has a marketing site with a working associated domains setup will find this quick; a team without one will discover that the payment integration is also a web hosting project.

Swift Package Manager support, with CocoaPods as the fallback

Tobias supports both Swift Package Manager and CocoaPods, and the readme shows the one command that enables SPM:

shell
flutter config --enable-swift-package-manager

Nothing else is required, because Flutter picks up ios/tobias/Package.swift automatically. If SPM is not enabled, the CocoaPods podspec is used as before.

The repository has an SPM_MIGRATION_PLAN.md at the top level, which tells you that the migration is a known, planned piece of work rather than an accident. The example directory also has a web/ folder alongside the android/, ios/ and ohos/ ones, and integration_test/ and test/ directories, so the plugin is exercised through the example application rather than only in unit tests.

One note on the framework choice. The plugin is described as working on iOS, Android and OpenHarmony, and the iOS instructions cover both dependency managers, but the native side is Objective-C against the vendor's SDK, and the Objective-C AppDelegate code in the readme is the older style of open URL handling. If your app has already moved to a scene-based AppDelegate, the URL handling story is yours to wire up.

Pay and auth, and the result map that comes back

The Dart API is small. You construct a Tobias instance and hand it the order information from your server:

dart
import 'package:tobias/tobias.dart' ;
Tobias tobias = Tobias();
tobias.pay(yourOrder);

The auth call follows the same shape, taking an auth string:

dart
import 'package:tobias/tobias.dart' ;
Tobias tobias = Tobias();
tobias.auth("your auth str);

The result is a map containing the results from Alipay, and it also carries an external field named platform, which says whether the result came from iOS or Android. That field is the one piece of Dart-facing logic in the plugin that you will actually branch on, since the payment result itself is an opaque payload.

The result sample in the readme shows the shape: a result field carrying a query string of partner, seller_id, out_trade_no, subject, total_fee, notify_url and the signature, a resultStatus of 9000, a memo field, and the platform field. Two notes come with it. Tobias uses pay_V2, so the V1 flow is not what you get. And the resultStatus value of 9000 in the sample is Alipay's own success code, which means your app has to interpret the status itself rather than relying on an exception.

There is also a check for whether the Alipay app is installed, which is the sane thing to do before offering an Alipay button on a device that does not have the app:

dart
Tobias tobias = Tobias();
var result = await tobias.isAliPayInstalled;

And a version call, tobias.version, which returns a map with version and platform.

The AppDelegate override that older integrations should delete

The readme carries an upgrade note that is only relevant to projects that started on Tobias before 1.0.0. There is no need to override AppDelegate since Tobias 1.0.0, and if you did that before, you should remove the following code from your AppDelegate:

objective-c
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
  return [TobiasPlugin handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
  return [TobiasPlugin handleOpenURL:url];
}

If you have to override those two functions, the readme says to make sure you have called super, and it shows both versions of the override doing that.

This is worth mentioning because it is a common source of a subtle bug. Leaving the old override in place after upgrading means your app handles the Alipay callback URL twice or in the wrong order, and the symptom is a payment that completes on the Alipay side but never returns to your app.

The other upgrade note concerns the SDK variant: the no_utdid variant of the iOS SDK was removed in 6.0.0, and if you depend on it you should stay on 5.x for now. The no_utdid option in pubspec.yaml is one of the keys that is now obsolete and ignored, which is consistent with that removal.

Editorial conclusion

Tobias fits a Flutter team that needs the native Alipay SDK for an in-app payment or auth flow and is prepared to configure the iOS target by hand, including Info.plist keys, associated domains and a universal link. It does not fit a team that wants the plugin to write its own iOS configuration, since 6.0.0 deliberately removed that behaviour. Before upgrading to 6.x, read SPM_MIGRATION_PLAN.md, check the app delegate overrides the readme asks you to remove, and confirm you are on pay_V2 and, if you need the no_utdid iOS variant, still on 5.x.

Frequently asked questions

What platforms does the Tobias Flutter plugin support?

Tobias is a Flutter plugin for the Alipay SDK and works on iOS, Android and OpenHarmony. The repository has android/, ios/ and ohos/ directories at the top level, and the result map includes a platform field indicating whether the result came from iOS or Android.

What changed in Tobias 6.0.0?

Tobias no longer modifies your Xcode project during pod install, and the tobias: section in pubspec.yaml with url_scheme, no_utdid, ios.ignore_security and ios.universal_link is obsolete and ignored. You have to configure Info.plist, the associated domains entitlement and the universal link by hand, and the no_utdid variant of the iOS SDK was removed.

How do I call the Alipay payment from Flutter with Tobias?

Import the package, create a Tobias instance and pass the order information from your server to pay, for example tobias.pay(yourOrder). The result is a map with the Alipay result payload, a resultStatus, a memo field and a platform field, and Tobias uses pay_V2.

What iOS configuration does the Tobias plugin need?

Add your own url scheme to CFBundleURLTypes, list alipays in LSApplicationQueriesSchemes so the app can query Alipay, add the associated domains entitlement for your universal link host, and add the NSAppTransportSecurity keys unless you have a specific reason not to, because Alipay still serves some content over HTTP.

Can I check whether the Alipay app is installed with Tobias?

Yes, tobias.isAliPayInstalled returns whether the Alipay app is present on the device, which you can await before offering an Alipay payment option. There is also tobias.version, which returns a map containing version and platform.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. OpenFlutter/tobias on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/openflutter-tobias.svg)](https://hysenlabs.com/projects/openflutter-tobias)

Was this useful?