Andorpay
Navegación de la documentación

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

ValorConfiguración
Base URLhttps://api.andorpay.com/v1
AutenticaciónAuthorization: Bearer ap_test_...
VersiónAndorpay-Version: 2026-01-01
ContenidoContent-Type: application/json

Crear un pago

POST /v1/checkouts
bash
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"
    }
  }'
Respuesta 201
json
{
  "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. 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. 2

    Completa un pago sandbox

    Prueba autorización sin challenge, 3DS y rechazo con los datos de la guía de pruebas.
  3. 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.

verify-andorpay-webhook.ts
typescript
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ódigoCorrección
401 api_key_invalidComprueba el Bearer token y que la clave siga activa.
403 merchant_feature_not_enabledEl producto usa suscripciones y la capacidad no está habilitada.
404 product_not_foundUsa un producto activo del comercio autenticado.
400 checkout_successUrl_invalidUsa una URL HTTPS válida; sólo localhost y 127.0.0.1 admiten HTTP.
400 checkout_amount_exceeds_priceEl importe en céntimos no puede superar el precio activo.
503No 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.

Siguiente paso

WhatsApp