# Android

### 1.After the payment is completed, redirect to the webpage for 3D  Secure authentication

After confirming the returned data after the payment contains the <mark style="color:blue;">`nextAction`</mark> object and the web redirection address<mark style="color:blue;">`redirectToUrl`</mark> is not empty, the web page will be redirected to 3D Secure authentication.

```
moneyCollect.confirmPayment(requestConfirmPayment, payment.clientSecret,
                object : ApiResultCallback<Payment> {
                    override fun onSuccess(payment: Payment) {
                        //if nextAction object is not null and redirectToUrl address is not null, further 3d verification
                        if (payment.nextAction != null) {
                            if (!TextUtils.isEmpty(payment.nextAction?.redirectToUrl)) {
                                val intent = Intent(activity, ValidationWebActivity::class.java)
                                //pass redirectToUrl
                                intent.putExtra(Constant.VALIDATION_PARAM_URL,payment.nextAction?.redirectToUrl)
                                //pass payment id
                                intent.putExtra(Constant.VALIDATION_PAYMENT_ID, payment.id)
                                //pass payment clientSecret
                                intent.putExtra(Constant.VALIDATION_PAYMENT_CLIENTSECRET,payment.clientSecret)
                                startActivityLauncher.launch(intent)
                            } else {
                                moneyCollectResultBackInterface?.paymentConfirmResultBack(false,
                                    Constant.PAYMENT_PENDING_MESSAGE)
                            }
                        } else {
                            //Need to deal with the state has succeeded, uncaptured, pending, failed, canceled
                            when (payment.status) {
                                Constant.PAYMENT_SUCCEEDED -> {
                                    var intent =  Intent()
                                    intent.putExtra(Constant.PAYMENT_RESULT_PAYMENT, payment)
                                    activity?.setResult(Constant.PAYMENT_RESULT_CODE,intent)
                                    moneyCollectResultBackInterface?.paymentConfirmResultBack(true,"")
                                }
                                Constant.PAYMENT_FAILED -> {
                                    moneyCollectResultBackInterface?.paymentConfirmResultBack(false,payment.errorMessage)
                                }
                                Constant.PAYMENT_UN_CAPTURED -> {
                                    moneyCollectResultBackInterface?.paymentConfirmResultBack(false,
                                        Constant.PAYMENT_UN_CAPTURED_MESSAGE)
                                }
                                Constant.PAYMENT_PENDING -> {
                                    moneyCollectResultBackInterface?.paymentConfirmResultBack(false,
                                        Constant.PAYMENT_PENDING_MESSAGE)
                                }
                                Constant.PAYMENT_CANCELED -> {
                                    moneyCollectResultBackInterface?.paymentConfirmResultBack(false,
                                        Constant.PAYMENT_CANCELED_MESSAGE)
                                }
                                else -> {
                                    moneyCollectResultBackInterface?.paymentConfirmResultBack(false,
                                        Constant.PAYMENT_PENDING_MESSAGE)
                                }
                            }
                        }
                    }

                    override fun onError(e: Exception) {
                        moneyCollectResultBackInterface?.failExceptionBack(e.message)
                    }
                })
```

### 2.3D Secure authentication on web

Check the current url address firstly after directing to the webpage. If the authenticated rules are met, <mark style="color:blue;">`retrievePayment`</mark> interface will be called and the payment result will be returned to the customer.

If you click <mark style="color:purple;">`Return`</mark>button during the verification process, an <mark style="color:purple;">`Exit`</mark> prompt box will be displayed. Clicking to exit will call the <mark style="color:blue;">`retrievePayment`</mark> interface, and then return the payment result to the customer. For details, please refer to the <mark style="color:blue;">`ValidationWebActivity`</mark> class under the MoneyCollectSDK demo.

```
//WebViewClient
   webView?.webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
                val hitTestResult = view?.hitTestResult
                if (!TextUtils.isEmpty(url) && hitTestResult == null) {
                    url?.let { view?.loadUrl(it) }
                    return true
                } else {
                    url?.let {
                        //Check the web address
                        if (url.contains("payment_id")
                              && url.contains("payment_client_secret")
                              && url.contains("source_redirect_slug")) {
                            retrievePayment()
                            return true
                        }
                    }
                }
                return super.shouldOverrideUrlLoading(view, url)
            }
   }

   //retrieve Payment
   private fun retrievePayment() {
        showLoadingDialog()
        paymentId?.let {
            moneyCollect.retrievePayment(it, clientSecret,
                object : ApiResultCallback<Payment> {
                    override fun onSuccess(result: Payment) {
                        //Status: succeeded,uncaptured,pending,failed,canceled
                        dismissLoadingDialog()
                        val resultStr: String? = when (result.status) {
                            Constant.PAYMENT_SUCCEEDED -> {
                                ""
                            }
                            Constant.PAYMENT_FAILED -> {
                                result.errorMessage
                            }
                            Constant.PAYMENT_UN_CAPTURED -> {
                                Constant.PAYMENT_UN_CAPTURED_MESSAGE
                            }
                            Constant.PAYMENT_PENDING -> {
                                Constant.PAYMENT_PENDING_MESSAGE
                            }
                            Constant.PAYMENT_CANCELED -> {
                                Constant.PAYMENT_CANCELED_MESSAGE
                            }
                            else -> {
                                Constant.PAYMENT_PENDING_MESSAGE
                            }
                        }
                        completeThreeDCheckout(resultStr,result)
                    }

                    override fun onError(e: Exception) {
                        dismissLoadingDialog()
                        completeThreeDCheckout(e.message,null)
                    }
                })
        }

    //pass payment result
    private fun completeThreeDCheckout(result: String?, resultPayment: Payment?) {
        val intent = Intent()
        intent.putExtra(Constant.WEB_RESULT_TAG, result)
        intent.putExtra(Constant.PAYMENT_RESULT_PAYMENT, resultPayment)
        setResult(Constant.WEB_RESULT_CODE,intent)
        finish()
    }
```

### 3.Get the payment result

```
 private val startActivityLauncher: ActivityResultLauncher<Intent> =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            //selected paymentmethods's list
            if (it.resultCode == Constant.PAYMENT_RESULT_CODE) {
                var payment =
                    it.data?.getParcelableExtra<Payment>(Constant.PAYMENT_RESULT_PAYMENT)
                if (payment != null) {
                    when (payment.status) {
                        Constant.PAYMENT_SUCCEEDED -> {
                            Log.e(TAG, Constant.PAYMENT_SUCCEEDED)
                        }
                        Constant.PAYMENT_FAILED -> {
                            payment?.errorMessage?.let { it1 ->
                                Log.e(TAG, it1)
                            }
                        }
                        Constant.PAYMENT_UN_CAPTURED -> {
                            Log.e(TAG, Constant.PAYMENT_UN_CAPTURED_MESSAGE)
                        }
                        Constant.PAYMENT_PENDING -> {
                            Log.e(TAG, Constant.PAYMENT_PENDING_MESSAGE)
                        }
                        Constant.PAYMENT_CANCELED -> {
                            Log.e(TAG, Constant.PAYMENT_CANCELED_MESSAGE)
                        }
                        else -> {
                            Log.e(TAG, Constant.PAYMENT_PENDING_MESSAGE)
                        }
                    }
                }
            }

        }
```

{% hint style="info" %}
Constant is data constant class. For details, please refer to the Constant class under the MoneyCollectSDK demo.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.moneycollect.com/docs/payment/3d-secure-authentication/android.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
