Skip to content

Commit a527c21

Browse files
committed
feat: add error code mapping and event handling utilities for payment processing
1 parent 5f49a64 commit a527c21

File tree

5 files changed

+412
-297
lines changed

5 files changed

+412
-297
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.margelo.nitro.plugpagnitro
2+
3+
import br.com.uol.pagseguro.plugpagservice.wrapper.PlugPag
4+
5+
/**
6+
* Utility class for mapping PlugPag SDK error codes to Nitro error codes
7+
* Eliminates duplication across multiple methods
8+
*/
9+
object ErrorCodeMapper {
10+
11+
/**
12+
* Maps PlugPag SDK result codes to Nitro ErrorCode enum
13+
* @param plugPagResult The result code from PlugPag SDK
14+
* @return Corresponding ErrorCode enum value
15+
*/
16+
fun mapToErrorCode(plugPagResult: Int): ErrorCode {
17+
return when (plugPagResult) {
18+
PlugPag.RET_OK -> ErrorCode.OK
19+
PlugPag.OPERATION_ABORTED -> ErrorCode.OPERATION_ABORTED
20+
PlugPag.AUTHENTICATION_FAILED -> ErrorCode.AUTHENTICATION_FAILED
21+
PlugPag.COMMUNICATION_ERROR -> ErrorCode.COMMUNICATION_ERROR
22+
PlugPag.NO_PRINTER_DEVICE -> ErrorCode.NO_PRINTER_DEVICE
23+
PlugPag.NO_TRANSACTION_DATA -> ErrorCode.NO_TRANSACTION_DATA
24+
else -> ErrorCode.COMMUNICATION_ERROR
25+
}
26+
}
27+
28+
/**
29+
* Maps PlugPag SDK result codes to string representation
30+
* @param plugPagResult The result code from PlugPag SDK
31+
* @return String representation of the error code
32+
*/
33+
fun mapToErrorCodeString(plugPagResult: Int): String {
34+
return when (plugPagResult) {
35+
PlugPag.RET_OK -> "RET_OK"
36+
PlugPag.OPERATION_ABORTED -> "OPERATION_ABORTED"
37+
PlugPag.AUTHENTICATION_FAILED -> "AUTHENTICATION_FAILED"
38+
PlugPag.COMMUNICATION_ERROR -> "COMMUNICATION_ERROR"
39+
PlugPag.NO_PRINTER_DEVICE -> "NO_PRINTER_DEVICE"
40+
PlugPag.NO_TRANSACTION_DATA -> "NO_TRANSACTION_DATA"
41+
else -> "COMMUNICATION_ERROR"
42+
}
43+
}
44+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.margelo.nitro.plugpagnitro
2+
3+
import android.util.Log
4+
import kotlinx.coroutines.Dispatchers
5+
import kotlinx.coroutines.withContext
6+
7+
/**
8+
* Generic exception handler for consistent error handling across all operations
9+
* Eliminates repetitive try/catch blocks
10+
*/
11+
object OperationHandler {
12+
13+
private const val TAG = "OperationHandler"
14+
15+
/**
16+
* Executes an operation with consistent error handling and context switching
17+
* @param operationName Name of the operation for logging
18+
* @param operation The suspend function to execute
19+
* @return Result of the operation
20+
* @throws Exception with formatted error message
21+
*/
22+
suspend fun <T> executeOperation(
23+
operationName: String,
24+
operation: suspend () -> T
25+
): T {
26+
return withContext(Dispatchers.IO) {
27+
try {
28+
Log.d(TAG, "Starting operation: $operationName")
29+
val result = operation()
30+
Log.d(TAG, "Operation completed successfully: $operationName")
31+
result
32+
} catch (e: Exception) {
33+
val errorMessage = "${operationName.uppercase()}_ERROR: ${e.message ?: "Unknown error"}"
34+
Log.e(TAG, "Error in operation $operationName", e)
35+
throw Exception(errorMessage)
36+
}
37+
}
38+
}
39+
40+
/**
41+
* Simplified version for operations that don't need context switching
42+
*/
43+
fun <T> executeSimpleOperation(
44+
operationName: String,
45+
operation: () -> T
46+
): T {
47+
return try {
48+
operation()
49+
} catch (e: Exception) {
50+
val errorMessage = "${operationName.uppercase()}_ERROR: ${e.message ?: "Unknown error"}"
51+
Log.e(TAG, "Error in operation $operationName", e)
52+
throw Exception(errorMessage)
53+
}
54+
}
55+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package com.margelo.nitro.plugpagnitro
2+
3+
import br.com.uol.pagseguro.plugpagservice.wrapper.PlugPagEventData
4+
import android.util.Log
5+
6+
/**
7+
* Configuration-driven event handler for payment events
8+
* Reduces complex switch statements to simple configuration
9+
*/
10+
object PaymentEventHandler {
11+
12+
private const val TAG = "PaymentEventHandler"
13+
14+
// Event configuration mapping
15+
private val eventConfig = mapOf(
16+
// Password events
17+
PlugPagEventData.EVENT_CODE_DIGIT_PASSWORD to EventConfig(
18+
baseCode = 1010.0,
19+
messageProvider = { data, context ->
20+
val count = context["passwordCount"] as? Int ?: 0
21+
"Senha: ${"*".repeat(minOf(count, 6))}"
22+
}
23+
),
24+
PlugPagEventData.EVENT_CODE_NO_PASSWORD to EventConfig(
25+
baseCode = 1011.0,
26+
message = "Digite sua senha"
27+
)
28+
)
29+
30+
// Pattern-based event mapping for dynamic messages
31+
private val patternConfig = listOf(
32+
PatternConfig(
33+
patterns = listOf("cartão", "card"),
34+
subPatterns = mapOf(
35+
listOf("inserir", "insert") to EventConfig(1004.0, "Aguardando cartão..."),
36+
listOf("remov", "retire") to EventConfig(1030.0, "Retire o cartão")
37+
),
38+
defaultConfig = EventConfig(1001.0, "Cartão detectado")
39+
),
40+
PatternConfig(
41+
patterns = listOf("processa", "process"),
42+
defaultConfig = EventConfig(1020.0, "Processando transação...")
43+
),
44+
PatternConfig(
45+
patterns = listOf("conecta", "connect"),
46+
defaultConfig = EventConfig(1021.0, "Conectando à rede...")
47+
),
48+
PatternConfig(
49+
patterns = listOf("envian", "send"),
50+
defaultConfig = EventConfig(1022.0, "Enviando dados...")
51+
),
52+
PatternConfig(
53+
patterns = listOf("aguard", "wait"),
54+
defaultConfig = EventConfig(1023.0, "Aguardando resposta...")
55+
),
56+
PatternConfig(
57+
patterns = listOf("aprovad", "approved"),
58+
defaultConfig = EventConfig(1031.0, "Transação aprovada")
59+
),
60+
PatternConfig(
61+
patterns = listOf("negad", "denied", "recusad"),
62+
defaultConfig = EventConfig(1032.0, "Transação negada")
63+
)
64+
)
65+
66+
/**
67+
* Handles payment events using configuration-driven approach
68+
* @param eventData The event data from PlugPag SDK
69+
* @param context Additional context (like password count)
70+
*/
71+
fun handleEvent(eventData: PlugPagEventData, context: MutableMap<String, Any> = mutableMapOf()) {
72+
val eventCode = eventData.eventCode
73+
val message = eventData.customMessage ?: ""
74+
75+
// Handle specific event codes first
76+
eventConfig[eventCode]?.let { config ->
77+
val finalMessage = config.messageProvider?.invoke(eventData, context)
78+
?: config.message
79+
?: message
80+
emitEvent(config.baseCode, finalMessage)
81+
return
82+
}
83+
84+
// Handle pattern-based events
85+
if (message.isNotEmpty()) {
86+
patternConfig.forEach { patternConfig ->
87+
if (patternConfig.patterns.any { pattern ->
88+
message.contains(pattern, ignoreCase = true)
89+
}) {
90+
// Check sub-patterns first
91+
patternConfig.subPatterns?.forEach { (subPatterns, config) ->
92+
if (subPatterns.any { subPattern ->
93+
message.contains(subPattern, ignoreCase = true)
94+
}) {
95+
emitEvent(config.baseCode, config.message ?: message)
96+
return
97+
}
98+
}
99+
// Use default pattern config
100+
emitEvent(
101+
patternConfig.defaultConfig.baseCode,
102+
patternConfig.defaultConfig.message ?: message
103+
)
104+
return
105+
}
106+
}
107+
108+
// Default case for unknown patterns
109+
emitEvent(1020.0, message)
110+
}
111+
}
112+
113+
private fun emitEvent(code: Double, message: String) {
114+
Log.d(TAG, "Emitting event - Code: $code, Message: $message")
115+
PlugpagEventEmitter.emitPaymentEvent(code, message)
116+
}
117+
118+
// Configuration data classes
119+
data class EventConfig(
120+
val baseCode: Double,
121+
val message: String? = null,
122+
val messageProvider: ((PlugPagEventData, Map<String, Any>) -> String)? = null
123+
)
124+
125+
data class PatternConfig(
126+
val patterns: List<String>,
127+
val subPatterns: Map<List<String>, EventConfig>? = null,
128+
val defaultConfig: EventConfig
129+
)
130+
}

0 commit comments

Comments
 (0)