Pay Monthly Messaging
  • 16 Jun 2025
  • 4 Minutes to read
  • Dark
    Light

Pay Monthly Messaging

  • Dark
    Light

Article summary

For legal and regulatory purposes, it is important that all pricing calculations be handled by Uplift only. Uplift typically returns a “from” price, which is an estimated monthly payment amount for the current shopping cart. Because the final monthly payment amount varies by the outcome of the underwriting process, the pricing is estimated, hence the word “from”. The Android SDK offers a variety of options to handle both base and incremental prices (such as ancillaries or upgrades) and other pricing options, as follows:

Price Type

Price TypeDescription
TotalType when the price represents the total price of the product.
AddonType when the price represents only an addon above the standard price of the product.

Price Model

Price ModelDescription
TotalUse this value when the price represents the total price.
PerNightUse this value when the price represents the per night price.
PerDayUse this value when the price represents the per day price.
AvgPerNightUse this value when the price represents the average per night price.
PerPersonUse this value when the price represents the per person price.
PerNightPerPersonUse this value when the price represents the per night per person price.
PerDayPerPersonUse this value when the price represents the per day per person price.
AvgPerNightPerPersonUse this value when the price represents the average per night per person price.

Example:

/**
 * @param priceId: Unique id to identify the price object
 * @param value: Total price of the reservation in USD cents
 * @param model: The pricing model that is used to calculate the price.
 *               For the total price of the reservation, use ULPMPriceModel.Total
 * @param type: The type of price. For the total price of the reservation, use ULPMPriceType.Total
 */
val price = ULPMPrice(
        priceId = hotelPriceId,
        value = 30000,
        model = ULPMPriceModel.Total,
        type = ULPMPriceType.Total
)

Configuring a PM Messaging

A ULPMMessage button can be created for each ULPMPrice. To configure a ULPMMessage,a ULPMTripInfo will need to be created. It is important to be as detailed as possible when constructing the ULPMTripInfo and include all avaliable information in this object. Please consult the test application to see an implementation. More detail about the ULPMTripInfo here. A ULPMMessage can be set up to display the monthly price amounts as a Pay Monthly Message.

You can configure this button with 2 different methods, each defining the way the info modal will appear. The button can be added to the desired layout in the following manner.

<com.uplift.sdk.ULPMMessage
android:id = "@+id/ulPmButton"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"/>

A delegate callback can be attached to the button, allowing the host application to be notified of certain events. Furthermore, if the modal is intended to be displayed in an embedded mode, it is also delegated through this mechanism.


The following demonstrates how the callback can be attached to the button.

val callback = object : ULPMMessageCallback {
    override fun embeddableViewCreated(fragment: androidx.fragment.app.Fragment) {
        // Callback method which is be called after the from pricing view has created.
    }
    override fun fullScreenPresented() {
        // Callback method which is be called after the from pricing full screen has created.
    }
    override fun viewDestroyed() {
        // Callback method which is be called after the from pricing
        // full screen/embedded screen has destroyed.
    }
    override fun modalOpened() {
        // Callback method which is be called after the from pricing modal has opened.
    }
    override fun modalClosed() {
        // Callback method which is be called after the from pricing modal has closed.
    }
    override fun error(error: ULError) {
        // Callback method which is called when an error has happened during the from pricing flow.
    }
}
runCatching {
    ulPmButton.setViewCallback(callback)
}.onFailure {
    Log.d("UpliftSDK", "SDK has not been initialized properly.")
}

The button can be configured using a ULPMPrice and a ULPMTripInfo object in the following manner.

val offerCallback = object : ULOfferCallback {
    override fun onSuccess(hasOffer: Boolean) {
        if (hasOffer) {
            // UpLift has a valid offer for the configured ULPMPrice  
        } else {
            // UpLift doesn't have any offer for the configured ULPMPrice  
        }
    }
    override fun onError(error: ULError) {
        // Callback method which is called when an error has happened during the configuration
    }
}
runCatching {
    ulPmButton.configurePMMessageWithPrice(
        price = price,
        tripInfo = tripInfo,
        offerCallback = offerCallback
    )
}.onFailure {
    Log.d("UpliftSDK", "SDK has not been initialized properly.")
}

If the application intends to open the modal in embedded mode, it can achieve this by setting the fullScreenPresent flag to false. In this case, the created modal fragment will reach the host application through the previously attached delegate callback's embeddableViewCreated function.

ulPmButton.fullScreenPresent = false

Updating a PM Messaging

To update the displayed value of a ULPMMessage, simply configure it again with a new ULPMPrice object.

Customizing the title of a PM Messaging

To reach the best user experience, UpLift provides the possibility to fully customize the title of a PMMessaging. To do that, you need to set your custom ULPMTitleBuilder to the button with titleBuilder property. It is an interface that requires to override a method that is returning with a CharSequence. With these changes, the title of the Messaging will be the returned CharSequence.

ulPmButton.titleBuilder = object : ULPMMessage.ULPMTitleBuilder {
    override fun formatString(title: String, price: Double): CharSequence {
        val fromSpannableString = SpannableString("from ")
        val priceSpannableString = SpannableString(String.format("$%.2f/mo", price))
        val underlineClickableString = object : ClickableSpan() {
            override fun onClick(widget: View) {}
            override fun updateDrawState(ds: TextPaint) {
                super.updateDrawState(ds)
                ds.isUnderlineText = true
                ds.color = Color.parseColor("#00AAE4")
            }
        }
        fromSpannableString.setSpan(
            ForegroundColorSpan(Color.parseColor("#00AAE4")),
            startPosition,
            endPosition,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        priceSpannableString.setSpan(
            StyleSpan(Typeface.BOLD),
            startPosition,
            endPosition,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        priceSpannableString.setSpan(
            RelativeSizeSpan(1.1f),
            startPosition,
            endPosition,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        priceSpannableString.setSpan(
            underlineClickableString,
            startPosition,
            endPosition,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        return TextUtils.concat(fromSpannableString, priceSpannableString)
    }
}

Was this article helpful?