Métodos de pago

Apple Pay

Acepta Apple Pay en la web con el botón del Web SDK: habilitación de dominios, disponibilidad, eventos y conciliación.

Apple Pay se acepta en la web mediante el botón del Web SDK (@tonder.io/web-sdk). El SDK renderiza el botón, presenta la hoja de pago de Apple y procesa el cargo; la transacción cae en /process/ con la misma forma que un pago con tarjeta y dispara los mismos webhooks — tu conciliación no cambia.

Apple Pay no existe en el SDK legacy ni como payment_method.type de API Direct. La única superficie de integración es el componente de botón del Web SDK.

Pruébalo en vivo: el demo de Apple Pay corre el código de esta página — ábrelo en Safari (macOS, iOS o iPadOS) para ver el botón real y el resultado de disponibilidad.

Paso 1: pide a Tonder habilitarlo y registrar tus dominios

No es un paso de código, y es la razón más común por la que una integración correcta falla en producción.

  • Tonder trata con Apple — tú nunca los contactas y no necesitas cuenta de desarrollador de Apple.
  • Tu parte es enviar a Tonder la lista de dominios que mostrarán el botón — los subdominios cuentan por separado — y alojar el archivo de verificación que Tonder te da.

Empieza este paso antes de escribir código: condiciona todo lo demás. Los pasos exactos y los modos de falla están en el README del SDK.

Paso 2: renderiza el botón

Apple Pay es el único flujo que no termina en una llamada a pay(). Apple exige que la hoja de pago se abra en el mismo tick que el toque, así que el SDK es dueño del clic, y el resultado llega por los callbacks de events.payment en lugar de una promesa devuelta.

Esos callbacks no son un mecanismo exclusivo de Apple Pay — se disparan para todos los métodos que el SDK cobra, así que un solo conjunto de handlers cubre el checkout completo.

El SDK renderiza el botón dentro de un elemento tuyo. Debe existir antes de mount() y debe quedar vacío — no le pongas un botón, un texto ni un icono dentro:

<div id="tonder-apple-pay-button"></div>
const tonder = createTonder({
  api_key: tonderPublicConfig.api_key,
  environment: 'stage', // cambia a 'production' al salir a producción
  session: { customer: { email: 'ada@example.com' } },
  // Se disparan para TODOS los métodos, no solo Apple Pay. Con pay() corren
  // junto a la promesa que devuelve; Apple Pay no tiene promesa, así que aquí
  // estos callbacks son el único canal.
  events: {
    payment: {
      on_completed: (transaction) => handleResult(transaction),
      on_error: (error) => showError(error.code),
      on_cancel: () => { /* el comprador cerró la hoja — no es un error */ },
    },
  },
});

await tonder.init();

// Pregunta antes de renderizar. La respuesta es un OBJETO, nunca un booleano:
// { available: true }, o { available: false, code, message }. Usar el objeto
// como condición siempre sería verdadero — lee .available.
const availability = tonder.isApplePayAvailable();

if (availability.available) {
  const button = tonder.create('apple_pay_button', {
    // Se llama SÍNCRONAMENTE cuando el comprador toca, así que lee lo que el
    // carrito tenga en ese momento — monto, moneda y referencias pueden
    // cambiar después del mount sin volver a montar el botón. No debe ser
    // async: Apple exige que la hoja abra en el mismo tick que el toque.
    payment: () => ({
      amount: 250,
      currency: 'MXN',
      return_url: 'https://merchant.example.com/return',
      client_reference: 'ORD-001',
    }),
  });
  await button.mount();
} else {
  // No adivines la razón: solo APPLE_PAY_UNSUPPORTED_BROWSER significa
  // "ofrece otro método"; los otros dos códigos son tuyos por arreglar.
  console.info('Apple Pay oculto:', availability.code, availability.message);
}

Cuando la disponibilidad es false

codeSignificaQué hacer
APPLE_PAY_UNSUPPORTED_BROWSEREl navegador no puede correr Apple PayOfrece otro método de pago — es el único código que es problema del comprador
APPLE_PAY_NOT_ENABLEDApple Pay no está habilitado para tu negocioTuyo por arreglar — ver el paso 1
NOT_INITIALIZEDLlamaste antes de que init() terminaraTuyo por arreglar — espera el await tonder.init()

Personaliza el botón

Safari dibuja el control de forma nativa, así que Apple solo permite cambiar estas llaves en customization.apple_pay_button — cualquier otra cosa se ignora:

LlaveEjemplo
type'check-out' (el call to action)
style'black'
locale'es-MX' (el idioma de la etiqueta)
width / height'100%' / '48px'
border_radius'8px'

El SDK lee customization una sola vez en createTonder() — cambiarla implica construir una instancia nueva y volver a montar. Lo mismo aplica a api_key y session.customer.

Un intento liquidado consume sus referencias, sea cual sea el resultado. En on_completed, acuña un client_reference y un idempotency_key nuevos para que el siguiente toque sea una orden nueva con su propio alcance de idempotencia.

Lo que queda fuera de esta guía — un id de contenedor personalizado y liberar el botón en un cambio de ruta — está en Apple Pay en el README del SDK.

pay({ payment_method: { type: 'apple_pay' } }) se rechaza a propósito. Apple Pay no puede cobrarse vía pay() — el requisito de gesto de Apple es la razón. Usa el componente de botón.

Paso 3: tu conciliación no cambia

Nada que hacer. El cargo de Apple Pay cae en /api/v1/process/ como tus cargos con tarjeta, produce una transacción con la misma forma y dispara el mismo webhook. Tu handler existente ya lo cubre.

Envía client_reference en el payment del botón exactamente como hoy y tu correlación sigue funcionando. Ver Modelo de webhooks.

Prueba Apple Pay

PruebaQué demuestra que funcionó
La hoja abre en un dispositivo realEl Simulador de iOS no puede probar Apple Pay web
Un rechazoLlega en on_completed con estado declinado, no en on_error
client_referenceAparece en el webhook y correlaciona tu orden

La fila del rechazo es la que sorprende: on_completed significa que el cargo llegó a una respuesta final, no que la respuesta fue sí.

Siguientes pasos

¿Te resultó útil esta página?

En esta página