Getnet DocsGetnet Docs

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ó PinpadConfig de onInitFinished)
  • Delegados implementados: RedsysBTPinpadPaymentDelegate para manejar resultados de transacciones

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ámetroTipoDescripción
valorIntImporte de transacción en céntimos (ej., 1550 para €15.50)
mMonedaIntCódigo de moneda ISO 4217 (978 = EUR, 840 = USD)
nFacturaStringNúmero de orden/factura único (caracteres alfanuméricos; no admite “ñ”/“Ñ”)
emailStringEmail del cliente para el ticket (opcional)
tlfClienteStringNúmero de teléfono del cliente (opcional)
datosPropietariosStringDatos 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:

  1. Solicita al cliente que presente su tarjeta (Insertar, Deslizar o Tocar)
  2. Lee los datos de la tarjeta vía el método seleccionado
  3. Solicita entrada de PIN si es requerido
  4. Procesa los datos de la tarjeta de forma segura
  5. Envía la solicitud de autorización a los servidores de TPV PC
  6. 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 Mostrarvalor (céntimos)Cálculo
€10.50105010.50 × 100
€100.0010000100.00 × 100
$25.99259925.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: