Updated on 2026-08-14
This commit is contained in:
parent
1f97352e5a
commit
c6dac76deb
16 changed files with 269 additions and 303 deletions
|
|
@ -1,39 +1,38 @@
|
|||
package com.tangem.datasource.api.paymentology
|
||||
|
||||
import com.tangem.datasource.api.paymentology.models.request.CheckRegistrationRequests
|
||||
import com.tangem.datasource.api.paymentology.models.request.RegisterKYCRequest
|
||||
import com.tangem.datasource.api.paymentology.models.request.RegisterWalletRequest
|
||||
import com.tangem.datasource.api.paymentology.models.response.AttestationResponse
|
||||
import com.tangem.datasource.api.paymentology.models.response.RegisterWalletResponse
|
||||
import com.tangem.datasource.api.paymentology.models.response.RegistrationResponse
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.Headers
|
||||
import retrofit2.http.POST
|
||||
|
||||
/**
|
||||
* Interface of Paymentology Api.
|
||||
*
|
||||
* IMPORTANT: Cannot replace [Headers] annotations with OkHttpClient.addHeader(), because OkHttp adds encoding to
|
||||
* content type value. But Paymentology API expects a value without the charset.
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface PaymentologyApi {
|
||||
|
||||
@Headers("Content-Type: application/json")
|
||||
@POST("card/verify")
|
||||
suspend fun checkRegistration(
|
||||
@Body request: CheckRegistrationRequests,
|
||||
): RegistrationResponse
|
||||
suspend fun checkRegistration(@Body request: CheckRegistrationRequests): RegistrationResponse
|
||||
|
||||
@Headers("Content-Type: application/json")
|
||||
@POST("card/get_challenge")
|
||||
suspend fun requestAttestationChallenge(
|
||||
@Body request: CheckRegistrationRequests.Item,
|
||||
): AttestationResponse
|
||||
suspend fun requestAttestationChallenge(@Body request: CheckRegistrationRequests.Item): AttestationResponse
|
||||
|
||||
@Headers("Content-Type: application/json")
|
||||
@POST("card/set_pin")
|
||||
suspend fun registerWallet(
|
||||
@Body request: RegisterWalletRequest,
|
||||
): RegisterWalletResponse
|
||||
suspend fun registerWallet(@Body request: RegisterWalletRequest): RegisterWalletResponse
|
||||
|
||||
@Headers("Content-Type: application/json")
|
||||
@POST("card/kyc")
|
||||
suspend fun registerKYC(
|
||||
@Body request: RegisterKYCRequest,
|
||||
): RegisterWalletResponse
|
||||
|
||||
companion object {
|
||||
val baseUrl: String = "https://paymentologygate.oa.r.appspot.com/"
|
||||
}
|
||||
suspend fun registerKYC(@Body request: RegisterKYCRequest): RegisterWalletResponse
|
||||
}
|
||||
|
|
@ -1,63 +1,30 @@
|
|||
package com.tangem.datasource.api.paymentology
|
||||
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.common.services.performRequest
|
||||
import com.tangem.datasource.api.common.MoshiConverter
|
||||
import com.tangem.datasource.api.common.createRetrofitInstance
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import com.tangem.datasource.utils.allowLogging
|
||||
import okhttp3.OkHttpClient
|
||||
import retrofit2.Retrofit
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class PaymentologyApiService(
|
||||
private val logEnabled: Boolean,
|
||||
) {
|
||||
private val api = createRetrofitInstance(
|
||||
baseUrl = PaymentologyApi.baseUrl,
|
||||
converterFactory = MoshiConverter.createFactory(MoshiConverter.sdkMoshi()),
|
||||
logEnabled = logEnabled,
|
||||
).create(PaymentologyApi::class.java)
|
||||
//TODO("Remove after removing Redux")
|
||||
@Deprecated("Use PaymentologyApi")
|
||||
object PaymentologyApiService {
|
||||
val api = createApi()
|
||||
|
||||
suspend fun checkRegistration(
|
||||
cardId: String,
|
||||
publicKey: ByteArray,
|
||||
): Result<RegistrationResponse> = withContext(Dispatchers.IO) {
|
||||
val requestItem = CheckRegistrationRequests.Item(cardId, publicKey.toHexString())
|
||||
val request = CheckRegistrationRequests(listOf(requestItem))
|
||||
performRequest {
|
||||
api.checkRegistration(request)
|
||||
}
|
||||
}
|
||||
private const val PAYMENTOLOGY_BASE_URL: String = "https://paymentologygate.oa.r.appspot.com/"
|
||||
|
||||
suspend fun requestAttestationChallenge(
|
||||
cardId: String,
|
||||
publicKey: ByteArray,
|
||||
): Result<AttestationResponse> = withContext(Dispatchers.IO) {
|
||||
val requestItem = CheckRegistrationRequests.Item(cardId, publicKey.toHexString())
|
||||
performRequest {
|
||||
api.requestAttestationChallenge(requestItem)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun registerWallet(
|
||||
request: RegisterWalletRequest,
|
||||
): Result<RegisterWalletResponse> = withContext(Dispatchers.IO) {
|
||||
performRequest {
|
||||
api.registerWallet(request)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun registerKYC(
|
||||
request: RegisterKYCRequest,
|
||||
): Result<RegisterWalletResponse> = withContext(Dispatchers.IO) {
|
||||
performRequest {
|
||||
api.registerKYC(request)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun stub(): PaymentologyApiService = PaymentologyApiService(false)
|
||||
private fun createApi(): PaymentologyApi {
|
||||
return Retrofit.Builder()
|
||||
.addConverterFactory(MoshiConverter.createFactory(MoshiConverter.sdkMoshi()))
|
||||
.baseUrl(PAYMENTOLOGY_BASE_URL)
|
||||
.client(
|
||||
OkHttpClient.Builder()
|
||||
.allowLogging()
|
||||
.build(),
|
||||
)
|
||||
.build()
|
||||
.create(PaymentologyApi::class.java)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
package com.tangem.datasource.api.paymentology
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.common.extensions.calculateHashCode
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
data class CheckRegistrationRequests(
|
||||
val requests: List<Item>,
|
||||
) {
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Item(
|
||||
@Json(name = "CID")
|
||||
val cardId: String = "",
|
||||
val publicKey: String = "",
|
||||
)
|
||||
}
|
||||
|
||||
data class RegisterWalletRequest(
|
||||
@Json(name = "CID")
|
||||
val cardId: String,
|
||||
val publicKey: ByteArray,
|
||||
val walletPublicKey: ByteArray,
|
||||
val walletSalt: ByteArray,
|
||||
val walletSignature: ByteArray,
|
||||
val cardSalt: ByteArray,
|
||||
val cardSignature: ByteArray,
|
||||
@Json(name = "PIN")
|
||||
val pin: String,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as RegisterWalletRequest
|
||||
|
||||
if (cardId != other.cardId) return false
|
||||
if (!publicKey.contentEquals(other.publicKey)) return false
|
||||
if (!walletPublicKey.contentEquals(other.walletPublicKey)) return false
|
||||
if (!walletSalt.contentEquals(other.walletSalt)) return false
|
||||
if (!walletSignature.contentEquals(other.walletSignature)) return false
|
||||
if (!cardSalt.contentEquals(other.cardSalt)) return false
|
||||
if (!cardSignature.contentEquals(other.cardSignature)) return false
|
||||
if (pin != other.pin) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = calculateHashCode(
|
||||
cardId.hashCode(),
|
||||
publicKey.contentHashCode(),
|
||||
walletPublicKey.contentHashCode(),
|
||||
walletSalt.contentHashCode(),
|
||||
walletSignature.contentHashCode(),
|
||||
cardSalt.contentHashCode(),
|
||||
cardSignature.contentHashCode(),
|
||||
pin.hashCode(),
|
||||
)
|
||||
}
|
||||
|
||||
data class RegisterKYCRequest(
|
||||
@Json(name = "CID")
|
||||
val cardId: String,
|
||||
val publicKey: ByteArray,
|
||||
val kycProvider: String,
|
||||
val kycRefId: String,
|
||||
) {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as RegisterKYCRequest
|
||||
|
||||
if (cardId != other.cardId) return false
|
||||
if (!publicKey.contentEquals(other.publicKey)) return false
|
||||
if (kycProvider != other.kycProvider) return false
|
||||
if (kycRefId != other.kycRefId) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = calculateHashCode(
|
||||
cardId.hashCode(),
|
||||
publicKey.contentHashCode(),
|
||||
kycProvider.hashCode(),
|
||||
kycRefId.hashCode(),
|
||||
)
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
package com.tangem.datasource.api.paymentology
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.tangem.common.extensions.calculateHashCode
|
||||
import com.tangem.common.services.Result
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface ResponseError {
|
||||
val success: Boolean
|
||||
val error: String?
|
||||
val errorCode: Int?
|
||||
|
||||
fun makeErrorMessage(): String {
|
||||
return error ?: "unknown error"
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T> ResponseError.tryExtractError(): Result<T> = when (success) {
|
||||
true -> Result.Success(this as T)
|
||||
else -> Result.Failure(Throwable(makeErrorMessage()))
|
||||
}
|
||||
|
||||
data class RegistrationResponse(
|
||||
val results: List<Item> = listOf(),
|
||||
override val success: Boolean,
|
||||
override val error: String?,
|
||||
override val errorCode: Int?,
|
||||
) : ResponseError {
|
||||
|
||||
data class Item(
|
||||
@Json(name = "CID")
|
||||
val cardId: String,
|
||||
val passed: Boolean?,
|
||||
val active: Boolean?,
|
||||
@Json(name = "pin_set")
|
||||
val pinSet: Boolean?,
|
||||
@Json(name = "blockchain_init")
|
||||
val blockchainInit: Boolean?,
|
||||
@Json(name = "kyc_passed")
|
||||
val kycPassed: Boolean?,
|
||||
@Json(name = "kyc_provider")
|
||||
val kycProvider: String?,
|
||||
@Json(name = "kyc_date")
|
||||
val kycDate: String?,
|
||||
@Json(name = "kyc_status")
|
||||
val kycStatus: KYCStatus?,
|
||||
@Json(name = "disabled_by_admin")
|
||||
val disabledByAdmin: Boolean?,
|
||||
val error: String?,
|
||||
)
|
||||
}
|
||||
|
||||
enum class KYCStatus {
|
||||
NOT_STARTED,
|
||||
STARTED,
|
||||
WAITING_FOR_APPROVAL,
|
||||
CORRECTION_REQUESTED,
|
||||
REJECTED,
|
||||
APPROVED,
|
||||
}
|
||||
|
||||
data class AttestationResponse(
|
||||
val challenge: ByteArray?,
|
||||
override val success: Boolean,
|
||||
override val error: String?,
|
||||
override val errorCode: Int?,
|
||||
) : ResponseError {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as AttestationResponse
|
||||
|
||||
if (!challenge.contentEquals(other.challenge)) return false
|
||||
if (success != other.success) return false
|
||||
if (error != other.error) return false
|
||||
if (errorCode != other.errorCode) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = calculateHashCode(
|
||||
challenge.contentHashCode(),
|
||||
success.hashCode(),
|
||||
error.hashCode(),
|
||||
errorCode.hashCode(),
|
||||
)
|
||||
}
|
||||
|
||||
data class RegisterWalletResponse(
|
||||
override val success: Boolean,
|
||||
override val error: String?,
|
||||
override val errorCode: Int?,
|
||||
) : ResponseError
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.datasource.api.paymentology.models.request
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
data class CheckRegistrationRequests(
|
||||
@Json(name = "requests") val requests: List<Item>,
|
||||
) {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Item(
|
||||
@Json(name = "CID") val cardId: String = "",
|
||||
@Json(name = "publicKey") val publicKey: String = "",
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.tangem.datasource.api.paymentology.models.request
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.tangem.common.extensions.calculateHashCode
|
||||
|
||||
data class RegisterKYCRequest(
|
||||
@Json(name = "CID") val cardId: String,
|
||||
@Json(name = "publicKey") val publicKey: ByteArray,
|
||||
@Json(name = "kycProvider") val kycProvider: String,
|
||||
@Json(name = "kycRefId") val kycRefId: String,
|
||||
) {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as RegisterKYCRequest
|
||||
|
||||
if (cardId != other.cardId) return false
|
||||
if (!publicKey.contentEquals(other.publicKey)) return false
|
||||
if (kycProvider != other.kycProvider) return false
|
||||
if (kycRefId != other.kycRefId) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = calculateHashCode(
|
||||
cardId.hashCode(),
|
||||
publicKey.contentHashCode(),
|
||||
kycProvider.hashCode(),
|
||||
kycRefId.hashCode(),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package com.tangem.datasource.api.paymentology.models.request
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.tangem.common.extensions.calculateHashCode
|
||||
|
||||
data class RegisterWalletRequest(
|
||||
@Json(name = "CID") val cardId: String,
|
||||
@Json(name = "publicKey") val publicKey: ByteArray,
|
||||
@Json(name = "walletPublicKey") val walletPublicKey: ByteArray,
|
||||
@Json(name = "walletSalt") val walletSalt: ByteArray,
|
||||
@Json(name = "walletSignature") val walletSignature: ByteArray,
|
||||
@Json(name = "cardSalt") val cardSalt: ByteArray,
|
||||
@Json(name = "cardSignature") val cardSignature: ByteArray,
|
||||
@Json(name = "PIN") val pin: String,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as RegisterWalletRequest
|
||||
|
||||
if (cardId != other.cardId) return false
|
||||
if (!publicKey.contentEquals(other.publicKey)) return false
|
||||
if (!walletPublicKey.contentEquals(other.walletPublicKey)) return false
|
||||
if (!walletSalt.contentEquals(other.walletSalt)) return false
|
||||
if (!walletSignature.contentEquals(other.walletSignature)) return false
|
||||
if (!cardSalt.contentEquals(other.cardSalt)) return false
|
||||
if (!cardSignature.contentEquals(other.cardSignature)) return false
|
||||
if (pin != other.pin) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = calculateHashCode(
|
||||
cardId.hashCode(),
|
||||
publicKey.contentHashCode(),
|
||||
walletPublicKey.contentHashCode(),
|
||||
walletSalt.contentHashCode(),
|
||||
walletSignature.contentHashCode(),
|
||||
cardSalt.contentHashCode(),
|
||||
cardSignature.contentHashCode(),
|
||||
pin.hashCode(),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.tangem.datasource.api.paymentology.models.response
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.tangem.common.extensions.calculateHashCode
|
||||
|
||||
data class AttestationResponse(
|
||||
@Json(name = "challenge") val challenge: ByteArray?,
|
||||
@Json(name = "success") override val success: Boolean,
|
||||
@Json(name = "error") override val error: String?,
|
||||
@Json(name = "errorCode") override val errorCode: Int?,
|
||||
) : ResponseError {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as AttestationResponse
|
||||
|
||||
if (!challenge.contentEquals(other.challenge)) return false
|
||||
if (success != other.success) return false
|
||||
if (error != other.error) return false
|
||||
if (errorCode != other.errorCode) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = calculateHashCode(
|
||||
challenge.contentHashCode(),
|
||||
success.hashCode(),
|
||||
error.hashCode(),
|
||||
errorCode.hashCode(),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.datasource.api.paymentology.models.response
|
||||
|
||||
enum class KYCStatus {
|
||||
NOT_STARTED,
|
||||
STARTED,
|
||||
WAITING_FOR_APPROVAL,
|
||||
CORRECTION_REQUESTED,
|
||||
REJECTED,
|
||||
APPROVED,
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.tangem.datasource.api.paymentology.models.response
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
data class RegisterWalletResponse(
|
||||
@Json(name = "success") override val success: Boolean,
|
||||
@Json(name = "error") override val error: String?,
|
||||
@Json(name = "errorCode") override val errorCode: Int?,
|
||||
) : ResponseError
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.tangem.datasource.api.paymentology.models.response
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
data class RegistrationResponse(
|
||||
@Json(name = "results") val results: List<Item> = listOf(),
|
||||
@Json(name = "success") override val success: Boolean,
|
||||
@Json(name = "error") override val error: String?,
|
||||
@Json(name = "errorCode") override val errorCode: Int?,
|
||||
) : ResponseError {
|
||||
|
||||
data class Item(
|
||||
@Json(name = "CID") val cardId: String,
|
||||
@Json(name = "passed") val passed: Boolean?,
|
||||
@Json(name = "active") val active: Boolean?,
|
||||
@Json(name = "pin_set") val pinSet: Boolean?,
|
||||
@Json(name = "blockchain_init") val blockchainInit: Boolean?,
|
||||
@Json(name = "kyc_passed") val kycPassed: Boolean?,
|
||||
@Json(name = "kyc_provider") val kycProvider: String?,
|
||||
@Json(name = "kyc_date") val kycDate: String?,
|
||||
@Json(name = "kyc_status") val kycStatus: KYCStatus?,
|
||||
@Json(name = "disabled_by_admin") val disabledByAdmin: Boolean?,
|
||||
@Json(name = "error") val error: String?,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.datasource.api.paymentology.models.response
|
||||
|
||||
import com.tangem.common.services.Result
|
||||
|
||||
interface ResponseError {
|
||||
val success: Boolean
|
||||
val error: String?
|
||||
val errorCode: Int?
|
||||
|
||||
fun makeErrorMessage(): String = error ?: "unknown error"
|
||||
}
|
||||
|
||||
inline fun <reified T> ResponseError.tryExtractError(): Result<T> = when (success) {
|
||||
true -> Result.Success(this as T)
|
||||
else -> Result.Failure(Throwable(makeErrorMessage()))
|
||||
}
|
||||
|
|
@ -53,5 +53,7 @@ class NetworkModule {
|
|||
private companion object {
|
||||
const val PROD_TANGEM_TECH_BASE_URL = "https://api.tangem-tech.com/v1/"
|
||||
const val DEV_TANGEM_TECH_BASE_URL = "https://devapi.tangem-tech.com/v1/"
|
||||
|
||||
private const val PAYMENTOLOGY_BASE_URL: String = "https://paymentologygate.oa.r.appspot.com/"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue