Saltar al contenido
pcreative Commerce

Cobrar con tarjeta y otras pasarelas

De serie, la tienda cobra por transferencia, contrarreembolso y Bizum. Eso funciona sin dar de alta nada y sin que nadie pueda cerrarte la cuenta.

De serie, la tienda cobra por transferencia, contrarreembolso y Bizum. Eso funciona sin dar de alta nada y sin que nadie pueda cerrarte la cuenta.

Si además quieres tarjeta, hay cinco pasarelas listas. Cada una aparece sola en cuanto pones sus credenciales; sin ellas, no existe.

Cuál elegir

Para quéTrae
MONEIEspañaBizum, tarjeta, PayPal, Apple y Google Pay
StripeInternacionalTarjeta, Apple y Google Pay, SEPA, iDEAL
PayPalEl botón que más pide el compradorPayPal y tarjeta
MollieNorte de EuropaiDEAL, Bancontact, tarjeta, SEPA
AdyenVolumen altoTarjeta y métodos locales de medio mundo

Si vendes en España, MONEI. Es Entidad de Pago con licencia del Banco de España, llega a las mismas vías bancarias que el TPV de tu banco y hace Bizum de verdad.

¿Y Redsys? Es el TPV de CaixaBank, BBVA o Santander, y sería la primera opción, pero sus librerías oficiales son PHP, Java y .NET. Integrarlo aquí significaría escribir su firma criptográfica a mano, y eso en un cobro es la clase de error que no encuentra ninguna prueba: lo encuentra el cliente al que se le ha cobrado dos veces. MONEI cubre ese terreno sin inventarse nada.

Encenderla

La vía principal es el panel: Ajustes → Pagos → Pasarelas de pago. Pega las claves de la pasarela y pulsa Guardar y activar. Se guardan cifradas, se activan al momento sin reiniciar y lo que guardes ahí manda sobre el .env. Para guardar, el servidor necesita una clave de cifrado: JWT_SECRET o PCC_CLAVE_CIFRADO.

Cada pasarela tiene además un interruptor de Modo de pruebas y la dirección de avisos para copiar (ver más abajo).

También puedes dar las claves en el .env del backend y reiniciar:

# La dirección pública del backend: de ella sale la URL de los avisos de pago
PCC_BACKEND_URL=https://api.tu-tienda.com

# MONEI: Bizum y tarjeta
MONEI_API_KEY=pk_...
MONEI_ACCOUNT_ID=...           # opcional

# Stripe: hacen falta las tres; sin la clave pública Stripe no se monta
STRIPE_API_KEY=sk_live_...
STRIPE_PUBLIC_KEY=pk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...

# PayPal
PAYPAL_CLIENT_ID=...
PAYPAL_CLIENT_SECRET=...
PAYPAL_WEBHOOK_ID=...          # opcional, ver más abajo
PAYPAL_SANDBOX=false           # sin esto, PayPal funciona en sandbox

# Mollie
MOLLIE_API_KEY=live_...

# Adyen: la clave, la cuenta de comercio y la client key son obligatorias
ADYEN_API_KEY=...
ADYEN_MERCHANT_ACCOUNT=...
ADYEN_CLIENT_KEY=...
ADYEN_HMAC_KEY=...             # opcional, pero sin ella no se acepta ningún aviso
ADYEN_SANDBOX=false            # sin esto, Adyen funciona en sandbox

# Adónde vuelve el comprador después de pagar fuera; si falta, se usa STOREFRONT_URL
PAYMENT_RETURN_URL=https://tu-tienda.com

Si falta un dato obligatorio, la pasarela sencillamente no se monta: no hay error, solo que no aparece.

Que cobre de verdad depende de la pasarela. Stripe, Mollie y MONEI lo saben por la propia clave (sk_live_, live_, pk_test_). PayPal y Adyen arrancan en sandbox salvo que pongas PAYPAL_SANDBOX=false o ADYEN_SANDBOX=false, o quites el Modo de pruebas en el panel.

El escaparate no necesita la clave pública de Stripe: se la pasa el backend junto con el pago. Los temas de fábrica devuelven al comprador a /checkout/volver, y de ahí a la misma dirección con su idioma, /en o /es.

Una pasarela nueva se enciende en todas las regiones al darse de alta. Para apagarla en una región, ve a Ajustes → Pagos → Métodos de pago: cada método tiene un interruptor por región.

Si vendes CBD o cáñamo

Stripe lo prohíbe en sus condiciones para Reino Unido y la UE, y Shopify Payments igual. No es un problema técnico ni se arregla configurando nada: la cuenta se cierra, normalmente sin aviso y con el dinero retenido.

Los procesadores especializados cobran del 1 % al 5 % y retienen reservas de hasta el 10 % durante 180 días.

Por eso los métodos de serie —transferencia, contrarreembolso y Bizum— no son un apaño mientras llega la tarjeta. Para ese sector son la vía fiable, y para cualquiera son lo que evita depender de que a nadie le parezca mal lo que vendes.

Cómo se paga, según la pasarela

Qué ve el comprador
Transferencia, contrarreembolso, BizumConfirma el pedido y ya está
PayPal, Mollie, MONEIVa a la página de la pasarela y vuelve
StripePaga sin salir de la tienda, en un formulario de Stripe
AdyenPaga sin salir, en el Drop-in de Adyen con todos sus métodos

Con las dos últimas el pedido se cierra al volver, no al pulsar el botón. Cerrarlo antes sería aceptar pedidos que nadie ha pagado.

Y la página de vuelta no se cree lo que diga la URL. Que el comprador haya vuelto solo significa «ya puedes mirar»: se le pregunta a la pasarela, y si el dinero no está, no hay pedido — por mucho que ponga ?success=true, que es algo que cualquiera puede escribir.

Adyen depende de su webhook

Con las demás, al volver se le pregunta a la pasarela y ya está. Con Adyen no se puede: su API no sabe contestar sobre una sesión sin un dato que solo tiene el navegador, y su propia documentación dice que el resultado llega asíncrono, en un webhook.

Ese webhook va firmado con HMAC, así que lo que dice es de fiar y trae dentro el estado y el importe. Pero significa una cosa importante:

Con Adyen, el webhook tiene que llegar. Si su URL no es accesible desde internet, el comprador paga y el pedido no se cierra. En local no funciona sin un túnel.

El Drop-in enseña de una vez todos los métodos que tengas activados en tu cuenta —tarjeta, iDEAL, Klarna, lo que sea— y se encarga él del 3-D Secure.

Los avisos de la pasarela

Cada pasarela avisa a la tienda cuando un pago cambia. La URL es siempre:

<PCC_BACKEND_URL>/pagos/aviso/pp_pasarela_<pasarela>

Por ejemplo, https://api.tu-tienda.com/pagos/aviso/pp_pasarela_stripe. El panel la enseña ya montada, con un botón para copiarla, en los ajustes de cada pasarela.

Por eso PCC_BACKEND_URL tiene que ser la dirección pública del backend, la que se alcanza desde internet. Sin ella no hay URL de aviso que dar.

  • MONEI y Mollie reciben esa URL con cada pago: no hay que pegarla en ningún sitio.
  • Stripe, PayPal y Adyen la necesitan dada de alta en su propio panel, como destino de sus avisos.

Si una pasarela necesita otra URL —un proxy, un túnel en local—, se fuerza con <PASARELA>_WEBHOOK_URL, por ejemplo MONEI_WEBHOOK_URL. Pisa a la calculada.

Lo que llega en ese aviso no se cree. Se comprueba la firma, se saca de él únicamente el identificador del pago y se le vuelve a preguntar a la pasarela cuál es el estado. Suena exagerado hasta que se piensa qué es un webhook: una petición que puede mandar cualquiera que adivine la URL, diciendo «esto ya está pagado».

Detalles por pasarela:

  • Stripe y Adyen firman con un secreto. Sin ese secreto configurado, la tienda no acepta ningún aviso suyo — una ruta abierta que marca pedidos como pagados no puede quedarse viva por un olvido en el .env.
  • MONEI firma con su cabecera propia; lo valida su SDK.
  • Mollie no firma, a propósito: su aviso trae solo el identificador justamente para que haya que repreguntar.
  • PayPal no usa un secreto compartido: se le pregunta a él si el aviso es suyo. Con PAYPAL_WEBHOOK_ID se hace esa comprobación; sin él, la seguridad la da volver a consultar el pedido.

Si algo falla

«falta el paquete stripe» — la pasarela está configurada pero su librería no está instalada. npm i stripe en el backend.

Una pasarela no aparece en el checkout — falta un dato obligatorio (en Adyen, la cuenta de comercio o la client key; en Stripe, la clave pública) y la pasarela no se monta. No hay mensaje de error: mira su ficha en Ajustes → Pagos, donde sale como Sin configurar. Mira también su interruptor en la región del comprador.

Un pago se queda en «pendiente» — mira el registro de avisos de la pasarela. Casi siempre es la URL del webhook mal puesta o inaccesible desde fuera.

Añadir otra pasarela

Las cinco viven en @pcreative/payments-contract, cada una sobre el SDK oficial de su pasarela. Para añadir una más se implementan seis operaciones —crear, consultar, capturar, cancelar, reembolsar y webhook— y se registra igual que las demás. El resto del sistema no se entera.