Skip to main content
本页面介绍官方 Dodo Payments Flutter package(位于 dodopayments_checkout,pub.dev)。此外还存在一个由社区构建的独立 package。请参阅 社区项目。

Checkout Sessions API

从你的后端创建此 SDK 打开的 checkout_url。

Mobile Integration Guide

了解此 SDK 如何融入完整的移动支付流程。
dodopayments_checkout 会在 iOS 的 SFSafariViewController 和 Android 的 Custom Tab 中打开 Dodo Payments 托管结账,并返回类型化的 CheckoutResult。它使用与独立 iOS 和 Android SDK 相同的原生代码,所有结账逻辑都位于该原生代码中。Dart 层通过类型化的 Pigeon channel 传递每次调用。该 package 不保存 API key,也不会调用 Dodo Payments API。 **要求:**Flutter 3.44 或更高版本、Dart 3.12 或更高版本、iOS 16 或更高版本,以及 Android minSdk 23。

安装

1

Add the Dependency

将 package 添加到 pubspec.yaml:
pubspec.yaml
外观自定义要求版本 1.1.0 或更高版本。Android plugin 默认针对 Android SDK 35 进行编译。如果其他 plugin 需要更高的 compileSdk,请在应用的 gradle.properties 中设置 dodoCompileSdk。
2

Register a Callback URL Scheme

注册一个 URL scheme,使操作系统将结账返回 URL 路由回你的应用。在传递给 SDK 的 returnUrl 中使用此 scheme,并在后端创建 session 时,将相同的 URL 设置为结账 session 的 return_url。此 URL 无需加载真实页面。
在 ios/Runner/Info.plist 中为你的 scheme 添加 URL 类型:
ios/Runner/Info.plist
SFSafariViewController 无法捕获自身的返回 URL,因此 iOS 会在你的应用中打开该 URL。将每个传入的 URL 转发给 SDK,例如通过 app_links:
你可以转发每个 URL。handleOpenURL 仅处理与正在进行的结账的 returnUrl 匹配的 URL,并为其解析 true。对于任何 其他 URL,它会解析 false。在 Android 上,它始终解析 false。

使用

使用后端返回的 checkout_url 调用 DodoCheckout.instance.start:
onEvent 接收 type 为 CheckoutEventType.opened、returnReceived 或 closed 的事件。仅将它们用于日志记录,切勿据此决定结果。

结果含义

SDK 根据返回 URL 中的查询参数构建 CheckoutResult。
result.status 是 UI 提示,而不是付款证明。请使用 payment.succeeded 或 subscription.active webhook 从后端确认每笔付款。
CheckoutStatus
必填
五个值之一:
  • succeeded:返回 URL 包含 status=succeeded(一次性付款)或 status=active(订阅)。
  • failed:付款被拒绝(status=failed)。
  • cancelled:客户在返回 URL 到达前关闭了浏览器视图。SDK 不知道结果,付款可能已经成功,因此不要显示失败页面。请改为对已放弃的 session进行对账。
  • pending:付款稍后结算(status=processing 或任何 requires_* 值),或者缺少或无法识别 status 参数。请按照 cancelled 进行对账。
  • expired:结账 session 已过期(status=expired)。
String?
当返回 URL 包含 payment_id 查询参数时显示它,但不要使用它来授予访问权限。请参阅验证付款。
String?
subscription_id 查询参数。用于订阅结账。
List<String>?
license_key 查询参数。在结账包含 license key 产品时设置。
String?
email 查询参数。在结账捕获 email address 时设置。
Map<String, String>
返回 URL 中的每个查询参数,原样返回。

验证付款

Webhooks

付款成功或订阅激活时,Dodo Payments 会调用你的后端。

Get Payment Detail

使用 secret key 查询 paymentId 以检查其状态。
只有在以下任一项确认付款后,才授予访问权限。不要仅依赖 result.status。

外观自定义

要更改结账浏览器的工具栏、按钮和配色方案,请将 BrowserCustomization 作为 customization 传递给 CheckoutParams。Android Custom Tabs 和 iOS SFSafariViewController 提供不同的原生控件,因此选项分为 AndroidBrowserOptions 和 IosBrowserOptions。每个平台都会忽略另一个平台的选项。每个字段都是可选的,默认值为 null。对于值为 null 的字段,SDK 不会设置该选项,而是由平台应用自身的默认值。
Color?
工具栏背景颜色。
Color?
导航栏颜色。
Color?
导航栏上方分隔线的颜色。
CloseButtonStyle?
standard 显示系统的“X”图标。back 显示由 SDK 绘制的返回箭头。
CloseButtonPosition?
工具栏中关闭按钮出现的一侧:start 或 end。
bool?
显示工具栏的分享图标。false 会将其隐藏。
bool?
在工具栏中 URL 下方显示页面标题。
bool?
页面滚动时自动隐藏工具栏。
bool?
在溢出菜单中显示“将此页面加入书签”。
bool?
在溢出菜单中显示“下载页面”。
BrowserColorScheme?
light 或 dark 会强制使用相应外观,而不考虑设备的系统设置。system 遵循系统设置。
DismissButtonStyle?
关闭按钮的样式:done、close 或 cancel。由 iOS 决定将其渲染为标签还是图标。
PresentationStyle?
pageSheet(在将此 null 留空时使用)会显示一张客户可以向下滑动关闭的卡片。fullScreen 会覆盖整个屏幕。
bool?
允许工具栏在页面滚动时折叠。仅当 presentationStyle 为 fullScreen 时才有效。使用 pageSheet 时,无论此设置如何,工具栏都会保持固定。
BrowserColorScheme?
light 或 dark 会强制使用相应外观,而不考虑设备的系统设置。system 遵循系统设置。
iOS 没有工具栏颜色选项,因为底层 SFSafariViewController tint 属性自 iOS 26 起已弃用。

错误

start 仅在误用或平台故障时抛出 CheckoutException。请从 code(一个 CheckoutErrorCode)中读取原因。原生代码字符串位于 nativeCode。 客户取消或付款被拒绝始终是结果,而不是 exception。
  • invalidCheckoutUrl(INVALID_CHECKOUT_URL):checkoutUrl 不是 checkout.dodopayments.com 或 test.checkout.dodopayments.com 上的 https 结账 session URL(路径以 /session/ 开头)。
  • invalidReturnUrl(INVALID_RETURN_URL):returnUrl 不是包含 scheme 和 host 的绝对 URL。
  • alreadyInProgress(ALREADY_IN_PROGRESS):另一个结账正在运行。一次只能运行一个结账。
  • platformError(PLATFORM_ERROR):意外的平台故障。未知的原生错误也会映射到此 code。

已放弃的 Session

原生 SDK 会在结账开始时记录结账 session,并仅在结账以 succeeded、failed 或 expired 结束时清除该记录。如果应用在结账期间被终止,或结果为 cancelled 或 pending,该记录会保留。请在下次启动时,以及每次出现 cancelled 或 pending 结果后检查该记录。
abandoned.sessionId 是结账 session ID,以 cks_ 开头。abandoned.createdAt 是结账开始时的 DateTime。你的后端可以使用 Get Checkout Session 查询该 session,该接口会返回其 payment_id 和 payment_status。在付款达到最终状态之前,应将其视为 pending,而不是 failed。

相关内容

Mobile Integration Guide

Android、iOS 和 React Native 使用相同的契约。

Community Projects

此外还存在一个由社区构建的独立 Flutter package。
最后修改于 2026年9月26日