SEPA Direct Debit

Client-Side Implementation

Availability

SEPA Direct Debit is available to eligible merchants using a custom client-side integration. It is only available in Android v4.13+, iOS v5.11+, and JavaScript v3 SDK. It's not currently available in Drop-in.

If you meet the criteria, Contact us to enable SEPA Direct Debit in your Sandbox or Production account.

Get the SDKAnchorIcon

Add the following in your app-level build.gradle:

  1. Kotlin
  2. Groovy
dependencies {
    implementation("com.braintreepayments.api:sepa-direct-debit:5.8.0")
}

Collect informationAnchorIcon

Once your component is ready, collect the required bank account information from the customer.

Bank information:

  • accountHolderName (the name of the account owner)
  • iban (International Bank Account Number)

Customer information:

  • billingAddress
  • customerId (customer id in the merchant's system)

Invoking the SEPA Direct Debit flowAnchorIcon

Construct a SEPADirectDebitClient, SEPADirectDebitLauncher and a SEPADirectDebitRequest. Call SEPADirectDebitClient.createPaymentAuthRequest() to launch the SEPA Direct Debit flow and call SEPADirectDebitLauncher.launch(). Finally, handle the result and call SEPADirectDebitClient.tokenize() and handle its result.

  1. Kotlin
class MyActivity : AppCompatActivity() {

    private lateinit var sepaDirectDebitLauncher: SEPADirectDebitLauncher
    private lateinit var sepaDirectDebitClient: SEPADirectDebitClient

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        sepaDirectDebitLauncher = SEPADirectDebitLauncher()
        sepaDirectDebitClient = SEPADirectDebitClient(
            context = this,
            authorization = "TOKENIZATION_KEY or CLIENT_TOKEN",
            returnUrlScheme = "RETURN_URL_SCHEME"
        )
    }

    // ALL OTHER ACTIVITY LAUNCH MODES
    override fun onResume() {
        super.onResume()
        handleReturnToApp(intent)
    }

    // ONLY REQUIRED IF YOUR ACTIVITY LAUNCH MODE IS SINGLE_TOP
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        handleReturnToApp(intent)
    }

    private fun handleReturnToApp(intent: Intent) {
        // fetch stored SEPADirectDebitPendingRequest.Started
        val pendingRequest: String = fetchPendingRequestFromPersistantStore()
        when (val paymentAuthResult = sepaDirectDebitLauncher.handleReturnToApp(
            pendingRequest = SEPADirectDebitPendingRequest.Started(pendingRequest),
            intent = intent
        )) {
            is SEPADirectDebitPaymentAuthResult.Success -> {
                completeSepaFlow(paymentAuthResult)
                // clear stored pending request
            }

            is SEPADirectDebitPaymentAuthResult.NoResult -> {
                // user returned to app without completing the flow, handle accordingly
            }

            is SEPADirectDebitPaymentAuthResult.Failure -> {
                // handle error case
            }
        }
    }

    private fun completeSepaFlow(paymentAuthResult: SEPADirectDebitPaymentAuthResult.Success) {
        sepaDirectDebitClient.tokenize(paymentAuthResult) { result ->
            when (result) {
                is SEPADirectDebitResult.Success -> {
                    // send result.nonce.string to server and create a transaction
                }
                is SEPADirectDebitResult.Failure -> { /* handle result.error */ }
                is SEPADirectDebitResult.Cancel -> { /* handle user canceled */ }
            }
        }
    }

    private fun startSEPADirectDebit() {
        val billingAddress = PostalAddress(
            recipientName = "John Doe",
            streetAddress = "123 Main St",
            countryCodeAlpha2 = "NL",
            locality = "Amsterdam",
            postalCode = "1072 AE",
        )

        val request = SEPADirectDebitRequest(
            accountHolderName = "John Doe",
            customerId = "1234",
            iban = "FR7618106000321234566666608",
            mandateType = SEPADirectDebitMandateType.ONE_OFF,
            billingAddress = billingAddress,
        )

        sepaDirectDebitClient.createPaymentAuthRequest(request) { paymentAuthRequest ->
            when (paymentAuthRequest) {
                is SEPADirectDebitPaymentAuthRequest.ReadyToLaunch -> {
                    val pendingRequest = sepaDirectDebitLauncher.launch(this, paymentAuthRequest)
                    when (pendingRequest) {
                        is SEPADirectDebitPendingRequest.Started -> {
                            // store pendingRequest
                        }

                        is SEPADirectDebitPendingRequest.Failure -> {
                            // handle error
                        }
                    }
                }

                is SEPADirectDebitPaymentAuthRequest.LaunchNotRequired -> {
                    // send paymentAuthRequest.nonce.string to server and create a transaction
                }

                is SEPADirectDebitPaymentAuthRequest.Failure -> {
                    // handle error
                }
            }
        }
    }
}

Next Page: Server-side

If you accept cookies, we’ll use them to improve and customize your experience and enable our partners to show you personalized PayPal ads when you visit other sites. Manage cookies and learn more