Updated on 2026-08-14
This commit is contained in:
parent
bd3ecd6e1a
commit
c204af2973
7 changed files with 72 additions and 80 deletions
|
|
@ -11,6 +11,7 @@ import com.tangem.tap.common.analytics.api.ErrorEventLogger
|
|||
import com.tangem.tap.common.analytics.api.ShopifyOrderEventHandler
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsEvent
|
||||
import com.tangem.tap.common.extensions.filterNotNull
|
||||
import com.tangem.tap.common.shop.data.ProductType
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -85,9 +86,9 @@ object Analytics : GlobalAnalyticsEventHandler {
|
|||
}
|
||||
}
|
||||
|
||||
override fun send(order: Storefront.Order) {
|
||||
override fun send(order: Storefront.Order, productType: ProductType) {
|
||||
analyticsHandlers.filterIsInstance<ShopifyOrderEventHandler>().forEach {
|
||||
it.send(order)
|
||||
it.send(order, productType)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.tap.common.analytics.AnalyticsParamAnOld
|
|||
import com.tangem.tap.common.analytics.events.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.extensions.filterNotNull
|
||||
import com.tangem.tap.common.shop.data.ProductType
|
||||
import com.tangem.tap.domain.configurable.config.Config
|
||||
|
||||
/**
|
||||
|
|
@ -83,7 +84,7 @@ interface BlockchainSdkErrorEventHandler {
|
|||
}
|
||||
|
||||
interface ShopifyOrderEventHandler {
|
||||
fun send(order: Storefront.Order)
|
||||
fun send(order: Storefront.Order, productType: ProductType)
|
||||
}
|
||||
|
||||
interface AnalyticsHandlerBuilder {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
package com.tangem.tap.common.analytics.events
|
||||
|
||||
import com.shopify.buy3.Storefront
|
||||
import com.tangem.common.Converter
|
||||
import com.tangem.tap.common.extensions.filterNotNull
|
||||
import com.tangem.tap.common.shop.data.ProductType
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
|
|
@ -10,13 +15,36 @@ sealed class Shop(
|
|||
|
||||
class ScreenOpened : IntroductionProcess("Shop Screen Opened")
|
||||
|
||||
class Purchased(productSku: String) : Shop(
|
||||
class Purchased(params: Map<String, String>) : Shop(
|
||||
event = "Purchased",
|
||||
params = mapOf("SKU" to productSku),
|
||||
params = params,
|
||||
)
|
||||
|
||||
class Redirected(partnerName: String) : Shop(
|
||||
event = "Redirected",
|
||||
params = mapOf("Partner" to partnerName),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class OrderToParamsConverter : Converter<Pair<Storefront.Order, ProductType>, Map<String, String>> {
|
||||
override fun convert(value: Pair<Storefront.Order, ProductType>): Map<String, String> {
|
||||
val order = value.first
|
||||
val productType = value.second
|
||||
|
||||
val code = (order.discountApplications.edges.firstOrNull()?.node as? Storefront.DiscountCodeApplication)?.code
|
||||
val sku = order.lineItems.edges.firstOrNull()?.node?.variant?.sku ?: productType.sku
|
||||
|
||||
val count = when (productType) {
|
||||
ProductType.WALLET_2_CARDS -> "2"
|
||||
ProductType.WALLET_3_CARDS -> "3"
|
||||
}
|
||||
val amount = "${order.totalPriceV2.amount} ${order.totalPriceV2.currencyCode.name}"
|
||||
|
||||
return mapOf(
|
||||
"Coupon Code" to code,
|
||||
"SKU" to sku,
|
||||
"Count" to count,
|
||||
"Amount" to amount,
|
||||
).filterNotNull()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package com.tangem.tap.common.analytics.handlers.appsFlyer
|
||||
|
||||
import com.appsflyer.AFInAppEventParameterName
|
||||
import com.appsflyer.AFInAppEventType
|
||||
import com.shopify.buy3.Storefront
|
||||
import com.tangem.common.Converter
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
import com.tangem.tap.common.analytics.api.ShopifyOrderEventHandler
|
||||
import com.tangem.tap.common.analytics.events.OrderToParamsConverter
|
||||
import com.tangem.tap.common.analytics.events.Shop
|
||||
import com.tangem.tap.common.shop.data.ProductType
|
||||
|
||||
class AppsFlyerAnalyticsHandler(
|
||||
private val client: AppsFlyerAnalyticsClient,
|
||||
|
|
@ -18,12 +18,12 @@ class AppsFlyerAnalyticsHandler(
|
|||
client.logEvent(event, params)
|
||||
}
|
||||
|
||||
override fun send(order: Storefront.Order) {
|
||||
send(ORDER_EVENT, OrderToParamsConverter().convert(order))
|
||||
override fun send(order: Storefront.Order, productType: ProductType) {
|
||||
val eventParams = OrderToParamsConverter().convert(order to productType)
|
||||
send(Shop.Purchased(eventParams))
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ORDER_EVENT = AFInAppEventType.PURCHASE
|
||||
const val ID = "AppsFlyer"
|
||||
}
|
||||
|
||||
|
|
@ -34,26 +34,4 @@ class AppsFlyerAnalyticsHandler(
|
|||
else -> null
|
||||
}?.let { AppsFlyerAnalyticsHandler(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private class OrderToParamsConverter : Converter<Storefront.Order, Map<String, String>> {
|
||||
|
||||
override fun convert(value: Storefront.Order): Map<String, String> {
|
||||
val sku = value.lineItems.edges.firstOrNull()?.node?.variant?.sku ?: "unknown"
|
||||
|
||||
val discountCode =
|
||||
(value.discountApplications.edges.firstOrNull()?.node as? Storefront.DiscountCodeApplication)?.code
|
||||
|
||||
val discountParams = if (discountCode != null) {
|
||||
mapOf(AFInAppEventParameterName.COUPON_CODE to discountCode)
|
||||
} else {
|
||||
mapOf()
|
||||
}
|
||||
|
||||
return mapOf(
|
||||
AFInAppEventParameterName.CONTENT_ID to sku,
|
||||
AFInAppEventParameterName.REVENUE to value.totalPriceV2.amount,
|
||||
AFInAppEventParameterName.CURRENCY to value.currencyCode.name,
|
||||
) + discountParams
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
package com.tangem.tap.common.analytics.handlers.firebase
|
||||
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.shopify.buy3.Storefront
|
||||
import com.tangem.blockchain.common.BlockchainError
|
||||
import com.tangem.common.Converter
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.tap.common.analytics.AnalyticsAnOld
|
||||
|
|
@ -15,6 +13,9 @@ import com.tangem.tap.common.analytics.api.SdkErrorEventHandler
|
|||
import com.tangem.tap.common.analytics.api.ShopifyOrderEventHandler
|
||||
import com.tangem.tap.common.analytics.converters.BlockchainSdkErrorConverter
|
||||
import com.tangem.tap.common.analytics.converters.CardSdkErrorConverter
|
||||
import com.tangem.tap.common.analytics.events.OrderToParamsConverter
|
||||
import com.tangem.tap.common.analytics.events.Shop
|
||||
import com.tangem.tap.common.shop.data.ProductType
|
||||
|
||||
class FirebaseAnalyticsHandler(
|
||||
private val client: FirebaseAnalyticsClient,
|
||||
|
|
@ -57,8 +58,9 @@ class FirebaseAnalyticsHandler(
|
|||
}
|
||||
}
|
||||
|
||||
override fun send(order: Storefront.Order) {
|
||||
send(FirebaseClient.ORDER_EVENT, OrderToParamsConverter().convert(order))
|
||||
override fun send(order: Storefront.Order, productType: ProductType) {
|
||||
val eventParams = OrderToParamsConverter().convert(order to productType)
|
||||
send(Shop.Purchased(eventParams))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
@ -72,25 +74,4 @@ class FirebaseAnalyticsHandler(
|
|||
else -> null
|
||||
}?.let { FirebaseAnalyticsHandler(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private class OrderToParamsConverter : Converter<Storefront.Order, Map<String, String>> {
|
||||
override fun convert(value: Storefront.Order): Map<String, String> {
|
||||
val sku = value.lineItems.edges.firstOrNull()?.node?.variant?.sku ?: "unknown"
|
||||
|
||||
val discountCode =
|
||||
(value.discountApplications.edges.firstOrNull()?.node as? Storefront.DiscountCodeApplication)?.code
|
||||
|
||||
val discountParams = if (discountCode != null) {
|
||||
mapOf(FirebaseAnalytics.Param.DISCOUNT to discountCode)
|
||||
} else {
|
||||
mapOf()
|
||||
}
|
||||
|
||||
return mapOf(
|
||||
FirebaseAnalytics.Param.ITEM_ID to sku,
|
||||
FirebaseAnalytics.Param.VALUE to value.totalPriceV2.amount,
|
||||
FirebaseAnalytics.Param.CURRENCY to value.currencyCode.name,
|
||||
) + discountParams
|
||||
}
|
||||
}
|
||||
|
|
@ -22,7 +22,6 @@ class TangemShopService(application: Application, shopifyShop: ShopifyShop) {
|
|||
|
||||
private val shopifyService = ShopifyService(application, shopifyShop)
|
||||
|
||||
|
||||
private val checkouts = mutableMapOf<ProductType, Storefront.Checkout>()
|
||||
private val variants = mutableMapOf<ProductType, Storefront.ProductVariant>()
|
||||
|
||||
|
|
@ -40,24 +39,27 @@ class TangemShopService(application: Application, shopifyShop: ShopifyShop) {
|
|||
variants.putAll(availableVariants)
|
||||
|
||||
if (variants.size < SKUS_TO_DISPLAY.size) {
|
||||
return Result.failure(Exception(
|
||||
"Shopify: products are missing, " +
|
||||
"\nproducts available: ${variants.keys.map { it.sku }}"))
|
||||
return Result.failure(
|
||||
Exception(
|
||||
"Shopify: products are missing, " +
|
||||
"\nproducts available: ${variants.keys.map { it.sku }}",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
val twoCardsProduct = TangemProduct(
|
||||
type = ProductType.WALLET_2_CARDS,
|
||||
totalSum = TotalSum(
|
||||
finalValue = variants[ProductType.WALLET_2_CARDS]?.priceV2?.format(),
|
||||
beforeDiscount = variants[ProductType.WALLET_2_CARDS]?.compareAtPriceV2?.format()
|
||||
)
|
||||
beforeDiscount = variants[ProductType.WALLET_2_CARDS]?.compareAtPriceV2?.format(),
|
||||
),
|
||||
)
|
||||
val threeCardsProduct = TangemProduct(
|
||||
type = ProductType.WALLET_3_CARDS,
|
||||
totalSum = TotalSum(
|
||||
finalValue = variants[ProductType.WALLET_3_CARDS]?.priceV2?.format(),
|
||||
beforeDiscount = variants[ProductType.WALLET_3_CARDS]?.compareAtPriceV2?.format()
|
||||
)
|
||||
beforeDiscount = variants[ProductType.WALLET_3_CARDS]?.compareAtPriceV2?.format(),
|
||||
),
|
||||
)
|
||||
createCheckouts()
|
||||
return Result.success(listOf(twoCardsProduct, threeCardsProduct))
|
||||
|
|
@ -85,7 +87,7 @@ class TangemShopService(application: Application, shopifyShop: ShopifyShop) {
|
|||
val totalPrice = checkouts[productType]!!.totalPriceV2.amount
|
||||
googlePayService.payWithGooglePay(
|
||||
totalPriceCents = totalPrice, currencyCode = checkouts[productType]!!.currencyCode.name,
|
||||
merchantID = shopifyService.shop.merchantID
|
||||
merchantID = shopifyService.shop.merchantID,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +106,7 @@ class TangemShopService(application: Application, shopifyShop: ShopifyShop) {
|
|||
suspend fun handleGooglePayResult(
|
||||
resultCode: Int,
|
||||
data: Intent?,
|
||||
productType: ProductType
|
||||
productType: ProductType,
|
||||
): Result<Unit> {
|
||||
val result = googlePayService.handleResponseFromGooglePay(resultCode, data)
|
||||
result.onSuccess {
|
||||
|
|
@ -119,7 +121,7 @@ class TangemShopService(application: Application, shopifyShop: ShopifyShop) {
|
|||
|
||||
private suspend fun completeTokenizedPayment(
|
||||
paymentData: PaymentData,
|
||||
productType: ProductType
|
||||
productType: ProductType,
|
||||
): Result<Storefront.Checkout> {
|
||||
val checkout = checkouts[productType]!!
|
||||
val googlePayResponse =
|
||||
|
|
@ -140,19 +142,18 @@ class TangemShopService(application: Application, shopifyShop: ShopifyShop) {
|
|||
phone = addressGPay.phoneNumber
|
||||
}
|
||||
|
||||
|
||||
val payment = Storefront.TokenizedPaymentInputV3(
|
||||
amount,
|
||||
idempotencyKey,
|
||||
address,
|
||||
paymentData.toJson(),
|
||||
Storefront.PaymentTokenType.GOOGLE_PAY
|
||||
Storefront.PaymentTokenType.GOOGLE_PAY,
|
||||
)
|
||||
.setTest(true)
|
||||
|
||||
return shopifyService.completeWithTokenizedPayment(
|
||||
payment = payment,
|
||||
checkoutID = checkout.id
|
||||
checkoutID = checkout.id,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -181,12 +182,12 @@ class TangemShopService(application: Application, shopifyShop: ShopifyShop) {
|
|||
productType,
|
||||
TotalSum(
|
||||
finalValue = it.totalPriceV2.format(),
|
||||
beforeDiscount = variants[productType]!!.compareAtPriceV2.format()
|
||||
beforeDiscount = variants[productType]!!.compareAtPriceV2.format(),
|
||||
),
|
||||
appliedDiscount = it.getAppliedDiscount()
|
||||
)
|
||||
appliedDiscount = it.getAppliedDiscount(),
|
||||
),
|
||||
|
||||
)
|
||||
)
|
||||
}
|
||||
return Result.failure(result.exceptionOrNull()!!)
|
||||
}
|
||||
|
|
@ -197,9 +198,7 @@ class TangemShopService(application: Application, shopifyShop: ShopifyShop) {
|
|||
|
||||
suspend fun waitForCheckout(productType: ProductType) {
|
||||
val result = shopifyService.checkout(true, checkouts[productType]!!.id)
|
||||
result.onSuccess {
|
||||
it.order?.let { Analytics.send(it) }
|
||||
}
|
||||
result.onSuccess { checkout -> checkout.order?.let { Analytics.send(it, productType) } }
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ import androidx.activity.OnBackPressedCallback
|
|||
import by.kirich1409.viewbindingdelegate.viewBinding
|
||||
import com.tangem.tap.common.GlobalLayoutStateHandler
|
||||
import com.tangem.tap.common.KeyboardObserver
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.events.Shop
|
||||
import com.tangem.tap.common.extensions.show
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.common.shop.data.ProductType
|
||||
|
|
@ -41,6 +43,8 @@ class ShopFragment : BaseStoreFragment(R.layout.fragment_shop), StoreSubscriber<
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Analytics.send(Shop.ScreenOpened())
|
||||
|
||||
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue