Processar uma Transação de Compra
Este guia explica como iniciar uma transação de compra padrão usando o aplicativo Tap on Phone. Você usa um Android Intent para iniciar a interface de pagamento, passar os detalhes da transação (como o valor e a moeda) e gerenciar a resposta quando o pagamento for concluído.
Pré-requisitos
Antes de processar uma compra, certifique-se de que você tem:
- Inicializado com sucesso o aplicativo Tap on Phone. (Consulte Inicializando o POS ou verifique usando Verificando o Status do POS).
- O
userId,userTokenemerchantIdassociados à sessão atual. - Implementado as APIs Activity Result do AndroidX em seu projeto.
Passo 1: Registrar o Activity Result Launcher
Quando o pagamento é concluído, o aplicativo Tap on Phone devolve o controle ao seu aplicativo por meio de um Activity Result. Você deve registrar um callback para gerenciar este resultado.
val paymentResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
val data = result.data
if (result.resultCode == Activity.RESULT_OK && data != null) {
// The transaction process completed and generated a receipt.
val status = data.getStringExtra("status") ?: "None"
if (status == "APPROVED") {
println("Payment approved successfully!")
// Extract receipt data and display success to the merchant
} else {
val declineCause = data.getStringExtra("declineCause") ?: "Unknown"
println("Payment declined: $declineCause")
// Display decline reason to the merchant
}
} else if (result.resultCode == Activity.RESULT_CANCELED) {
// The user canceled the payment, or a pre-transaction error occurred.
val errorCode = data?.getStringExtra("errorCode") ?: "None"
val errorMessage = data?.getStringExtra("errorMessage") ?: "User Canceled"
println("Payment canceled or failed: $errorMessage ($errorCode)")
}
}Uma resposta RESULT_OK significa que o processo foi concluído, mas não garante que o pagamento foi aprovado. Sempre avalie a string status dentro dos dados do intent retornado.
Passo 2: Escutar o ID da Transação (Recomendado)
Assim que o aplicativo Tap on Phone começa a processar o intent de pagamento, ele transmite (broadcasts) um sdkTransactionId único. Se o seu aplicativo falhar (crash) ou perder o Activity Result final, você precisará deste ID para recuperar o status da transação.
Registre um broadcast receiver antes de iniciar o intent de pagamento:
val transactionIdReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val transactionId = intent?.getStringExtra("sdkTransactionId")
println("Transaction started with ID: $transactionId")
// Save this ID temporarily in case you need to recover the transaction
}
}
// Register the receiver
ContextCompat.registerReceiver(
requireActivity(), // or 'this' if in an Activity
transactionIdReceiver,
IntentFilter("com.dejamobile.cbp.sps.TRANSACTION_BROADCAST_RESPONSE"),
ContextCompat.RECEIVER_EXPORTED
)O app Tap on Phone pode emitir este broadcast várias vezes por chamada de intent se ocorrer um erro no início e um novo ID de transação for gerado.
Passo 3: Construir e Iniciar o Intent de Pagamento
Crie um intent explícito direcionado à POSActivity do aplicativo Tap on Phone. Você deve incluir os detalhes da transação como extras.
Preste atenção especial ao valor (amount):
- Valor (Amount): Você deve fornecer o valor total em centavos (por exemplo,
$12.00é1200). Este valor representa o valor total da transação, incluindo quaisquer gorjetas. - Gorjeta (Tip): Se você fornecer um valor de gorjeta, você também deve fornecê-lo em centavos. Isso é estritamente um metadado. O aplicativo Tap on Phone não adiciona a gorjeta ao campo
amountautomaticamente.
private fun performPurchase(amountInCents: Long, tipInCents: Long? = null) {
// 1. Calculate the final total amount
var finalAmount = amountInCents
if (tipInCents != null) {
finalAmount += tipInCents
}
// 2. Build the intent
val intent = Intent().apply {
setClassName(
"com.dejamobile.cbp.sps.app",
"com.dejamobile.cbp.sps.app.POSActivity"
)
// Session Identifiers
putExtra("userId", userId)
putExtra("userToken", userToken)
putExtra("merchantId", merchantId)
// Transaction Details
putExtra("transactionType", "PURCHASE")
putExtra("amount", finalAmount)
if (tipInCents != null) {
putExtra("tip", tipInCents)
}
// Optional Configuration
putExtra("paymentMode", "Card") // Default is "Card". "Link" is also supported.
putExtra("externalTransactionReference", "ORDER-12345") // Link this payment to your internal order ID
putExtra("locale", "en_US") // Force a specific language on the payment screen
putExtra("transitionAuto", true) // Automatically transition back to your app after completion
}
// 3. Launch the intent
paymentResultLauncher.launch(intent)
}Passo 4: Gerenciar o Resultado
Quando você inicia o intent, o aplicativo Tap on Phone assume o controle da tela, solicita ao usuário que aproxime um cartão ou dispositivo, e processa o pagamento com a rede adquirente.
Após a conclusão, a interface do Tap on Phone é fechada e o seu paymentResultLauncher recebe o resultado. Extraia os dados do recibo para formatar um recibo para o cliente ou registrar a transação no seu backend.
- Lembre-se de cancelar o registro (unregister) do seu
transactionIdReceiverapós a conclusão do pagamento para evitar vazamentos de memória.
Próximos Passos
- Aprenda como extrair e formatar todos os dados do recibo em Gerenciar Resultados de Transações.
- Entenda como processar cancelamentos e estornos em Processar um Estorno ou Cancelamento.