Saltar al contenido principal

Acepta pagos

El SDK tiene cuatro llamadas: isSupported, prepare, acceptPayment y presentEducation. La API es @MainActor. Llámala desde el actor principal, por ejemplo desde una vista de SwiftUI.

Ejemplo​

import MoneiTapToPay

// Al iniciarse, y otra vez después de cada renovación del token.
func startTapToPay() async {
guard TapToPay.isSupported else { return } // Oculta Tap to Pay en el iPhone en tu interfaz.
do {
let token = try await myServer.fetchPosToken() // Solo el campo "token".
try await TapToPay.prepare(token: token)
} catch {
// Consulta "Gestiona errores y resultados desconocidos".
}
}

// Cuando el cliente paga.
func pay(amountInCents: Int, orderId: String) async {
do {
let result = try await TapToPay.acceptPayment(
amount: amountInCents,
orderId: orderId,
callbackUrl: URL(string: "https://example.com/monei/webhook"))
switch result.status {
case .approved: showApproved(result)
case .declined: showDeclined(result)
@unknown default: showPending(orderId)
}
} catch TapToPayError.outcomeUnknown(let orderId) {
// No vuelvas a intentarlo. Busca este orderId en MONEI.
showPending(orderId)
} catch {
// Consulta "Gestiona errores y resultados desconocidos".
}
}

Comprueba la compatibilidad del dispositivo​

TapToPay.isSupported es true cuando el dispositivo es compatible con Tap to Pay en el iPhone: un iPhone XS o posterior con iOS 18.5 o posterior. Cuando es false, oculta Tap to Pay en el iPhone en tu interfaz. En un dispositivo no compatible, todas las llamadas lanzan notSupported.

Prepara el lector​

Llama a TapToPay.prepare(token:) al iniciarse la app, y otra vez después de cada renovación del token.

  • prepare guarda el token y prepara el lector en segundo plano, para que el primer pago empiece más rápido.
  • El token se queda solo en memoria. Llama otra vez a prepare después de cada inicio.
  • prepare no muestra los términos de Apple.
  • prepare pide permiso de ubicación si el usuario todavía no ha respondido, y espera hasta que el usuario responde. No hay límite de tiempo para la respuesta. Si el usuario no permite el acceso a la ubicación, prepare lanza locationDenied. Si Info.plist no tiene NSLocationWhenInUseUsageDescription, prepare lanza locationDenied inmediatamente.
  • El SDK necesita una ubicación para preparar el lector. El primer prepare o acceptPayment después del inicio espera hasta 15 segundos para obtenerla. Si el dispositivo no obtiene una ubicación en este tiempo, la llamada lanza paymentFailed(code: .locationTimeout).

Cuando la app vuelve al primer plano, el SDK prepara otra vez el lector. No necesitas hacerlo tú.

Cobra un pago​

Llama a TapToPay.acceptPayment(amount:orderId:callbackUrl:) cuando el cliente paga.

ParámetroTipoDescripción
amountIntEl importe en céntimos de euro, mayor que 0. Por ejemplo, 1050 es 10,50 EUR.
orderIdStringTu propia referencia del pedido. No puede estar vacía. Usa un orderId nuevo para cada pedido. MONEI lo guarda con el pago, y tú lo usas para conciliar.
callbackUrlURL?La URL a la que MONEI envía el webhook firmado con el resultado del pago. Defínela siempre. Consulta Confirma el pago con el webhook.

Qué ocurre durante un pago:

  1. Si la cuenta todavía no está vinculada, el primer acceptPayment en un dispositivo muestra los términos de Tap to Pay en el iPhone de Apple. El usuario debe aceptarlos.
  2. Apple muestra la pantalla de pago. El cliente acerca la tarjeta.
  3. MONEI procesa el pago.
  4. acceptPayment devuelve un PaymentResult o lanza un TapToPayError.

Solo puede ejecutarse un pago a la vez. Durante un pago, acceptPayment lanza busy, así que desactiva tu botón de pago.

El SDK nunca vuelve a intentar un pago

Si acceptPayment lanza outcomeUnknown, la tarjeta puede estar cobrada. No vuelvas a intentarlo, y no cobres otra vez con un orderId nuevo. Consulta Resultado desconocido.

Lee el resultado​

acceptPayment devuelve un PaymentResult:

PropiedadTipoDescripción
paymentIdStringEl ID del pago en MONEI.
statusStatus.approved o .declined.
cardBrandString?El nombre de la red de la tarjeta en minúsculas, por ejemplo visa o amex. unknown para una red que el SDK no conoce. nil si la red no está disponible.
last4String?Los últimos 4 dígitos de la tarjeta, o nil.
orderIdStringEl orderId del pago.

Un resultado con el estado .declined no es un error. La tarjeta se leyó y el emisor rechazó el pago. El pago está en MONEI con su paymentId.

Confirma el pago con el webhook​

Pasa siempre callbackUrl. MONEI envía a esta URL un webhook firmado con el resultado del pago. El webhook firmado es el único resultado de pago fiable. Usa el resultado de la app solo para la interfaz.

  • Verifica la firma en tu servidor antes de completar el pedido. Consulta Verificar la firma.
  • La callbackUrl debe usar https, tener 2048 caracteres o menos, y su host no puede ser una dirección IP privada. El SDK no comprueba la URL. MONEI la comprueba después de leer la tarjeta. Si la URL no es válida, MONEI no crea el pago, y acceptPayment puede lanzar outcomeUnknown. Asegúrate de que la URL es válida antes de aceptar pagos.
  • Para saber cuándo envía MONEI este webhook, consulta Callback del pago.

Muestra las pantallas educativas de Apple​

Llama a TapToPay.presentEducation(from:) para mostrar las pantallas de Apple que enseñan cómo acercar una tarjeta. Muéstralas, por ejemplo, en el primer uso y desde tu menú de ayuda.

try await TapToPay.presentEducation(from: viewController)

Sentencias switch​

El SDK usa library evolution, y sus enums públicos no están congelados. Un switch sobre PaymentResult.Status, TapToPayError o TapToPayErrorCode necesita un caso @unknown default. Sin él, tu app no compila.

Referencia de la API​

SímboloDescripción
TapToPay.isSupported: Booltrue cuando el dispositivo es compatible con Tap to Pay en el iPhone.
TapToPay.prepare(token: String) async throwsGuarda el token y prepara el lector en segundo plano. No muestra los términos de Apple. Pide permiso de ubicación si el usuario todavía no ha respondido.
TapToPay.acceptPayment(amount: Int, orderId: String, callbackUrl: URL?) async throws -> PaymentResultCobra un pago con tarjeta. amount está en céntimos de euro y debe ser mayor que 0. orderId no puede estar vacío.
TapToPay.presentEducation(from: UIViewController) async throwsMuestra las pantallas de Apple que enseñan cómo acercar una tarjeta.
PaymentResultpaymentId, status, cardBrand, last4 y orderId. Consulta Lee el resultado.
TapToPayErrorEl error que lanzan todas las llamadas. Consulta Gestiona errores y resultados desconocidos.

Preguntas frecuentes​

¿Por qué tarda más el primer pago?​

En el primer inicio, el SDK pide permiso de ubicación y espera la respuesta del usuario. Después necesita una ubicación antes de poder preparar el lector, y espera hasta 15 segundos para obtenerla. En el primer pago en un dispositivo, Apple también puede mostrar sus términos de Tap to Pay en el iPhone. Llama a prepare al iniciarse la app, para que el lector esté listo antes de que el cliente pague.

¿Debo llamar otra vez a prepare cuando la app vuelve del segundo plano?​

No. El SDK prepara otra vez el lector cuando la app vuelve al primer plano. Llama otra vez a prepare solo después de un inicio y después de una renovación del token.

¿Cada pedido necesita un orderId nuevo?​

Sí. Usa un orderId nuevo y no vacío para cada pedido. MONEI lo guarda con el pago, y tú lo usas para conciliar. Después de outcomeUnknown, no cobres otra vez con un orderId nuevo hasta que conozcas el resultado del primer pago. Consulta Resultado desconocido.