跳转到主要内容

前提条件

在将 Dodo Payments 集成到您的移动应用之前,请确保您拥有:
  • Dodo Payments 账户:具有 API 访问权限的活跃商户账户
  • API 凭证:来自仪表板的 API 密钥和 webhook 密钥
  • 移动应用项目:Android、iOS、React Native 或 Flutter 应用程序
  • 后端服务器:安全处理结账会话创建

集成工作流程

移动集成遵循一个安全的 4 步骤流程,其中您的后端处理 API 调用,而您的移动应用管理用户体验。
1

后端:创建结账会话

结账会话 API 文档

了解如何在您的后端使用 Node.js、Python 等创建结账会话。请参阅专门的 结账会话 API 文档中的完整示例和参数参考。
安全性:结账会话必须在您的后端服务器上创建,绝不能在移动应用中创建。这可以保护您的 API 密钥并确保正确的验证。
2

移动:获取结账 URL

您的移动应用调用您的后端以获取结账 URL:
func getCheckoutURL(productId: String, customerEmail: String, customerName: String) async throws -> String {
    let url = URL(string: "https://your-backend.com/api/create-checkout-session")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    
    let requestData: [String: Any] = [
        "productId": productId,
        "customerEmail": customerEmail,
        "customerName": customerName
    ]
    request.httpBody = try JSONSerialization.data(withJSONObject: requestData)
    
    let (data, _) = try await URLSession.shared.data(for: request)
    let response = try JSONDecoder().decode(CheckoutResponse.self, from: data)
    return response.checkout_url
}
安全性:移动应用仅与您的后端通信,绝不直接与 Dodo Payments API 通信。
3

移动:在浏览器中打开结账

在安全的应用内浏览器中打开结账 URL 以进行支付处理。

查看平台特定的集成示例

查看 Android、iOS 和 Flutter 移动支付的完整代码和设置说明。
4

后端:处理支付完成

通过 webhook 和重定向 URL 处理支付完成,以确认支付状态。

平台特定集成

在下面选择您的移动平台以获取完整的实现示例:

Android 集成

Chrome 自定义标签实现

// Add Chrome Custom Tabs dependency to build.gradle
implementation 'androidx.browser:browser:1.5.0'

// In your Activity
class PaymentActivity : AppCompatActivity() {
    private var customTabsSession: CustomTabsSession? = null
    private var customTabsClient: CustomTabsClient? = null
    private var customTabsServiceConnection: CustomTabsServiceConnection? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // Initialize Custom Tabs
        customTabsServiceConnection = object : CustomTabsServiceConnection() {
            override fun onCustomTabsServiceConnected(name: ComponentName, client: CustomTabsClient) {
                customTabsClient = client
                customTabsClient?.warmup(0L)
                customTabsSession = customTabsClient?.newSession(object : CustomTabsCallback() {
                    override fun onNavigationEvent(navigationEvent: Int, extras: Bundle?) {
                        // Handle navigation events
                    }
                })
            }
            override fun onServiceDisconnected(name: ComponentName) {
                customTabsClient = null
            }
        }
        CustomTabsClient.bindCustomTabsService(
            this,
            "com.android.chrome",
            customTabsServiceConnection!!
        )
        // Get checkout URL from backend and launch
        lifecycleScope.launch {
            try {
                val checkoutURL = getCheckoutURL("prod_123", "[email protected]", "Customer Name")
                val customTabsIntent = CustomTabsIntent.Builder(customTabsSession)
                    .build()
                customTabsIntent.launchUrl(this@PaymentActivity, Uri.parse(checkoutURL))
            } catch (e: Exception) {
                // Handle error
                Log.e("PaymentActivity", "Failed to get checkout URL", e)
            }
        }
    }
}

最佳实践

  • 安全性:绝不要在应用代码中存储 API 密钥。使用安全存储和 SSL 钉扎。
  • 用户体验:显示加载指示器,优雅地处理错误,并提供清晰的消息。
  • 测试:使用测试卡,模拟网络错误,并在各种设备上进行测试。

故障排除

常见问题

  • WebView 未打开支付链接:确保支付链接有效并使用 HTTPS。
  • 未收到回调:检查您的返回 URL 和 webhook 配置。
  • API 密钥错误:验证您的 API 密钥是否正确并具有必要的权限。

其他资源

如有问题或需要支持,请联系 [email protected]