Skip to content

Commit

Permalink
Merge pull request #41 from tillhub/feature/UNTIL-12204/s-pos_impleme…
Browse files Browse the repository at this point in the history
…ntation

[UNTIL-12204] SPOS implementation
  • Loading branch information
SloInfinity authored Nov 21, 2024
2 parents 4676300 + 6b56079 commit 35ce605
Show file tree
Hide file tree
Showing 53 changed files with 3,641 additions and 154 deletions.
16 changes: 15 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ simpleXml = "2.7.1"
junit = "4.13.2"
mockk = "1.13.8"
kotest = "5.8.0"
robolectric = "4.14"
androidxCoreTest = "1.6.1"
kotestRobolectric = "0.4.0"
kotestExtensionsAndroid = "0.1.1"

lifecycle = "2.7.0"
activity-compose = "1.8.2"
Expand Down Expand Up @@ -78,6 +82,10 @@ kotest-assertions = { group = "io.kotest", name = "kotest-assertions-core-jvm",
kotest-property = { group = "io.kotest", name = "kotest-property-jvm", version.ref = "kotest" }
kotest-api = { group = "io.kotest", name = "kotest-framework-api", version.ref = "kotest" }
lifecycle-runtime-testing = { group = "androidx.lifecycle", name = "lifecycle-runtime-testing", version.ref = "lifecycle" }
robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "robolectric" }
kotest-robolectric = { group = "io.kotest.extensions", name = "kotest-extensions-robolectric", version.ref = "kotestRobolectric" }
kotest-extensions-android = { group = "br.com.colman", name = "kotest-extensions-android", version.ref = "kotestExtensionsAndroid" }
androidx-test-core = { group = "androidx.test", name = "core-ktx", version.ref = "androidxCoreTest" }

[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
Expand Down Expand Up @@ -114,6 +122,12 @@ testing = [
"kotest.assertions",
"kotest.property",
"kotest-api",
"lifecycle-runtime-testing"
"lifecycle-runtime-testing",
]
robolectric = [
"robolectric",
"kotest-robolectric",
"androidx-test-core",
"kotest-extensions-android"
]

3 changes: 2 additions & 1 deletion payment-engine/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ dependencies {

// Unit tests
testImplementation(libs.bundles.testing)
testImplementation(libs.bundles.robolectric)
}

afterEvaluate {
Expand All @@ -92,7 +93,7 @@ afterEvaluate {
create<MavenPublication>("payment-engine") {
groupId = "de.tillhub.paymentengine"
artifactId = "payment-engine"
version = "2.2.0"
version = "3.0.0"

from(components.getByName("release"))
}
Expand Down
1 change: 1 addition & 0 deletions payment-engine/config/detekt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,7 @@ libraries:
- '**/main/java/de/tillhub/paymentengine/ReconciliationManager.kt'
- '**/main/java/de/tillhub/paymentengine/RefundManager.kt'
- '**/main/java/de/tillhub/paymentengine/ReversalManager.kt'
- '**/main/java/de/tillhub/paymentengine/ConnectionManager.kt'
- '**/main/java/de/tillhub/paymentengine/data/CardSaleConfig.kt'
- '**/main/java/de/tillhub/paymentengine/data/ISOAlphaCurrency.kt'
- '**/main/java/de/tillhub/paymentengine/data/Payment.kt'
Expand Down
1 change: 1 addition & 0 deletions payment-engine/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
-keep class de.tillhub.paymentengine.ReconciliationManager { *; }
-keep class de.tillhub.paymentengine.RefundManager { *; }
-keep class de.tillhub.paymentengine.ReversalManager { *; }
-keep class de.tillhub.paymentengine.ConnectionManager { *; }
-keep class de.tillhub.paymentengine.helper.SingletonHolder { *; }
-keep class de.tillhub.paymentengine.analytics.PaymentAnalytics { *; }

Expand Down
4 changes: 4 additions & 0 deletions payment-engine/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<queries>
<package android:name="de.spayment.akzeptanz" />
</queries>

<application
android:networkSecurityConfig="@xml/network_security_config">
<service
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal abstract class CardManagerImpl(
)
) : CardManager {

protected val defaultConfig: Terminal by lazy {
internal val defaultConfig: Terminal by lazy {
Terminal.ZVT()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package de.tillhub.paymentengine

import androidx.activity.result.ActivityResultCaller
import androidx.activity.result.ActivityResultLauncher
import de.tillhub.paymentengine.contract.TerminalConnectContract
import de.tillhub.paymentengine.contract.TerminalDisconnectContract
import de.tillhub.paymentengine.data.Terminal
import de.tillhub.paymentengine.data.TerminalOperationStatus
import kotlinx.coroutines.flow.MutableStateFlow

/**
* This is called to start of S-POS terminal connect and disconnect,
* it sets up the manager so the connection to the terminal is viable.
*/
interface ConnectionManager : CardManager {
fun startSPOSConnect()
fun startSPOSConnect(configName: String)
fun startSPOSConnect(config: Terminal)

fun startSPOSDisconnect()
fun startSPOSDisconnect(configName: String)
fun startSPOSDisconnect(config: Terminal)
}

internal class ConnectionManagerImpl(
configs: MutableMap<String, Terminal>,
terminalState: MutableStateFlow<TerminalOperationStatus>,
resultCaller: ActivityResultCaller,
private val connectContract: ActivityResultLauncher<Terminal> =
resultCaller.registerForActivityResult(TerminalConnectContract()) { result ->
terminalState.tryEmit(result)
},
private val disconnectContract: ActivityResultLauncher<Terminal> =
resultCaller.registerForActivityResult(TerminalDisconnectContract()) { result ->
terminalState.tryEmit(result)
}
) : CardManagerImpl(configs, terminalState), ConnectionManager {

override fun startSPOSConnect() {
val configName = configs.values.firstOrNull()?.name.orEmpty()
startSPOSConnect(configName)
}

override fun startSPOSConnect(configName: String) {
val terminalConfig = configs.getOrDefault(configName, defaultConfig)
startSPOSConnect(terminalConfig)
}

override fun startSPOSConnect(config: Terminal) {
terminalState.tryEmit(TerminalOperationStatus.Pending.Connecting)
connectContract.launch(config)
}

override fun startSPOSDisconnect() {
val configName = configs.values.firstOrNull()?.name.orEmpty()
startSPOSDisconnect(configName)
}

override fun startSPOSDisconnect(configName: String) {
val terminalConfig = configs.getOrDefault(configName, defaultConfig)
startSPOSDisconnect(terminalConfig)
}

override fun startSPOSDisconnect(config: Terminal) {
terminalState.tryEmit(TerminalOperationStatus.Pending.Disconnecting)
disconnectContract.launch(config)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,11 @@ class PaymentEngine private constructor() {
}
}

fun newConnectionManager(registry: ActivityResultCaller): ConnectionManager {
return ConnectionManagerImpl(configs, terminalState, registry).also {
terminalState.tryEmit(TerminalOperationStatus.Waiting)
}
}

companion object : SingletonHolder<PaymentEngine>(::PaymentEngine)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,71 @@ import java.math.BigDecimal
* it sets up the manager so the data from the transaction is collected correctly.
*/
interface PaymentManager : CardManager {
fun startPaymentTransaction(amount: BigDecimal, currency: ISOAlphaCurrency)
fun startPaymentTransaction(amount: BigDecimal, currency: ISOAlphaCurrency, configName: String)
fun startPaymentTransaction(amount: BigDecimal, currency: ISOAlphaCurrency, config: Terminal)
fun startPaymentTransaction(
transactionId: String,
amount: BigDecimal,
tip: BigDecimal = BigDecimal.ZERO,
currency: ISOAlphaCurrency
)

fun startPaymentTransaction(
transactionId: String,
amount: BigDecimal,
tip: BigDecimal = BigDecimal.ZERO,
currency: ISOAlphaCurrency,
configName: String
)

fun startPaymentTransaction(
transactionId: String,
amount: BigDecimal,
tip: BigDecimal = BigDecimal.ZERO,
currency: ISOAlphaCurrency,
config: Terminal
)
}

internal class PaymentManagerImpl(
configs: MutableMap<String, Terminal>,
terminalState: MutableStateFlow<TerminalOperationStatus>,
resultCaller: ActivityResultCaller
) : CardManagerImpl(configs, terminalState), PaymentManager {

resultCaller: ActivityResultCaller,
private val paymentResultContract: ActivityResultLauncher<PaymentRequest> =
resultCaller.registerForActivityResult(PaymentResultContract()) { result ->
terminalState.tryEmit(result)
}
) : CardManagerImpl(configs, terminalState), PaymentManager {

override fun startPaymentTransaction(amount: BigDecimal, currency: ISOAlphaCurrency) {
override fun startPaymentTransaction(
transactionId: String,
amount: BigDecimal,
tip: BigDecimal,
currency: ISOAlphaCurrency
) {
val configName = configs.values.firstOrNull()?.name.orEmpty()
startPaymentTransaction(amount, currency, configName)
startPaymentTransaction(transactionId, amount, tip, currency, configName)
}

override fun startPaymentTransaction(
transactionId: String,
amount: BigDecimal,
tip: BigDecimal,
currency: ISOAlphaCurrency,
configName: String
) {
val terminalConfig = configs.getOrDefault(configName, defaultConfig)
startPaymentTransaction(amount, currency, terminalConfig)
startPaymentTransaction(transactionId, amount, tip, currency, terminalConfig)
}

override fun startPaymentTransaction(
transactionId: String,
amount: BigDecimal,
tip: BigDecimal,
currency: ISOAlphaCurrency,
config: Terminal
) {
terminalState.tryEmit(TerminalOperationStatus.Pending.Payment(amount, currency))
paymentResultContract.launch(
PaymentRequest(config, amount, currency)
PaymentRequest(config, transactionId, amount, tip, currency)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ interface ReconciliationManager : CardManager {
internal class ReconciliationManagerImpl(
configs: MutableMap<String, Terminal>,
terminalState: MutableStateFlow<TerminalOperationStatus>,
resultCaller: ActivityResultCaller
) : CardManagerImpl(configs, terminalState), ReconciliationManager {

resultCaller: ActivityResultCaller,
private val reconciliationContract: ActivityResultLauncher<Terminal> =
resultCaller.registerForActivityResult(TerminalReconciliationContract()) { result ->
terminalState.tryEmit(result)
}
) : CardManagerImpl(configs, terminalState), ReconciliationManager {

override fun startReconciliation() {
val configName = configs.values.firstOrNull()?.name.orEmpty()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,25 @@ import java.math.BigDecimal
* it sets up the manager so the data from the transaction is collected correctly.
*/
interface RefundManager : CardManager {
fun startRefundTransaction(amount: BigDecimal, currency: ISOAlphaCurrency)
fun startRefundTransaction(amount: BigDecimal, currency: ISOAlphaCurrency, configName: String)
fun startRefundTransaction(amount: BigDecimal, currency: ISOAlphaCurrency, config: Terminal)
fun startRefundTransaction(
transactionId: String,
amount: BigDecimal,
currency: ISOAlphaCurrency
)

fun startRefundTransaction(
transactionId: String,
amount: BigDecimal,
currency: ISOAlphaCurrency,
configName: String
)

fun startRefundTransaction(
transactionId: String,
amount: BigDecimal,
currency: ISOAlphaCurrency,
config: Terminal
)
}

internal class RefundManagerImpl(
Expand All @@ -31,28 +47,39 @@ internal class RefundManagerImpl(
terminalState.tryEmit(result)
}

override fun startRefundTransaction(amount: BigDecimal, currency: ISOAlphaCurrency) {
override fun startRefundTransaction(
transactionId: String,
amount: BigDecimal,
currency: ISOAlphaCurrency
) {
val configName = configs.values.firstOrNull()?.name.orEmpty()
startRefundTransaction(amount, currency, configName)
startRefundTransaction(transactionId, amount, currency, configName)
}

override fun startRefundTransaction(
transactionId: String,
amount: BigDecimal,
currency: ISOAlphaCurrency,
configName: String
) {
val terminalConfig = configs.getOrDefault(configName, defaultConfig)
startRefundTransaction(amount, currency, terminalConfig)
startRefundTransaction(transactionId, amount, currency, terminalConfig)
}

override fun startRefundTransaction(
transactionId: String,
amount: BigDecimal,
currency: ISOAlphaCurrency,
config: Terminal
) {
terminalState.tryEmit(TerminalOperationStatus.Pending.Refund(amount, currency))
refundContract.launch(
RefundRequest(config, amount, currency)
RefundRequest(
config = config,
transactionId = transactionId,
amount = amount,
currency = currency
)
)
}
}
Loading

0 comments on commit 35ce605

Please sign in to comment.