--- title: "SCA for transaction history" description: "Learn how to use our Authentication SDK to authenticate your users when they request their transaction history." url: "https://docs.adyen.com/business-accounts/sca-for-transaction-history" source_url: "https://docs.adyen.com/business-accounts/sca-for-transaction-history.md" canonical: "https://docs.adyen.com/business-accounts/sca-for-transaction-history" last_modified: "2022-11-30T17:52:00+01:00" language: "en" --- # SCA for transaction history Learn how to use our Authentication SDK to authenticate your users when they request their transaction history. [View source](/business-accounts/sca-for-transaction-history.md) Each time a user in the European Economic Area (EEA) wants to check their transaction history, you must authenticate them using SCA. This process ensures that sensitive financial data is only accessible to authorized users, fulfilling PSD2 regulatory requirements for secure data retrieval.\ \ Use the Authentication SDK to integrate this verification flow directly into your transaction history request. ## Requirements Before you begin, take into account the following requirements, limitations, and preparations. | Requirement | Description | | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Integration type** | This feature is supported with an [Adyen for Platforms](/platforms) or a [Classic integration](/point-of-sale/classic-library-deprecation). | | **[API credentials](/development-resources/api-credentials/)** | You must have an [API key](/development-resources/api-credentials/#generate-api-key) (recommended) or [basic authentication username and password](/development-resources/api-credentials/#basic-authentication) to access this API. Ensure that you have asked your Adyen contact to assign the following role to your API credential: - **TransferService Webservice Retrieve role** | | **Setup steps** | Before you begin:- Make sure that you have [installed the Authentication SDK](/business-accounts/install-auth-sdk). - Make sure that you have [registered a device](/business-accounts/register-sca-devices) for your user. | ## How it works To retrieve transaction history, verify device eligibility, trigger a secure challenge via the SDK, and retrieve the data, perform the following: 1. [Check SCA eligibility](#initiate-authentication) 2. [Initiate a request for your user's transaction history](#initiate-request-transactions) using the `sdkOutput` that you got when you checked the device for SCA eligibility. 3. [Authenticate your user](#authenticate-user) with the Authentication SDK. 4. [Get the transaction history](#get-transactions) using the `sdkOutput` from the authentication step. ## Check SCA eligibility Before requesting the transaction history, you must check for SCA eligibility and initiate the process to authenticate your users. The following tabs explain how to check for SCA eligibility and initiate authentication using Kotlin, Swift, or JavaScript. ### Tab: Android (Kotlin) To initiate authentication on an Android device: To check if the Android device is eligible for SCA: 1. Initiate the `AdyenAuthentication` class in your Activity or Fragment. **Initiate authentication** ```kotlin private lateinit var adyenAuthentication: AdyenAuthentication override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) adyenAuthentication = AdyenAuthentication(this) } ``` 2. Check if SCA is available on the device. **Check SCA eligibility** ```kotlin lifecycleScope.launch { val availabilityResult: AvailabilityResult = adyenAuthentication.checkAvailability() if (availabilityResult is AvailabilityResult.Available) { availabilityResult.sdkOutput } } ``` The function returns an `sdkOutput`. 3. Pass the `sdkOutput` to your server. ### Tab: iOS (Swift) To initiate authentication on an iOS device: To check if the iOS device is eligible for SCA: 1. Initialize the `AuthenticationService` class. **Initialize authentication service** ```swift let configuration = AuthenticationService.Configuration( localizedRegistrationReason: registrationReason, localizedAuthenticationReason: authenticationReason, appleTeamIdendtifier: appleTeamIdentifier ) let authenticationService = AuthenticationService(configuration: configuration) ``` 2. Check if SCA is available on the device. **Check SCA eligibility** ```swift let sdkOutput = try authenticationService.checkSupport() /// send the sdkOutput to your backend ``` The function returns an `sdkOutput`. 3. Pass the `sdkOutput` to your server. ### Tab: Web (JavaScript) To initiate authentication on a web browser on your web-enabled device: To check if the web browser on your web-enabled device is eligible for SCA: 1. Import the node package in your application. `RelyingPartyName` is the name the user will be presented with when creating or validating a `WebAuthn` operation. We recommend that the value of the `RelyingPartyName` be the merchant name or the URL domain. **Import web sdk and initiate authentication** ```javascript import ScaWebauthn from '@adyen/bpscaweb'; const scaWebauthn = ScaWebauthn.create({ relyingPartyName: 'merchant', }); const sdkOutput = await scaWebauthn.checkAvailability().catch((error) => /* SCA_UNAVAILABLE error*/); ``` If the user's browser supports SCA, the function returns `sdkOutput` to exchange in requests to the server. If SCA is not supported, the method throws an `SCA_UNAVAILABLE` error. 2. Pass the `sdkOutput` to your server. You will use the `sdkOutput` when [initiating a request for transaction history](#initiate-request-transactions). ## Initiate a request for the transaction history To request the transaction history for the specified balance account: 1. Make a GET [/transactions](https://docs.adyen.com/api-explorer/transfers/latest/get/transactions) request, specifying the following parameter in the header: | Request header | Description | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | `WWW-Authenticate` | `SCA realm`: **Transaction**. `auth-param1`: Base64-encoded value of **sdkOutput** you get when you [initiate authentication](#initiate-authentication).. | Provide the following query parameters: | Parameter | Required | Description | | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [balanceAccountId](https://docs.adyen.com/api-explorer/transfers/latest/get/transactions#query-balanceAccountId) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Unique identifier of the balance account to get the transaction history for. | | [createdSince](https://docs.adyen.com/api-explorer/transfers/latest/get/transactions#query-createdSince) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Only include transactions that have been created on or after this point in time. The value must be in ISO 8601 format. For example, **2022-05-30T15:07:40Z**. | | [createdUntil](https://docs.adyen.com/api-explorer/transfers/latest/get/transactions#query-createdUntil) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Only include transactions that have been created on or before this point in time. The value must be in ISO 8601 format. For example, **2022-05-31T15:07:40Z**. | **Request transaction history** #### curl ```bash curl https://balanceplatform-api-test.adyen.com/btl/v4/transactions?balanceAccountId=BA00000000000000000000002&createdSince=2022-05-30T15:07:40Z&createdUntil=2022-05-31T15:07:40Z \ -H 'x-api-key: ADYEN_BALANCE_PLATFORM_API_KEY' \ -H 'content-type: application/json' \ -H 'WWW-Authenticate: SCA realm="Transaction" auth-param1="eyJjaGFsbGVuZ2UiOiJiVlV6ZW5wek0waFNl..."' \ -X GET \ -d '{ }' ``` #### Java ```java // Adyen Java API Library v33.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.transfers.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.service.transfers.*; Client client = new Client("ADYEN_BALANCE_PLATFORM_API_KEY", Environment.TEST); // Send the request TransactionsApi service = new TransactionsApi(client); TransactionSearchResponse response = service.getAllTransactions("String", "String", "String", "String", "String", LocalDateTime.parse("2025-01-01T15:00:00");, LocalDateTime.parse("2025-01-01T15:00:00");, 1, null); ``` #### PHP ```php setXApiKey("ADYEN_BALANCE_PLATFORM_API_KEY"); $client->setEnvironment(Environment::TEST); $requestOptions['queryParams'] = array('balancePlatform' => 'string', 'paymentInstrumentId' => 'string', 'accountHolderId' => 'string', 'balanceAccountId' => 'string', 'cursor' => 'string', 'createdSince' => 'date-time', 'createdUntil' => 'date-time', 'limit' => 'integer'); // Send the request $service = new TransactionsApi($client); $response = $service->getAllTransactions($requestOptions); ``` #### C\# ```cs // Adyen .net API Library v28.0.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Transfers; using Adyen.Service.Transfers; var config = new Config() { XApiKey = "ADYEN_BALANCE_PLATFORM_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Send the request var service = new TransactionsService(client); var response = service.GetAllTransactions(balancePlatform: "string", paymentInstrumentId: "string", accountHolderId: "string", balanceAccountId: "string", cursor: "string", createdSince: DateTime.Parse("2025-01-01T15:00:00"), createdUntil: DateTime.Parse("2025-01-01T15:00:00"), limit: 1); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v23.3.0 const { Client, TransfersAPI } = require('@adyen/api-library'); const client = new Client({ apiKey: "ADYEN_BALANCE_PLATFORM_API_KEY", environment: "TEST" }); // Send the request const transfersAPI = new TransfersAPI(client); const response = transfersAPI.TransactionsApi.getAllTransactions("string", "string", "string", "string", "string", Date.now(), Date.now(), 1); ``` #### Go ```go // Adyen Go API Library v17.0.0 import ( "context" "github.com/adyen/adyen-go-api-library/v17/src/common" "github.com/adyen/adyen-go-api-library/v17/src/adyen" "github.com/adyen/adyen-go-api-library/v17/src/transfers" ) client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_BALANCE_PLATFORM_API_KEY", Environment: common.TestEnv, }) // Send the request service := client.Transfers() req := service.TransactionsApi.GetAllTransactionsInput() req = req.BalancePlatform("string").PaymentInstrumentId("string").AccountHolderId("string").BalanceAccountId("string").Cursor("string").CreatedSince(DateTime.Parse("2025-01-01T15:00:00")).CreatedUntil(DateTime.Parse("2025-01-01T15:00:00")).Limit(1) res, httpRes, err := service.TransactionsApi.GetAllTransactions(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.3.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_BALANCE_PLATFORM_API_KEY" adyen.client.platform = "test" # The environment to use library in. query_parameters = { "balancePlatform" : "string", "paymentInstrumentId" : "string", "accountHolderId" : "string", "balanceAccountId" : "string", "cursor" : "string", "createdSince" : "date-time", "createdUntil" : "date-time", "limit" : "integer" } # Send the request result = adyen.transfers.transactions_api.get_all_transactions(query_parameters=query_parameters) ``` #### Ruby ```rb # Adyen Ruby API Library v10.1.1 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_BALANCE_PLATFORM_API_KEY' adyen.env = :test # Set to "live" for live environment # Create the request object(s) query_params = { :balancePlatform => 'string', :paymentInstrumentId => 'string', :accountHolderId => 'string', :balanceAccountId => 'string', :cursor => 'string', :createdSince => 'date-time', :createdUntil => 'date-time', :limit => 'integer' } # Send the request result = adyen.transfers.transactions_api.get_all_transactions(query_params: query_params) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v23.3.0 import { Client, TransfersAPI, Types } from "@adyen/api-library"; const client = new Client({ apiKey: "ADYEN_BALANCE_PLATFORM_API_KEY", environment: "TEST" }); // Send the request const transfersAPI = new TransfersAPI(client); const response = transfersAPI.TransactionsApi.getAllTransactions("string", "string", "string", "string", "string", Date.now(), Date.now(), 1); ``` 2. In the response, note the following field in the header: * `auth-param1`: Base64-encoded blob of data. You will need `auth-param1` when [authenticating your user using the SDK](#authenticate-user). **Response** ```json { "type": "https://docs.adyen.com/errors/unauthorized", "title": "Unauthorized", "status": 401, "errorCode": "00_401" } ``` 3. Pass `auth-param1` to the SDK as `sdkInput`. ## Authenticate your user After [initiating the request](#initiate-request-transactions), you have 10 minutes to complete the authentication process and [finalize the request](#get-transactions). To authenticate your user with the Authentication SDK: 1. Trigger the SDK and pass the `auth-param1` value from the previous step as `sdkInput`. ### Tab: Android (Kotlin) **Authenticate with SCA SDK** ```kotlin lifecycleScope.launch { if (adyenAuthentication.hasCredential("sdkInput")) { // Authenticate existing credential val authenticationResult: AuthenticationResult = adyenAuthentication.authenticate("sdkInput") when (authenticationResult) { is AuthenticationResult.AuthenticationSuccessful -> { authenticationResult.sdkOutput } is AuthenticationResult.Canceled -> { // User cancelled the authentication flow } is AuthenticationResult.Error -> { // Unexpected error authenticationResult.errorMessage } is AuthenticationResult.AuthenticationError -> { // FIDO API Error authenticationResult.authenticationError } } } else { // None of the existing credentials exist in this device } } ``` If successful, the SDK generates a Base64-encoded `sdkOutput` data blob. ### Tab: iOS (Swift) **Authenticate with SCA SDK** ```swift delegatedAuthenticationSession.authenticate(withBase64URLString: sdkInput) { [weak self] result in switch result { case let .success(sdkOutput): /// send the sdkOutput to the backend case let .failure(error): /// authentication failed } } ``` The SDK uses the [Apple DeviceCheck framework](https://developer.apple.com/documentation/devicecheck) to generate a Base64-encoded `sdkOutput` data blob. To do this, the SDK authenticates the user using Touch ID, Face ID, or the device passcode. To enable Face ID support, add `NSFaceIDUsageDescription` to `Info.plist`. ### Tab: Web (JavaScript) **Authenticate with SCA SDK** ```javascript const sdkOutput = await scaWebauthn.authenticate(sdkInput); ``` If successful, the SDK generates a Base64-encoded `sdkOutput` data blob. 2. Pass `sdkOutput` to your server. ## Get the transaction history To finalize the request to get the transaction history: 1. Make a GET [/transactions](https://docs.adyen.com/api-explorer/transfers/latest/get/transactions) request, specifying the following parameter in the request header. | Request header | Description | | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | `WWW-Authenticate` | `SCA realm`: **Transaction**. `auth-param1`: Base64-encoded value of **sdkOutput** you get when you [initiate authentication](#initiate-authentication). | **Get user transaction history** #### curl ```bash curl https://balanceplatform-api-test.adyen.com/btl/v4/transactions?balanceAccountId=BA00000000000000000000002&createdSince=2022-05-30T15:07:40Z&createdUntil=2022-05-31T15:07:40Z \ -H 'x-api-key: ADYEN_BALANCE_PLATFORM_API_KEY' \ -H 'content-type: application/json' \ -H 'WWW-Authenticate: SCA realm="Transaction" auth-param1="CeCcEEJf2UPC7pB0K7AtEgLZX7cTvnqNznJF..."' \ -X GET \ -d '{ }' ``` #### Java ```java // Adyen Java API Library v33.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.transfers.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.service.transfers.*; Client client = new Client("ADYEN_BALANCE_PLATFORM_API_KEY", Environment.TEST); // Send the request TransactionsApi service = new TransactionsApi(client); TransactionSearchResponse response = service.getAllTransactions("String", "String", "String", "String", "String", LocalDateTime.parse("2025-01-01T15:00:00");, LocalDateTime.parse("2025-01-01T15:00:00");, 1, null); ``` #### PHP ```php setXApiKey("ADYEN_BALANCE_PLATFORM_API_KEY"); $client->setEnvironment(Environment::TEST); $requestOptions['queryParams'] = array('balancePlatform' => 'string', 'paymentInstrumentId' => 'string', 'accountHolderId' => 'string', 'balanceAccountId' => 'string', 'cursor' => 'string', 'createdSince' => 'date-time', 'createdUntil' => 'date-time', 'limit' => 'integer'); // Send the request $service = new TransactionsApi($client); $response = $service->getAllTransactions($requestOptions); ``` #### C\# ```cs // Adyen .net API Library v28.0.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Transfers; using Adyen.Service.Transfers; var config = new Config() { XApiKey = "ADYEN_BALANCE_PLATFORM_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Send the request var service = new TransactionsService(client); var response = service.GetAllTransactions(balancePlatform: "string", paymentInstrumentId: "string", accountHolderId: "string", balanceAccountId: "string", cursor: "string", createdSince: DateTime.Parse("2025-01-01T15:00:00"), createdUntil: DateTime.Parse("2025-01-01T15:00:00"), limit: 1); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v23.3.0 const { Client, TransfersAPI } = require('@adyen/api-library'); const client = new Client({ apiKey: "ADYEN_BALANCE_PLATFORM_API_KEY", environment: "TEST" }); // Send the request const transfersAPI = new TransfersAPI(client); const response = transfersAPI.TransactionsApi.getAllTransactions("string", "string", "string", "string", "string", Date.now(), Date.now(), 1); ``` #### Go ```go // Adyen Go API Library v17.0.0 import ( "context" "github.com/adyen/adyen-go-api-library/v17/src/common" "github.com/adyen/adyen-go-api-library/v17/src/adyen" "github.com/adyen/adyen-go-api-library/v17/src/transfers" ) client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_BALANCE_PLATFORM_API_KEY", Environment: common.TestEnv, }) // Send the request service := client.Transfers() req := service.TransactionsApi.GetAllTransactionsInput() req = req.BalancePlatform("string").PaymentInstrumentId("string").AccountHolderId("string").BalanceAccountId("string").Cursor("string").CreatedSince(DateTime.Parse("2025-01-01T15:00:00")).CreatedUntil(DateTime.Parse("2025-01-01T15:00:00")).Limit(1) res, httpRes, err := service.TransactionsApi.GetAllTransactions(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.3.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_BALANCE_PLATFORM_API_KEY" adyen.client.platform = "test" # The environment to use library in. query_parameters = { "balancePlatform" : "string", "paymentInstrumentId" : "string", "accountHolderId" : "string", "balanceAccountId" : "string", "cursor" : "string", "createdSince" : "date-time", "createdUntil" : "date-time", "limit" : "integer" } # Send the request result = adyen.transfers.transactions_api.get_all_transactions(query_parameters=query_parameters) ``` #### Ruby ```rb # Adyen Ruby API Library v10.1.1 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_BALANCE_PLATFORM_API_KEY' adyen.env = :test # Set to "live" for live environment # Create the request object(s) query_params = { :balancePlatform => 'string', :paymentInstrumentId => 'string', :accountHolderId => 'string', :balanceAccountId => 'string', :cursor => 'string', :createdSince => 'date-time', :createdUntil => 'date-time', :limit => 'integer' } # Send the request result = adyen.transfers.transactions_api.get_all_transactions(query_params: query_params) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v23.3.0 import { Client, TransfersAPI, Types } from "@adyen/api-library"; const client = new Client({ apiKey: "ADYEN_BALANCE_PLATFORM_API_KEY", environment: "TEST" }); // Send the request const transfersAPI = new TransfersAPI(client); const response = transfersAPI.TransactionsApi.getAllTransactions("string", "string", "string", "string", "string", Date.now(), Date.now(), 1); ``` 2. Use the content of the [data](https://docs.adyen.com/api-explorer/transfers/latest/get/transactions#responses-200-data) array to present the transaction information to your user. **Response** ```json { "data": [ { "balancePlatform": "YOUR_BALANCE_PLATFORM", "creationDate": "2023-08-10T14:51:20+02:00", "id": "EVJN42272224222B5JB8BRC84N686ZEUR", "accountHolder": { "description": "Your description for the account holder", "id": "AH00000000000000000000001" }, "amount": { "currency": "USD", "value": -1000 }, "balanceAccount": { "description": "Your description for the account holder", "id": "BA00000000000000000000001" }, "bookingDate": "2023-08-10T14:51:33+02:00", "status": "booked", "transfer": { "id": "3JNC3O5ZVFLLGV4B", "reference": "Your internal reference for the transfer" }, "valueDate": "2023-08-10T14:51:20+02:00" }, { "balancePlatform": "YOUR_BALANCE_PLATFORM", "creationDate": "2023-08-10T15:34:31+02:00", "id": "EVJN4227C224222B5JB8G3Q89N2NB6EUR", "accountHolder": { "description": "Your description for the account holder", "id": "AH00000000000000000000001" }, "amount": { "currency": "USD", "value": 123 }, "balanceAccount": { "description": "Your description for the account holder", "id": "BA00000000000000000000001" }, "bookingDate": "2023-08-10T15:34:40+02:00", "status": "booked", "transfer": { "id": "48POO45ZVG11166J", "reference": "Your internal reference for the transfer" }, "valueDate": "2023-08-10T15:34:31+02:00" } ], "_links": { "next": { "href": "https://balanceplatform-api-test.adyen.com/btl/v4/transactions?balancePlatform=YOUR_BALANCE_PLATFORM&createdUntil=2023-08-20T13%3A07%3A40Z&createdSince=2023-08-10T10%3A50%3A40Z&cursor=S2B-c0p1N0tdN0l6RGhYK1YpM0lgOTUyMDlLXElyKE9LMCtyaFEuMj1NMHgidCsrJi1ZNnhqXCtqVi5JPGpRK1F2fCFqWzU33JTojSVNJc1J1VXhncS10QDd6JX9FQFl5Zn0uNyUvSXJNQTo" } } } ``` ## See also * [How SCA works](/business-accounts/how-sca-works)