From 58fc99a609b8c6701ddb4b10e679ef32c9304448 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 14 May 2025 20:28:57 +0300 Subject: [PATCH 01/33] authorizeInvoice() api method for `apm-payment` endpoint and basic request/response --- ...lternativePaymentAuthorizationRequestBody.kt | 8 ++++++++ ...iveAlternativePaymentAuthorizationRequest.kt | 10 ++++++++++ ...ternativePaymentAuthorizationResponseBody.kt | 17 +++++++++++++++++ ...veAlternativePaymentAuthorizationResponse.kt | 16 ++++++++++++++++ .../processout/sdk/api/network/InvoicesApi.kt | 8 ++++++++ 5 files changed, 59 insertions(+) create mode 100644 sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/NativeAlternativePaymentAuthorizationRequestBody.kt create mode 100644 sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt create mode 100644 sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/NativeAlternativePaymentAuthorizationResponseBody.kt create mode 100644 sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/NativeAlternativePaymentAuthorizationRequestBody.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/NativeAlternativePaymentAuthorizationRequestBody.kt new file mode 100644 index 000000000..614aa8e05 --- /dev/null +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/NativeAlternativePaymentAuthorizationRequestBody.kt @@ -0,0 +1,8 @@ +package com.processout.sdk.api.model.request.napm.v2 + +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +internal data class NativeAlternativePaymentAuthorizationRequestBody( + val gatewayConfigurationId: String +) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt new file mode 100644 index 000000000..03ae56926 --- /dev/null +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt @@ -0,0 +1,10 @@ +package com.processout.sdk.api.model.request.napm.v2 + +import com.processout.sdk.core.annotation.ProcessOutInternalApi + +/** @suppress */ +@ProcessOutInternalApi +data class PONativeAlternativePaymentAuthorizationRequest( + val invoiceId: String, + val gatewayConfigurationId: String +) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/NativeAlternativePaymentAuthorizationResponseBody.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/NativeAlternativePaymentAuthorizationResponseBody.kt new file mode 100644 index 000000000..c3f1069d4 --- /dev/null +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/NativeAlternativePaymentAuthorizationResponseBody.kt @@ -0,0 +1,17 @@ +package com.processout.sdk.api.model.response.napm.v2 + +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +internal data class NativeAlternativePaymentAuthorizationResponseBody( + val state: State +) { + + @JsonClass(generateAdapter = false) + enum class State { + NEXT_STEP_REQUIRED, + PENDING_CAPTURE, + CAPTURED, + FAILED + } +} diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt new file mode 100644 index 000000000..11552eb35 --- /dev/null +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -0,0 +1,16 @@ +package com.processout.sdk.api.model.response.napm.v2 + +import com.processout.sdk.core.annotation.ProcessOutInternalApi + +/** @suppress */ +@ProcessOutInternalApi +data class PONativeAlternativePaymentAuthorizationResponse( + val state: State +) { + + enum class State { + NEXT_STEP_REQUIRED, + PENDING_CAPTURE, + CAPTURED + } +} diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt b/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt index c3124e4c1..fec2bf1f6 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt @@ -4,7 +4,9 @@ import com.processout.sdk.api.model.request.InvoiceAuthorizationRequestWithDevic import com.processout.sdk.api.model.request.NativeAPMRequestBody import com.processout.sdk.api.model.request.NativeAlternativePaymentCaptureRequest import com.processout.sdk.api.model.request.POCreateInvoiceRequest +import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuthorizationRequestBody import com.processout.sdk.api.model.response.* +import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody import com.processout.sdk.api.network.HeaderConstants.CLIENT_SECRET import retrofit2.Response import retrofit2.http.* @@ -18,6 +20,12 @@ internal interface InvoicesApi { @Header(CLIENT_SECRET) clientSecret: String? ): Response + @POST("/invoices/{id}/apm-payment") + suspend fun authorizeInvoice( + @Path("id") invoiceId: String, + @Body request: NativeAlternativePaymentAuthorizationRequestBody + ): Response + @POST("/invoices/{id}/native-payment") suspend fun initiatePayment( @Path("id") invoiceId: String, From ee97026038b7ee1e640fba96492e2446fc2f07cb Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Thu, 15 May 2025 14:37:22 +0300 Subject: [PATCH 02/33] authorizeInvoice() in invoices repository --- .../repository/DefaultInvoicesRepository.kt | 45 +++++++++++++++++++ .../sdk/api/repository/InvoicesRepository.kt | 6 +++ 2 files changed, 51 insertions(+) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt index da03358dd..81a9e2b07 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt @@ -1,10 +1,16 @@ package com.processout.sdk.api.repository import com.processout.sdk.api.model.request.* +import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuthorizationRequestBody +import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest import com.processout.sdk.api.model.response.* +import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody +import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody.State.* +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse import com.processout.sdk.api.network.HeaderConstants.CLIENT_SECRET import com.processout.sdk.api.network.InvoicesApi import com.processout.sdk.core.* +import com.processout.sdk.core.POFailure.Code.Generic import com.processout.sdk.di.ContextGraph import kotlinx.coroutines.launch import retrofit2.Response @@ -25,6 +31,15 @@ internal class DefaultInvoicesRepository( ) } + override suspend fun authorizeInvoice( + request: PONativeAlternativePaymentAuthorizationRequest + ) = apiCall { + api.authorizeInvoice( + invoiceId = request.invoiceId, + request = request.toBody() + ) + }.map() + override suspend fun initiatePayment( request: PONativeAlternativePaymentMethodRequest ) = apiCall { @@ -121,12 +136,42 @@ internal class DefaultInvoicesRepository( deviceData = contextGraph.deviceData ) + private fun PONativeAlternativePaymentAuthorizationRequest.toBody() = + NativeAlternativePaymentAuthorizationRequestBody( + gatewayConfigurationId = gatewayConfigurationId + ) + private fun PONativeAlternativePaymentMethodRequest.toBody() = NativeAPMRequestBody( gatewayConfigurationId = gatewayConfigurationId, nativeApm = NativeAPMRequestParameters(parameterValues = parameters) ) + private fun ProcessOutResult.map() = fold( + onSuccess = { responseBody -> + when (responseBody.state) { + FAILED -> ProcessOutResult.Failure( // TODO: map values from response body + code = Generic(), + message = "" + ) + else -> ProcessOutResult.Success( + PONativeAlternativePaymentAuthorizationResponse( + state = when (responseBody.state) { + NEXT_STEP_REQUIRED -> PONativeAlternativePaymentAuthorizationResponse.State.NEXT_STEP_REQUIRED + PENDING_CAPTURE -> PONativeAlternativePaymentAuthorizationResponse.State.PENDING_CAPTURE + CAPTURED -> PONativeAlternativePaymentAuthorizationResponse.State.CAPTURED + else -> return ProcessOutResult.Failure( + code = Generic(), + message = "Unsupported payment state: ${responseBody.state}." + ) + } + ) + ) + } + }, + onFailure = { it } + ) + private fun ProcessOutResult>.map() = fold( onSuccess = { response -> response.body()?.let { invoice -> diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/InvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/InvoicesRepository.kt index 8030d06d4..64f931cfe 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/InvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/InvoicesRepository.kt @@ -4,7 +4,9 @@ import com.processout.sdk.api.model.request.POCreateInvoiceRequest import com.processout.sdk.api.model.request.POInvoiceAuthorizationRequest import com.processout.sdk.api.model.request.POInvoiceRequest import com.processout.sdk.api.model.request.PONativeAlternativePaymentMethodRequest +import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest import com.processout.sdk.api.model.response.* +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse import com.processout.sdk.core.ProcessOutCallback import com.processout.sdk.core.ProcessOutResult import com.processout.sdk.core.annotation.ProcessOutInternalApi @@ -15,6 +17,10 @@ internal interface InvoicesRepository { request: POInvoiceAuthorizationRequest ): ProcessOutResult + suspend fun authorizeInvoice( + request: PONativeAlternativePaymentAuthorizationRequest + ): ProcessOutResult + suspend fun initiatePayment( request: PONativeAlternativePaymentMethodRequest ): ProcessOutResult From 8b16db902e3b45235b819948cafd89e36fad866b Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Thu, 15 May 2025 19:12:12 +0300 Subject: [PATCH 03/33] Remove NativeAlternativePaymentAuthorizationResponseBody --- ...rnativePaymentAuthorizationResponseBody.kt | 17 ---------- ...AlternativePaymentAuthorizationResponse.kt | 3 ++ .../processout/sdk/api/network/InvoicesApi.kt | 4 +-- .../repository/DefaultInvoicesRepository.kt | 31 +------------------ 4 files changed, 6 insertions(+), 49 deletions(-) delete mode 100644 sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/NativeAlternativePaymentAuthorizationResponseBody.kt diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/NativeAlternativePaymentAuthorizationResponseBody.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/NativeAlternativePaymentAuthorizationResponseBody.kt deleted file mode 100644 index c3f1069d4..000000000 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/NativeAlternativePaymentAuthorizationResponseBody.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.processout.sdk.api.model.response.napm.v2 - -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -internal data class NativeAlternativePaymentAuthorizationResponseBody( - val state: State -) { - - @JsonClass(generateAdapter = false) - enum class State { - NEXT_STEP_REQUIRED, - PENDING_CAPTURE, - CAPTURED, - FAILED - } -} diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index 11552eb35..e9c8c69da 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -1,13 +1,16 @@ package com.processout.sdk.api.model.response.napm.v2 import com.processout.sdk.core.annotation.ProcessOutInternalApi +import com.squareup.moshi.JsonClass /** @suppress */ @ProcessOutInternalApi +@JsonClass(generateAdapter = true) data class PONativeAlternativePaymentAuthorizationResponse( val state: State ) { + @JsonClass(generateAdapter = false) enum class State { NEXT_STEP_REQUIRED, PENDING_CAPTURE, diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt b/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt index fec2bf1f6..39869984a 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt @@ -6,7 +6,7 @@ import com.processout.sdk.api.model.request.NativeAlternativePaymentCaptureReque import com.processout.sdk.api.model.request.POCreateInvoiceRequest import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuthorizationRequestBody import com.processout.sdk.api.model.response.* -import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse import com.processout.sdk.api.network.HeaderConstants.CLIENT_SECRET import retrofit2.Response import retrofit2.http.* @@ -24,7 +24,7 @@ internal interface InvoicesApi { suspend fun authorizeInvoice( @Path("id") invoiceId: String, @Body request: NativeAlternativePaymentAuthorizationRequestBody - ): Response + ): Response @POST("/invoices/{id}/native-payment") suspend fun initiatePayment( diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt index 81a9e2b07..60b805fdd 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt @@ -4,13 +4,9 @@ import com.processout.sdk.api.model.request.* import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuthorizationRequestBody import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest import com.processout.sdk.api.model.response.* -import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody -import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody.State.* -import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse import com.processout.sdk.api.network.HeaderConstants.CLIENT_SECRET import com.processout.sdk.api.network.InvoicesApi import com.processout.sdk.core.* -import com.processout.sdk.core.POFailure.Code.Generic import com.processout.sdk.di.ContextGraph import kotlinx.coroutines.launch import retrofit2.Response @@ -38,7 +34,7 @@ internal class DefaultInvoicesRepository( invoiceId = request.invoiceId, request = request.toBody() ) - }.map() + } override suspend fun initiatePayment( request: PONativeAlternativePaymentMethodRequest @@ -147,31 +143,6 @@ internal class DefaultInvoicesRepository( nativeApm = NativeAPMRequestParameters(parameterValues = parameters) ) - private fun ProcessOutResult.map() = fold( - onSuccess = { responseBody -> - when (responseBody.state) { - FAILED -> ProcessOutResult.Failure( // TODO: map values from response body - code = Generic(), - message = "" - ) - else -> ProcessOutResult.Success( - PONativeAlternativePaymentAuthorizationResponse( - state = when (responseBody.state) { - NEXT_STEP_REQUIRED -> PONativeAlternativePaymentAuthorizationResponse.State.NEXT_STEP_REQUIRED - PENDING_CAPTURE -> PONativeAlternativePaymentAuthorizationResponse.State.PENDING_CAPTURE - CAPTURED -> PONativeAlternativePaymentAuthorizationResponse.State.CAPTURED - else -> return ProcessOutResult.Failure( - code = Generic(), - message = "Unsupported payment state: ${responseBody.state}." - ) - } - ) - ) - } - }, - onFailure = { it } - ) - private fun ProcessOutResult>.map() = fold( onSuccess = { response -> response.body()?.let { invoice -> From 82715b0b7f7076f15226176117f5323ec00d04ed Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Thu, 15 May 2025 19:28:39 +0300 Subject: [PATCH 04/33] authorize() function in invoices service --- .../sdk/api/service/DefaultInvoicesService.kt | 7 +++++++ .../processout/sdk/api/service/POInvoicesService.kt | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/service/DefaultInvoicesService.kt b/sdk/src/main/kotlin/com/processout/sdk/api/service/DefaultInvoicesService.kt index 696e33a1c..9a880b3c8 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/service/DefaultInvoicesService.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/service/DefaultInvoicesService.kt @@ -6,10 +6,12 @@ import com.processout.sdk.api.model.request.POCreateInvoiceRequest import com.processout.sdk.api.model.request.POInvoiceAuthorizationRequest import com.processout.sdk.api.model.request.POInvoiceRequest import com.processout.sdk.api.model.request.PONativeAlternativePaymentMethodRequest +import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest import com.processout.sdk.api.model.response.POInvoice import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethod import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodCapture import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodTransactionDetails +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse import com.processout.sdk.api.repository.InvoicesRepository import com.processout.sdk.core.* import com.processout.sdk.core.POFailure.Code.Cancelled @@ -162,6 +164,11 @@ internal class DefaultInvoicesService( } } + override suspend fun authorize( + request: PONativeAlternativePaymentAuthorizationRequest + ): ProcessOutResult = + repository.authorizeInvoice(request) + override suspend fun initiatePayment( request: PONativeAlternativePaymentMethodRequest ): ProcessOutResult = diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/service/POInvoicesService.kt b/sdk/src/main/kotlin/com/processout/sdk/api/service/POInvoicesService.kt index 062651f2f..9a3134220 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/service/POInvoicesService.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/service/POInvoicesService.kt @@ -4,10 +4,12 @@ import com.processout.sdk.api.model.request.POCreateInvoiceRequest import com.processout.sdk.api.model.request.POInvoiceAuthorizationRequest import com.processout.sdk.api.model.request.POInvoiceRequest import com.processout.sdk.api.model.request.PONativeAlternativePaymentMethodRequest +import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest import com.processout.sdk.api.model.response.POInvoice import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethod import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodCapture import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodTransactionDetails +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse import com.processout.sdk.core.ProcessOutCallback import com.processout.sdk.core.ProcessOutResult import com.processout.sdk.core.annotation.ProcessOutInternalApi @@ -63,6 +65,15 @@ interface POInvoicesService { threeDSService: PO3DSService ): ProcessOutResult + /** + * Authorize invoice with the given request. + */ + /** @suppress */ + @ProcessOutInternalApi + suspend fun authorize( + request: PONativeAlternativePaymentAuthorizationRequest + ): ProcessOutResult + /** * Initiates native alternative payment with the given request. */ From cae577ed512f0e4ecd598910032022c341109f11 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Thu, 15 May 2025 19:32:20 +0300 Subject: [PATCH 05/33] Move NativeAlternativePaymentAuthorizationRequestBody --- .../NativeAlternativePaymentAuthorizationRequestBody.kt | 8 -------- .../v2/PONativeAlternativePaymentAuthorizationRequest.kt | 6 ++++++ 2 files changed, 6 insertions(+), 8 deletions(-) delete mode 100644 sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/NativeAlternativePaymentAuthorizationRequestBody.kt diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/NativeAlternativePaymentAuthorizationRequestBody.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/NativeAlternativePaymentAuthorizationRequestBody.kt deleted file mode 100644 index 614aa8e05..000000000 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/NativeAlternativePaymentAuthorizationRequestBody.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.processout.sdk.api.model.request.napm.v2 - -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -internal data class NativeAlternativePaymentAuthorizationRequestBody( - val gatewayConfigurationId: String -) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt index 03ae56926..150668500 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt @@ -1,6 +1,7 @@ package com.processout.sdk.api.model.request.napm.v2 import com.processout.sdk.core.annotation.ProcessOutInternalApi +import com.squareup.moshi.JsonClass /** @suppress */ @ProcessOutInternalApi @@ -8,3 +9,8 @@ data class PONativeAlternativePaymentAuthorizationRequest( val invoiceId: String, val gatewayConfigurationId: String ) + +@JsonClass(generateAdapter = true) +internal data class NativeAlternativePaymentAuthorizationRequestBody( + val gatewayConfigurationId: String +) From b4b5fc537fdced5d345e89d7ca51100ddbb0e732 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Mon, 19 May 2025 12:24:42 +0300 Subject: [PATCH 06/33] Added 'parameters' to PONativeAlternativePaymentAuthorizationRequest --- ...eAlternativePaymentAuthorizationRequest.kt | 36 ++++++++++++++++--- .../repository/DefaultInvoicesRepository.kt | 28 ++++++++++++--- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt index 150668500..e83960527 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt @@ -1,16 +1,44 @@ package com.processout.sdk.api.model.request.napm.v2 import com.processout.sdk.core.annotation.ProcessOutInternalApi +import com.squareup.moshi.Json import com.squareup.moshi.JsonClass /** @suppress */ @ProcessOutInternalApi data class PONativeAlternativePaymentAuthorizationRequest( val invoiceId: String, - val gatewayConfigurationId: String -) + val gatewayConfigurationId: String, + val parameters: Map? = null +) { + + sealed class Parameter { + data class Value(val value: String) : Parameter() + + data class Phone( + val dialingCode: String, + val value: String + ) : Parameter() + } +} @JsonClass(generateAdapter = true) internal data class NativeAlternativePaymentAuthorizationRequestBody( - val gatewayConfigurationId: String -) + @Json(name = "gateway_configuration_id") + val gatewayConfigurationId: String, + @Json(name = "submit_data") + val submitData: SubmitData? +) { + + @JsonClass(generateAdapter = true) + data class SubmitData( + val parameters: Map + ) + + @JsonClass(generateAdapter = true) + data class Parameter( + val value: String, + @Json(name = "dialing_code") + val dialingCode: String? + ) +} diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt index 60b805fdd..a7d1e3cd3 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt @@ -2,7 +2,10 @@ package com.processout.sdk.api.repository import com.processout.sdk.api.model.request.* import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuthorizationRequestBody +import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuthorizationRequestBody.SubmitData import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest +import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter.Phone +import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter.Value import com.processout.sdk.api.model.response.* import com.processout.sdk.api.network.HeaderConstants.CLIENT_SECRET import com.processout.sdk.api.network.InvoicesApi @@ -132,17 +135,32 @@ internal class DefaultInvoicesRepository( deviceData = contextGraph.deviceData ) - private fun PONativeAlternativePaymentAuthorizationRequest.toBody() = - NativeAlternativePaymentAuthorizationRequestBody( - gatewayConfigurationId = gatewayConfigurationId - ) - private fun PONativeAlternativePaymentMethodRequest.toBody() = NativeAPMRequestBody( gatewayConfigurationId = gatewayConfigurationId, nativeApm = NativeAPMRequestParameters(parameterValues = parameters) ) + private fun PONativeAlternativePaymentAuthorizationRequest.toBody() = + NativeAlternativePaymentAuthorizationRequestBody( + gatewayConfigurationId = gatewayConfigurationId, + submitData = parameters?.let { SubmitData(parameters = it.map()) } + ) + + private fun Map.map() = + mapValues { (_, parameter) -> + when (parameter) { + is Value -> NativeAlternativePaymentAuthorizationRequestBody.Parameter( + value = parameter.value, + dialingCode = null + ) + is Phone -> NativeAlternativePaymentAuthorizationRequestBody.Parameter( + value = parameter.value, + dialingCode = parameter.dialingCode + ) + } + } + private fun ProcessOutResult>.map() = fold( onSuccess = { response -> response.body()?.let { invoice -> From e831fa2392fbf67e4ae6f0dc1178db25fc22f2db Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Mon, 19 May 2025 12:40:15 +0300 Subject: [PATCH 07/33] KDoc --- .../PONativeAlternativePaymentAuthorizationRequest.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt index e83960527..8288c552f 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt @@ -4,6 +4,13 @@ import com.processout.sdk.core.annotation.ProcessOutInternalApi import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +/** + * Request parameters for native alternative payment authorization. + * + * @param[invoiceId] Invoice identifier. + * @param[gatewayConfigurationId] Gateway configuration identifier. + * @param[parameters] Payment parameters. + */ /** @suppress */ @ProcessOutInternalApi data class PONativeAlternativePaymentAuthorizationRequest( @@ -12,9 +19,12 @@ data class PONativeAlternativePaymentAuthorizationRequest( val parameters: Map? = null ) { + /** Payment parameter. */ sealed class Parameter { + /** Arbitrary value. */ data class Value(val value: String) : Parameter() + /** Phone number value. */ data class Phone( val dialingCode: String, val value: String From 95c75591ef55ee877f0064a59974739ef9b0ca0f Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Mon, 19 May 2025 21:00:48 +0300 Subject: [PATCH 08/33] Base NextStep --- ...AlternativePaymentAuthorizationResponse.kt | 118 +++++++++++++++++- .../com/processout/sdk/di/NetworkGraph.kt | 20 +++ 2 files changed, 136 insertions(+), 2 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index e9c8c69da..f2835ad10 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -1,13 +1,16 @@ package com.processout.sdk.api.model.response.napm.v2 +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.NextStep.SubmitData.Parameter +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.State import com.processout.sdk.core.annotation.ProcessOutInternalApi +import com.squareup.moshi.Json import com.squareup.moshi.JsonClass /** @suppress */ @ProcessOutInternalApi -@JsonClass(generateAdapter = true) data class PONativeAlternativePaymentAuthorizationResponse( - val state: State + val state: State, + val nextStep: NextStep? ) { @JsonClass(generateAdapter = false) @@ -16,4 +19,115 @@ data class PONativeAlternativePaymentAuthorizationResponse( PENDING_CAPTURE, CAPTURED } + + sealed class NextStep { + + data class SubmitData( + val parameterDefinitions: List + ) : NextStep() { + + sealed class Parameter { + + @JsonClass(generateAdapter = true) + data class Text( + val key: String, + val label: String, + val required: Boolean + ) : Parameter() + + @JsonClass(generateAdapter = true) + data class SingleSelect( + val key: String, + val label: String, + val required: Boolean + ) : Parameter() + + @JsonClass(generateAdapter = true) + data class Bool( + val key: String, + val label: String, + val required: Boolean + ) : Parameter() + + @JsonClass(generateAdapter = true) + data class Digits( + val key: String, + val label: String, + val required: Boolean + ) : Parameter() + + @JsonClass(generateAdapter = true) + data class Phone( + val key: String, + val label: String, + val required: Boolean + ) : Parameter() + + @JsonClass(generateAdapter = true) + data class Email( + val key: String, + val label: String, + val required: Boolean + ) : Parameter() + + @JsonClass(generateAdapter = true) + data class Card( + val key: String, + val label: String, + val required: Boolean + ) : Parameter() + + @JsonClass(generateAdapter = true) + data class Otp( + val key: String, + val label: String, + val required: Boolean + ) : Parameter() + + data object Unknown : Parameter() + } + } + + data class Redirect( + val url: String + ) : NextStep() + + data object Unknown : NextStep() + } +} + +@JsonClass(generateAdapter = true) +internal data class NativeAlternativePaymentAuthorizationResponseBody( + val state: State, + @Json(name = "next_step") + val nextStep: NextStep? +) { + + sealed class NextStep { + + @JsonClass(generateAdapter = true) + data class SubmitData( + val parameters: Parameters + ) : NextStep() { + + @JsonClass(generateAdapter = true) + data class Parameters( + @Json(name = "parameter_definitions") + val parameterDefinitions: List + ) + } + + @JsonClass(generateAdapter = true) + data class Redirect( + val parameters: Parameters + ) : NextStep() { + + @JsonClass(generateAdapter = true) + data class Parameters( + val url: String + ) + } + + data object Unknown : NextStep() + } } diff --git a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt index c4e15f9b2..b55b469b5 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt @@ -2,6 +2,8 @@ package com.processout.sdk.di import com.processout.sdk.api.model.response.PODynamicCheckoutPaymentMethod import com.processout.sdk.api.model.response.PODynamicCheckoutPaymentMethod.* +import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody.NextStep +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.NextStep.SubmitData.Parameter import com.processout.sdk.api.network.* import com.processout.sdk.api.network.interceptor.BasicAuthInterceptor import com.processout.sdk.api.network.interceptor.RetryInterceptor @@ -53,6 +55,24 @@ internal class DefaultNetworkGraph( override val moshi: Moshi by lazy { Moshi.Builder() .add(Date::class.java, Rfc3339DateJsonAdapter()) + .add( + PolymorphicJsonAdapterFactory.of(NextStep::class.java, "type") + .withSubtype(NextStep.SubmitData::class.java, "submit_data") + .withSubtype(NextStep.Redirect::class.java, "redirect") + .withDefaultValue(NextStep.Unknown) + ) + .add( + PolymorphicJsonAdapterFactory.of(Parameter::class.java, "type") + .withSubtype(Parameter.Text::class.java, "text") + .withSubtype(Parameter.SingleSelect::class.java, "single-select") + .withSubtype(Parameter.Bool::class.java, "boolean") + .withSubtype(Parameter.Digits::class.java, "digits") + .withSubtype(Parameter.Phone::class.java, "phone") + .withSubtype(Parameter.Email::class.java, "email") + .withSubtype(Parameter.Card::class.java, "card") + .withSubtype(Parameter.Otp::class.java, "otp") + .withDefaultValue(Parameter.Unknown) + ) .add( PolymorphicJsonAdapterFactory.of(PODynamicCheckoutPaymentMethod::class.java, "type") .withSubtype(Card::class.java, "card") From f4100bc009a6c334e9ba9ab42651c28607cc86c6 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 20 May 2025 11:36:03 +0300 Subject: [PATCH 09/33] Parameter 'minLength' and 'maxLength' --- ...AlternativePaymentAuthorizationResponse.kt | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index f2835ad10..d2f15882c 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -32,7 +32,11 @@ data class PONativeAlternativePaymentAuthorizationResponse( data class Text( val key: String, val label: String, - val required: Boolean + val required: Boolean, + @Json(name = "min_length") + val minLength: Int?, + @Json(name = "max_length") + val maxLength: Int? ) : Parameter() @JsonClass(generateAdapter = true) @@ -53,7 +57,11 @@ data class PONativeAlternativePaymentAuthorizationResponse( data class Digits( val key: String, val label: String, - val required: Boolean + val required: Boolean, + @Json(name = "min_length") + val minLength: Int?, + @Json(name = "max_length") + val maxLength: Int? ) : Parameter() @JsonClass(generateAdapter = true) @@ -74,14 +82,22 @@ data class PONativeAlternativePaymentAuthorizationResponse( data class Card( val key: String, val label: String, - val required: Boolean + val required: Boolean, + @Json(name = "min_length") + val minLength: Int?, + @Json(name = "max_length") + val maxLength: Int? ) : Parameter() @JsonClass(generateAdapter = true) data class Otp( val key: String, val label: String, - val required: Boolean + val required: Boolean, + @Json(name = "min_length") + val minLength: Int?, + @Json(name = "max_length") + val maxLength: Int? ) : Parameter() data object Unknown : Parameter() From 38096656d4408195345fe93dbb63f83749ed0363 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 20 May 2025 11:44:59 +0300 Subject: [PATCH 10/33] AvailableValue --- ...iveAlternativePaymentAuthorizationResponse.kt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index d2f15882c..9264c753d 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -43,8 +43,20 @@ data class PONativeAlternativePaymentAuthorizationResponse( data class SingleSelect( val key: String, val label: String, - val required: Boolean - ) : Parameter() + val required: Boolean, + @Json(name = "available_values") + val availableValues: List, + @Json(ignore = true) + val preselectedValue: AvailableValue? = availableValues.find { it.preselected } + ) : Parameter() { + + @JsonClass(generateAdapter = true) + data class AvailableValue( + val key: String, + val label: String, + val preselected: Boolean + ) + } @JsonClass(generateAdapter = true) data class Bool( From 991db11fcd387fce47f9e6a14e6f1c7741cb133b Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 20 May 2025 12:34:52 +0300 Subject: [PATCH 11/33] DialingCode --- ...NativeAlternativePaymentAuthorizationResponse.kt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index 9264c753d..56dc0fe02 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -80,8 +80,17 @@ data class PONativeAlternativePaymentAuthorizationResponse( data class Phone( val key: String, val label: String, - val required: Boolean - ) : Parameter() + val required: Boolean, + @Json(name = "dialing_code") + val dialingCodes: List? + ) : Parameter() { + + @JsonClass(generateAdapter = true) + data class DialingCode( + val id: String, + val value: String + ) + } @JsonClass(generateAdapter = true) data class Email( From 36cd9e4ca012ba33c66fa98fa1463a82d632a746 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 20 May 2025 14:45:19 +0300 Subject: [PATCH 12/33] OTP Subtype --- ...tiveAlternativePaymentAuthorizationResponse.kt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index 56dc0fe02..8d7dd0d50 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -3,6 +3,7 @@ package com.processout.sdk.api.model.response.napm.v2 import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.NextStep.SubmitData.Parameter import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.State import com.processout.sdk.core.annotation.ProcessOutInternalApi +import com.processout.sdk.core.util.findBy import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -113,13 +114,25 @@ data class PONativeAlternativePaymentAuthorizationResponse( @JsonClass(generateAdapter = true) data class Otp( val key: String, + @Json(name = "subtype") + val rawSubtype: String, val label: String, val required: Boolean, @Json(name = "min_length") val minLength: Int?, @Json(name = "max_length") val maxLength: Int? - ) : Parameter() + ) : Parameter() { + + val subtype: Subtype + get() = Subtype::rawValue.findBy(rawSubtype) ?: Subtype.UNKNOWN + + enum class Subtype(val rawValue: String) { + TEXT("text"), + DIGITS("digits"), + UNKNOWN(String()) + } + } data object Unknown : Parameter() } From 8df51b1243580f8ea3af78055cc6c6a262355f8f Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 20 May 2025 16:35:41 +0300 Subject: [PATCH 13/33] CustomerInstruction --- ...AlternativePaymentAuthorizationResponse.kt | 58 ++++++++++++++++--- .../com/processout/sdk/di/NetworkGraph.kt | 17 ++++-- 2 files changed, 62 insertions(+), 13 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index 8d7dd0d50..6a5d2f077 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -1,5 +1,8 @@ package com.processout.sdk.api.model.response.napm.v2 +import com.processout.sdk.api.model.response.POBarcode +import com.processout.sdk.api.model.response.POImageResource +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.CustomerInstruction import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.NextStep.SubmitData.Parameter import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.State import com.processout.sdk.core.annotation.ProcessOutInternalApi @@ -11,7 +14,8 @@ import com.squareup.moshi.JsonClass @ProcessOutInternalApi data class PONativeAlternativePaymentAuthorizationResponse( val state: State, - val nextStep: NextStep? + val nextStep: NextStep?, + val customerInstructions: List? ) { @JsonClass(generateAdapter = false) @@ -46,11 +50,12 @@ data class PONativeAlternativePaymentAuthorizationResponse( val label: String, val required: Boolean, @Json(name = "available_values") - val availableValues: List, - @Json(ignore = true) - val preselectedValue: AvailableValue? = availableValues.find { it.preselected } + val availableValues: List ) : Parameter() { + val preselectedValue: AvailableValue? + get() = availableValues.find { it.preselected } + @JsonClass(generateAdapter = true) data class AvailableValue( val key: String, @@ -125,9 +130,9 @@ data class PONativeAlternativePaymentAuthorizationResponse( ) : Parameter() { val subtype: Subtype - get() = Subtype::rawValue.findBy(rawSubtype) ?: Subtype.UNKNOWN + get() = Subtype::rawType.findBy(rawSubtype) ?: Subtype.UNKNOWN - enum class Subtype(val rawValue: String) { + enum class Subtype(val rawType: String) { TEXT("text"), DIGITS("digits"), UNKNOWN(String()) @@ -144,13 +149,52 @@ data class PONativeAlternativePaymentAuthorizationResponse( data object Unknown : NextStep() } + + sealed class CustomerInstruction { + + @JsonClass(generateAdapter = true) + data class Text( + val label: String?, + val value: String + ) : CustomerInstruction() + + @JsonClass(generateAdapter = true) + data class Image( + val value: POImageResource + ) : CustomerInstruction() + + @JsonClass(generateAdapter = true) + data class Barcode( + @Json(name = "subtype") + val rawSubtype: String, + @Json(name = "value") + val rawValue: String + ) : CustomerInstruction() { + + val value: POBarcode + get() = POBarcode( + rawType = rawSubtype, + rawValue = rawValue + ) + } + + @JsonClass(generateAdapter = true) + data class Group( + val label: String?, + val instructions: List + ) : CustomerInstruction() + + data object Unknown : CustomerInstruction() + } } @JsonClass(generateAdapter = true) internal data class NativeAlternativePaymentAuthorizationResponseBody( val state: State, @Json(name = "next_step") - val nextStep: NextStep? + val nextStep: NextStep?, + @Json(name = "customer_instructions") + val customerInstructions: List? ) { sealed class NextStep { diff --git a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt index b55b469b5..d8720ad45 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt @@ -3,6 +3,7 @@ package com.processout.sdk.di import com.processout.sdk.api.model.response.PODynamicCheckoutPaymentMethod import com.processout.sdk.api.model.response.PODynamicCheckoutPaymentMethod.* import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody.NextStep +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.CustomerInstruction import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.NextStep.SubmitData.Parameter import com.processout.sdk.api.network.* import com.processout.sdk.api.network.interceptor.BasicAuthInterceptor @@ -60,8 +61,7 @@ internal class DefaultNetworkGraph( .withSubtype(NextStep.SubmitData::class.java, "submit_data") .withSubtype(NextStep.Redirect::class.java, "redirect") .withDefaultValue(NextStep.Unknown) - ) - .add( + ).add( PolymorphicJsonAdapterFactory.of(Parameter::class.java, "type") .withSubtype(Parameter.Text::class.java, "text") .withSubtype(Parameter.SingleSelect::class.java, "single-select") @@ -72,8 +72,14 @@ internal class DefaultNetworkGraph( .withSubtype(Parameter.Card::class.java, "card") .withSubtype(Parameter.Otp::class.java, "otp") .withDefaultValue(Parameter.Unknown) - ) - .add( + ).add( + PolymorphicJsonAdapterFactory.of(CustomerInstruction::class.java, "type") + .withSubtype(CustomerInstruction.Text::class.java, "text") + .withSubtype(CustomerInstruction.Image::class.java, "image_url") + .withSubtype(CustomerInstruction.Barcode::class.java, "barcode") + .withSubtype(CustomerInstruction.Group::class.java, "group") + .withDefaultValue(CustomerInstruction.Unknown) + ).add( PolymorphicJsonAdapterFactory.of(PODynamicCheckoutPaymentMethod::class.java, "type") .withSubtype(Card::class.java, "card") .withSubtype(CardCustomerToken::class.java, "card_customer_token") @@ -81,8 +87,7 @@ internal class DefaultNetworkGraph( .withSubtype(AlternativePayment::class.java, "apm") .withSubtype(AlternativePaymentCustomerToken::class.java, "apm_customer_token") .withDefaultValue(Unknown) - ) - .build() + ).build() } private val retrofit: Retrofit by lazy { From 005f7310c69d7b7ce085cbe72226b5239252bdc0 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 20 May 2025 16:40:06 +0300 Subject: [PATCH 14/33] Phone -> PhoneNumber --- .../napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt | 2 +- .../v2/PONativeAlternativePaymentAuthorizationResponse.kt | 2 +- .../sdk/api/repository/DefaultInvoicesRepository.kt | 4 ++-- sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt index 8288c552f..668bc5758 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt @@ -25,7 +25,7 @@ data class PONativeAlternativePaymentAuthorizationRequest( data class Value(val value: String) : Parameter() /** Phone number value. */ - data class Phone( + data class PhoneNumber( val dialingCode: String, val value: String ) : Parameter() diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index 6a5d2f077..fe2411bde 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -83,7 +83,7 @@ data class PONativeAlternativePaymentAuthorizationResponse( ) : Parameter() @JsonClass(generateAdapter = true) - data class Phone( + data class PhoneNumber( val key: String, val label: String, val required: Boolean, diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt index a7d1e3cd3..45e5d4af8 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt @@ -4,7 +4,7 @@ import com.processout.sdk.api.model.request.* import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuthorizationRequestBody import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuthorizationRequestBody.SubmitData import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest -import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter.Phone +import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter.PhoneNumber import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter.Value import com.processout.sdk.api.model.response.* import com.processout.sdk.api.network.HeaderConstants.CLIENT_SECRET @@ -154,7 +154,7 @@ internal class DefaultInvoicesRepository( value = parameter.value, dialingCode = null ) - is Phone -> NativeAlternativePaymentAuthorizationRequestBody.Parameter( + is PhoneNumber -> NativeAlternativePaymentAuthorizationRequestBody.Parameter( value = parameter.value, dialingCode = parameter.dialingCode ) diff --git a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt index d8720ad45..b360e62f7 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt @@ -67,7 +67,7 @@ internal class DefaultNetworkGraph( .withSubtype(Parameter.SingleSelect::class.java, "single-select") .withSubtype(Parameter.Bool::class.java, "boolean") .withSubtype(Parameter.Digits::class.java, "digits") - .withSubtype(Parameter.Phone::class.java, "phone") + .withSubtype(Parameter.PhoneNumber::class.java, "phone") .withSubtype(Parameter.Email::class.java, "email") .withSubtype(Parameter.Card::class.java, "card") .withSubtype(Parameter.Otp::class.java, "otp") From b4d0da1a796e5b7f1a3057a2a89ddbcf97ed22e1 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 20 May 2025 17:02:43 +0300 Subject: [PATCH 15/33] Map response --- .../processout/sdk/api/network/InvoicesApi.kt | 4 ++-- .../repository/DefaultInvoicesRepository.kt | 22 ++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt b/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt index 39869984a..fec2bf1f6 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt @@ -6,7 +6,7 @@ import com.processout.sdk.api.model.request.NativeAlternativePaymentCaptureReque import com.processout.sdk.api.model.request.POCreateInvoiceRequest import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuthorizationRequestBody import com.processout.sdk.api.model.response.* -import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse +import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody import com.processout.sdk.api.network.HeaderConstants.CLIENT_SECRET import retrofit2.Response import retrofit2.http.* @@ -24,7 +24,7 @@ internal interface InvoicesApi { suspend fun authorizeInvoice( @Path("id") invoiceId: String, @Body request: NativeAlternativePaymentAuthorizationRequestBody - ): Response + ): Response @POST("/invoices/{id}/native-payment") suspend fun initiatePayment( diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt index 45e5d4af8..d812e2874 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt @@ -7,6 +7,9 @@ import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAu import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter.PhoneNumber import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter.Value import com.processout.sdk.api.model.response.* +import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody +import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody.NextStep +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse import com.processout.sdk.api.network.HeaderConstants.CLIENT_SECRET import com.processout.sdk.api.network.InvoicesApi import com.processout.sdk.core.* @@ -37,7 +40,7 @@ internal class DefaultInvoicesRepository( invoiceId = request.invoiceId, request = request.toBody() ) - } + }.map { it.toModel() } override suspend fun initiatePayment( request: PONativeAlternativePaymentMethodRequest @@ -161,6 +164,23 @@ internal class DefaultInvoicesRepository( } } + private fun NativeAlternativePaymentAuthorizationResponseBody.toModel() = + PONativeAlternativePaymentAuthorizationResponse( + state = state, + nextStep = nextStep?.let { + when (it) { + is NextStep.SubmitData -> PONativeAlternativePaymentAuthorizationResponse.NextStep.SubmitData( + parameterDefinitions = it.parameters.parameterDefinitions + ) + is NextStep.Redirect -> PONativeAlternativePaymentAuthorizationResponse.NextStep.Redirect( + url = it.parameters.url + ) + NextStep.Unknown -> PONativeAlternativePaymentAuthorizationResponse.NextStep.Unknown + } + }, + customerInstructions = customerInstructions + ) + private fun ProcessOutResult>.map() = fold( onSuccess = { response -> response.body()?.let { invoice -> From f96ffb096dd9acf0a581376912119dc1165c38a4 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 20 May 2025 19:22:03 +0300 Subject: [PATCH 16/33] PONativeAlternativePaymentRequest --- .../napm/v2/PONativeAlternativePaymentRequest.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentRequest.kt diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentRequest.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentRequest.kt new file mode 100644 index 000000000..ef91d4a90 --- /dev/null +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentRequest.kt @@ -0,0 +1,16 @@ +package com.processout.sdk.api.model.request.napm.v2 + +import com.processout.sdk.core.annotation.ProcessOutInternalApi + +/** + * Request parameters for native alternative payment. + * + * @param[invoiceId] Invoice identifier. + * @param[gatewayConfigurationId] Gateway configuration identifier. + */ +/** @suppress */ +@ProcessOutInternalApi +data class PONativeAlternativePaymentRequest( + val invoiceId: String, + val gatewayConfigurationId: String +) From f97107cc258597b56996070442827466cb7de95c Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Tue, 20 May 2025 19:53:06 +0300 Subject: [PATCH 17/33] GET nativeAlternativePayment() --- .../com/processout/sdk/api/network/InvoicesApi.kt | 6 ++++++ .../sdk/api/repository/DefaultInvoicesRepository.kt | 10 ++++++++++ .../sdk/api/repository/InvoicesRepository.kt | 5 +++++ .../sdk/api/service/DefaultInvoicesService.kt | 6 ++++++ .../processout/sdk/api/service/POInvoicesService.kt | 10 ++++++++++ 5 files changed, 37 insertions(+) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt b/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt index fec2bf1f6..7552314a0 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/network/InvoicesApi.kt @@ -26,6 +26,12 @@ internal interface InvoicesApi { @Body request: NativeAlternativePaymentAuthorizationRequestBody ): Response + @GET("/invoices/{invoiceId}/apm-payment/{gatewayConfigurationId}") + suspend fun nativeAlternativePayment( + @Path("invoiceId") invoiceId: String, + @Path("gatewayConfigurationId") gatewayConfigurationId: String + ): Response + @POST("/invoices/{id}/native-payment") suspend fun initiatePayment( @Path("id") invoiceId: String, diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt index d812e2874..8ebf85c7c 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt @@ -6,6 +6,7 @@ import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuth import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter.PhoneNumber import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter.Value +import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentRequest import com.processout.sdk.api.model.response.* import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody.NextStep @@ -42,6 +43,15 @@ internal class DefaultInvoicesRepository( ) }.map { it.toModel() } + override suspend fun nativeAlternativePayment( + request: PONativeAlternativePaymentRequest + ) = apiCall { + api.nativeAlternativePayment( + invoiceId = request.invoiceId, + gatewayConfigurationId = request.gatewayConfigurationId + ) + }.map { it.toModel() } + override suspend fun initiatePayment( request: PONativeAlternativePaymentMethodRequest ) = apiCall { diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/InvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/InvoicesRepository.kt index 64f931cfe..5b617539b 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/InvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/InvoicesRepository.kt @@ -5,6 +5,7 @@ import com.processout.sdk.api.model.request.POInvoiceAuthorizationRequest import com.processout.sdk.api.model.request.POInvoiceRequest import com.processout.sdk.api.model.request.PONativeAlternativePaymentMethodRequest import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest +import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentRequest import com.processout.sdk.api.model.response.* import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse import com.processout.sdk.core.ProcessOutCallback @@ -21,6 +22,10 @@ internal interface InvoicesRepository { request: PONativeAlternativePaymentAuthorizationRequest ): ProcessOutResult + suspend fun nativeAlternativePayment( + request: PONativeAlternativePaymentRequest + ): ProcessOutResult + suspend fun initiatePayment( request: PONativeAlternativePaymentMethodRequest ): ProcessOutResult diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/service/DefaultInvoicesService.kt b/sdk/src/main/kotlin/com/processout/sdk/api/service/DefaultInvoicesService.kt index 9a880b3c8..5d46b4f4c 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/service/DefaultInvoicesService.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/service/DefaultInvoicesService.kt @@ -7,6 +7,7 @@ import com.processout.sdk.api.model.request.POInvoiceAuthorizationRequest import com.processout.sdk.api.model.request.POInvoiceRequest import com.processout.sdk.api.model.request.PONativeAlternativePaymentMethodRequest import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest +import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentRequest import com.processout.sdk.api.model.response.POInvoice import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethod import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodCapture @@ -169,6 +170,11 @@ internal class DefaultInvoicesService( ): ProcessOutResult = repository.authorizeInvoice(request) + override suspend fun nativeAlternativePayment( + request: PONativeAlternativePaymentRequest + ): ProcessOutResult = + repository.nativeAlternativePayment(request) + override suspend fun initiatePayment( request: PONativeAlternativePaymentMethodRequest ): ProcessOutResult = diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/service/POInvoicesService.kt b/sdk/src/main/kotlin/com/processout/sdk/api/service/POInvoicesService.kt index 9a3134220..65cdce2ff 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/service/POInvoicesService.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/service/POInvoicesService.kt @@ -5,6 +5,7 @@ import com.processout.sdk.api.model.request.POInvoiceAuthorizationRequest import com.processout.sdk.api.model.request.POInvoiceRequest import com.processout.sdk.api.model.request.PONativeAlternativePaymentMethodRequest import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest +import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentRequest import com.processout.sdk.api.model.response.POInvoice import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethod import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodCapture @@ -74,6 +75,15 @@ interface POInvoicesService { request: PONativeAlternativePaymentAuthorizationRequest ): ProcessOutResult + /** + * Fetch native alternative payment details. + */ + /** @suppress */ + @ProcessOutInternalApi + suspend fun nativeAlternativePayment( + request: PONativeAlternativePaymentRequest + ): ProcessOutResult + /** * Initiates native alternative payment with the given request. */ From ace15d8ef0d5d1ba5a66937e6d2fc42addebf5e4 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 21 May 2025 11:09:09 +0300 Subject: [PATCH 18/33] dialing_codes --- .../napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index fe2411bde..68a5524a6 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -87,7 +87,7 @@ data class PONativeAlternativePaymentAuthorizationResponse( val key: String, val label: String, val required: Boolean, - @Json(name = "dialing_code") + @Json(name = "dialing_codes") val dialingCodes: List? ) : Parameter() { From c245431fbe84c9aa030161989dd0b83fa4ba59ca Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 21 May 2025 12:23:19 +0300 Subject: [PATCH 19/33] KDoc --- ...AlternativePaymentAuthorizationResponse.kt | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index 68a5524a6..29e1590b8 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -10,6 +10,13 @@ import com.processout.sdk.core.util.findBy import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +/** + * Specifies details of native alternative payment. + * + * @param[state] State of native alternative payment. + * @param[nextStep] Next required step in the payment flow. + * @param[customerInstructions] Instructions for the customer that provide additional information and/or describe required actions. + */ /** @suppress */ @ProcessOutInternalApi data class PONativeAlternativePaymentAuthorizationResponse( @@ -18,21 +25,41 @@ data class PONativeAlternativePaymentAuthorizationResponse( val customerInstructions: List? ) { + /** + * State of native alternative payment. + */ @JsonClass(generateAdapter = false) enum class State { + /** Next step is required to proceed. */ NEXT_STEP_REQUIRED, + + /** Payment is ready to be captured. */ PENDING_CAPTURE, + + /** Payment is captured. */ CAPTURED } + /** + * Specifies the next required step in the payment flow. + */ sealed class NextStep { + /** + * Indicates that the next required step is submitting data for the expected [parameterDefinitions]. + */ data class SubmitData( val parameterDefinitions: List ) : NextStep() { + /** + * Payment parameter definition. + */ sealed class Parameter { + /** + * Text parameter. + */ @JsonClass(generateAdapter = true) data class Text( val key: String, @@ -44,6 +71,9 @@ data class PONativeAlternativePaymentAuthorizationResponse( val maxLength: Int? ) : Parameter() + /** + * Single selection parameter. + */ @JsonClass(generateAdapter = true) data class SingleSelect( val key: String, @@ -64,6 +94,9 @@ data class PONativeAlternativePaymentAuthorizationResponse( ) } + /** + * Boolean parameter. + */ @JsonClass(generateAdapter = true) data class Bool( val key: String, @@ -71,6 +104,9 @@ data class PONativeAlternativePaymentAuthorizationResponse( val required: Boolean ) : Parameter() + /** + * Digits only parameter. + */ @JsonClass(generateAdapter = true) data class Digits( val key: String, @@ -82,6 +118,9 @@ data class PONativeAlternativePaymentAuthorizationResponse( val maxLength: Int? ) : Parameter() + /** + * Phone number parameter. + */ @JsonClass(generateAdapter = true) data class PhoneNumber( val key: String, @@ -98,6 +137,9 @@ data class PONativeAlternativePaymentAuthorizationResponse( ) } + /** + * Email parameter. + */ @JsonClass(generateAdapter = true) data class Email( val key: String, @@ -105,6 +147,9 @@ data class PONativeAlternativePaymentAuthorizationResponse( val required: Boolean ) : Parameter() + /** + * Card number parameter. + */ @JsonClass(generateAdapter = true) data class Card( val key: String, @@ -116,6 +161,9 @@ data class PONativeAlternativePaymentAuthorizationResponse( val maxLength: Int? ) : Parameter() + /** + * One-Time Password (OTP) parameter. + */ @JsonClass(generateAdapter = true) data class Otp( val key: String, @@ -139,17 +187,29 @@ data class PONativeAlternativePaymentAuthorizationResponse( } } + /** + * Unknown parameter. + */ data object Unknown : Parameter() } } + /** + * Indicates that the next required step is a redirect to the URL. + */ data class Redirect( val url: String ) : NextStep() + /** + * The next step is unknown. + */ data object Unknown : NextStep() } + /** + * Specifies instructions for the customer, providing additional information and/or describing required actions. + */ sealed class CustomerInstruction { @JsonClass(generateAdapter = true) From 338f8c47db8db781964d468758b5be9dfd25755e Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 21 May 2025 14:38:54 +0300 Subject: [PATCH 20/33] AvailableValue --- .../PONativeAlternativePaymentAuthorizationResponse.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index 29e1590b8..73538fb79 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -86,9 +86,16 @@ data class PONativeAlternativePaymentAuthorizationResponse( val preselectedValue: AvailableValue? get() = availableValues.find { it.preselected } + /** + * Available parameter value. + * + * @param[value] Parameter value. + * @param[label] Parameter display label. + * @param[preselected] Indicates whether the parameter should be preselected by default. + */ @JsonClass(generateAdapter = true) data class AvailableValue( - val key: String, + val value: String, val label: String, val preselected: Boolean ) From e8e71ef4601c24eab09af6df37dff92e30a2afa7 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 21 May 2025 15:03:11 +0300 Subject: [PATCH 21/33] Moshi adapters --- .../com/processout/sdk/di/NetworkGraph.kt | 72 ++++++++++--------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt index b360e62f7..bb60ec37b 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt @@ -56,40 +56,48 @@ internal class DefaultNetworkGraph( override val moshi: Moshi by lazy { Moshi.Builder() .add(Date::class.java, Rfc3339DateJsonAdapter()) - .add( - PolymorphicJsonAdapterFactory.of(NextStep::class.java, "type") - .withSubtype(NextStep.SubmitData::class.java, "submit_data") - .withSubtype(NextStep.Redirect::class.java, "redirect") - .withDefaultValue(NextStep.Unknown) - ).add( - PolymorphicJsonAdapterFactory.of(Parameter::class.java, "type") - .withSubtype(Parameter.Text::class.java, "text") - .withSubtype(Parameter.SingleSelect::class.java, "single-select") - .withSubtype(Parameter.Bool::class.java, "boolean") - .withSubtype(Parameter.Digits::class.java, "digits") - .withSubtype(Parameter.PhoneNumber::class.java, "phone") - .withSubtype(Parameter.Email::class.java, "email") - .withSubtype(Parameter.Card::class.java, "card") - .withSubtype(Parameter.Otp::class.java, "otp") - .withDefaultValue(Parameter.Unknown) - ).add( - PolymorphicJsonAdapterFactory.of(CustomerInstruction::class.java, "type") - .withSubtype(CustomerInstruction.Text::class.java, "text") - .withSubtype(CustomerInstruction.Image::class.java, "image_url") - .withSubtype(CustomerInstruction.Barcode::class.java, "barcode") - .withSubtype(CustomerInstruction.Group::class.java, "group") - .withDefaultValue(CustomerInstruction.Unknown) - ).add( - PolymorphicJsonAdapterFactory.of(PODynamicCheckoutPaymentMethod::class.java, "type") - .withSubtype(Card::class.java, "card") - .withSubtype(CardCustomerToken::class.java, "card_customer_token") - .withSubtype(GooglePay::class.java, "googlepay") - .withSubtype(AlternativePayment::class.java, "apm") - .withSubtype(AlternativePaymentCustomerToken::class.java, "apm_customer_token") - .withDefaultValue(Unknown) - ).build() + .addNativeAlternativePaymentAdapter() + .addDynamicCheckoutAdapter() + .build() } + private fun Moshi.Builder.addNativeAlternativePaymentAdapter() = + add( + PolymorphicJsonAdapterFactory.of(NextStep::class.java, "type") + .withSubtype(NextStep.SubmitData::class.java, "submit_data") + .withSubtype(NextStep.Redirect::class.java, "redirect") + .withDefaultValue(NextStep.Unknown) + ).add( + PolymorphicJsonAdapterFactory.of(Parameter::class.java, "type") + .withSubtype(Parameter.Text::class.java, "text") + .withSubtype(Parameter.SingleSelect::class.java, "single-select") + .withSubtype(Parameter.Bool::class.java, "boolean") + .withSubtype(Parameter.Digits::class.java, "digits") + .withSubtype(Parameter.PhoneNumber::class.java, "phone") + .withSubtype(Parameter.Email::class.java, "email") + .withSubtype(Parameter.Card::class.java, "card") + .withSubtype(Parameter.Otp::class.java, "otp") + .withDefaultValue(Parameter.Unknown) + ).add( + PolymorphicJsonAdapterFactory.of(CustomerInstruction::class.java, "type") + .withSubtype(CustomerInstruction.Text::class.java, "text") + .withSubtype(CustomerInstruction.Image::class.java, "image_url") + .withSubtype(CustomerInstruction.Barcode::class.java, "barcode") + .withSubtype(CustomerInstruction.Group::class.java, "group") + .withDefaultValue(CustomerInstruction.Unknown) + ) + + private fun Moshi.Builder.addDynamicCheckoutAdapter() = + add( + PolymorphicJsonAdapterFactory.of(PODynamicCheckoutPaymentMethod::class.java, "type") + .withSubtype(Card::class.java, "card") + .withSubtype(CardCustomerToken::class.java, "card_customer_token") + .withSubtype(GooglePay::class.java, "googlepay") + .withSubtype(AlternativePayment::class.java, "apm") + .withSubtype(AlternativePaymentCustomerToken::class.java, "apm_customer_token") + .withDefaultValue(Unknown) + ) + private val retrofit: Retrofit by lazy { Retrofit.Builder() .baseUrl(baseUrl) From 2bf6b4d3fd1f75892b3c11eef7f1fdf449bee132 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 21 May 2025 15:10:15 +0300 Subject: [PATCH 22/33] KDoc --- .../v2/PONativeAlternativePaymentAuthorizationResponse.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index 73538fb79..7a19205e6 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -137,6 +137,12 @@ data class PONativeAlternativePaymentAuthorizationResponse( val dialingCodes: List? ) : Parameter() { + /** + * International dialing code. + * + * @param[id] Country code identifier. + * @param[value] Dialing code value. + */ @JsonClass(generateAdapter = true) data class DialingCode( val id: String, From 50606b543b1d4d090dec9b46538fb31231b11f19 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 21 May 2025 15:24:22 +0300 Subject: [PATCH 23/33] OTP KDoc --- .../v2/PONativeAlternativePaymentAuthorizationResponse.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index 7a19205e6..34f5d72e6 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -193,9 +193,17 @@ data class PONativeAlternativePaymentAuthorizationResponse( val subtype: Subtype get() = Subtype::rawType.findBy(rawSubtype) ?: Subtype.UNKNOWN + /** + * One-Time Password (OTP) subtype. + */ enum class Subtype(val rawType: String) { + /** Text OTP. */ TEXT("text"), + + /** Digits only OTP. */ DIGITS("digits"), + + /** Unknown OTP subtype. */ UNKNOWN(String()) } } From b0bbe82cf08b9f16cb40a3da56d481d4691934ca Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 21 May 2025 15:36:28 +0300 Subject: [PATCH 24/33] KDoc --- ...AlternativePaymentAuthorizationResponse.kt | 49 ++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index 34f5d72e6..e85c79c9e 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -59,6 +59,12 @@ data class PONativeAlternativePaymentAuthorizationResponse( /** * Text parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + * @param[minLength] Optional minimum length. + * @param[maxLength] Optional maximum length. */ @JsonClass(generateAdapter = true) data class Text( @@ -73,6 +79,11 @@ data class PONativeAlternativePaymentAuthorizationResponse( /** * Single selection parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + * @param[availableValues] Available values. */ @JsonClass(generateAdapter = true) data class SingleSelect( @@ -83,6 +94,7 @@ data class PONativeAlternativePaymentAuthorizationResponse( val availableValues: List ) : Parameter() { + /** Preselected value. */ val preselectedValue: AvailableValue? get() = availableValues.find { it.preselected } @@ -90,8 +102,8 @@ data class PONativeAlternativePaymentAuthorizationResponse( * Available parameter value. * * @param[value] Parameter value. - * @param[label] Parameter display label. - * @param[preselected] Indicates whether the parameter should be preselected by default. + * @param[label] Value display label. + * @param[preselected] Indicates whether the value should be preselected by default. */ @JsonClass(generateAdapter = true) data class AvailableValue( @@ -103,6 +115,10 @@ data class PONativeAlternativePaymentAuthorizationResponse( /** * Boolean parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. */ @JsonClass(generateAdapter = true) data class Bool( @@ -113,6 +129,12 @@ data class PONativeAlternativePaymentAuthorizationResponse( /** * Digits only parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + * @param[minLength] Optional minimum length. + * @param[maxLength] Optional maximum length. */ @JsonClass(generateAdapter = true) data class Digits( @@ -127,6 +149,11 @@ data class PONativeAlternativePaymentAuthorizationResponse( /** * Phone number parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + * @param[dialingCodes] Supported international dialing codes. */ @JsonClass(generateAdapter = true) data class PhoneNumber( @@ -152,6 +179,10 @@ data class PONativeAlternativePaymentAuthorizationResponse( /** * Email parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. */ @JsonClass(generateAdapter = true) data class Email( @@ -162,6 +193,12 @@ data class PONativeAlternativePaymentAuthorizationResponse( /** * Card number parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + * @param[minLength] Optional minimum length. + * @param[maxLength] Optional maximum length. */ @JsonClass(generateAdapter = true) data class Card( @@ -176,6 +213,13 @@ data class PONativeAlternativePaymentAuthorizationResponse( /** * One-Time Password (OTP) parameter. + * + * @param[key] Parameter key. + * @param[rawSubtype] Raw OTP subtype. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + * @param[minLength] Optional minimum length. + * @param[maxLength] Optional maximum length. */ @JsonClass(generateAdapter = true) data class Otp( @@ -190,6 +234,7 @@ data class PONativeAlternativePaymentAuthorizationResponse( val maxLength: Int? ) : Parameter() { + /** OTP subtype. */ val subtype: Subtype get() = Subtype::rawType.findBy(rawSubtype) ?: Subtype.UNKNOWN From eddfdfdf2452785ed169725d39060e6aa0f7bd6f Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 21 May 2025 16:35:50 +0300 Subject: [PATCH 25/33] CustomerInstruction KDoc --- ...AlternativePaymentAuthorizationResponse.kt | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index e85c79c9e..32b082bc7 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -274,21 +274,38 @@ data class PONativeAlternativePaymentAuthorizationResponse( } /** - * Specifies instructions for the customer, providing additional information and/or describing required actions. + * Specifies instruction for the customer, providing additional information and/or describing required actions. */ sealed class CustomerInstruction { + /** + * Customer instruction provided as a markdown text. + * + * @param[label] Optional instruction display label. + * @param[value] Markdown text. + */ @JsonClass(generateAdapter = true) data class Text( val label: String?, val value: String ) : CustomerInstruction() + /** + * Customer instruction provided as an image resource. + * + * @param[value] Image resource. + */ @JsonClass(generateAdapter = true) data class Image( val value: POImageResource ) : CustomerInstruction() + /** + * Customer instruction provided via barcode. + * + * @param[rawSubtype] Raw barcode subtype. + * @param[rawValue] Base64 encoded value. + */ @JsonClass(generateAdapter = true) data class Barcode( @Json(name = "subtype") @@ -297,6 +314,7 @@ data class PONativeAlternativePaymentAuthorizationResponse( val rawValue: String ) : CustomerInstruction() { + /** Barcode value. */ val value: POBarcode get() = POBarcode( rawType = rawSubtype, @@ -304,12 +322,21 @@ data class PONativeAlternativePaymentAuthorizationResponse( ) } + /** + * Group of customer instructions. + * + * @param[label] Optional group display label. + * @param[instructions] Grouped instructions for the customer that provide additional information and/or describe required actions. + */ @JsonClass(generateAdapter = true) data class Group( val label: String?, val instructions: List ) : CustomerInstruction() + /** + * Unknown customer instruction type. + */ data object Unknown : CustomerInstruction() } } From ce978de2bee751bfb165425521224df39e120b95 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 21 May 2025 17:24:34 +0300 Subject: [PATCH 26/33] PhoneNumber: value -> number --- ...iveAlternativePaymentAuthorizationRequest.kt | 17 +++++++++++++---- .../api/repository/DefaultInvoicesRepository.kt | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt index 668bc5758..1c14ccda3 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt @@ -19,15 +19,24 @@ data class PONativeAlternativePaymentAuthorizationRequest( val parameters: Map? = null ) { - /** Payment parameter. */ + /** + * Payment parameter. + */ sealed class Parameter { - /** Arbitrary value. */ + /** + * Arbitrary string value. + */ data class Value(val value: String) : Parameter() - /** Phone number value. */ + /** + * Phone number value. + * + * @param[dialingCode] International dialing code. + * @param[number] The rest of the number without dialing code. + */ data class PhoneNumber( val dialingCode: String, - val value: String + val number: String ) : Parameter() } } diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt index 8ebf85c7c..c9d335129 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt @@ -168,7 +168,7 @@ internal class DefaultInvoicesRepository( dialingCode = null ) is PhoneNumber -> NativeAlternativePaymentAuthorizationRequestBody.Parameter( - value = parameter.value, + value = parameter.number, dialingCode = parameter.dialingCode ) } From e978e669814bae78e23bf4e00f4a0c4954e15396 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 21 May 2025 18:06:03 +0300 Subject: [PATCH 27/33] Parameter.Value -> Parameter.String --- .../v2/PONativeAlternativePaymentAuthorizationRequest.kt | 6 +++--- .../sdk/api/repository/DefaultInvoicesRepository.kt | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt index 1c14ccda3..b8d03cadd 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt @@ -26,7 +26,7 @@ data class PONativeAlternativePaymentAuthorizationRequest( /** * Arbitrary string value. */ - data class Value(val value: String) : Parameter() + data class String(val value: kotlin.String) : Parameter() /** * Phone number value. @@ -35,8 +35,8 @@ data class PONativeAlternativePaymentAuthorizationRequest( * @param[number] The rest of the number without dialing code. */ data class PhoneNumber( - val dialingCode: String, - val number: String + val dialingCode: kotlin.String, + val number: kotlin.String ) : Parameter() } } diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt index c9d335129..b39124ec9 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt @@ -4,8 +4,7 @@ import com.processout.sdk.api.model.request.* import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuthorizationRequestBody import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuthorizationRequestBody.SubmitData import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest -import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter.PhoneNumber -import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter.Value +import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentRequest import com.processout.sdk.api.model.response.* import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody @@ -160,14 +159,14 @@ internal class DefaultInvoicesRepository( submitData = parameters?.let { SubmitData(parameters = it.map()) } ) - private fun Map.map() = + private fun Map.map() = mapValues { (_, parameter) -> when (parameter) { - is Value -> NativeAlternativePaymentAuthorizationRequestBody.Parameter( + is Parameter.String -> NativeAlternativePaymentAuthorizationRequestBody.Parameter( value = parameter.value, dialingCode = null ) - is PhoneNumber -> NativeAlternativePaymentAuthorizationRequestBody.Parameter( + is Parameter.PhoneNumber -> NativeAlternativePaymentAuthorizationRequestBody.Parameter( value = parameter.number, dialingCode = parameter.dialingCode ) From 2cc4c6353e42f39f7ecd094131d12ff6727f3ac9 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Wed, 21 May 2025 18:28:02 +0300 Subject: [PATCH 28/33] Fix submitting parameters --- ...ativeAlternativePaymentAuthorizationRequest.kt | 15 ++++++--------- .../api/repository/DefaultInvoicesRepository.kt | 10 ++-------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt index b8d03cadd..b35920781 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt @@ -26,7 +26,9 @@ data class PONativeAlternativePaymentAuthorizationRequest( /** * Arbitrary string value. */ - data class String(val value: kotlin.String) : Parameter() + data class String( + val value: kotlin.String + ) : Parameter() /** * Phone number value. @@ -34,7 +36,9 @@ data class PONativeAlternativePaymentAuthorizationRequest( * @param[dialingCode] International dialing code. * @param[number] The rest of the number without dialing code. */ + @JsonClass(generateAdapter = true) data class PhoneNumber( + @Json(name = "dialing_code") val dialingCode: kotlin.String, val number: kotlin.String ) : Parameter() @@ -51,13 +55,6 @@ internal data class NativeAlternativePaymentAuthorizationRequestBody( @JsonClass(generateAdapter = true) data class SubmitData( - val parameters: Map - ) - - @JsonClass(generateAdapter = true) - data class Parameter( - val value: String, - @Json(name = "dialing_code") - val dialingCode: String? + val parameters: Map ) } diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt index b39124ec9..722c1e770 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt @@ -162,14 +162,8 @@ internal class DefaultInvoicesRepository( private fun Map.map() = mapValues { (_, parameter) -> when (parameter) { - is Parameter.String -> NativeAlternativePaymentAuthorizationRequestBody.Parameter( - value = parameter.value, - dialingCode = null - ) - is Parameter.PhoneNumber -> NativeAlternativePaymentAuthorizationRequestBody.Parameter( - value = parameter.number, - dialingCode = parameter.dialingCode - ) + is Parameter.String -> parameter.value + is Parameter.PhoneNumber -> parameter } } From 0752086425762e5db2cf7b6da505fa4712b8c334 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Thu, 22 May 2025 13:43:39 +0300 Subject: [PATCH 29/33] Mark 'Unknown' case in enums and sealed classes as internal for backward compatibility --- ...AlternativePaymentAuthorizationResponse.kt | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index 32b082bc7..1dd56812c 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -37,7 +37,14 @@ data class PONativeAlternativePaymentAuthorizationResponse( PENDING_CAPTURE, /** Payment is captured. */ - CAPTURED + CAPTURED, + + /** + * Placeholder that allows adding additional cases while staying backward compatible. + * __Warning:__ Do not match this case directly, use _when-else_ instead. + */ + @ProcessOutInternalApi + UNKNOWN } /** @@ -248,14 +255,20 @@ data class PONativeAlternativePaymentAuthorizationResponse( /** Digits only OTP. */ DIGITS("digits"), - /** Unknown OTP subtype. */ + /** + * Placeholder that allows adding additional cases while staying backward compatible. + * __Warning:__ Do not match this case directly, use _when-else_ instead. + */ + @ProcessOutInternalApi UNKNOWN(String()) } } /** - * Unknown parameter. + * Placeholder that allows adding additional cases while staying backward compatible. + * __Warning:__ Do not match this case directly, use _when-else_ instead. */ + @ProcessOutInternalApi data object Unknown : Parameter() } } @@ -268,8 +281,10 @@ data class PONativeAlternativePaymentAuthorizationResponse( ) : NextStep() /** - * The next step is unknown. + * Placeholder that allows adding additional cases while staying backward compatible. + * __Warning:__ Do not match this case directly, use _when-else_ instead. */ + @ProcessOutInternalApi data object Unknown : NextStep() } @@ -335,8 +350,10 @@ data class PONativeAlternativePaymentAuthorizationResponse( ) : CustomerInstruction() /** - * Unknown customer instruction type. + * Placeholder that allows adding additional cases while staying backward compatible. + * __Warning:__ Do not match this case directly, use _when-else_ instead. */ + @ProcessOutInternalApi data object Unknown : CustomerInstruction() } } From 6f23269aeebeb89e19af68118416be40a24ac62a Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Thu, 22 May 2025 14:01:20 +0300 Subject: [PATCH 30/33] PONativeAlternativePaymentNextStep --- ...AlternativePaymentAuthorizationResponse.kt | 246 +---------------- .../v2/PONativeAlternativePaymentNextStep.kt | 249 ++++++++++++++++++ .../repository/DefaultInvoicesRepository.kt | 7 +- .../com/processout/sdk/di/NetworkGraph.kt | 2 +- 4 files changed, 256 insertions(+), 248 deletions(-) create mode 100644 sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentNextStep.kt diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index 1dd56812c..4115188f6 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -3,10 +3,9 @@ package com.processout.sdk.api.model.response.napm.v2 import com.processout.sdk.api.model.response.POBarcode import com.processout.sdk.api.model.response.POImageResource import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.CustomerInstruction -import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.NextStep.SubmitData.Parameter import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.State +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentNextStep.SubmitData.Parameter import com.processout.sdk.core.annotation.ProcessOutInternalApi -import com.processout.sdk.core.util.findBy import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -21,7 +20,7 @@ import com.squareup.moshi.JsonClass @ProcessOutInternalApi data class PONativeAlternativePaymentAuthorizationResponse( val state: State, - val nextStep: NextStep?, + val nextStep: PONativeAlternativePaymentNextStep?, val customerInstructions: List? ) { @@ -47,247 +46,6 @@ data class PONativeAlternativePaymentAuthorizationResponse( UNKNOWN } - /** - * Specifies the next required step in the payment flow. - */ - sealed class NextStep { - - /** - * Indicates that the next required step is submitting data for the expected [parameterDefinitions]. - */ - data class SubmitData( - val parameterDefinitions: List - ) : NextStep() { - - /** - * Payment parameter definition. - */ - sealed class Parameter { - - /** - * Text parameter. - * - * @param[key] Parameter key. - * @param[label] Parameter display label. - * @param[required] Indicates whether the parameter is required. - * @param[minLength] Optional minimum length. - * @param[maxLength] Optional maximum length. - */ - @JsonClass(generateAdapter = true) - data class Text( - val key: String, - val label: String, - val required: Boolean, - @Json(name = "min_length") - val minLength: Int?, - @Json(name = "max_length") - val maxLength: Int? - ) : Parameter() - - /** - * Single selection parameter. - * - * @param[key] Parameter key. - * @param[label] Parameter display label. - * @param[required] Indicates whether the parameter is required. - * @param[availableValues] Available values. - */ - @JsonClass(generateAdapter = true) - data class SingleSelect( - val key: String, - val label: String, - val required: Boolean, - @Json(name = "available_values") - val availableValues: List - ) : Parameter() { - - /** Preselected value. */ - val preselectedValue: AvailableValue? - get() = availableValues.find { it.preselected } - - /** - * Available parameter value. - * - * @param[value] Parameter value. - * @param[label] Value display label. - * @param[preselected] Indicates whether the value should be preselected by default. - */ - @JsonClass(generateAdapter = true) - data class AvailableValue( - val value: String, - val label: String, - val preselected: Boolean - ) - } - - /** - * Boolean parameter. - * - * @param[key] Parameter key. - * @param[label] Parameter display label. - * @param[required] Indicates whether the parameter is required. - */ - @JsonClass(generateAdapter = true) - data class Bool( - val key: String, - val label: String, - val required: Boolean - ) : Parameter() - - /** - * Digits only parameter. - * - * @param[key] Parameter key. - * @param[label] Parameter display label. - * @param[required] Indicates whether the parameter is required. - * @param[minLength] Optional minimum length. - * @param[maxLength] Optional maximum length. - */ - @JsonClass(generateAdapter = true) - data class Digits( - val key: String, - val label: String, - val required: Boolean, - @Json(name = "min_length") - val minLength: Int?, - @Json(name = "max_length") - val maxLength: Int? - ) : Parameter() - - /** - * Phone number parameter. - * - * @param[key] Parameter key. - * @param[label] Parameter display label. - * @param[required] Indicates whether the parameter is required. - * @param[dialingCodes] Supported international dialing codes. - */ - @JsonClass(generateAdapter = true) - data class PhoneNumber( - val key: String, - val label: String, - val required: Boolean, - @Json(name = "dialing_codes") - val dialingCodes: List? - ) : Parameter() { - - /** - * International dialing code. - * - * @param[id] Country code identifier. - * @param[value] Dialing code value. - */ - @JsonClass(generateAdapter = true) - data class DialingCode( - val id: String, - val value: String - ) - } - - /** - * Email parameter. - * - * @param[key] Parameter key. - * @param[label] Parameter display label. - * @param[required] Indicates whether the parameter is required. - */ - @JsonClass(generateAdapter = true) - data class Email( - val key: String, - val label: String, - val required: Boolean - ) : Parameter() - - /** - * Card number parameter. - * - * @param[key] Parameter key. - * @param[label] Parameter display label. - * @param[required] Indicates whether the parameter is required. - * @param[minLength] Optional minimum length. - * @param[maxLength] Optional maximum length. - */ - @JsonClass(generateAdapter = true) - data class Card( - val key: String, - val label: String, - val required: Boolean, - @Json(name = "min_length") - val minLength: Int?, - @Json(name = "max_length") - val maxLength: Int? - ) : Parameter() - - /** - * One-Time Password (OTP) parameter. - * - * @param[key] Parameter key. - * @param[rawSubtype] Raw OTP subtype. - * @param[label] Parameter display label. - * @param[required] Indicates whether the parameter is required. - * @param[minLength] Optional minimum length. - * @param[maxLength] Optional maximum length. - */ - @JsonClass(generateAdapter = true) - data class Otp( - val key: String, - @Json(name = "subtype") - val rawSubtype: String, - val label: String, - val required: Boolean, - @Json(name = "min_length") - val minLength: Int?, - @Json(name = "max_length") - val maxLength: Int? - ) : Parameter() { - - /** OTP subtype. */ - val subtype: Subtype - get() = Subtype::rawType.findBy(rawSubtype) ?: Subtype.UNKNOWN - - /** - * One-Time Password (OTP) subtype. - */ - enum class Subtype(val rawType: String) { - /** Text OTP. */ - TEXT("text"), - - /** Digits only OTP. */ - DIGITS("digits"), - - /** - * Placeholder that allows adding additional cases while staying backward compatible. - * __Warning:__ Do not match this case directly, use _when-else_ instead. - */ - @ProcessOutInternalApi - UNKNOWN(String()) - } - } - - /** - * Placeholder that allows adding additional cases while staying backward compatible. - * __Warning:__ Do not match this case directly, use _when-else_ instead. - */ - @ProcessOutInternalApi - data object Unknown : Parameter() - } - } - - /** - * Indicates that the next required step is a redirect to the URL. - */ - data class Redirect( - val url: String - ) : NextStep() - - /** - * Placeholder that allows adding additional cases while staying backward compatible. - * __Warning:__ Do not match this case directly, use _when-else_ instead. - */ - @ProcessOutInternalApi - data object Unknown : NextStep() - } - /** * Specifies instruction for the customer, providing additional information and/or describing required actions. */ diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentNextStep.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentNextStep.kt new file mode 100644 index 000000000..a692c117f --- /dev/null +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentNextStep.kt @@ -0,0 +1,249 @@ +package com.processout.sdk.api.model.response.napm.v2 + +import com.processout.sdk.core.annotation.ProcessOutInternalApi +import com.processout.sdk.core.util.findBy +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +/** + * Specifies the next required step in the payment flow. + */ +/** @suppress */ +@ProcessOutInternalApi +sealed class PONativeAlternativePaymentNextStep { + + /** + * Indicates that the next required step is submitting data for the expected [parameterDefinitions]. + */ + data class SubmitData( + val parameterDefinitions: List + ) : PONativeAlternativePaymentNextStep() { + + /** + * Payment parameter definition. + */ + sealed class Parameter { + + /** + * Text parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + * @param[minLength] Optional minimum length. + * @param[maxLength] Optional maximum length. + */ + @JsonClass(generateAdapter = true) + data class Text( + val key: String, + val label: String, + val required: Boolean, + @Json(name = "min_length") + val minLength: Int?, + @Json(name = "max_length") + val maxLength: Int? + ) : Parameter() + + /** + * Single selection parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + * @param[availableValues] Available values. + */ + @JsonClass(generateAdapter = true) + data class SingleSelect( + val key: String, + val label: String, + val required: Boolean, + @Json(name = "available_values") + val availableValues: List + ) : Parameter() { + + /** Preselected value. */ + val preselectedValue: AvailableValue? + get() = availableValues.find { it.preselected } + + /** + * Available parameter value. + * + * @param[value] Parameter value. + * @param[label] Value display label. + * @param[preselected] Indicates whether the value should be preselected by default. + */ + @JsonClass(generateAdapter = true) + data class AvailableValue( + val value: String, + val label: String, + val preselected: Boolean + ) + } + + /** + * Boolean parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + */ + @JsonClass(generateAdapter = true) + data class Bool( + val key: String, + val label: String, + val required: Boolean + ) : Parameter() + + /** + * Digits only parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + * @param[minLength] Optional minimum length. + * @param[maxLength] Optional maximum length. + */ + @JsonClass(generateAdapter = true) + data class Digits( + val key: String, + val label: String, + val required: Boolean, + @Json(name = "min_length") + val minLength: Int?, + @Json(name = "max_length") + val maxLength: Int? + ) : Parameter() + + /** + * Phone number parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + * @param[dialingCodes] Supported international dialing codes. + */ + @JsonClass(generateAdapter = true) + data class PhoneNumber( + val key: String, + val label: String, + val required: Boolean, + @Json(name = "dialing_codes") + val dialingCodes: List? + ) : Parameter() { + + /** + * International dialing code. + * + * @param[id] Country code identifier. + * @param[value] Dialing code value. + */ + @JsonClass(generateAdapter = true) + data class DialingCode( + val id: String, + val value: String + ) + } + + /** + * Email parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + */ + @JsonClass(generateAdapter = true) + data class Email( + val key: String, + val label: String, + val required: Boolean + ) : Parameter() + + /** + * Card number parameter. + * + * @param[key] Parameter key. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + * @param[minLength] Optional minimum length. + * @param[maxLength] Optional maximum length. + */ + @JsonClass(generateAdapter = true) + data class Card( + val key: String, + val label: String, + val required: Boolean, + @Json(name = "min_length") + val minLength: Int?, + @Json(name = "max_length") + val maxLength: Int? + ) : Parameter() + + /** + * One-Time Password (OTP) parameter. + * + * @param[key] Parameter key. + * @param[rawSubtype] Raw OTP subtype. + * @param[label] Parameter display label. + * @param[required] Indicates whether the parameter is required. + * @param[minLength] Optional minimum length. + * @param[maxLength] Optional maximum length. + */ + @JsonClass(generateAdapter = true) + data class Otp( + val key: String, + @Json(name = "subtype") + val rawSubtype: String, + val label: String, + val required: Boolean, + @Json(name = "min_length") + val minLength: Int?, + @Json(name = "max_length") + val maxLength: Int? + ) : Parameter() { + + /** OTP subtype. */ + val subtype: Subtype + get() = Subtype::rawType.findBy(rawSubtype) ?: Subtype.UNKNOWN + + /** + * One-Time Password (OTP) subtype. + */ + enum class Subtype(val rawType: String) { + /** Text OTP. */ + TEXT("text"), + + /** Digits only OTP. */ + DIGITS("digits"), + + /** + * Placeholder that allows adding additional cases while staying backward compatible. + * __Warning:__ Do not match this case directly, use _when-else_ instead. + */ + @ProcessOutInternalApi + UNKNOWN(String()) + } + } + + /** + * Placeholder that allows adding additional cases while staying backward compatible. + * __Warning:__ Do not match this case directly, use _when-else_ instead. + */ + @ProcessOutInternalApi + data object Unknown : Parameter() + } + } + + /** + * Indicates that the next required step is a redirect to the URL. + */ + data class Redirect( + val url: String + ) : PONativeAlternativePaymentNextStep() + + /** + * Placeholder that allows adding additional cases while staying backward compatible. + * __Warning:__ Do not match this case directly, use _when-else_ instead. + */ + @ProcessOutInternalApi + data object Unknown : PONativeAlternativePaymentNextStep() +} diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt index 722c1e770..23363b585 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt @@ -10,6 +10,7 @@ import com.processout.sdk.api.model.response.* import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody.NextStep import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentNextStep import com.processout.sdk.api.network.HeaderConstants.CLIENT_SECRET import com.processout.sdk.api.network.InvoicesApi import com.processout.sdk.core.* @@ -172,13 +173,13 @@ internal class DefaultInvoicesRepository( state = state, nextStep = nextStep?.let { when (it) { - is NextStep.SubmitData -> PONativeAlternativePaymentAuthorizationResponse.NextStep.SubmitData( + is NextStep.SubmitData -> PONativeAlternativePaymentNextStep.SubmitData( parameterDefinitions = it.parameters.parameterDefinitions ) - is NextStep.Redirect -> PONativeAlternativePaymentAuthorizationResponse.NextStep.Redirect( + is NextStep.Redirect -> PONativeAlternativePaymentNextStep.Redirect( url = it.parameters.url ) - NextStep.Unknown -> PONativeAlternativePaymentAuthorizationResponse.NextStep.Unknown + NextStep.Unknown -> PONativeAlternativePaymentNextStep.Unknown } }, customerInstructions = customerInstructions diff --git a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt index bb60ec37b..8c0fc9b11 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt @@ -4,7 +4,7 @@ import com.processout.sdk.api.model.response.PODynamicCheckoutPaymentMethod import com.processout.sdk.api.model.response.PODynamicCheckoutPaymentMethod.* import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody.NextStep import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.CustomerInstruction -import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.NextStep.SubmitData.Parameter +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentNextStep.SubmitData.Parameter import com.processout.sdk.api.network.* import com.processout.sdk.api.network.interceptor.BasicAuthInterceptor import com.processout.sdk.api.network.interceptor.RetryInterceptor From 1426971f0f362c7aed96b25cd1fbedcf6c06e94b Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Thu, 22 May 2025 14:19:05 +0300 Subject: [PATCH 31/33] NativeAlternativePaymentNextStep --- ...AlternativePaymentAuthorizationResponse.kt | 34 ++----------------- .../v2/PONativeAlternativePaymentNextStep.kt | 29 ++++++++++++++++ .../repository/DefaultInvoicesRepository.kt | 19 ++++++----- .../com/processout/sdk/di/NetworkGraph.kt | 10 +++--- 4 files changed, 47 insertions(+), 45 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index 4115188f6..c375402a9 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -4,7 +4,6 @@ import com.processout.sdk.api.model.response.POBarcode import com.processout.sdk.api.model.response.POImageResource import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.CustomerInstruction import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.State -import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentNextStep.SubmitData.Parameter import com.processout.sdk.core.annotation.ProcessOutInternalApi import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -120,36 +119,7 @@ data class PONativeAlternativePaymentAuthorizationResponse( internal data class NativeAlternativePaymentAuthorizationResponseBody( val state: State, @Json(name = "next_step") - val nextStep: NextStep?, + val nextStep: NativeAlternativePaymentNextStep?, @Json(name = "customer_instructions") val customerInstructions: List? -) { - - sealed class NextStep { - - @JsonClass(generateAdapter = true) - data class SubmitData( - val parameters: Parameters - ) : NextStep() { - - @JsonClass(generateAdapter = true) - data class Parameters( - @Json(name = "parameter_definitions") - val parameterDefinitions: List - ) - } - - @JsonClass(generateAdapter = true) - data class Redirect( - val parameters: Parameters - ) : NextStep() { - - @JsonClass(generateAdapter = true) - data class Parameters( - val url: String - ) - } - - data object Unknown : NextStep() - } -} +) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentNextStep.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentNextStep.kt index a692c117f..167132142 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentNextStep.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentNextStep.kt @@ -1,5 +1,6 @@ package com.processout.sdk.api.model.response.napm.v2 +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentNextStep.SubmitData.Parameter import com.processout.sdk.core.annotation.ProcessOutInternalApi import com.processout.sdk.core.util.findBy import com.squareup.moshi.Json @@ -247,3 +248,31 @@ sealed class PONativeAlternativePaymentNextStep { @ProcessOutInternalApi data object Unknown : PONativeAlternativePaymentNextStep() } + +internal sealed class NativeAlternativePaymentNextStep { + + @JsonClass(generateAdapter = true) + data class SubmitData( + val parameters: Parameters + ) : NativeAlternativePaymentNextStep() { + + @JsonClass(generateAdapter = true) + data class Parameters( + @Json(name = "parameter_definitions") + val parameterDefinitions: List + ) + } + + @JsonClass(generateAdapter = true) + data class Redirect( + val parameters: Parameters + ) : NativeAlternativePaymentNextStep() { + + @JsonClass(generateAdapter = true) + data class Parameters( + val url: String + ) + } + + data object Unknown : NativeAlternativePaymentNextStep() +} diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt index 23363b585..a3b99b869 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt @@ -8,7 +8,7 @@ import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAu import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentRequest import com.processout.sdk.api.model.response.* import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody -import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody.NextStep +import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentNextStep import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentNextStep import com.processout.sdk.api.network.HeaderConstants.CLIENT_SECRET @@ -173,13 +173,16 @@ internal class DefaultInvoicesRepository( state = state, nextStep = nextStep?.let { when (it) { - is NextStep.SubmitData -> PONativeAlternativePaymentNextStep.SubmitData( - parameterDefinitions = it.parameters.parameterDefinitions - ) - is NextStep.Redirect -> PONativeAlternativePaymentNextStep.Redirect( - url = it.parameters.url - ) - NextStep.Unknown -> PONativeAlternativePaymentNextStep.Unknown + is NativeAlternativePaymentNextStep.SubmitData -> + PONativeAlternativePaymentNextStep.SubmitData( + parameterDefinitions = it.parameters.parameterDefinitions + ) + is NativeAlternativePaymentNextStep.Redirect -> + PONativeAlternativePaymentNextStep.Redirect( + url = it.parameters.url + ) + NativeAlternativePaymentNextStep.Unknown -> + PONativeAlternativePaymentNextStep.Unknown } }, customerInstructions = customerInstructions diff --git a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt index 8c0fc9b11..527901c54 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt @@ -2,7 +2,7 @@ package com.processout.sdk.di import com.processout.sdk.api.model.response.PODynamicCheckoutPaymentMethod import com.processout.sdk.api.model.response.PODynamicCheckoutPaymentMethod.* -import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody.NextStep +import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentNextStep import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.CustomerInstruction import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentNextStep.SubmitData.Parameter import com.processout.sdk.api.network.* @@ -63,10 +63,10 @@ internal class DefaultNetworkGraph( private fun Moshi.Builder.addNativeAlternativePaymentAdapter() = add( - PolymorphicJsonAdapterFactory.of(NextStep::class.java, "type") - .withSubtype(NextStep.SubmitData::class.java, "submit_data") - .withSubtype(NextStep.Redirect::class.java, "redirect") - .withDefaultValue(NextStep.Unknown) + PolymorphicJsonAdapterFactory.of(NativeAlternativePaymentNextStep::class.java, "type") + .withSubtype(NativeAlternativePaymentNextStep.SubmitData::class.java, "submit_data") + .withSubtype(NativeAlternativePaymentNextStep.Redirect::class.java, "redirect") + .withDefaultValue(NativeAlternativePaymentNextStep.Unknown) ).add( PolymorphicJsonAdapterFactory.of(Parameter::class.java, "type") .withSubtype(Parameter.Text::class.java, "text") From 7e7627d290e66d953959d01b7b16693f6e801296 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Thu, 22 May 2025 14:33:47 +0300 Subject: [PATCH 32/33] PONativeAlternativePaymentCustomerInstruction --- ...AlternativePaymentAuthorizationResponse.kt | 76 +----------------- ...veAlternativePaymentCustomerInstruction.kt | 78 +++++++++++++++++++ .../com/processout/sdk/di/NetworkGraph.kt | 14 ++-- 3 files changed, 87 insertions(+), 81 deletions(-) create mode 100644 sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentCustomerInstruction.kt diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt index c375402a9..a56a314d2 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentAuthorizationResponse.kt @@ -1,8 +1,5 @@ package com.processout.sdk.api.model.response.napm.v2 -import com.processout.sdk.api.model.response.POBarcode -import com.processout.sdk.api.model.response.POImageResource -import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.CustomerInstruction import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.State import com.processout.sdk.core.annotation.ProcessOutInternalApi import com.squareup.moshi.Json @@ -20,7 +17,7 @@ import com.squareup.moshi.JsonClass data class PONativeAlternativePaymentAuthorizationResponse( val state: State, val nextStep: PONativeAlternativePaymentNextStep?, - val customerInstructions: List? + val customerInstructions: List? ) { /** @@ -44,75 +41,6 @@ data class PONativeAlternativePaymentAuthorizationResponse( @ProcessOutInternalApi UNKNOWN } - - /** - * Specifies instruction for the customer, providing additional information and/or describing required actions. - */ - sealed class CustomerInstruction { - - /** - * Customer instruction provided as a markdown text. - * - * @param[label] Optional instruction display label. - * @param[value] Markdown text. - */ - @JsonClass(generateAdapter = true) - data class Text( - val label: String?, - val value: String - ) : CustomerInstruction() - - /** - * Customer instruction provided as an image resource. - * - * @param[value] Image resource. - */ - @JsonClass(generateAdapter = true) - data class Image( - val value: POImageResource - ) : CustomerInstruction() - - /** - * Customer instruction provided via barcode. - * - * @param[rawSubtype] Raw barcode subtype. - * @param[rawValue] Base64 encoded value. - */ - @JsonClass(generateAdapter = true) - data class Barcode( - @Json(name = "subtype") - val rawSubtype: String, - @Json(name = "value") - val rawValue: String - ) : CustomerInstruction() { - - /** Barcode value. */ - val value: POBarcode - get() = POBarcode( - rawType = rawSubtype, - rawValue = rawValue - ) - } - - /** - * Group of customer instructions. - * - * @param[label] Optional group display label. - * @param[instructions] Grouped instructions for the customer that provide additional information and/or describe required actions. - */ - @JsonClass(generateAdapter = true) - data class Group( - val label: String?, - val instructions: List - ) : CustomerInstruction() - - /** - * Placeholder that allows adding additional cases while staying backward compatible. - * __Warning:__ Do not match this case directly, use _when-else_ instead. - */ - @ProcessOutInternalApi - data object Unknown : CustomerInstruction() - } } @JsonClass(generateAdapter = true) @@ -121,5 +49,5 @@ internal data class NativeAlternativePaymentAuthorizationResponseBody( @Json(name = "next_step") val nextStep: NativeAlternativePaymentNextStep?, @Json(name = "customer_instructions") - val customerInstructions: List? + val customerInstructions: List? ) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentCustomerInstruction.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentCustomerInstruction.kt new file mode 100644 index 000000000..96377ed3b --- /dev/null +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/response/napm/v2/PONativeAlternativePaymentCustomerInstruction.kt @@ -0,0 +1,78 @@ +package com.processout.sdk.api.model.response.napm.v2 + +import com.processout.sdk.api.model.response.POBarcode +import com.processout.sdk.api.model.response.POImageResource +import com.processout.sdk.core.annotation.ProcessOutInternalApi +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +/** + * Specifies instruction for the customer, providing additional information and/or describing required actions. + */ +/** @suppress */ +@ProcessOutInternalApi +sealed class PONativeAlternativePaymentCustomerInstruction { + + /** + * Customer instruction provided as a markdown text. + * + * @param[label] Optional instruction display label. + * @param[value] Markdown text. + */ + @JsonClass(generateAdapter = true) + data class Text( + val label: String?, + val value: String + ) : PONativeAlternativePaymentCustomerInstruction() + + /** + * Customer instruction provided as an image resource. + * + * @param[value] Image resource. + */ + @JsonClass(generateAdapter = true) + data class Image( + val value: POImageResource + ) : PONativeAlternativePaymentCustomerInstruction() + + /** + * Customer instruction provided via barcode. + * + * @param[rawSubtype] Raw barcode subtype. + * @param[rawValue] Base64 encoded value. + */ + @JsonClass(generateAdapter = true) + data class Barcode( + @Json(name = "subtype") + val rawSubtype: String, + @Json(name = "value") + val rawValue: String + ) : PONativeAlternativePaymentCustomerInstruction() { + + /** Barcode value. */ + val value: POBarcode + get() = POBarcode( + rawType = rawSubtype, + rawValue = rawValue + ) + } + + /** + * Group of customer instructions. + * + * @param[label] Optional group display label. + * @param[instructions] Grouped instructions for the customer that provide additional information and/or describe required actions. + */ + @JsonClass(generateAdapter = true) + data class Group( + val label: String?, + val instructions: List + ) : PONativeAlternativePaymentCustomerInstruction() + + /** + * Placeholder that allows adding additional cases while staying backward compatible. + * __Warning:__ Do not match this case directly, use _when-else_ instead. + */ + @ProcessOutInternalApi + data object Unknown : PONativeAlternativePaymentCustomerInstruction() +} diff --git a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt index 527901c54..add1d7f3d 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt @@ -3,7 +3,7 @@ package com.processout.sdk.di import com.processout.sdk.api.model.response.PODynamicCheckoutPaymentMethod import com.processout.sdk.api.model.response.PODynamicCheckoutPaymentMethod.* import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentNextStep -import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.CustomerInstruction +import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentCustomerInstruction import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentNextStep.SubmitData.Parameter import com.processout.sdk.api.network.* import com.processout.sdk.api.network.interceptor.BasicAuthInterceptor @@ -79,12 +79,12 @@ internal class DefaultNetworkGraph( .withSubtype(Parameter.Otp::class.java, "otp") .withDefaultValue(Parameter.Unknown) ).add( - PolymorphicJsonAdapterFactory.of(CustomerInstruction::class.java, "type") - .withSubtype(CustomerInstruction.Text::class.java, "text") - .withSubtype(CustomerInstruction.Image::class.java, "image_url") - .withSubtype(CustomerInstruction.Barcode::class.java, "barcode") - .withSubtype(CustomerInstruction.Group::class.java, "group") - .withDefaultValue(CustomerInstruction.Unknown) + PolymorphicJsonAdapterFactory.of(PONativeAlternativePaymentCustomerInstruction::class.java, "type") + .withSubtype(PONativeAlternativePaymentCustomerInstruction.Text::class.java, "text") + .withSubtype(PONativeAlternativePaymentCustomerInstruction.Image::class.java, "image_url") + .withSubtype(PONativeAlternativePaymentCustomerInstruction.Barcode::class.java, "barcode") + .withSubtype(PONativeAlternativePaymentCustomerInstruction.Group::class.java, "group") + .withDefaultValue(PONativeAlternativePaymentCustomerInstruction.Unknown) ) private fun Moshi.Builder.addDynamicCheckoutAdapter() = From c509cb3138c20783d4514b7861b31d8022694da9 Mon Sep 17 00:00:00 2001 From: Vitalii Vanziak Date: Thu, 22 May 2025 17:13:15 +0300 Subject: [PATCH 33/33] Backward compatible request parameters --- ...eAlternativePaymentAuthorizationRequest.kt | 59 ++++++++++++------- .../repository/DefaultInvoicesRepository.kt | 7 ++- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt index b35920781..dcfc43b4d 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/request/napm/v2/PONativeAlternativePaymentAuthorizationRequest.kt @@ -22,26 +22,45 @@ data class PONativeAlternativePaymentAuthorizationRequest( /** * Payment parameter. */ - sealed class Parameter { - /** - * Arbitrary string value. - */ - data class String( - val value: kotlin.String - ) : Parameter() - - /** - * Phone number value. - * - * @param[dialingCode] International dialing code. - * @param[number] The rest of the number without dialing code. - */ - @JsonClass(generateAdapter = true) - data class PhoneNumber( - @Json(name = "dialing_code") - val dialingCode: kotlin.String, - val number: kotlin.String - ) : Parameter() + data class Parameter internal constructor( + internal val value: Value + ) { + + companion object { + /** + * Arbitrary string parameter. + */ + fun string(value: String) = Parameter(Value.String(value)) + + /** + * Phone number parameter. + * + * @param[dialingCode] International dialing code. + * @param[number] The rest of the number without dialing code. + */ + fun phoneNumber( + dialingCode: String, + number: String + ) = Parameter( + Value.PhoneNumber( + dialingCode = dialingCode, + number = number + ) + ) + } + + internal sealed class Value { + data class String( + val value: kotlin.String + ) : Value() + + @JsonClass(generateAdapter = true) + data class PhoneNumber( + @Json(name = "dialing_code") + val dialingCode: kotlin.String, + val number: kotlin.String + ) : Value() + } } } diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt index a3b99b869..c1a9b766a 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/repository/DefaultInvoicesRepository.kt @@ -5,6 +5,7 @@ import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuth import com.processout.sdk.api.model.request.napm.v2.NativeAlternativePaymentAuthorizationRequestBody.SubmitData import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter +import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentAuthorizationRequest.Parameter.Value import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentRequest import com.processout.sdk.api.model.response.* import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentAuthorizationResponseBody @@ -162,9 +163,9 @@ internal class DefaultInvoicesRepository( private fun Map.map() = mapValues { (_, parameter) -> - when (parameter) { - is Parameter.String -> parameter.value - is Parameter.PhoneNumber -> parameter + when (val value = parameter.value) { + is Value.String -> value.value + is Value.PhoneNumber -> value } }