Crear una venta
La venta es la transacción en la que los fondos se autorizan y capturan en una sola operación. Este es el flujo más común para venta minorista y servicios inmediatos, donde el pago se procesa instantáneamente.
Esta guía te explica cómo procesar una transacción de venta completa usando el SDK de Get Mini, desde la creación del DTO de pago hasta el manejo del resultado de la autorización.
Requisitos
Antes de comenzar, asegúrate de tener:
- SDK inicializado con entorno y licencia a través de
CommonUtils - Configuración de comercio de un inicio de sesión exitoso (
DatosLoginResponseDTO) - PIN pad conectado e inicializado (recibió
PinpadConfigdeonInitFinished) - Delegados implementados:
RedsysBTPinpadPaymentDelegatepara manejar resultados de transacciones
Completa Inicializar el SDK e Inicio Rápido: Tu Primera Venta antes de proceder.
Proceso de pago
Paso 1: Crear el DTO de pago
Prepara los datos de la transacción usando PagoDTO. El importe debe especificarse en céntimos (multiplicar por 100):
// Importar vía Bridging Header: PagoDTO.h
func createPaymentData() -> PagoDTO {
let amount: Float = 15.50 // Importe en unidades de moneda
let pagoDTO = PagoDTO(
valor: Int(amount * 100), // Convertir a céntimos: 1550
mMoneda: 978, // Código ISO 4217 (978 = EUR)
nFactura: "SALE\(Int.random(in: 1000...9999))", // ID de orden único
email: "", // Email del cliente opcional
tlfCliente: "", // Teléfono del cliente opcional
datosPropietarios: "" // Datos de comercio personalizados opcionales
)
return pagoDTO
}| Parámetro | Tipo | Descripción |
|---|---|---|
valor | Int | Importe de transacción en céntimos (ej., 1550 para €15.50) |
mMoneda | Int | Código de moneda ISO 4217 (978 = EUR, 840 = USD) |
nFactura | String | Número de orden/factura único (caracteres alfanuméricos; no admite “ñ”/“Ñ”) |
email | String | Email del cliente para el ticket (opcional) |
tlfCliente | String | Número de teléfono del cliente (opcional) |
datosPropietarios | String | Datos de comercio personalizados (opcional) |
Siempre convierte importes a céntimos para asegurar precisión. Para €15.50, usa 1550 como el valor.
Paso 2: Ejecutar el pago
Llama a payWithPinpadBluetooth con el dispositivo conectado, datos del comercio, configuración del PIN pad y DTO de pago:
// Importar vía Bridging Header: RedsysPinpadManager.h, MerchanDTO.h
func executePayment() {
guard let config = pinpadConfig else {
print("PIN pad no inicializado")
return
}
// Crear MerchanDTO con campos requeridos de la respuesta de login
let merchantDTO = MerchanDTO()
merchantDTO.fuc = "999008881"
merchantDTO.fucExtendido = "999008881" // Usualmente igual que FUC
merchantDTO.terminal = "001"
merchantDTO.password = "merchant_pass" // Contraseña del login
// Crear DTO de pago
let pagoDTO = createPaymentData()
// Ejecutar pago
pinpadManager.payWithPinpadBluetooth(
selectedDevice,
merchan: merchantDTO,
config: config,
andPagoDTO: pagoDTO,
withDelegate: self
)
}Cuando llamas a payWithPinpadBluetooth, el SDK:
- Solicita al cliente que presente su tarjeta (Insertar, Deslizar o Tocar)
- Lee los datos de la tarjeta vía el método seleccionado
- Solicita entrada de PIN si es requerido
- Procesa los datos de la tarjeta de forma segura
- Envía la solicitud de autorización a los servidores de TPV PC
- Devuelve el resultado vía callbacks del delegado
Paso 3: Manejar resultados de transacción
El SDK entrega resultados a través de los callbacks de RedsysBTPinpadPaymentDelegate.
Manejo de Éxito
func onPaymentFinished(_ result: RespuestaTransaccionDTO!, orError error: Error!) {
if let transaction = result, error == nil {
// Transacción exitosa - autorizada y capturada
print("Venta Exitosa!")
print("Código de Autorización: \(transaction.codigoAutorizacion ?? "N/A")")
// Guardar detalles de la transacción
saveTransaction(
authCode: transaction.codigoRespuesta ?? "",
orderId: transaction.pedido ?? "",
amount: transaction.importe ?? ""
)
// Verificar si se requiere firma (transacciones sin PIN)
// Nota: AutenticadoPorPin es una propiedad BOOL de Objective-C
if !transaction.autenticadoPorPin {
captureCustomerSignature(for: transaction)
}
// Mostrar mensaje de éxito
showSuccessAlert()
} else {
// Transacción fallida
handlePaymentError(error)
}
}Actualizaciones de Progreso
func onPaymentProcess(_ result: Any!, orError error: Error!) {
// Llamado durante el procesamiento para actualizaciones de UI
print("Pago en progreso...")
updateProgressIndicator()
}Manejo de Errores
func handlePaymentError(_ error: Error?) {
print("Pago fallido: \(error?.localizedDescription ?? "Error desconocido")")
// Mostrar mensaje de error amigable al usuario
showErrorAlert(message: "Transacción rechazada. Por favor intente de nuevo.")
// Registrar error para soporte
logTransactionError(error)
}Consideraciones clave
A diferencia de las preautorizaciones, en una venta los fondos se autorizan y capturan inmediatamente.
Formateo de importes
Siempre convierte importes decimales a céntimos para el campo PagoDTO.valor:
| Importe a Mostrar | valor (céntimos) | Cálculo |
|---|---|---|
| €10.50 | 1050 | 10.50 × 100 |
| €100.00 | 10000 | 100.00 × 100 |
| $25.99 | 2599 | 25.99 × 100 |
IDs de orden únicos
El campo nFactura debe ser único para cada transacción. Genera IDs usando marcas de tiempo, UUIDs o números secuenciales para prevenir problemas de seguimiento de orden duplicados.
Gestión de firma
Para transacciones donde autenticadoPorPin == false, capturar una firma digital es obligatorio para cumplir con los requisitos legales. La propiedad BOOL autenticadoPorPin indica si se usó autenticación por PIN. Consulta el proceso de envío de firma en Ciclo de Vida de la Transacción.
Mejores prácticas
Prevenir Transacciones Duplicadas
Deshabilita los botones de pago mientras onPaymentProcess esté activo para prevenir múltiples intentos de pago simultáneos:
func executePayment() {
payButton.isEnabled = false
// Ejecutar pago...
}
func onPaymentFinished(_ result: RespuestaTransaccionDTO!, orError error: Error!) {
payButton.isEnabled = true // Rehabilitar después de completar
// Manejar resultado...
}Guardar Datos de Transacción
Siempre guarda los códigos de autorización inmediatamente tras el éxito. Necesitarás estos para devoluciones y conciliación.
Proporcionar Retroalimentación Clara
Actualiza tu UI durante onPaymentProcess para mostrar a los clientes que el procesamiento está ocurriendo. Muestra mensajes claros de éxito o error basados en el resultado final.
Solución de Problemas
Tiempo de Espera de Transacción
Si el pago agota el tiempo de espera esperando la presentación de la tarjeta, asegúrate de que el PIN pad esté encendido y mostrando el aviso de listo. Verifica la estabilidad de la conexión Bluetooth.
Transacciones Rechazadas
Los rechazos de tarjeta ocurren a nivel del banco emisor. Muestra el motivo del rechazo a los clientes y ofrece reintentar con una tarjeta o método de pago diferente.
Firma Requerida pero No Capturada
Si autenticadoPorPin == false, debes capturar y enviar una firma usando envioFirmaDigitalizada. Consulta Seguridad y licencias para detalles.
Próximos pasos
Explora funcionalidades de pago adicionales:
- Crear un pago preautorizado - Reservar fondos para captura posterior
- Ciclo de Vida de la Transacción - Entender el flujo de pago completo
- Seguridad y licencias - Aprender sobre seguridad de pagos