Saltar al contenido principal

Integración de app iOS

Acepta pagos NFC desde tu app iOS usando el MoneiPaySDK. El SDK gestiona la construcción de la URL, el análisis de la redirección de finalización, los tiempos de espera y el manejo de errores.

Fuente: github.com/MONEI/monei-pay-ios-sdk

No se requieren permisos especiales

Utiliza esquemas de URL estándar — no se necesitan permisos especiales, certificados ni aprobaciones de Apple.

Cómo funciona

  1. Tu app llama a MoneiPay.acceptPayment(...) con un token y un importe
  2. El SDK abre MONEI Pay para la transacción NFC por contacto
  3. MONEI Pay redirige de vuelta a tu app con el resultado
  4. El SDK analiza la redirección de finalización y resuelve un PaymentResult

Requisitos previos

  • Cuenta MONEI
  • iOS 15.0+, Swift 5.9+
  • MONEI Pay instalado en el dispositivo
  • Token de autenticación POS desde tu backend (consulta Primeros pasos)

Integración

1. Instala el SDK

En Xcode: File → Add Package Dependencies → introduce https://github.com/MONEI/monei-pay-ios-sdkUp to Next Major Version desde 1.0.0.

O en Package.swift:

Package.swift
dependencies: [
.package(url: "https://github.com/MONEI/monei-pay-ios-sdk", from: "1.0.0")
]

2. Configura Info.plist

Info.plist
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>your-app</string>
</array>
</dict>
</array>

<key>LSApplicationQueriesSchemes</key>
<array>
<string>monei-pay</string>
</array>
aviso

Reemplaza your-app con el esquema de URL único de tu app (p. ej. tu bundle ID). Cada app de comercio debe usar un esquema diferente.

3. Conecta el gestor de finalización

YourApp.swift
import SwiftUI
import MoneiPaySDK

@main
struct YourApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL { url in
MoneiPay.handleCompleteRedirect(url: url)
}
}
}
}

4. Acepta un pago

import MoneiPaySDK

func acceptPayment() async {
do {
let result = try await MoneiPay.acceptPayment(
token: "eyJ...",
amount: 1500,
description: "Order #123",
customerName: "John Doe",
customerEmail: "john@example.com",
callbackUrl: "https://merchant.com/webhook/monei",
completeScheme: "your-app"
)

if result.success {
print("Payment approved: \(result.transactionId)")
print("Card: \(result.cardBrand ?? "") \(result.maskedCardNumber ?? "")")
}
} catch let error as MoneiPayError {
switch error {
case .moneiPayNotInstalled:
break
case .paymentCancelled:
break
case .paymentTimeout:
break
case .tokenExpired, .invalidToken:
break
case .notAuthenticated, .accountNotConfigured:
break
case .paymentFailed(let reason):
print("Payment failed: \(reason ?? "unknown")")
default:
print("Error: \(error.localizedDescription)")
}
}
}
Modelo de confianza

callbackUrl es un webhook firmado de confianza entregado de servidor a servidor — úsalo para completar pedidos. completeScheme (y la complete_url resultante) es solo una redirección del lado del cliente — devuelve al usuario a tu app pero no está firmada. Consulta Entrega de resultados para más detalles.

Referencia del SDK

MoneiPay.acceptPayment(...)

ParámetroTipoObligatorioDescripción
tokenStringToken de autenticación POS (JWT en bruto, sin prefijo "Bearer ")
amountIntImporte del pago en céntimos (p. ej. 1500 = 15,00 EUR)
descriptionString?NoDescripción del pago
customerNameString?NoNombre del cliente
customerEmailString?NoCorreo electrónico del cliente
customerPhoneString?NoTeléfono del cliente
callbackUrlString?NoURL del webhook firmado de confianza. Debe ser https:// estricto, máx. 2048 caracteres. Consulta Entrega de resultados.
orderIdString?NoReferencia de pedido del comercio. Configúralo para que aparezca en el webhook de callback para la conciliación con tu pedido POS. Máx. 2048 caracteres. Si se omite, MONEI genera uno.
transactionTypeString?NoTipo de transacción opcional: SALE (por defecto), AUTH, REFUND, CAPTURE, CANCEL, PAYOUT, VERIF. Validado en el servidor; los valores no válidos son rechazados.
completeSchemeStringEsquema de URL registrado de tu app — usado para redirigir al usuario de vuelta tras completar el pago
timeoutTimeInterval?NoTiempo de espera en segundos (por defecto: 60)

PaymentResult

PropiedadTipoDescripción
transactionIdStringID de transacción de MONEI
successBoolIndica si el pago fue aprobado
amountInt?Importe del pago en céntimos
cardBrandString?Marca de la tarjeta (p. ej. visa, mastercard)
maskedCardNumberString?Número de tarjeta enmascarado (p. ej. ****1234)

Tipos de error

ErrorDescripción
moneiPayNotInstalledMONEI Pay no está instalado
paymentInProgressOtro pago ya está activo
paymentTimeoutSin respuesta dentro del tiempo de espera
paymentCancelledEl usuario canceló
paymentFailed(reason:)Pago rechazado o fallido
invalidParameters(_:)Entrada no válida (p. ej. importe no positivo, callbackUrl o complete_url mal formados)
tokenExpiredEl token de autenticación POS ha expirado (>24h)
invalidTokenEl token de autenticación POS está mal formado o firmado con la clave incorrecta
notAuthenticatedNo hay token POS y el usuario no ha iniciado sesión en MONEI Pay
accountNotConfiguredLa cuenta de MONEI Pay no tiene la configuración POS requerida
failedToOpenNo se pudo abrir MONEI Pay

Integración manual (esquema de URL)

Si prefieres no usar el SDK, puedes integrarte directamente mediante esquemas de URL.

Mostrar integración manual con esquema de URL

Abre la URL de pago

func acceptPayment(amountInCents: Int) {
var components = URLComponents(string: "monei-pay://accept-payment")!
components.queryItems = [
URLQueryItem(name: "amount", value: String(amountInCents)),
URLQueryItem(name: "auth_token", value: "eyJ..."),
URLQueryItem(name: "callback_url", value: "https://merchant.com/webhook/monei"),
URLQueryItem(name: "complete_url", value: "your-app://payment-result")
]

guard let url = components.url else { return }
UIApplication.shared.open(url)
}

Gestiona la redirección de finalización

struct PaymentResult {
let success: Bool
let transactionId: String?
let amount: String?
let cardBrand: String?
let maskedCardNumber: String?
let error: String?

init(from url: URL) {
let params = URLComponents(url: url, resolvingAgainstBaseURL: false)?
.queryItems?
.reduce(into: [String: String]()) { $0[$1.name] = $1.value } ?? [:]

self.success = params["success"] == "true"
self.transactionId = params["transaction_id"]
self.amount = params["amount"]
self.cardBrand = params["card_brand"]
self.maskedCardNumber = params["masked_card_number"]
self.error = params["error"]
}
}
Modelo de confianza

Los parámetros de consulta en la redirección de complete_url no están firmados — pueden suplantarse. Usa callback_url (webhook firmado) o Obtener pago para confirmar el resultado real antes de completar un pedido. Consulta Entrega de resultados.

Parámetros de la URL

Parámetros de la solicitud

ParámetroTipoObligatorioDescripción
amountIntegerImporte del pago en céntimos (p. ej. 1500 = 15,00 EUR)
auth_tokenStringToken de autenticación POS (JWT en bruto)
callback_urlStringNoURL del webhook firmado de confianza. Debe ser https:// estricto, máx. 2048 caracteres. Recibe un POST firmado con HMAC MONEI-Signature al completar.
complete_urlStringNoURL que se abre en el dispositivo tras completarse el pago. Acepta https://, esquemas de URL personalizados, Universal Links. Máx. 2048 caracteres. No firmada.
descriptionStringNoDescripción del pago
customer_nameStringNoNombre del cliente
customer_emailStringNoCorreo electrónico del cliente
customer_phoneStringNoTeléfono del cliente
order_idStringNoReferencia de pedido del comercio. Aparece en el webhook de callback para la conciliación. Máx. 2048 caracteres. Si se omite, MONEI genera uno.
transaction_typeStringNoTipo de transacción opcional: SALE, AUTH, REFUND, CAPTURE, CANCEL, PAYOUT, VERIF. Validado en el servidor.

Parámetros de redirección de complete_url (éxito)

ParámetroTipoDescripción
successString"true"
transaction_idStringID de transacción de MONEI
amountStringImporte del pago en céntimos
card_brandStringMarca de la tarjeta (p. ej. visa, mastercard)
masked_card_numberStringNúmero de tarjeta enmascarado (p. ej. ****1234)

Parámetros de redirección de complete_url (error)

ParámetroTipoDescripción
successString"false"
errorStringCódigo de error — consulta lista de códigos de error

App de ejemplo

El directorio examples/MerchantDemo contiene una app SwiftUI que demuestra el flujo completo. Abre MerchantDemo.xcodeproj, configura tu equipo de firma y ejecútala en un dispositivo físico con MONEI Pay instalado. El proyecto referencia el SDK como paquete local, por lo que los cambios en el SDK se aplican de inmediato.

Resolución de problemas

moneiPayNotInstalled

MONEI Pay debe estar instalado en el dispositivo. Instálalo desde el App Store.

failedToOpen

Verifica que monei-pay aparece en LSApplicationQueriesSchemes en tu Info.plist. Sin ello, iOS bloquea la comprobación canOpenURL.

paymentTimeout

El tiempo de espera por defecto es de 60 segundos. Auméntalo mediante el parámetro timeout si es necesario. El temporizador usa tiempo de reloj real — poner tu app en segundo plano no lo pausa.

La redirección de finalización no se recibe

Comprueba que tu esquema de URL está registrado en CFBundleURLTypes en Info.plist y que MoneiPay.handleCompleteRedirect(url:) se llama en onOpenURL (SwiftUI) o en application(_:open:options:) (UIKit). Consulta Conecta el gestor de finalización.

El pago funciona en el simulador pero no en el dispositivo

Los pagos NFC requieren un dispositivo físico con MONEI Pay instalado. Los simuladores no son compatibles.