Documentation Index Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
Use this file to discover all available pages before exploring further.
Quick Start Bringen Sie Ihre mobile Zahlungsintegration in 4 einfachen Schritten zum Laufen
Platform Examples Vollständige Codebeispiele für Android, iOS, React Native und Flutter
Voraussetzungen
Bevor Sie Dodo Payments in Ihre mobile App integrieren, stellen Sie sicher, dass Sie Folgendes haben:
Dodo Payments-Konto : Aktives Händlerkonto mit API-Zugriff
API-Anmeldeinformationen : API-Schlüssel und Webhook-Geheimschlüssel aus Ihrem Dashboard
Mobile App-Projekt : Android-, iOS-, React Native- oder Flutter-Anwendung
Backend-Server : Um die Erstellung von Checkout-Sitzungen sicher zu handhaben
Integrationsworkflow
Die mobile Integration folgt einem sicheren 4-Schritte-Prozess, bei dem Ihr Backend die API-Aufrufe verwaltet und Ihre mobile App die Benutzererfahrung steuert.
Backend: Create Checkout Session
Checkout Session API Docs Erfahren Sie, wie Sie eine Checkout-Sitzung in Ihrem Backend mit Node.js, Python und mehr erstellen. Sehen Sie sich vollständige Beispiele und Parameterreferenzen in der speziellen Checkout Sessions API -Dokumentation an.
Sicherheit : Checkout-Sitzungen müssen auf Ihrem Backend-Server erstellt werden, niemals in der mobilen App. Dies schützt Ihre API-Schlüssel und gewährleistet eine ordnungsgemäße Validierung.
Mobile: Get Checkout URL
Ihre mobile App ruft Ihr Backend auf, um die Checkout-URL zu erhalten: 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
}
suspend fun getCheckoutURL (productId: String , customerEmail: String , customerName: String ): String {
val client = OkHttpClient ()
val requestBody = JSONObject (). apply {
put ( "productId" , productId)
put ( "customerEmail" , customerEmail)
put ( "customerName" , customerName)
}. toString (). toRequestBody ( "application/json" . toMediaType ())
val request = Request. Builder ()
. url ( "https://your-backend.com/api/create-checkout-session" )
. post (requestBody)
. build ()
val response = client. newCall (request). execute ()
val responseBody = response.body?. string ()
val jsonResponse = JSONObject (responseBody ?: "" )
return jsonResponse. getString ( "checkout_url" )
}
const getCheckoutURL = async ( productId , customerEmail , customerName ) => {
try {
const response = await fetch ( 'https://your-backend.com/api/create-checkout-session' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
productId ,
customerEmail ,
customerName
})
});
const data = await response . json ();
return data . checkout_url ;
} catch ( error ) {
console . error ( 'Failed to get checkout URL:' , error );
throw error ;
}
};
Sicherheit : Mobile Apps kommunizieren nur mit Ihrem Backend, niemals direkt mit der Dodo Payments API.
Mobile: Open Checkout in Browser
Öffnen Sie die Checkout-URL in einem sicheren In-App-Browser für die Zahlungsabwicklung.
See platform-specific integration examples Sehen Sie sich vollständigen Code und Einrichtungsanleitungen für Android, iOS und Flutter Mobile Zahlungen an.
Backend: Handle Payment Completion
Verarbeiten Sie den Zahlungsabschluss über Webhooks und Redirect-URLs, um den Zahlungsstatus zu bestätigen.
Wählen Sie Ihre mobile Plattform unten für vollständige Implementierungsbeispiele:
Android
iOS
React Native
Flutter
Android-Integration Implementierung von Chrome Custom Tabs // 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" , "customer@example.com" , "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)
}
}
}
}
iOS-Integration Implementierung von SFSafariViewController import SafariServices
class PaymentViewController : UIViewController {
override func viewDidLoad () {
super . viewDidLoad ()
Task {
do {
let checkoutURL = try await getCheckoutURL (
productId : "prod_123" ,
customerEmail : "customer@example.com" ,
customerName : "Customer Name"
)
if let url = URL ( string : checkoutURL) {
let safariVC = SFSafariViewController ( url : url)
present (safariVC, animated : true , completion : nil )
}
} catch {
// Handle error
print ( "Failed to get checkout URL: \( error ) " )
}
}
}
}
Deep Link-Verarbeitung Konfigurieren Sie URL-Schemata, um Weiterleitungen zum Abschluss der Zahlung zu verarbeiten: 1. Richten Sie URL-Schemata in Info.plist ein: < key > CFBundleURLTypes </ key >
< array >
< dict >
< key > CFBundleURLName </ key >
< string > myapp </ string >
< key > CFBundleURLSchemes </ key >
< array >
< string > myapp </ string >
</ array >
</ dict >
</ array >
2. Verarbeiten Sie Weiterleitungen in AppDelegate: func application ( _ app : UIApplication, open url : URL, options : [UIApplication.OpenURLOptionsKey : Any ] = [ : ]) -> Bool {
if url.scheme == "myapp" && url.host == "payment-status" {
NotificationCenter. default . post ( name : . paymentCompleted , object : url)
return true
}
return false
}
3. Hören Sie auf den Zahlungsabschluss: NotificationCenter. default . addObserver ( self , selector : #selector ( handlePaymentCompletion (_:)), name : . paymentCompleted , object : nil )
@objc func handlePaymentCompletion ( _ notification : Notification) {
if let url = notification.object as? URL {
safariVC ? . dismiss ( animated : true )
// Parse payment status from URL parameters
let components = URLComponents ( url : url, resolvingAgainstBaseURL : false )
let paymentId = components ? . queryItems ? . first ( where : { $0 . name == "payment_id" }) ? . value
let status = components ? . queryItems ? . first ( where : { $0 . name == "status" }) ? . value
// Handle payment completion
}
}
React Native-Integration Verwendung von Checkout-Links (InAppBrowser) Öffnen Sie Dodos gehostete Checkout-Seite in einem In-App-Browser. InAppBrowser-Implementierung import React from 'react' ;
import { View , TouchableOpacity , Text , Alert } from 'react-native' ;
import { InAppBrowser } from 'react-native-inappbrowser-reborn' ;
const PaymentButton = ({ productId , onPaymentComplete }) => {
const openPaymentLink = async () => {
try {
// Get checkout URL from backend
const checkoutURL = await getCheckoutURL (
productId ,
'customer@example.com' ,
'Customer Name'
);
const result = await InAppBrowser . open ( checkoutURL , {
// iOS options
dismissButtonStyle: 'cancel' ,
preferredBarTintColor: '#453AA4' ,
preferredControlTintColor: 'white' ,
readerMode: false ,
animated: true ,
modalPresentationStyle: 'fullScreen' ,
modalTransitionStyle: 'coverVertical' ,
modalEnabled: true ,
enableBarCollapsing: false ,
// Android options
showTitle: true ,
toolbarColor: '#453AA4' ,
secondaryToolbarColor: 'black' ,
navigationBarColor: 'black' ,
navigationBarDividerColor: 'white' ,
enableUrlBarHiding: true ,
enableDefaultShare: true ,
forceCloseOnRedirection: false ,
animations: {
startEnter: 'slide_in_right' ,
startExit: 'slide_out_left' ,
endEnter: 'slide_in_left' ,
endExit: 'slide_out_right'
},
headers: {
'my-custom-header' : 'my custom header value'
}
});
// Handle payment completion based on result
if ( result . type === 'dismiss' ) {
// User dismissed the browser
console . log ( 'Payment browser dismissed' );
}
} catch ( error ) {
Alert . alert ( 'Error' , 'Failed to open payment page' );
console . error ( 'InAppBrowser error:' , error );
}
};
return (
< View style = { { padding: 20 } } >
< TouchableOpacity
style = { {
backgroundColor: '#007AFF' ,
padding: 15 ,
borderRadius: 8 ,
alignItems: 'center'
} }
onPress = { openPaymentLink }
>
< Text style = { { color: 'white' , fontSize: 16 , fontWeight: 'bold' } } >
Pay Now
</ Text >
</ TouchableOpacity >
</ View >
);
};
export default PaymentButton ;
Deep Link-Verarbeitung für Zahlungs-Callbacks // App.js or your main component
import React , { useEffect } from 'react' ;
import { Linking } from 'react-native' ;
const App = () => {
useEffect (() => {
// Handle deep links when app is already running
const handleDeepLink = ( url ) => {
if ( url . includes ( 'payment-status' )) {
const urlParams = new URLSearchParams ( url . split ( '?' )[ 1 ]);
const paymentId = urlParams . get ( 'payment_id' );
const status = urlParams . get ( 'status' );
// Handle payment completion
handlePaymentCallback ( paymentId , status );
}
};
// Listen for deep links
const subscription = Linking . addEventListener ( 'url' , ({ url }) => {
handleDeepLink ( url );
});
// Handle deep link if app was opened from a link
Linking . getInitialURL (). then (( url ) => {
if ( url ) {
handleDeepLink ( url );
}
});
return () => subscription ?. remove ();
}, []);
const handlePaymentCallback = ( paymentId , status ) => {
if ( status === 'succeeded' ) {
// Navigate to success screen or show success message
console . log ( 'Payment successful:' , paymentId );
} else {
// Handle payment failure
console . log ( 'Payment failed:' , paymentId );
}
};
// Your app components...
};
export default App ;
Paketabhängigkeiten Fügen Sie diese Abhängigkeit zu Ihrem package.json hinzu: {
"dependencies" : {
"react-native-inappbrowser-reborn" : "^6.4.0"
}
}
Installationsbefehle # Install InAppBrowser
npm install react-native-inappbrowser-reborn
cd ios && pod install
Android-Konfiguration Fügen Sie zu android/app/src/main/AndroidManifest.xml hinzu: < activity
android:name = "com.reactnativeinappbrowserreborn.InAppBrowserActivity"
android:theme = "@style/Theme.AppCompat.Dialog"
android:exported = "false" />
iOS-Konfiguration Fügen Sie zu ios/YourApp/Info.plist hinzu: < key > CFBundleURLTypes </ key >
< array >
< dict >
< key > CFBundleURLName </ key >
< string > myapp </ string >
< key > CFBundleURLSchemes </ key >
< array >
< string > myapp </ string >
</ array >
</ dict >
</ array >
Verwenden Sie InAppBrowser für eine native Browser-Erfahrung. Behandeln Sie Deep Links für Zahlungscallbacks.
Alternative: Native Payment SDK Für ein integrierteres Zahlungserlebnis mit nativer UI und vollständiger Anpassung bietet Dodo Payments ein React Native SDK an. Regionale Compliance : In-App-Zahlungs-SDKs unterliegen regionalen Einschränkungen. Auf iOS sind native Zahlungs-SDKs nur in der EU legal (gemäß DMA-Bestimmungen). Auf Android sind sie in Märkten mit User Choice Billing (UCB) legal. Für andere Regionen verwenden Sie den oben beschriebenen Checkout-Link-Ansatz, um die Einhaltung von App Store und Play Store sicherzustellen.
React Native SDK Integration Guide Vollständige Anleitung zur Integration des React Native SDK von Dodo mit nativen Zahlungssheets, vollständigen Anpassungsoptionen und direkter Zahlungsabwicklung. Enthält Einrichtung, Implementierung und Testanweisungen.
Flutter-Integration import 'package:flutter/material.dart' ;
import 'package:webview_flutter/webview_flutter.dart' ;
import 'package:http/http.dart' as http;
import 'dart:convert' ;
Future < String > getCheckoutURL ( String productId, String customerEmail, String customerName) async {
final response = await http. post (
Uri . parse ( 'https://your-backend.com/api/create-checkout-session' ),
headers : { 'Content-Type' : 'application/json' },
body : json. encode ({
'productId' : productId,
'customerEmail' : customerEmail,
'customerName' : customerName,
}),
);
if (response.statusCode == 200 ) {
final data = json. decode (response.body);
return data[ 'checkout_url' ];
} else {
throw Exception ( 'Failed to get checkout URL: ${ response . statusCode } ' );
}
}
class PaymentScreen extends StatefulWidget {
@override
_PaymentScreenState createState () => _PaymentScreenState ();
}
class _PaymentScreenState extends State < PaymentScreen > {
late WebViewController _controller;
String ? checkoutURL;
@override
void initState () {
super . initState ();
_getCheckoutURL ();
}
Future < void > _getCheckoutURL () async {
try {
final url = await getCheckoutURL ( 'prod_123' , 'customer@example.com' , 'Customer Name' );
setState (() {
checkoutURL = url;
});
} catch (e) {
// Handle error
print ( 'Failed to get checkout URL: $ e ' );
}
}
@override
Widget build ( BuildContext context) {
return Scaffold (
appBar : AppBar (title : Text ( 'Payment' )),
body : checkoutURL == null
? Center (child : CircularProgressIndicator ())
: WebView (
initialUrl : checkoutURL,
javascriptMode : JavascriptMode .unrestricted,
onWebViewCreated : ( WebViewController webViewController) {
_controller = webViewController;
},
navigationDelegate : ( NavigationRequest request) {
if (request.url. contains ( 'payment_id' ) && request.url. contains ( 'status' )) {
// Handle payment completion
final uri = Uri . parse (request.url);
final paymentId = uri.queryParameters[ 'payment_id' ];
final status = uri.queryParameters[ 'status' ];
handlePaymentCompletion (paymentId, status);
return NavigationDecision .prevent;
}
return NavigationDecision .navigate;
},
),
);
}
void handlePaymentCompletion ( String ? paymentId, String ? status) {
if (status == 'succeeded' ) {
// Payment successful
} else {
// Payment failed
}
}
}
Verwenden Sie WebView für Zahlungslinks. Verarbeiten Sie die Redirect-URL, um den Zahlungsabschluss zu erkennen.
Best Practices
Sicherheit : Speichern Sie API-Schlüssel niemals in Ihrem App-Code. Verwenden Sie sichere Speicherung und SSL-Pinning.
Benutzererfahrung : Zeigen Sie Ladeindikatoren an, behandeln Sie Fehler elegant und geben Sie klare Nachrichten aus.
Testen : Verwenden Sie Testkarten, simulieren Sie Netzwerkfehler und testen Sie auf verschiedenen Geräten.
Fehlersuche
Häufige Probleme
WebView öffnet den Zahlungslink nicht : Stellen Sie sicher, dass der Zahlungslink gültig ist und HTTPS verwendet.
Callback nicht empfangen : Überprüfen Sie Ihre Rückkehr-URL und die Webhook-Konfiguration.