---
title: "Thực hiện mua hàng trong ứng dụng Android SDK"
description: "Hướng dẫn xử lý in-app purchase và gói đăng ký bằng Adapty."
---

Hiển thị paywall trong ứng dụng là bước quan trọng để cung cấp cho người dùng quyền truy cập vào nội dung hoặc dịch vụ cao cấp. Tuy nhiên, chỉ cần hiển thị paywall là đủ để hỗ trợ thanh toán nếu bạn dùng [Paywall Builder](adapty-paywall-builder) để tùy chỉnh paywall.

Nếu không dùng Paywall Builder, bạn phải sử dụng một phương thức riêng là `.makePurchase()` để hoàn tất giao dịch và mở khóa nội dung. Phương thức này là cổng để người dùng tương tác với paywall và thực hiện giao dịch mong muốn.

Nếu paywall của bạn có ưu đãi đang hoạt động cho sản phẩm mà người dùng đang mua, Adapty sẽ tự động áp dụng ưu đãi đó tại thời điểm thanh toán.

:::warning
Lưu ý rằng ưu đãi giới thiệu chỉ được áp dụng tự động nếu bạn sử dụng paywall được thiết lập bằng Paywall Builder.

Trong các trường hợp khác, bạn cần [xác minh tính đủ điều kiện của người dùng cho ưu đãi giới thiệu trên iOS](fetch-paywalls-and-products#check-intro-offer-eligibility-on-ios). Bỏ qua bước này có thể khiến ứng dụng bị từ chối khi phát hành. Hơn nữa, điều này có thể dẫn đến việc tính giá đầy đủ cho những người dùng đủ điều kiện nhận ưu đãi giới thiệu.
:::

Hãy đảm bảo bạn đã [hoàn thành cấu hình ban đầu](quickstart) mà không bỏ sót bước nào. Nếu không, chúng tôi không thể xác thực các giao dịch mua hàng.

## Thực hiện mua hàng \{#make-purchase\}

:::note
**Đang dùng [Paywall Builder](adapty-paywall-builder)?** Các giao dịch mua hàng được xử lý tự động — bạn có thể bỏ qua bước này.

**Cần hướng dẫn từng bước?** Xem [hướng dẫn quickstart](android-implement-paywalls-manually) để biết cách triển khai đầy đủ từ đầu đến cuối.
:::

<Tabs groupId="current-os" queryString>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin showLineNumbers
Adapty.makePurchase(activity, product, null) { result ->
    when (result) {
        is AdaptyResult.Success -> {
            when (val purchaseResult = result.value) {
                is AdaptyPurchaseResult.Success -> {
                    val profile = purchaseResult.profile
                    if (profile.accessLevels["YOUR_ACCESS_LEVEL"]?.isActive == true) {
                        // Grant access to the paid features
                    }
                }

                is AdaptyPurchaseResult.UserCanceled -> {
                    // Handle the case where the user canceled the purchase
                }

                is AdaptyPurchaseResult.Pending -> {
                    // Handle deferred purchases (e.g., the user will pay offline with cash)
                }
            }
        }
        is AdaptyResult.Error -> {
            val error = result.error
            // Handle the error
        }
    }
}
```
</TabItem>
<TabItem value="java" label="Java" default>

```java showLineNumbers
Adapty.makePurchase(activity, product, null, result -> {
    if (result instanceof AdaptyResult.Success) {
        AdaptyPurchaseResult purchaseResult = ((AdaptyResult.Success<AdaptyPurchaseResult>) result).getValue();

        if (purchaseResult instanceof AdaptyPurchaseResult.Success) {
            AdaptyProfile profile = ((AdaptyPurchaseResult.Success) purchaseResult).getProfile();
            AdaptyProfile.AccessLevel premium = profile.getAccessLevels().get("YOUR_ACCESS_LEVEL");

            if (premium != null && premium.isActive()) {
                // Grant access to the paid features
            }
        } else if (purchaseResult instanceof AdaptyPurchaseResult.UserCanceled) {
            // Handle the case where the user canceled the purchase
        } else if (purchaseResult instanceof AdaptyPurchaseResult.Pending) {
            // Handle deferred purchases (e.g., the user will pay offline with cash)
        }
    } else if (result instanceof AdaptyResult.Error) {
        AdaptyError error = ((AdaptyResult.Error) result).getError();
        // Handle the error
    }
});
```
</TabItem>

</Tabs>

Tham số yêu cầu:

| Tham số     | Bắt buộc | Mô tả                                                                                               |
| :---------- | :------- | :-------------------------------------------------------------------------------------------------- |
| **Product** | bắt buộc | Đối tượng [`AdaptyPaywallProduct`](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall-product/) lấy từ paywall. |

Tham số phản hồi:

| Tham số     | Mô tả                                                                                                                                                                                                                                                                                                                                                                  |
|-------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Profile** | <p>Nếu yêu cầu thành công, phản hồi sẽ chứa đối tượng này. Đối tượng [AdaptyProfile](https://android.adapty.io/adapty/com.adapty.models/-adapty-profile/) cung cấp thông tin toàn diện về mức độ truy cập, gói đăng ký và các sản phẩm mua một lần của người dùng trong ứng dụng.</p><p>Kiểm tra trạng thái mức độ truy cập để xác định xem người dùng có quyền truy cập cần thiết vào ứng dụng hay không.</p> |

:::warning
**Lưu ý:** nếu bạn vẫn đang dùng StoreKit của Apple phiên bản thấp hơn v2.0 và Adapty SDK phiên bản thấp hơn v2.9.0, bạn cần cung cấp [Apple App Store shared secret](app-store-connection-configuration#step-5-enter-app-store-shared-secret) thay thế. Phương thức này hiện đã bị Apple ngừng hỗ trợ.
:::

## Thay đổi gói đăng ký khi mua hàng \{#change-subscription-when-making-a-purchase\}

Khi người dùng chọn gói đăng ký mới thay vì gia hạn gói hiện tại, cách thức hoạt động phụ thuộc vào cửa hàng. Với Google Play, gói đăng ký không được cập nhật tự động. Bạn cần xử lý việc chuyển đổi trong code của ứng dụng như mô tả bên dưới.

Để thay thế gói đăng ký bằng gói khác trên Android, hãy gọi phương thức `.makePurchase()` với tham số bổ sung:

<Tabs groupId="current-os" queryString>
<TabItem value="kotlin" label="Kotlin" default>
```kotlin showLineNumbers
Adapty.makePurchase(
    activity, 
    product, 
    AdaptyPurchaseParameters.Builder()
        .withSubscriptionUpdateParams(subscriptionUpdateParams)
        .build()
) { result ->
    when (result) {
        is AdaptyResult.Success -> {
            when (val purchaseResult = result.value) {
                is AdaptyPurchaseResult.Success -> {
                    val profile = purchaseResult.profile

                    // successful cross-grade
                }

                is AdaptyPurchaseResult.UserCanceled -> {
                    // user canceled the purchase flow
                }

                is AdaptyPurchaseResult.Pending -> {
                    // the purchase has not been finished yet, e.g. user will pay offline by cash
                }
            }
        }
        is AdaptyResult.Error -> {
            val error = result.error
            // Handle the error
        }
    }
}
```
Tham số yêu cầu bổ sung:

| Tham số                      | Bắt buộc | Mô tả                                                        |
| :--------------------------- | :------- | :----------------------------------------------------------- |
| **subscriptionUpdateParams** | bắt buộc | Đối tượng [`AdaptySubscriptionUpdateParameters`](https://android.adapty.io/adapty/com.adapty.models/-adapty-subscription-update-parameters/). |

</TabItem>
<TabItem value="java" label="Java" default>

```java showLineNumbers
Adapty.makePurchase(
    activity, 
    product, 
    new AdaptyPurchaseParameters.Builder()
        .withSubscriptionUpdateParams(subscriptionUpdateParams)
        .build(),
    result -> {
    if (result instanceof AdaptyResult.Success) {
        AdaptyPurchaseResult purchaseResult = ((AdaptyResult.Success<AdaptyPurchaseResult>) result).getValue();

        if (purchaseResult instanceof AdaptyPurchaseResult.Success) {
            AdaptyProfile profile = ((AdaptyPurchaseResult.Success) purchaseResult).getProfile();

            // successful cross-grade
        } else if (purchaseResult instanceof AdaptyPurchaseResult.UserCanceled) {
            // user canceled the purchase flow
        } else if (purchaseResult instanceof AdaptyPurchaseResult.Pending) {
            // the purchase has not been finished yet, e.g. user will pay offline by cash
        }
    } else if (result instanceof AdaptyResult.Error) {
        AdaptyError error = ((AdaptyResult.Error) result).getError();
        // Handle the error
    }
});
```
Tham số yêu cầu bổ sung:

| Tham số                      | Bắt buộc | Mô tả                                                        |
| :--------------------------- | :------- | :----------------------------------------------------------- |
| **subscriptionUpdateParams** | bắt buộc | Đối tượng [`AdaptySubscriptionUpdateParameters`](https://android.adapty.io/adapty/com.adapty.models/-adapty-subscription-update-parameters/). |

</TabItem>

</Tabs>

Bạn có thể đọc thêm về gói đăng ký và các chế độ thay thế trong tài liệu Google Developer:

- [Về các chế độ thay thế](https://developer.android.com/google/play/billing/subscriptions#replacement-modes)
- [Khuyến nghị của Google về các chế độ thay thế](https://developer.android.com/google/play/billing/subscriptions#replacement-recommendations)
- Chế độ thay thế [`CHARGE_PRORATED_PRICE`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.ReplacementMode#CHARGE_PRORATED_PRICE()). Lưu ý: phương thức này chỉ khả dụng để nâng cấp gói đăng ký. Hạ cấp không được hỗ trợ.
- Chế độ thay thế [`DEFERRED`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.ReplacementMode#DEFERRED()). Lưu ý: Thay đổi gói đăng ký thực sự chỉ xảy ra khi chu kỳ thanh toán của gói đăng ký hiện tại kết thúc.

### Quản lý gói trả trước \{#manage-prepaid-plans\}

Nếu người dùng ứng dụng của bạn có thể mua [gói trả trước](https://developer.android.com/google/play/billing/subscriptions#prepaid-plans) (ví dụ: mua gói đăng ký không tự gia hạn trong vài tháng), bạn có thể bật [giao dịch đang chờ xử lý](https://developer.android.com/google/play/billing/subscriptions#pending) cho các gói trả trước.

<Tabs>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin showLineNumbers

AdaptyConfig.Builder("PUBLIC_SDK_KEY")
    .withEnablePendingPrepaidPlans(true)
    .build()
```
</TabItem>
<TabItem value="java" label="Java" default>

```java showLineNumbers

new AdaptyConfig.Builder("PUBLIC_SDK_KEY")
    .withEnablePendingPrepaidPlans(true)
    .build();
```
</TabItem>
</Tabs>