# Braintree Android SDK

[](https://github.com/braintree/braintree_android/actions/workflows/instrumentation_tests.yml)
Welcome to Braintree's Android SDK. This library will help you accept card and alternative payments in your Android app.
:mega: A new major version of the SDK is now available. See the [v5 migration guide](v5_MIGRATION_GUIDE.md) for details.
**The Braintree SDK supports Android API 23 and above.**
The Braintree SDK requires Java 11 and uses Kotlin 1.9.10.
## 📣 Announcements
**Upgrade your integration to continue accepting Braintree payments** The SSL certificates for the Android SDK are set to expire by March 30, 2026. Upgrade to v4.45.0+ or v5.0.0+ to continue processing payments using the Braintree SDK. 
## Adding It To Your Project
The features of the Braintree SDK are organized into modules that can be imported as dependencies in your `build.gradle` file.
See the [Migration Guide](v5_MIGRATION_GUIDE.md) for specific dependencies required for each module.
For an integration offering card payments, add the following dependency in your `build.gradle`:
```groovy
dependencies {
implementation 'com.braintreepayments.api:card:5.33.0'
}
```
To preview the latest work in progress builds, add the following SNAPSHOT dependency in your `build.gradle`:
```groovy
dependencies {
implementation 'com.braintreepayments.api:card:5.0.0-beta2-SNAPSHOT'
}
```
You will also need to add the Sonatype snapshots repo to your top-level `build.gradle` to import SNAPSHOT builds:
```groovy
allprojects {
repositories {
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
}
```
## Dependencies
See [DEPENDENCIES.md](DEPENDENCIES.md) for a full list of runtime dependencies used by each module.
## Documentation
Start with [**'Hello, Client!'**](https://developer.paypal.com/braintree/docs/start/hello-client/android/v4) for instructions on basic setup and usage.
Next, read the [**full documentation**](https://developer.paypal.com/braintree/docs/guides/overview) for information about integration options, such as Drop-In UI, PayPal and credit card tokenization.
## Upgrade Your SDK Version
We always recommend updating to the latest version of the SDK which can be found in our [CHANGELOG](https://github.com/braintree/braintree_android/blob/main/CHANGELOG.md).
For major version upgrades, feel free to check out the [MIGRATION GUIDE](https://github.com/braintree/braintree_android/blob/main/v5_MIGRATION_GUIDE.md).
For more details on how to add and managed build dependencies, see the [**Android Developer Guidelines**](https://developer.android.com/build/dependencies).
## Versions
This SDK abides by our Client SDK Deprecation Policy. For more information on the potential statuses of an SDK check our [developer docs](https://developer.paypal.com/braintree/docs/guides/client-sdk/deprecation-policy).
| Major version number | Status | Released | Deprecated | Unsupported |
|----------------------|-------------|---------------|--------------|--------------|
| 5.x.x | Active | October 2024 | TBA | TBA |
| 4.x.x | Deprecated | June 2021 | October 2025 | October 2026 |
| 3.x.x | Unsupported | February 2019 | June 2022 | June 2023 |
| 2.x.x | Unsupported | November 2015 | March 2020 | March 2021 |
Versions 3.x.x and below are unsupported.
## Payment Buttons
The Braintree Android SDK now allows merchants to draw and render both PayPal and Venmo payment buttons using a discrete set of parameters. The SDK will handle the loading and disable state of the button and allow you to display and offer buttons meeting the current brand guidelines versus maintaining responsibility on your own. We will call the `tokenize` methods with your request and allow you a seamless branded experience in your mobile apps.
*Note:* Ensure you include the `UIComponents` module in your project to use this feature.
If you would like to draw a PayPal branded button in your mobile app, you can do so like this:
```xml
<com.braintreepayments.api.uicomponents.PayPalButton
android:id="@+id/payPalButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
custom:buttonColor="blue" />
```
```kotlin
class ExampleFragment : Fragment() {
private lateinit var payPalButton: PayPalButton
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
payPalButton = view.findViewById<PayPalButton>(R.id.payPalButton)
payPalButton.initialize(
activityResultCaller = this,
authorization = "[TOKENIZATION_KEY or CLIENT_TOKEN]",
appLinkReturnUrl = Uri.parse("https://merchant-app.com"),
deepLinkFallbackUrlScheme = "com.merchant.app.payments"
)
payPalButton.updatePayPalRequest(PayPalRequest(...))
paypalButton.setLaunchCallback = { launchResult ->
when (launchResult) {
is PayPalPendingRequest.Started-> {
// store pending request to disk
}
is PayPalPendingRequest.Failure -> {
// handle error
}
}
}
}
override fun onResume() {
super.onResume()
val pendingRequest = fetchPendingRequest()
if (pendingRequest != null) {
payPalButton.handleReturnToApp(pendingRequest, intent) { payPalResult ->
when (payPalResult) {
is PayPalResult.Success -> {
// handle success
}
is PayPalResult.Failure -> {
// handle failure
}
is PayPalResult.Cancel -> {
// handle canceled
}
}
}
// clear the stored pending request
clearPendingRequest()
// clear intent data
intent.data = null
}
}
}
```
Similarly, if you would like to draw a Venmo branded button in your mobile app, you can do so like this:
```xml
<com.braintreepayments.api.uicomponents.VenmoButton
android:id="@+id/venmoButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
custom:buttonColor="blue" />
```
```kotlin
class ExampleFragment : Fragment() {
private lateinit var venmoButton: VenmoButton
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
venmoButton = view.findViewById<VenmoButton>(R.id.venmoButton)
venmoButton.initialize(
activityResultCaller = this,
authorization = "[TOKENIZATION_KEY or CLIENT_TOKEN]",
appLinkReturnUrl = Uri.parse("https://merchant-app.com"),
deepLinkFallbackUrlScheme = "com.merchant.app.payments"
)
venmoButton.setVenmoRequest(VenmoRequest(...))
venmoButton.setLaunchCallback = { launchResult ->
when (launchResult) {
is VenmoPendingRequest.Started-> {
// store pending request to disk
}
is VenmoPendingRequest.Failure -> {
// handle error
}
}
}
}
override fun onResume() {
super.onResume()
val pendingRequest = fetchPendingRequest()
if (pendingRequest != null) {
venmoButton.handleReturnToApp(pendingRequest, intent) { venmoResult ->
when (venmoResult) {
is VenmoResult.Success -> {
// handle success
}
is VenmoResult.Failure -> {
// handle failure
}
is VenmoResult.Cancel -> {
// handle canceled
}
}
}
// clear the stored pending request
clearPendingRequest()
// clear intent data
intent.data = null
}
}
}
```
### Compose support for Buttons
We now offer support for Jetpack Compose composable buttons.
Similar to the XML buttons, the Braintree Android SDK now allows merchants to draw and render both PayPal and Venmo
payment buttons using a discrete set of parameters. The SDK will handle the loading and disable state of the button
and allow you to display and offer buttons meeting the current brand guidelines versus maintaining responsibility on
your own. We will call the `tokenize` methods with your request and allow you a seamless branded experience in your
mobile apps. The call to `handleReturnToApp` when the control is returned to the merchant app is handled within the
SDK. You are no longer required to add this logic to your code.
For PayPal button, you should invoke the PayPalButton composable like this:
```kotlin
private val paypalTokenizeCallback = PayPalTokenizeCallback { payPalResult ->
when (payPalResult) {
is PayPalResult.Success -> {
handlePayPalResult(payPalResult.nonce)
}
is PayPalResult.Cancel -> {
handleError(Exception("User did not complete PayPal payment flow"))
}
is PayPalResult.Failure -> {
handleError(payPalResult.error)
}
}
// clear intent data
intent.data = null
}
PayPalButton(
style = paypalStyle,
payPalRequest = paypalRequest,
authorization = authStringArg,
appLinkReturnUrl = "https://merchant-app.com".toUri(),
deepLinkFallbackUrlScheme = "com.merchant.app.payments",
paypalTokenizeCallback = paypalTokenizeCallback
)
```
For Venmo button, you should invoke the VenmoButton composable like this:
```kotlin
private val venmoTokenizeCallback = VenmoTokenizeCallback { venmoResult ->
when (venmoResult) {
is VenmoResult.Success -> {
handleVenmoResult(venmoResult.nonce)
}
is VenmoResult.Cancel -> {
handleError(Exception("User did not complete Venmo payment flow"))
}
is VenmoResult.Failure -> {
handleError(venmoResult.error)
}
}
// clear intent data
intent.data = null
}
VenmoButton(
style = venmoStyle,
venmoRequest = venmoRequest,
authorization = authStringArg,
appLinkReturnUrl = "https://merchant-app.com".toUri(),
deepLinkFallbackUrlScheme = "com.merchant.app.payments",
venmoTokenizeCallback = venmoTokenizeCallback
)
```
After you've received a result, clear out the `intent.data` by setting it to null.
```kotlin
intent.data = null
```
## Card Fields
The Braintree Android SDK provides a `CardFields` view that renders a complete card entry form with fields for card number, expiration date, and CVV. It handles input validation, card brand detection, and focus advancement between fields automatically.
*Note:* Ensure you include the `UIComponents` module in your project to use this feature.
If you would like to integrate `CardFields` into your mobile app, you can do so like this:
```xml
<com.braintreepayments.api.uicomponents.cardfields.CardFields
android:id="@+id/cardFields"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/payButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
android:text="Pay" />
```
```kotlin
class ExampleFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val cardFields = view.findViewById<CardFields>(R.id.cardFields)
val payButton = view.findViewById<Button>(R.id.payButton)
cardFields.initialize("[TOKENIZATION_KEY or CLIENT_TOKEN]")
cardFields.setCardFieldsResultCallback { result ->
when (result) {
is CardFieldsResult.Success -> {
// send result.nonce.string to your server to complete the transaction
}
is CardFieldsResult.Failure -> {
// handle card tokenization error
}
}
}
// CardFields reports whether the form is valid; use it to enable your submit button
cardFields.setOnValidationChangedListener { isFormValid ->
payButton.isEnabled = isFormValid
}
// Tokenize the entered card details when the user taps Pay
payButton.setOnClickListener { cardFields.submit() }
}
}
```
### Compose support for Card Fields
The Braintree Android SDK now offers support for a Jetpack Compose `CardFields` composable. Similar to the XML view, it renders a
complete card entry form with fields for card number, expiration date, and CVV. Additionally, it handles input validation,
card brand detection, and focus advancement between fields automatically. On input validation, the controller will update `isFormValid` which
can be used to enable and disable a button of your design to submit the payment.
You should invoke the `CardFields` composable like this:
```kotlin
@Composable
fun ExampleCardFieldsScreen(authorization: String) {
val cardFieldsController = rememberCardFieldsController(
authorization = "[TOKENIZATION_KEY or CLIENT_TOKEN]",
// optionally attach additional data, such as cardholder name or billing address
request = Card(
cardholderName = "John Doe",
postalCode = "12345"
)
)
val isFormValid by cardFieldsController.isFormValid.collectAsState()
Column {
CardFields(controller = cardFieldsController)
Button(
enabled = isFormValid,
onClick = {
cardFieldsController.submit { result ->
when (result) {
is CardFieldsResult.Success -> {
// send result.nonce.string to your server to complete the transaction
}
is CardFieldsResult.Failure -> {
// handle card tokenization error
}
}
}
}
) {
Text("Pay")
}
}
}
```
## Help
* [Read the docs](https://developer.paypal.com/braintree/docs/guides/overview)
* [Check out the reference docs](https://braintree.github.io/braintree_android/current/)
* Find a bug? [Open an issue](https://github.com/braintree/braintree_android/issues)
* Want to contribute? [Check out contributing guidelines](CONTRIBUTING.md) and [submit a pull request](https://help.github.com/articles/creating-a-pull-request).
## Feedback
The Braintree Android SDK is in active development. We welcome your feedback!
Here are a few ways to get in touch:
* [GitHub Issues](https://github.com/braintree/braintree_android/issues/new/choose) - For generally applicable issues and feedback
* [Braintree Support](https://developer.paypal.com/braintree/articles) / [support@braintreepayments.com](mailto:support@braintreepayments.com) -
for personal support at any phase of integration
## License
The Braintree Android SDK is open source and available under the MIT license. See the [LICENSE](LICENSE) file for more info.