summaryrefslogtreecommitdiffhomepage
path: root/android/lib/payment
diff options
context:
space:
mode:
Diffstat (limited to 'android/lib/payment')
-rw-r--r--android/lib/payment/build.gradle.kts44
-rw-r--r--android/lib/payment/src/main/AndroidManifest.xml2
-rw-r--r--android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/PaymentProvider.kt3
-rw-r--r--android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/PaymentRepository.kt20
-rw-r--r--android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/ProductIds.kt5
-rw-r--r--android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PaymentAvailability.kt25
-rw-r--r--android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PaymentProduct.kt7
-rw-r--r--android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PaymentStatus.kt6
-rw-r--r--android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/ProductId.kt3
-rw-r--r--android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/ProductPrice.kt3
-rw-r--r--android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PurchaseResult.kt34
-rw-r--r--android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/VerificationResult.kt19
12 files changed, 171 insertions, 0 deletions
diff --git a/android/lib/payment/build.gradle.kts b/android/lib/payment/build.gradle.kts
new file mode 100644
index 0000000000..23f945b4f9
--- /dev/null
+++ b/android/lib/payment/build.gradle.kts
@@ -0,0 +1,44 @@
+plugins {
+ id(Dependencies.Plugin.androidLibraryId)
+ id(Dependencies.Plugin.kotlinAndroidId)
+}
+
+android {
+ namespace = "net.mullvad.mullvadvpn.lib.payment"
+ compileSdk = Versions.Android.compileSdkVersion
+
+ defaultConfig {
+ minSdk = Versions.Android.minSdkVersion
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+
+ kotlinOptions {
+ jvmTarget = Versions.jvmTarget
+ }
+
+ lint {
+ lintConfig = file("${rootProject.projectDir}/config/lint.xml")
+ abortOnError = true
+ warningsAsErrors = true
+ }
+
+ packaging {
+ resources {
+ pickFirsts += setOf(
+ // Fixes packaging error caused by: jetified-junit-*
+ "META-INF/LICENSE.md",
+ "META-INF/LICENSE-notice.md"
+ )
+ }
+ }
+}
+
+dependencies {
+ implementation(Dependencies.Kotlin.stdlib)
+ implementation(Dependencies.KotlinX.coroutinesAndroid)
+}
diff --git a/android/lib/payment/src/main/AndroidManifest.xml b/android/lib/payment/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..b2d3ea1235
--- /dev/null
+++ b/android/lib/payment/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
diff --git a/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/PaymentProvider.kt b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/PaymentProvider.kt
new file mode 100644
index 0000000000..431b406dc0
--- /dev/null
+++ b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/PaymentProvider.kt
@@ -0,0 +1,3 @@
+package net.mullvad.mullvadvpn.lib.payment
+
+@JvmInline value class PaymentProvider(val paymentRepository: PaymentRepository?)
diff --git a/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/PaymentRepository.kt b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/PaymentRepository.kt
new file mode 100644
index 0000000000..73fd0c061d
--- /dev/null
+++ b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/PaymentRepository.kt
@@ -0,0 +1,20 @@
+package net.mullvad.mullvadvpn.lib.payment
+
+import android.app.Activity
+import kotlinx.coroutines.flow.Flow
+import net.mullvad.mullvadvpn.lib.payment.model.PaymentAvailability
+import net.mullvad.mullvadvpn.lib.payment.model.ProductId
+import net.mullvad.mullvadvpn.lib.payment.model.PurchaseResult
+import net.mullvad.mullvadvpn.lib.payment.model.VerificationResult
+
+interface PaymentRepository {
+
+ fun purchaseProduct(
+ productId: ProductId,
+ activityProvider: () -> Activity
+ ): Flow<PurchaseResult>
+
+ fun verifyPurchases(): Flow<VerificationResult>
+
+ fun queryPaymentAvailability(): Flow<PaymentAvailability>
+}
diff --git a/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/ProductIds.kt b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/ProductIds.kt
new file mode 100644
index 0000000000..8754968891
--- /dev/null
+++ b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/ProductIds.kt
@@ -0,0 +1,5 @@
+package net.mullvad.mullvadvpn.lib.payment
+
+object ProductIds {
+ const val OneMonth = "one_month"
+}
diff --git a/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PaymentAvailability.kt b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PaymentAvailability.kt
new file mode 100644
index 0000000000..012237d825
--- /dev/null
+++ b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PaymentAvailability.kt
@@ -0,0 +1,25 @@
+package net.mullvad.mullvadvpn.lib.payment.model
+
+sealed interface PaymentAvailability {
+ data object Loading : PaymentAvailability
+
+ data class ProductsAvailable(val products: List<PaymentProduct>) : PaymentAvailability
+
+ data object ProductsUnavailable : PaymentAvailability
+
+ data object NoProductsFounds : PaymentAvailability
+
+ sealed interface Error : PaymentAvailability {
+ data object BillingUnavailable : Error
+
+ data object ServiceUnavailable : Error
+
+ data object FeatureNotSupported : Error
+
+ data object DeveloperError : Error
+
+ data object ItemUnavailable : Error
+
+ data class Other(val exception: Throwable) : Error
+ }
+}
diff --git a/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PaymentProduct.kt b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PaymentProduct.kt
new file mode 100644
index 0000000000..8945453d37
--- /dev/null
+++ b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PaymentProduct.kt
@@ -0,0 +1,7 @@
+package net.mullvad.mullvadvpn.lib.payment.model
+
+data class PaymentProduct(
+ val productId: ProductId,
+ val price: ProductPrice,
+ val status: PaymentStatus?
+)
diff --git a/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PaymentStatus.kt b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PaymentStatus.kt
new file mode 100644
index 0000000000..37574249a6
--- /dev/null
+++ b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PaymentStatus.kt
@@ -0,0 +1,6 @@
+package net.mullvad.mullvadvpn.lib.payment.model
+
+enum class PaymentStatus {
+ PENDING,
+ VERIFICATION_IN_PROGRESS
+}
diff --git a/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/ProductId.kt b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/ProductId.kt
new file mode 100644
index 0000000000..f14fefab28
--- /dev/null
+++ b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/ProductId.kt
@@ -0,0 +1,3 @@
+package net.mullvad.mullvadvpn.lib.payment.model
+
+@JvmInline value class ProductId(val value: String)
diff --git a/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/ProductPrice.kt b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/ProductPrice.kt
new file mode 100644
index 0000000000..5dc90db5fb
--- /dev/null
+++ b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/ProductPrice.kt
@@ -0,0 +1,3 @@
+package net.mullvad.mullvadvpn.lib.payment.model
+
+@JvmInline value class ProductPrice(val value: String)
diff --git a/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PurchaseResult.kt b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PurchaseResult.kt
new file mode 100644
index 0000000000..f5b89bffe6
--- /dev/null
+++ b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/PurchaseResult.kt
@@ -0,0 +1,34 @@
+package net.mullvad.mullvadvpn.lib.payment.model
+
+sealed interface PurchaseResult {
+ data object FetchingProducts : PurchaseResult
+
+ data object FetchingObfuscationId : PurchaseResult
+
+ data object BillingFlowStarted : PurchaseResult
+
+ data object VerificationStarted : PurchaseResult
+
+ sealed interface Completed : PurchaseResult {
+ data object Success : Completed
+
+ data object Cancelled : Completed
+
+ // This ends our part of the purchase flow. The rest is handled by Google and the api.
+ data object Pending : Completed
+ }
+
+ sealed interface Error : PurchaseResult {
+ data class NoProductFound(val productId: ProductId) : Error
+
+ data class FetchProductsError(val productId: ProductId, val exception: Throwable?) : Error
+
+ data class TransactionIdError(val productId: ProductId, val exception: Throwable?) : Error
+
+ data class BillingError(val exception: Throwable?) : Error
+
+ data class VerificationError(val exception: Throwable?) : Error
+ }
+
+ fun isTerminatingState(): Boolean = this is Completed || this is Error
+}
diff --git a/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/VerificationResult.kt b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/VerificationResult.kt
new file mode 100644
index 0000000000..725ea0af68
--- /dev/null
+++ b/android/lib/payment/src/main/kotlin/net/mullvad/mullvadvpn/lib/payment/model/VerificationResult.kt
@@ -0,0 +1,19 @@
+package net.mullvad.mullvadvpn.lib.payment.model
+
+sealed interface VerificationResult {
+ data object FetchingUnfinishedPurchases : VerificationResult
+
+ data object VerificationStarted : VerificationResult
+
+ // No verification was needed as there is no purchases to verify
+ data object NothingToVerify : VerificationResult
+
+ data object Success : VerificationResult
+
+ // Generic error, add more cases as needed
+ sealed interface Error : VerificationResult {
+ data class BillingError(val exception: Throwable?) : Error
+
+ data class VerificationError(val exception: Throwable?) : Error
+ }
+}