Adyen Flutter (beta)
Important
This package is a beta version. Breaking changes might be included in later versions.
The Adyen Flutter package provides you with the building blocks to create a seamless checkout experience for your Android and iOS Flutter app.
You can integrate in two ways:
- Drop-in: An out-of-the-box solution that includes all available payment methods for shoppers to choose. This wrapper for the native iOS and Android Adyen Drop-in is the quickest way to accept payments in your app.
- Components:
- Card Component: A card widget for shoppers to pay with a card. The Card Component also supports stored cards.
- Google Pay Component: A widget that renders a Google Pay button.
- Apple Pay Component: A widget that renders an Apple Pay button.
- Instant Component: A way to support payment methods that do not require additional input fields (PayPal, Klarna, etc.).
Android | iOS |
---|---|
Before you begin
- Get an Adyen test account.
- Get your Client key. Your client app does not communicate with the Adyen API directly.
- Get your API key. You need the API key to make requests from your server .
- Set up your webhooks to get the payment outcome.
Install the package
Android integration
This package supports Android 5.0 or later.
Adjust your activity to inherit from FlutterFragmentActivity
:
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity: FlutterFragmentActivity() {
// ...
}
For Components
Declare the intent filter in your AndroidManifest.xml
file for every component you are using:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="YOUR_APPLICATION_ID e.g. com.adyen.checkout.flutter.example"
android:path="YOUR_CUSTOM_PATH e.g. /card or /googlePay"
android:scheme="adyencheckout" />
</intent-filter>
iOS integration
This package supports iOS 12 or later.
Add the return URL handler to your AppDelegate.swift
file:
override func application(_: UIApplication, open url: URL, options _: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
RedirectComponent.applicationDidOpen(from: url)
return true
}
In your app, add a custom URL Scheme that matches the return URL.
For Drop-in only
Voucher payment methods require a photo library usage description. Add them to the Info.plist
file.
For Apple Pay (Drop-in or Component)
In your Runner target, add Apple Pay as a capability and enter your merchant id. Follow the steps on the enable Apple Pay page.
How it works
You can use Adyen Flutter with either of our server-side flows:
- Sessions flow
- Advanced flow
You must use Checkout API v71 or later.
Drop-in with Sessions flow
- From your backend, make a
/sessions
request.
The response contains:
sessionData
: the payment session data you need to pass to your front end.id
: a unique identifier for the session data.
-
Pass these values to your app.
-
Create the
DropInConfiguration
.
final DropInConfiguration dropInConfiguration = DropInConfiguration(
// Change the environment to live when you are ready to accept real payments.
environment: Environment.test,
clientKey: CLIENT_KEY,
countryCode: COUNTRY_CODE,
shopperLocale: SHOPPER_LOCALE,
amount: AMOUNT,
);
The DropInConfiguration
also supports optional payment method configurations.
- Call the
create
method, passing the required properties:
final SessionCheckout sessionCheckout = await AdyenCheckout.session.create(
sessionId: sessionResponse.id,
sessionData: sessionResponse.sessionData,
configuration: dropInConfiguration,
);
- Call
startDropin
to start the Drop-in UI and wait for the session payment result. Drop-in handles the payment flow:
final PaymentResult paymentResult = await AdyenCheckout.session.startDropIn(
dropInConfiguration: dropInConfiguration,
checkout: sessionCheckout,
);
- Handle the payment result.
- Inform the shopper.
Use the
resultCode
from the API response to show your shopper the current payment status. - Update your order management system.
You get the final payment status in an AUTHORISATION webhook. Use the
merchantReference
from the webhook to match it to your order reference. For a successful payment, the event containssuccess
: true.
- Inform the shopper.
Use the
Drop-in with Advanced flow
- From your backend, make a
/paymentMethods
request. - Create the
DropInConfiguration
. In this object, you can also add optional payment method configurations.
final DropInConfiguration dropInConfiguration = DropInConfiguration(
// Change the environment to live when you are ready to accept real payments.
environment: Environment.test,
clientKey: CLIENT_KEY,
countryCode: COUNTRY_CODE,
shopperLocale: SHOPPER_LOCALE,
amount: AMOUNT,
);
- Create an
AdvancedCheckout
and provide two callbacks:
onSubmit
: from your backend, make a/payments
request. The callback returns two parameters:data
: payment data that needs to be forwarded.extra
: extra information (e.g. shipping address) in case it is specified for the payment method configuration. Can be null if not needed.
onAdditionalDetails
: from your server, make a/payments/details
final AdvancedCheckout advancedCheckout = AdvancedCheckout(
onSubmit: YOUR_ON_SUBMIT_CALL,
onAdditionalDetails: YOUR_ON_ADDITIONAL_DETAILS_CALL,
);
- Start the Drop-in UI and wait for the payment result. Drop-in handles the payment flow:
final paymentResult = await AdyenCheckout.advanced.startDropIn(
dropInConfiguration: dropInConfiguration,
paymentMethodsResponse: paymentMethodsResponse,
checkout: advancedCheckout,
);
- Handle the payment result.
Inform the shopper.
Use the
resultCode
from the API response to show your shopper the current payment status. Update your order management system. You get the final payment status in an AUTHORISATION webhook. Use themerchantReference
from the webhook to match it to your order reference. For a successful payment, the event containssuccess
: true.
Card Component with Sessions flow
- From your backend, make a
sessions
request. The response contains:
sessionData
: the payment session data.id
: a unique identifier for the session data.
-
Pass these values to your app.
-
Create the
CardComponentConfiguration
.
final CardComponentConfiguration cardComponentConfiguration = CardComponentConfiguration(
// Change the environment to live when you are ready to accept real payments.
environment: Environment.test,
clientKey: CLIENT_KEY,
countryCode: COUNTRY_CODE,
shopperLocale: SHOPPER_LOCALE,
amount: AMOUNT,
);
- Call the
create
method, passing the required properties:
final sessionCheckout = await AdyenCheckout.session.create(
sessionId: sessionResponse.id,
sessionData: sessionResponse.sessionData,
configuration: cardComponentConfiguration,
);
- Get the card payment method to use from the
sessionCheckout
object. - Create the card component widget:
AdyenCardComponent(
configuration: cardComponentConfiguration,
paymentMethod: paymentMethod,
checkout: sessionCheckout,
onPaymentResult: (paymentResult) async {
// handle paymentResult
},
);
Card Component with Advanced flow
- From your server, make a
/paymentMethods
request. - Get the card payment method from the payment methods list.
- Create the
CardComponentConfiguration
.
final CardComponentConfiguration cardComponentConfiguration = CardComponentConfiguration(
// Change the environment to live when you are ready to accept real payments.
environment: Environment.test,
clientKey: CLIENT_KEY,
countryCode: COUNTRY_CODE,
shopperLocale: SHOPPER_LOCALE,
amount: AMOUNT,
);
- Create an
AdvancedCheckout
and provide two callbacks:
onSubmit
: from your backend, make a/payments
request. The callback returns two parameters:data
: payment data that needs to be forwarded.extra
: Will be null because it is not supported for cards.
onAdditionalDetails
: from your backend, make a/payments/details
final AdvancedCheckout advancedCheckout = AdvancedCheckout(
onSubmit: YOUR_ON_SUBMIT_CALL,
onAdditionalDetails: YOUR_ON_ADDITIONAL_DETAILS_CALL,
);
- Create the card component widget:
AdyenCardComponent(
configuration: cardComponentConfiguration,
paymentMethod: paymentMethod,
checkout: advancedCheckout,
onPaymentResult: (paymentResult) async {
// handle paymentResult
},
);
Apple Pay Component with Sessions flow
- From your backend, make a
sessions
request. The response contains:
sessionData
: the payment session data.id
: a unique identifier for the session data.
-
Pass these values to your app.
-
In your Flutter app, create a
ApplePayComponentConfiguration
instance. It requires aApplePayConfiguration
which contains your merchant id and merchant name.
final ApplePayConfiguration applePayConfiguration = ApplePayConfiguration(
merchantId: MERCHANT_ID,
merchantName: MERCHANT_NAME,
);
final ApplePayComponentConfiguration applePayComponentConfiguration = ApplePayComponentConfiguration(
// Change the environment to live when you are ready to accept real payments.
environment: Environment.test
clientKey: CLIENT_KEY,
countryCode: COUNTRY_CODE,
amount: AMOUNT,
applePayConfiguration: applePayComponentConfiguration,
);
- Create a
SessionCheckout
by calling theAdyenCheckout.session.create()
while passing the required properties:
final sessionCheckout = await AdyenCheckout.session.create(
sessionId: sessionResponse.id,
sessionData: sessionResponse.sessionData,
configuration: applePayComponentConfiguration,
);
- Get the Apple Pay payment method from the
sessionCheckout
object. - Use the Apple Pay component widget:
AdyenApplePayComponent(
configuration: applePayComponentConfiguration,
paymentMethod: applePayPaymentMethod,
checkout: sessionCheckout,
style: ApplePayButtonStyle(width: 200, height: 48),
onPaymentResult: (paymentResult) {
//Handle the payment result
},
),
Apple Pay Component with Advanced flow
- From your backend, make a
/paymentMethods
request. - Get the Apple Pay payment method by filtering the payment methods list.
- Create the
ApplePayComponentConfiguration
. It requires theApplePayConfiguration
which contains your merchant id and merchant name. You can also provide optional properties for an enhanced Apple Pay use case.
final ApplePayConfiguration applePayConfiguration = ApplePayConfiguration(
merchantId: MERCHANT_ID,
merchantName: MERCHANT_NAME,
);
final ApplePayComponentConfiguration applePayComponentConfiguration = ApplePayComponentConfiguration(
// Change the environment to live when you are ready to accept real payments.
environment: Environment.test
clientKey: CLIENT_KEY,
countryCode: COUNTRY_CODE,
amount: AMOUNT,
applePayConfiguration: applePayComponentConfiguration,
);
- Create an
AdvancedCheckout
and provide two callbacks:
onSubmit
: from your backend, make a/payments
request. The callback returns two parameters:data
: payment data that needs to be forwarded.extra
: extra information (e.g. shipping address) in case it is specified in the Apple Pay configuration. Can be null if not needed.
onAdditionalDetails
: from your backend, make a/payments/details
final AdvancedCheckout advancedCheckout = AdvancedCheckout(
onSubmit: YOUR_ON_SUBMIT_CALL,
onAdditionalDetails: YOUR_ON_ADDITIONAL_DETAILS_CALL,
);
- Create the Apple Pay component widget:
AdyenApplePayComponent(
configuration: applePayComponentConfiguration,
paymentMethod: paymentMethod,
checkout: advancedCheckout,
style: ApplePayButtonStyle(width: 200, height: 48),
onPaymentResult: (paymentResult) {
//Handle the payment result
},
),
Google Pay Component with Sessions flow
- From your backend, make a
sessions
request. The response contains:
sessionData
: the payment session data.id
: a unique identifier for the session data.
-
Pass these values to your app.
-
In your Flutter app, create a
GooglePayComponentConfiguration
instance. It requires aGooglePayConfiguration
which contains the Google Pay environment.
final GooglePayComponentConfiguration googlePayComponentConfiguration = GooglePayComponentConfiguration(
// Change the environment to live when you are ready to accept real payments.
environment: Environment.test,
clientKey: CLIENT_KEY,
countryCode: COUNTRY_CODE,
amount: AMOUNT,
googlePayConfiguration: const GooglePayConfiguration(
// Change the environment to live when you are ready to accept real payments.
googlePayEnvironment: GooglePayEnvironment.test,
),
);
- Create a
SessionCheckout
by calling theAdyenCheckout.session.create()
while passing the required properties:
final sessionCheckout = await AdyenCheckout.session.create(
sessionId: sessionResponse.id,
sessionData: sessionResponse.sessionData,
configuration: googlePayComponentConfiguration,
);
- Get the Google Pay payment method from the
sessionCheckout
object. - Use the Google Pay component widget:
AdyenGooglePayComponent(
configuration: googlePayComponentConfiguration,
paymentMethod: paymentMethod,
checkout: sessionCheckout,
loadingIndicator: const CircularProgressIndicator(),
onPaymentResult: (paymentResult) {
//Handle the payment result
},
),
Google Pay Component with Advanced flow
- From your backend, make a
/paymentMethods
request. - Get the Google Pay payment method by filtering the payment methods list.
- Create the
GooglePayComponentConfiguration
. It requires theGooglePayConfiguration
which contains the Google Pay environment. You can also provide optional properties for an enhanced Google Pay use case.
final GooglePayComponentConfiguration googlePayComponentConfiguration = GooglePayComponentConfiguration(
// Change the environment to live when you are ready to accept real payments.
environment: Environment.test,
clientKey: CLIENT_KEY,
countryCode: COUNTRY_CODE,
amount: AMOUNT,
googlePayConfiguration: const GooglePayConfiguration(
// Change the environment to live when you are ready to accept real payments.
googlePayEnvironment: GooglePayEnvironment.test,
shippingAddressRequired: true,
),
);
- Create an
AdvancedCheckout
and provide two callbacks:
onSubmit
: from your backend, make a/payments
request. The callback returns two parameters:data
: payment data that needs to be forwarded.extra
: extra information (e.g. shipping address) in case it is specified in the Google Pay configuration. Can be null if not needed.
onAdditionalDetails
: from your backend, make a/payments/details
final AdvancedCheckout advancedCheckout = AdvancedCheckout(
onSubmit: YOUR_ON_SUBMIT_CALL,
onAdditionalDetails: YOUR_ON_ADDITIONAL_DETAILS_CALL,
);
- Create the Google Pay component widget:
AdyenGooglePayComponent(
configuration: googlePayComponentConfiguration,
paymentMethod: paymentMethod,
checkout: advancedCheckout,
style: GooglePayButtonStyle(width: 250, cornerRadius: 4),
loadingIndicator: const CircularProgressIndicator(),
onPaymentResult: (paymentResult) {
//Handle the payment result
},
),
Instant Component with Sessions flow
- From your backend, make a
sessions
request. The response contains:
sessionData
: the payment session data.id
: a unique identifier for the session data.
-
Pass these values to your app.
-
In your Flutter app, create an
InstantComponentConfiguration
.
final InstantComponentConfiguration instantComponentConfiguration = InstantComponentConfiguration(
// Change the environment to live when you are ready to accept real payments.
environment: Environment.test,
clientKey: CLIENT_KEY,
countryCode: COUNTRY_CODE,
amount: AMOUNT,
);
- Create a
SessionCheckout
by calling theAdyenCheckout.session.create()
while passing the required properties:
final SessionCheckout sessionCheckout = await AdyenCheckout.session.create(
sessionId: sessionResponse.id,
sessionData: sessionResponse.sessionData,
configuration: instantComponentConfiguration,
);
- Get your required instant payment method by filtering the payment methods list provided by the
SessionCheckout
. - Use the instant component:
final PaymentResult paymentResult = await AdyenCheckout.session.startInstantComponent(
configuration: instantComponentConfiguration,
paymentMethod: paymentMethodResponse,
checkout: sessionCheckout,
);
Instant Component with Advanced flow
- From your backend, make a
/paymentMethods
request. - Get the instant payment method by filtering the payment methods list.
- In your Flutter app, create an
InstantComponentConfiguration
.
final InstantComponentConfiguration instantComponentConfiguration = InstantComponentConfiguration(
// Change the environment to live when you are ready to accept real payments.
environment: Environment.test,
clientKey: CLIENT_KEY,
countryCode: COUNTRY_CODE,
amount: AMOUNT,
);
- Create an
AdvancedCheckout
and provide two callbacks:
onSubmit
: from your backend, make a/payments
request. The callback returns two parameters:data
: payment data that needs to be forwarded.extra
: extra information if available (e.g. shipping address). Can be null if not needed.
onAdditionalDetails
: from your backend, make a/payments/details
final AdvancedCheckout advancedCheckout = AdvancedCheckout(
onSubmit: YOUR_ON_SUBMIT_CALL,
onAdditionalDetails: YOUR_ON_ADDITIONAL_DETAILS_CALL,
);
- Use the instant component:
final PaymentResult paymentResult = await AdyenCheckout.advanced.startInstantComponent(
configuration: instantComponentConfiguration,
paymentMethod: paymentMethodResponse,
checkout: advancedCheckout,
);
Multi Component setup
The SDK currently supports component combination in the advanced flow only. By using this flow, you can use the card component together with the Google Pay or Apple Pay component.
UI Customization
Android
Follow the Android SDK customization docs.
iOS
In Xcode create swift class AdyenAppearance
extending protocol AdyenComponentAppearanceProvider
or AdyenDropInAppearanceProvider
depending of your integration.
SDK will use reflection to find the class with this exact name. Our example app contains a demo implementation.
Drop-in:
import Adyen
import adyen_checkout
class AdyenAppearance: AdyenDropInAppearanceProvider {
static func createDropInStyle() -> Adyen.DropInComponent.Style {
# provide your custom style here
}
}
Card Component:
import Adyen
import adyen_checkout
class AdyenAppearance: AdyenComponentAppearanceProvider {
static func createCardComponentStyle() -> Adyen.FormComponentStyle {
# provide your custom style here
}
}
Support
If you have a feature request, or spot a bug or a technical problem, create an issue.
For other questions, contact our support team.
Contributing
We merge every pull request into the main
branch. We aim to keep main
in good shape, which allows us to release a new version whenever we need to.
We strongly encourage you to provide feedback or contribute to our repository. Have a look at our contribution guidelines to find out how to raise a pull request.
License
This repository is available under the MIT license.