# Purchases

***

**This part of SDK is important for subscriptions information**

Ready to work\
Configure product information in Google Play

### **Displaying Products**

To fetch the products, you have to call method:

```kotlin
/**
 * parameter1：skus，The product id list
 */
Appflow.getSkuDetails(skus: List<String>, listener: SkuDetailsListener)
```

**Example**

```kotlin
val skus = listOf("SKU_WEEKLY", "SKU_MONTHLY", "SKU_YEARLY")
Appflow.getSkuDetails(skus, object : SkuDetailsListener {
    override fun onError(error: PurchasesError) {}
    override fun onReceived(map: HashMap<String, ProductDetails>) {
        for (product in map) {
            val skuDetails = product.value
            Log.d(TAG,"productId:${skuDetails.productId}")
    				Log.d(TAG,"title:${skuDetails.title}")
    				Log.d(TAG,"description:${skuDetails.description}")
    				Log.d(TAG,"name:${skuDetails.name}")
    				Log.d(TAG,"subscriptionOfferDetails:${skuDetails.subscriptionOfferDetails}")
        }
    }
})
```

### API Reference

| SkuDetailsListener                                |                  |
| ------------------------------------------------- | ---------------- |
| onReceived(map: HashMap\<String, ProductDetails>) | Success callback |
| onError(error : PurchasesError)                   | Failure callback |

| PurchasesError |               |
| -------------- | ------------- |
| code           | error code    |
| message        | error message |

| ProductDetails                                                                 |                                                                                    |
| ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| getDescription() : String                                                      | Returns the description of the product.                                            |
| getName() : String                                                             | Returns the name of the product being sold.                                        |
| getProductId() : String                                                        | Returns the product's Id.                                                          |
| getProductType() : String                                                      | Returns the BillingClient.ProductType of the product.                              |
| getTitle() : String                                                            | Returns the title of the product being sold.                                       |
| getOneTimePurchaseOfferDetails : ProductDetails.OneTimePurchaseOfferDetails    | eturns the offer details of an one-time purchase product.                          |
| getSubscriptionOfferDetails() : List\<ProductDetails.SubscriptionOfferDetails> | returns a list containing all available offers to purchase a subscription product. |

| PurchaseType |                                                |
| ------------ | ---------------------------------------------- |
| INAPP        | A type of SKU for Android apps in-app products |
| SUBS         | A type of SKU for Android apps subscriptions   |

| ProductDetails.OneTimePurchaseOfferDetails |                                                                                                               |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| getFormattedPrice() : String               | Returns formatted price for the payment, including its currency sign.                                         |
| getPriceAmountMicros() : Long              | Returns the price for the payment in micro-units, where 1,000,000 micro-units equal one unit of the currency. |
| getPriceCurrencyCode() : String            | Returns ISO 4217 currency code for price.                                                                     |

| ProductDetails.SubscriptionOfferDetails           |                                                                                                                               |
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| getBasePlanId() : String                          | Returns the base plan id associated with the subscription product.                                                            |
| getOfferId() : String                             | Returns the offer id associated with the subscription product.                                                                |
| getOfferTags() : List                             | Returns the offer tags associated with this Subscription Offer.                                                               |
| getOfferToken() : String                          | Returns the offer token required to pass in launchBillingFlow to purchase the subscription product with these pricing phases. |
| getPricingPhases() : ProductDetails.PricingPhases | Returns the pricing phases for the subscription product.                                                                      |

| ProductDetails.PricingPhases                               |                                                                     |
| ---------------------------------------------------------- | ------------------------------------------------------------------- |
| getPricingPhaseList() : List\<ProductDetails.PricingPhase> | Returns the pricing phases as a time ordered list of Pricing phase. |

| ProductDetails.PricingPhase     |                                                                                                                     |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| getBillingCycleCount() : Int    | Number of cycles for which the billing period is applied.                                                           |
| getBillingPeriod() : String     | Billing period for which the given price applies, specified in ISO 8601 format.                                     |
| getFormattedPrice() : String    | Returns formatted price for the payment cycle, including its currency sign.                                         |
| getPriceAmountMicros() : Long   | Returns the price for the payment cycle in micro-units, where 1,000,000 micro-units equal one unit of the currency. |
| getPriceCurrencyCode() : String | Returns ISO 4217 currency code for price.                                                                           |
| getRecurrenceMode() : Int       | Returns ProductDetails.RecurrenceMode for the pricing phase.                                                        |

### **Making Purchases**

Making Purchases, you have to call method:

```kotlin
/**
 * parameter1：activity，The context must be of type Activity
 * parameter2：productDetails，The ProductDetails object corresponding to the product
 * parameter3：offerToken，to get an offer token, call ProductDetails.subscriptionOfferDetails() for a list of
 * offers that are available to the user
 */
Appflow.purchasePackage(activity: Activity, productDetails: ProductDetails, offerToken: String, listener: MakePurchaseListener)

/**
 * parameter1：activity，The context must be of type Activity
 * parameter2：productDetails，The ProductDetails object corresponding to the product
 * Notice：The first offer token is used by default
 */
Appflow.purchasePackage(activity: Activity, productDetails: ProductDetails, listener: MakePurchaseListener)
```

**Example**

```kotlin
Appflow.purchasePackage(activity, productDetails, offerToken, object : MakePurchaseListener{
    override fun onCompleted(purchase: Purchase) {
        //After the purchase is successful, you can obtain the order id,
        //order token and other information through the Purchase object
    }

    override fun onError(error: PurchasesError, userCancelled: Boolean) {
        //When userCancelled is true, it means that the user cancels the purchase; 
        //when userCancelled is true, it means that the purchase fails
        //You can get specific failure information through PurchasesError
    }
})
```

### API Reference

<figure><img src="/files/daQdLHt4mexLAD4UA46j" alt=""><figcaption></figcaption></figure>

### **Subscription Status**

Get the subscription status of a product, you have to call method:

```kotlin
Appflow.getSubscriberInfo(listener: ReceivePurchaserInfoListener)
```

### Example

```kotlin
Appflow.getSubscriberInfo(object : ReceivePurchaserInfoListener {
    override fun onReceived(subscriber: IapIap.Subscriber) {
        for (info in subscriber.entitlementsList) {
            Log.d(TAG,"sku:${info.productId}")
            Log.d(TAG,"isActive:${info.isActive}")
        }
    }

    override fun onError(error: PurchasesError) {}
})
```

**API Reference**

<figure><img src="/files/yqR6HmpDa7w9W07TrkzS" alt=""><figcaption></figcaption></figure>

### **Upgrade/Downgrade product**

\*\*To upgrade/downgrade a product, you have to call method:

```kotlin
/**
 * parameter1：activity，The context must be of type Activity
 * parameter2：packageToPurchase，The ProductDetails object corresponding to the product
 * parameter3：offerToken，to get an offer token, call ProductDetails.subscriptionOfferDetails() for a list of
 * offers that are available to the user
 * parameter4：upgradeInfo，Upgrade/Downgrade Product Information Object
 */
Appflow.purchasePackage(
        activity: Activity,
        packageToPurchase: ProductDetails,
  			offerToken: String,
        upgradeInfo: UpgradeInfo,
        listener: MakePurchaseListener
    )

/**
 * parameter1：activity，The context must be of type Activity
 * parameter2：packageToPurchase，The ProductDetails object corresponding to the product
 * parameter3：upgradeInfo，Upgrade/Downgrade Product Information Object
 * Notice：The first offer token is used by default
 */
Appflow.purchasePackage(
        activity: Activity,
        packageToPurchase: ProductDetails,
        upgradeInfo: UpgradeInfo,
        listener: MakePurchaseListener
    )
```

**Example**

```kotlin
val upgradeInfo = UpgradeInfo(productId, BillingFlowParams.ProrationMode.DEFERRED)
Appflow.purchasePackage(activity, packageToPurchase, offerToken, upgradeInfo, object : MakePurchaseListener{
    override fun onCompleted(purchase: Purchase) {}
    override fun onError(error: PurchasesError, userCancelled: Boolean) {}
})
```

## API Reference

<figure><img src="/files/MbumGXF7o00xO91pHVLz" alt=""><figcaption></figcaption></figure>


---

# 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://doc.appflow.ai/docs/sdk-set-up-instructions/android-sdk/purchases.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.
