# Android

{% tabs %}
{% tab title="Prebuilt checkout page" %}
![](https://3906929740-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQyT5pndc80PGeNrMulEU%2Fuploads%2F9zm3WAmBxm9aE2LNjDdi%2Fimage.png?alt=media\&token=7291eb6a-c35e-4acd-b138-178b96bddba1)

#### Set up MoneyCollect <mark style="color:blue;">`Server side`</mark>    <mark style="color:blue;">`Client side`</mark>

Firstly, you need a MoneyCollect account. [Register now](https://portal.moneycollect.com/registerr).

### 1.Set up Server-side

If the client side wants to access most of the MoneyCollect Server API, it needs MoneyCollect dashboard to initiate a request through the private key.&#x20;

[Download ](https://github.com/MoneyCollect/moneycollect-api-android-demo/tree/mcappserver)the mock merchant portal interface code on github.

#### 1.1 Using your own key to replace <mark style="color:purple;">`the public key`</mark> and <mark style="color:purple;">`private key`</mark> in the MobilePayController.java file

```
//Your account PUBLIC_SECRET("Bearer "+PUBLIC_SECRET)
private static final String PUBLIC_SECRET = "Bearer live_pu_OGJ0EidwEg4GjymEiRD7cUBk7IQIYmhwhJlUM****";
//Your account PRIVATE_SECRET("Bearer "+PRIVATE_SECRET)
private static final String PRIVATE_SECRET = "Bearer live_pr_OGJ0EidwEg4GjymEiRD4MRxBCo0OumdH6URv****";
```

{% hint style="info" %}
The format of PUBLIC\_SECRET & PRIVATE\_SECRET is（"Bearer"+PUBLIC\_SECRET）
{% endhint %}

#### 1.2 Modify server port（Default to be 9898）

```
server.port=9898
```

The merchant replaces <mark style="color:purple;">`the public key`</mark> and <mark style="color:purple;">`private key`</mark> in the code with their own,  and then switch on the server. (Default server port  is 9099 which can be modified).（The dashboard interface address is the local ip:9898）

### 2.Set up Client-side

Import MoneyCollect android SDK and initialize SDK.

#### 2.1 Add configuration in  build.gradle file

To install the SDK, add `moneycollect-android` to the dependencies block of your `build.gradle` file:

```
repositories {
   jcenter()
   maven{ url "https://raw.githubusercontent.com/MoneyCollect/moneycollect-api-android-demo/mcsdk" }
 }
```

#### 2.2 Add viewbinding and the MoneyCollect library to the app’s main module build.gradle

```
buildFeatures{
        viewBinding = true
   }
```

```
dependencies {
   //The specific version number will be determined according to your needs
   implementation "com.moneycollect.payment:android_mc:0.0.1"
}
```

#### 2.3 Initialize SDK

Initialize MoneyCollect android sdk() in the project application

```
/**
* context: Context,            (context)
* publishableKey: String,      (publishable key)
* customerServerUrl: String?   (Local ip:9898)
**/
MoneyCollectSdk.init(this, "live_pu_OGJ0EidwEg4GjymEiRD7cUBk7IQIYmhwhJlUM****","http://192.168.2.100:9898/")
```

### 3.Construct the data parameters to initiate transaction, and then start the payment activity

The merchant constructs the transaction request parameters and clicks the Checkout button to start the payment activity.（<mark style="color:blue;">`TestRequestData`</mark> is data constant class，please check [moneycollect-api-android-demo](https://github.com/MoneyCollect/moneycollect-api-android-demo/tree/mcjavademo) for more details）

{% tabs %}
{% tab title="Kotlin" %}

```
// ...
class PaymentSheetDemoActivity: AppCompatActivity() {

    //RequestCreatePayment Object
    var testRequestPayment = TestRequestData.testRequestPayment
    //RequestConfirmPayment Object
    var testConfirmPayment = TestRequestData.testConfirmPayment
    //RequestPaymentMethod Object
    var testRequestPaymentMethod = TestRequestData.testRequestPaymentMethod
    //support payment credit card
    var testBankIvList = TestRequestData.testBankIvList
    //customerId
    var customerId = TestRequestData.customerId
    // ...
    fun presentPaymentSheet() {
        //PayCardActivity contain SaveWithPaymentCardFragment and AddWithPaymentFragment,Support them to switch to each other
        var intent = Intent(this, PayCardActivity::class.java)
        //Bundle Object
        var bundle = Bundle()
        //pass currentPaymentModel
        bundle.putSerializable(Constant.CURRENT_PAYMENT_MODEL, currentPaymentModel)
        //pass RequestCreatePayment
        bundle.putParcelable(Constant.CREATE_PAYMENT_REQUEST_TAG, testRequestPayment)
        //pass RequestConfirmPayment
        bundle.putParcelable(Constant.CONFIRM_PAYMENT_REQUEST_TAG, testConfirmPayment)
        //pass customerId
        bundle.putString(Constant.CUSTOMER_ID_TAG, TestRequestData.customerId)
        //pass default RequestPaymentMethod
        bundle?.putParcelable(Constant.CREATE_PAYMENT_METHOD_REQUEST_TAG, testRequestPaymentMethod)
        //pass default supportBankList
        bundle?.putSerializable(Constant.SUPPORT_BANK_LIST_TAG, testBankIvList)
        intent.putExtra(CURRENT_PAYMENT_BUNDLE, bundle)
        //start payment
        startActivityLauncher.launch(intent)
    }

    private val startActivityLauncher: ActivityResultLauncher<Intent> =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
        }
}
```

After the customer completes the payment by clicking <mark style="color:blue;">Pay Now</mark> button, the payment activity will be dismissed and return to the PaymentSheetDemoActivity. At the same time，will callback PAYMENT\_RESULT\_PAYMENT.

```
// ...
class PaymentSheetDemoActivity: AppCompatActivity() {

     private val startActivityLauncher: ActivityResultLauncher<Intent> =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (it.resultCode == Constant.PAYMENT_RESULT_CODE) {
                // resultPayment
                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)
                       }
                    }
                }
            }

        }
}

```

**Use the completion block for handling the payment result.**

If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
{% endtab %}

{% tab title="Java" %}

```
// ...
public class PaymentSheetDemoActivity extends AppCompatActivity {

   //RequestCreatePayment Object
    RequestCreatePayment testRequestPayment = TestRequestData.Companion.getTestRequestPayment();
    //RequestConfirmPayment Object
    RequestConfirmPayment testConfirmPayment = TestRequestData.Companion.getTestConfirmPayment();
    //RequestPaymentMethod Object
    RequestPaymentMethod testRaymentMethod = TestRequestData.Companion.getTestRequestPaymentMethod();
    //support payment credit card
    List<Integer>  testBankIvList = TestRequestData.Companion.getTestBankIvList();
    //customerId
    String customerId = TestRequestData.Companion.getCustomerId();
    // ...
    private void presentPaymentSheet() {
        //PayCardActivity contain SaveWithPaymentCardFragment and AddWithPaymentFragment,Support them to switch to each other
        Intent intent = new Intent(this, PayCardActivity.class);
        //Bundle Object
        Bundle bundle = new Bundle();
        //pass currentPaymentModel
        bundle.putSerializable(
                Constant.CURRENT_PAYMENT_MODEL,
                currentPaymentModel
        );
        //pass RequestCreatePayment
        bundle.putParcelable(
                Constant.CREATE_PAYMENT_REQUEST_TAG,
                testRequestPayment
        );
        //pass RequestConfirmPayment
        bundle.putParcelable(
                Constant.CONFIRM_PAYMENT_REQUEST_TAG,
                testConfirmPayment
        );
        //pass currentId
        bundle.putString(
                Constant.CUSTOMER_ID_TAG,
                customerId
        );
        //pass RequestPaymentMethod
        bundle.putParcelable(Constant.CREATE_PAYMENT_METHOD_REQUEST_TAG, testRaymentMethod);
        //pass default supportBankList
        bundle.putSerializable(Constant.SUPPORT_BANK_LIST_TAG, TestRequestData.Companion.getTestBankIvList());
        intent.putExtra(CURRENT_PAYMENT_BUNDLE, bundle);
        startActivityLauncher.launch(intent);
    }

    private ActivityResultLauncher<Intent> startActivityLauncher =
            PaymentSheetDemoActivity.this.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
                @SuppressLint("LongLogTag")
                @Override
                public void onActivityResult(ActivityResult result) {
                }
            });
}
```

After the customer completes the payment by tapping Pay Now button, the payment activity will be dismissed and return to the PaymentSheetDemoActivity. At the same time，will callback PAYMENT\_RESULT\_PAYMENT.

```
// ...
public class PaymentSheetDemoActivity extends AppCompatActivity {

         private ActivityResultLauncher<Intent> startActivityLauncher =
            PaymentSheetDemoActivity.this.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
                @SuppressLint("LongLogTag")
                @Override
                public void onActivityResult(ActivityResult result) {
                    // resultPayment
                    if (result.getResultCode() == Constant.PAYMENT_RESULT_CODE) {
                        Payment payment =
                                result.getData().getParcelableExtra(Constant.PAYMENT_RESULT_PAYMENT);
                        if (payment != null) {
                            if(payment.getStatus() != null) {
                                switch (payment.getStatus()) {
                                    case Constant.PAYMENT_SUCCEEDED:
                                        Log.e(TAG, Constant.PAYMENT_SUCCESSFUL_MESSAGE);
                                        break;
                                    case Constant.PAYMENT_FAILED:
                                        Log.e(TAG, payment.getErrorMessage());
                                        break;
                                    case Constant.PAYMENT_UN_CAPTURED:
                                        Log.e(TAG, Constant.PAYMENT_UN_CAPTURED_MESSAGE);
                                        break;
                                    case Constant.PAYMENT_PENDING:
                                        Log.e(TAG, Constant.PAYMENT_PENDING_MESSAGE);
                                        break;
                                    case Constant.PAYMENT_CANCELED:
                                        Log.e(TAG, Constant.PAYMENT_CANCELED_MESSAGE);
                                        break;
                                    default:
                                        Log.e(TAG, Constant.PAYMENT_PENDING_MESSAGE);
                                        break;
                                }
                            }else {
                                Log.e(TAG, Constant.PAYMENT_PENDING_MESSAGE);
                            }
                        }
                    }
                }
            });
}
```

**Use the completion block for handling the payment result.**

If payment fails with an error, display the appropriate message to your customer so they can take action and try again. If no error has occurred, tell your customer that the payment was successful.
{% endtab %}
{% endtabs %}

### 4.Additional testing resources

There are several test cards you can use to make sure your integration is ready for production. Use them with any CVC, postal code, and future expiration date.

<table><thead><tr><th width="173.5104880378872">Card Number</th><th width="188.87210677098545">Brand</th><th>DESCRIPTION</th></tr></thead><tbody><tr><td>4242 4242 4242 4242</td><td>Visa</td><td><mark style="color:green;">Succeeds</mark> and immediately processes the payment.</td></tr><tr><td>3566 0020 2036 0505</td><td>JCBA</td><td><mark style="color:green;">Succeeds</mark> and immediately processes the payment.</td></tr><tr><td>6011 1111 1111 1117</td><td>Discover</td><td><mark style="color:green;">Succeeds</mark> and immediately processes the payment.</td></tr><tr><td>3782 8224 6310 0052</td><td>American Express</td><td><mark style="color:green;">Succeeds</mark> and immediately processes the payment.</td></tr><tr><td>5555 5555 5555 4444</td><td>Mastercard</td><td><mark style="color:green;">Succeeds</mark> and immediately processes the payment.</td></tr><tr><td>4000002500003155</td><td>Visa</td><td>This card requires <mark style="color:orange;">3D</mark> authentication on all transactions</td></tr><tr><td>4000 0000 0000 0077</td><td>Visa</td><td>Always fails with a decline code of <mark style="color:red;"><code>declined</code></mark>.</td></tr></tbody></table>

{% endtab %}

{% tab title="Custom payment flow" %}
![Mobile Sdk发起交易示例图](https://3906929740-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQyT5pndc80PGeNrMulEU%2Fuploads%2F0Bh5VClAay8VnfnUa89w%2Fimage.png?alt=media\&token=64087e76-64cc-4959-852d-ef4d279d12a4)

#### Set up MoneyCollect <mark style="color:blue;">`Server side`</mark>    <mark style="color:blue;">`Client side`</mark>

Firstly, you need a MoneyCollect account. [Register now](https://portal.moneycollect.com/registerr)

### 1.Set up Server-side

If the client side wants to access most of the <mark style="color:blue;">`MoneyConnectServer`</mark> API, it needs MoneyCollect dashboard to initiate a request through <mark style="color:blue;">`the private key`</mark>.

[Download ](https://github.com/MoneyCollect/moneycollect-api-android-demo/tree/mcappserver)the mock merchant portal server interface code on github.

#### 1.1 Using your own key to replace the public key and private key in the MobilePayController.java file

```
//Your account PUBLIC_SECRET("Bearer "+PUBLIC_SECRET)
private static final String PUBLIC_SECRET = "Bearer live_pu_OGJ0EidwEg4GjymEiRD7cUBk7IQIYmhwhJlUM****";
//Your account PRIVATE_SECRET("Bearer "+PRIVATE_SECRET)
private static final String PRIVATE_SECRET = "Bearer live_pr_OGJ0EidwEg4GjymEiRD4MRxBCo0OumdH6URv****";
```

{% hint style="info" %}
The format of PUBLIC\_SECRET & PRIVATE\_SECRET is（"Bearer"+PUBLIC\_SECRET）
{% endhint %}

#### 1.2 Modify server port（default to be 9898）

```
server.port=9898
```

The merchant replaces <mark style="color:blue;">`the public key`</mark> and <mark style="color:blue;">`private key`</mark> in the code with their own,  and then switch on the server. (Default server port  is 9099 which can be modified).（The dashboard interface address is the local ip:9898）

### 2. Set up Client-side

Import MoneyCollect android SDK and initialize SDK.

#### 2.1 Add configuration in project build.gradle

```
repositories {
   jcenter()
   maven{ url "https://raw.githubusercontent.com/MoneyCollect/moneycollect-api-android-demo/mcsdk" }
 }
```

#### 2.2 Add viewbinding and the MoneyCollect library to the app’s main module build.gradle

```
buildFeatures{
        viewBinding = true
   }
```

```
dependencies {
   //The specific version number will be determined according to your needs
   implementation "com.moneycollect.payment:android_mc:0.0.1"
}
```

#### 2.3 Initialize SDK

Initialize MoneyCollect android sdk() in the project application

```
/**
* context: Context,            (context)
* publishableKey: String,      (publishable key)
* customerServerUrl: String?   (Local ip:9898)
**/
MoneyCollectSdk.init(this, "live_pu_OGJ0EidwEg4GjymEiRD7cUBk7IQIYmhwhJlUM****","http://192.168.2.100:9898/");
```

### 3. Create a payment

After the merchant collects the user information, create a payment and complete the payment on the client side.(<mark style="color:blue;">`TestRequestData`</mark> is data constant class，please check [moneycollect-api-android-demo](https://github.com/MoneyCollect/moneycollect-api-android-demo/tree/mcjavademo) for more details).

#### Collect transaction information

{% tabs %}
{% tab title="Java" %}

```
//RequestCreatePayment Object
    RequestCreatePayment testRequestPayment = TestRequestData.Companion.getTestRequestPayment();
```

{% endtab %}

{% tab title="Kotlin" %}

```
//RequestCreatePayment Object
    val requestCreatePayment= TestRequestData.testRequestPayment
```

{% endtab %}
{% endtabs %}

#### Create a payment

{% tabs %}
{% tab title="Java" %}

```
    moneyCollect.createPayment(testRequestPayment , new ApiResultCallback<Payment>() {
        @Override
        public void onSuccess(@NotNull Payment result) {
            if (result.getConfirmationMethod().equals(RequestCreatePayment.ConfirmationMethod.Manual)) {
                confirmPayment(result);
            }
        }

        @Override
        public void onError(@NotNull Exception e) {
            moneyCollectResultBackInterface.failExceptionBack(e.getMessage());
        }
    });
```

{% endtab %}

{% tab title="Kotlin" %}

```
   moneyCollect.createPayment(requestCreatePayment, object : ApiResultCallback<Payment> {
        override fun onSuccess(result: Payment) {
           if (result.confirmationMethod.equals(RequestCreatePayment.ConfirmationMethod.Manual)) {
               confirmPayment(result)
           }
        }

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

{% endtab %}
{% endtabs %}

When the transaction is created and<mark style="color:blue;">`confirmationMethod`</mark>is <mark style="color:blue;">`manual`</mark>,confirmation of the payment is required to complete this transaction.

If <mark style="color:blue;">`confirmationMethod`</mark> is <mark style="color:blue;">`automatic`</mark>, the transaction can be completed directly.

#### Confirm a payment

{% tabs %}
{% tab title="Java" %}

```
private void confirmPayment(Payment payment) {
        RequestConfirmPayment requestConfirmPayment = new RequestConfirmPayment(
                BigInteger.valueOf(payment.getAmount()),
                payment.getCurrency(),
                payment.getId(),
                payment.getIp(),
                payment.getNotifyUrl(),
                payment.getPaymentMethod(),
                payment.getReceiptEmail(),
                payment.getReturnUrl(),
                payment.getSetupFutureUsage(),
                new RequestConfirmPayment.Shipping(
                        currentRequestConfirmPayment.getShipping().address,
                        currentRequestConfirmPayment.getShipping().firstName,
                        currentRequestConfirmPayment.getShipping().lastName,
                        currentRequestConfirmPayment.getShipping().phone
                ), currentRequestConfirmPayment.getWebsite()
        );

        moneyCollect.confirmPayment(requestConfirmPayment, payment.getClientSecret(), new ApiResultCallback<Payment>() {
                    @Override
                    public void onSuccess(@NotNull Payment payment) {
                        if (payment==null){
                            moneyCollectResultBackInterface.paymentConfirmResultBack(false, Constant.PAYMENT_PENDING_MESSAGE);
                            return;
                        }
                        if (payment.getNextAction() != null) {
                            String redirectToUrl = payment.getNextAction().redirectToUrl;
                            if (!TextUtils.isEmpty(redirectToUrl)) {
                                Intent intent = new Intent(getActivity(), ValidationWebActivity.class);
                                intent.putExtra(Constant.VALIDATION_PARAM_URL, redirectToUrl);
                                intent.putExtra(Constant.VALIDATION_PAYMENT_ID, payment.getId());
                                startActivityLauncher.launch(intent);
                            } else {
                                moneyCollectResultBackInterface.paymentConfirmResultBack(false, Constant.PAYMENT_PENDING_MESSAGE);
                            }
                        } else {
                            String status = payment.getStatus();
                            if (status != null) {
                                switch (status) {
                                    case Constant.PAYMENT_SUCCEEDED:
                                        Intent intent = new Intent();
                                        intent.putExtra(Constant.PAYMENT_RESULT_PAYMENT, payment);
                                        if (getActivity()!=null) {
                                            getActivity().setResult(Constant.PAYMENT_RESULT_CODE, intent);
                                        }
                                        moneyCollectResultBackInterface.paymentConfirmResultBack(true, "");
                                        break;
                                    case Constant.PAYMENT_FAILED:
                                        moneyCollectResultBackInterface.paymentConfirmResultBack(false, payment.getErrorMessage());
                                        break;
                                    case Constant.PAYMENT_UN_CAPTURED:
                                        moneyCollectResultBackInterface.paymentConfirmResultBack(false, Constant.PAYMENT_UN_CAPTURED_MESSAGE);
                                        break;
                                    case Constant.PAYMENT_PENDING:
                                        moneyCollectResultBackInterface.paymentConfirmResultBack(false, Constant.PAYMENT_PENDING_MESSAGE);
                                        break;
                                    case Constant.PAYMENT_CANCELED:
                                        moneyCollectResultBackInterface.paymentConfirmResultBack(false, Constant.PAYMENT_CANCELED_MESSAGE);
                                        break;
                                    default:
                                        moneyCollectResultBackInterface.paymentConfirmResultBack(false, Constant.PAYMENT_PENDING_MESSAGE);
                                        break;
                                }
                            } else {
                                moneyCollectResultBackInterface.paymentConfirmResultBack(false, Constant.PAYMENT_PENDING_MESSAGE);
                            }
                        }
                    }

                    @Override
                    public void onError(@NotNull Exception e) {
                        moneyCollectResultBackInterface.failExceptionBack(e.getMessage());
                    }
                }
        );

    }
```

{% endtab %}

{% tab title="Kotlin" %}

```
private fun confirmPayment(payment: Payment) {
    var testConfirmPayment = RequestConfirmPayment(
        amount = payment.amount?.toBigInteger(),
        currency = payment.currency,
        id = payment.id,
        ip = payment.ip,
        notifyUrl = payment.notifyUrl,
        paymentMethod = payment.paymentMethod,
        receiptEmail = payment.receiptEmail,
        returnUrl = payment.returnUrl,
        setupFutureUsage = payment.setupFutureUsage,
        shipping = RequestConfirmPayment.Shipping(
            address = address,
            firstName = "Jenny",
            lastName = "Rosen",
            phone = "+18008675309"
        ),
        website = "https://baidu222.com"
    )

    moneyCollect.confirmPayment(requestConfirmPayment, payment.clientSecret, object : ApiResultCallback<Payment> {
        override fun onSuccess(result: Payment) {
            //if nextAction object is not null and redirectToUrl address is not null, further 3 d verification
            if (result.nextAction != null) {
                if (!TextUtils.isEmpty(result.nextAction?.redirectToUrl)) {
                    val intent = Intent(activity, ValidationWebActivity::class.java)
                    intent.putExtra(Constant.VALIDATION_PARAM_URL,result.nextAction?.redirectToUrl)
                    intent.putExtra(Constant.VALIDATION_PAYMENT_ID, result.id)
                    intent.putExtra(Constant.VALIDATION_PAYMENT_CLIENTSECRET, result.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 (result.status) {
                    Constant.PAYMENT_SUCCEEDED -> {
                        var intent =  Intent()
                        intent.putExtra(Constant.PAYMENT_RESULT_PAYMENT, result)
                        activity?.setResult(Constant.PAYMENT_RESULT_CODE,intent)
                        moneyCollectResultBackInterface?.paymentConfirmResultBack(true,"")
                    }
                    Constant.PAYMENT_FAILED -> {
                        moneyCollectResultBackInterface?.paymentConfirmResultBack(false,result.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)
        }
    })
} 
```

{% endtab %}
{% endtabs %}

If the payment needs to integrate 3D secure authentication, please refer to [3D secure authentication](https://docs.moneycollect.com/documentation/payment/3d-secure-authentication/android).

### 4. Additional testing resources

There are several test cards you can use to make sure your integration is ready for production. Use them with any<mark style="color:purple;">`CVC`</mark>, <mark style="color:purple;">`postal code`</mark>, and <mark style="color:purple;">`future expiration date`</mark>.

<table><thead><tr><th>Card Number</th><th width="169.66666666666666">Brand</th><th>DESCRIPTION</th></tr></thead><tbody><tr><td>4242 4242 4242 4242</td><td>Visa</td><td><mark style="color:green;">Succeeds</mark> and immediately processes the payment.</td></tr><tr><td>3566 0020 2036 0505</td><td>JCBA</td><td><mark style="color:green;">Succeeds</mark> and immediately processes the payment.</td></tr><tr><td>6011 1111 1111 1117</td><td>Discover</td><td><mark style="color:green;">Succeeds</mark> and immediately processes the payment.</td></tr><tr><td>3782 8224 6310 0052</td><td>American Express</td><td><mark style="color:green;">Succeeds</mark> and immediately processes the payment.</td></tr><tr><td>5555 5555 5555 4444</td><td>Mastercard</td><td><mark style="color:green;">Succeeds</mark> and immediately processes the payment.</td></tr><tr><td>4000002500003155</td><td>Visa</td><td>This card requires <mark style="color:orange;">3D</mark> authentication on all transaction</td></tr><tr><td>4000 0000 0000 0077</td><td>Visa</td><td>Always fails with a decline code of <mark style="color:red;"><code>declined</code></mark>.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}
