Documentación para desarrolladores
REST API
Usa HTTPS desde cualquier backend, valida el contrato con cURL y redirige al comprador al checkout alojado.
Antes de empezar
Necesitas una API key de pruebas, un producto activo y un backend capaz de realizar peticiones HTTPS. cURL sirve para validar la cuenta antes de trasladar la misma petición al lenguaje de tu aplicación.
Configuración
| Valor | Configuración |
|---|---|
| Base URL | https://api.andorpay.com/v1 |
| Autenticación | Authorization: Bearer ap_test_... |
| Versión | Andorpay-Version: 2026-01-01 |
| Contenido | Content-Type: application/json |
Crear un pago
curl https://api.andorpay.com/v1/checkouts \
--request POST \
--header "Authorization: Bearer $ANDORPAY_API_KEY" \
--header "Andorpay-Version: 2026-01-01" \
--header "Content-Type: application/json" \
--data '{
"productId": "ap_prod_starter_monthly",
"externalCustomerId": "customer_42",
"customer": {
"email": "ana@example.com",
"name": "Ana Garcia",
"billingDetails": {
"line1": "Carrer Prat de la Creu 12",
"city": "Andorra la Vella",
"postal_code": "AD500",
"country": "AD"
},
"tax": {
"value": "F-123456-Z",
"type": "andorra_nrt"
}
},
"successUrl": "https://shop.example.com/payment/success",
"failUrl": "https://shop.example.com/payment/failed",
"reconciliation": {
"merchantReference": "cart_1048"
}
}'{
"id": "ap_chk_01JQ8P9A3Y9B5J7V2V0M9R4S8T",
"sessionId": "ap_chk_01JQ8P9A3Y9B5J7V2V0M9R4S8T",
"hostedUrl": "https://shop.andorpay.com/checkout/ap_chk_01JQ8P9A3Y9B5J7V2V0M9R4S8T",
"expiresAt": "2026-08-23T11:30:00.000Z",
"request_id": "req_01JQ8T2M0D6F4Q7F3K8A9V2N1C"
}Devuelve o redirige al comprador al hostedUrl. No expongas la API key en esa respuesta y no generes la URL alojada manualmente. La sesión caduca en expiresAt, normalmente 30 minutos después de crearla.
Probar la integración
- 1
Ejecuta la petición con ap_test_
Confirma un estado 201, guarda request_id para diagnóstico y abre hostedUrl antes de su caducidad. - 2
Completa un pago sandbox
Prueba autorización sin challenge, 3DS y rechazo con los datos de la guía de pruebas. - 3
Compara los tres estados
El resultado debe coincidir en Redsys, AndorPay y tu sistema después de procesar el webhook.
Configurar webhooks
Publica una ruta HTTPS que conserve el cuerpo sin procesar. La firma HMAC SHA-256 cubretimestamp.cuerpo y admite una diferencia máxima de 5 minutos.
import { createHmac, timingSafeEqual } from "node:crypto"
export function verifyAndorpayWebhook(
rawBody: string,
signatureHeader: string,
secret: string,
) {
const values = new Map(signatureHeader.split(",").map((part) => part.trim().split("=", 2)))
const timestamp = values.get("t")
const signature = values.get("v1")
if (!timestamp || !signature || !/^[a-f0-9]{64}$/i.test(signature)) return false
const timestampSeconds = Number(timestamp)
if (!Number.isFinite(timestampSeconds)) return false
if (Math.abs(Date.now() / 1000 - timestampSeconds) > 300) return false
const expected = createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex")
const receivedBuffer = Buffer.from(signature, "hex")
const expectedBuffer = Buffer.from(expected, "hex")
return receivedBuffer.length === expectedBuffer.length && timingSafeEqual(receivedBuffer, expectedBuffer)
}Ejecuta esta verificación antes de JSON. Después conecta el evento válido con tu capa de aplicación y responde 2xx cuando lo haya aceptado. Una reentrega conserva el mismo event.id.
Errores frecuentes
| Estado o código | Corrección |
|---|---|
| 401 api_key_invalid | Comprueba el Bearer token y que la clave siga activa. |
| 403 merchant_feature_not_enabled | El producto usa suscripciones y la capacidad no está habilitada. |
| 404 product_not_found | Usa un producto activo del comercio autenticado. |
| 400 checkout_successUrl_invalid | Usa una URL HTTPS válida; sólo localhost y 127.0.0.1 admiten HTTP. |
| 400 checkout_amount_exceeds_price | El importe en céntimos no puede superar el precio activo. |
| 503 | No repitas un cobro a ciegas. Conserva request_id y comprueba si existe un resultado pendiente. |
Pasar a producción
Configura Redsys productivo, autoriza dominios, genera una API key ap_live_ y cambia el secreto en tu backend. El cuerpo y las cabeceras permanecen iguales.
Valida una operación real de importe reducido, la entrega firmada y el efecto de negocio antes de habilitar todo el tráfico.