Cómo crear un marketplace multi-vendedor en Webflow Cloud con Stripe Connect

Cómo crear un marketplace multi-vendedor en Webflow Cloud con Stripe Connect

Aprende a crear un marketplace multi-vendedor en Webflow Cloud, incorpora vendedores con Stripe Connect y divide cada pago con un cargo de destino.

Cómo crear un marketplace multi-vendedor en Webflow Cloud con Stripe Connect

Ismail Ajagbe
Redactor técnico
Ver perfil del autor
Ismail Ajagbe
Redactor técnico
Ver perfil del autor
Índice de contenidos

Un marketplace solo es rentable cuando cada vendedor recibe su pago en el instante en que el cliente finaliza la compra, y Webflow Cloud te ofrece el entorno de servidor necesario para dividir ese pago, registrar el pedido y mantener todo el flujo bajo tu propio código.

Un proceso de pago de tienda única envía el dinero a una sola cuenta. Un marketplace debe recibir un pago y dirigir la mayor parte al vendedor que realizó la venta, mientras retiene una comisión de plataforma para el dueño del negocio. Esa división debe ocurrir en un servidor que tus clientes nunca vean.

Webflow Cloud ejecuta tu aplicación en Cloudflare Workers, lo que te brinda un lugar para almacenar tus claves de Stripe, comunicarte con Stripe Connect y leer o escribir en una base de datos, todo en el edge. La tienda puede permanecer en Webflow, pero el dinero y los datos se mueven a través del código que tú controlas.

En esta guía, construimos esa infraestructura en seis pasos, desde el esquema de la base de datos y un cliente de Stripe compatible con Workers, hasta la incorporación de vendedores, pagos divididos y un webhook firmado que confirma cada venta.

¿Qué necesitas para construir un marketplace multi-vendedor en Webflow Cloud?

Necesitas una aplicación Next.js en Webflow Cloud, una cuenta de Stripe con Connect habilitado y un enlace a una base de datos SQLite para los datos de tu marketplace. Stripe Connect es obligatorio, ya que permite que un solo pago se distribuya entre varios vendedores.

Aquí tienes la lista completa de lo que necesitas:

  • Un proyecto de Webflow Cloud ejecutando una aplicación Next.js, ya sea desplegada o en desarrollo local
  • Una cuenta de Stripe con Connect habilitado en el panel de control
  • Tu clave secreta de Stripe y un secreto de firma de webhook
  • Un enlace a una base de datos SQLite (D1) declarado en tu wrangler.json
  • Node.js 22 o superior instalado localmente

Los vendedores solo necesitan un correo electrónico para empezar. Stripe Connect se encarga de la incorporación, recopila sus datos bancarios y de identidad, y devuelve un ID de cuenta que tú guardas para el vendedor.

Si ya tienes configurado el inicio de sesión con Auth0 en Webflow Cloud, esa misma sesión te indica qué vendedor se está incorporando y qué cliente está comprando.

6 pasos para construir un marketplace multi-vendedor en Webflow Cloud

La construcción sigue el flujo del dinero: configura los datos, conecta Stripe, incorpora a un vendedor, lista lo que vende, procesa un pago dividido y luego confírmalo.

Esta es la secuencia que sigo en cada marketplace de Webflow Cloud:

  • Modelar vendedores, productos y pedidos en SQLite
  • Crear un cliente de Stripe que se ejecute en el entorno de Workers
  • Incorporar vendedores con Stripe Connect
  • Listar los productos de cada vendedor desde la base de datos
  • Recibe un pago de un cliente y divídelo con el vendedor
  • Confirma el pedido pagado desde un webhook de Stripe

Cada paso se ejecuta en un Route Handler, por lo que tu clave secreta de Stripe y el enlace a la base de datos permanecen en el servidor y nunca llegan al navegador.

1. Modela vendedores, productos y pedidos en SQLite

Un marketplace es una relación entre tres elementos:

  • Los vendedores que ofrecen sus productos
  • Los productos que listan
  • Los pedidos que conectan a los compradores con los vendedores

Webflow Cloud te ofrece un enlace a base de datos SQLite para este tipo de datos relacionales estructurados, y es la fuente de verdad que utiliza el resto de la guía.

Declara la base de datos en wrangler.json en la raíz de tu aplicación:

{
  "d1_databases": [
    {
      "binding": "DB",
      "database_name": "marketplace",
      "database_id": "1234",
      "migrations_dir": "./migrations"
    }
  ]
}

Deja database_id como marcador de posición. Webflow Cloud genera el valor real y lo inyecta al desplegar, así que no necesitas buscarlo de antemano. Las migraciones en migrations_dir se aplican automáticamente durante el despliegue.

Creación de una migración

Crea una migración en ./migrations que defina las tres tablas:

-- migrations/0001_init.sql
CREATE TABLE vendors (
  id                TEXT PRIMARY KEY,
  name              TEXT NOT NULL,
  email             TEXT NOT NULL,
  stripe_account_id TEXT,
  onboarded         INTEGER NOT NULL DEFAULT 0
);

CREATE TABLE products (
  id          TEXT PRIMARY KEY,
  vendor_id   TEXT NOT NULL REFERENCES vendors(id),
  title       TEXT NOT NULL,
  price_cents INTEGER NOT NULL,
  active      INTEGER NOT NULL DEFAULT 1
);

CREATE TABLE orders (
  id                    TEXT PRIMARY KEY,
  product_id            TEXT NOT NULL REFERENCES products(id),
  vendor_id             TEXT NOT NULL REFERENCES vendors(id),
  amount_cents          INTEGER NOT NULL,
  platform_fee_cents    INTEGER NOT NULL,
  -- UNIQUE is what makes the webhook safe to retry. Stripe can
  -- deliver the same event more than once, and without this each
  -- delivery writes another paid order for the same payment.
  stripe_payment_intent TEXT NOT NULL UNIQUE,
  status                TEXT NOT NULL DEFAULT 'pending'
);

La columna stripe_account_id conecta tu base de datos con Stripe: permanece vacía hasta que un vendedor se registra, y es la cuenta a la que se dirigirán todos los pagos posteriormente.

Creación de un asistente para la base de datos

Mantén un pequeño asistente que te proporcione el enlace y nunca lo leas al principio de un módulo, ya que el enlace solo existe dentro de una solicitud:

// lib/db.ts
import { getCloudflareContext } from '@opennextjs/cloudflare'
import type { D1Database } from '@cloudflare/workers-types'

// Grab the DB binding at request time. Calling this at module scope would
// run before Webflow Cloud has attached the binding to the request context.
export function db(): D1Database {
  const { env } = getCloudflareContext()
  return env.DB as D1Database
}

Con el esquema migrado y el asistente listo, cualquier controlador posterior podrá acceder a los datos de tu marketplace con una simple consulta.

2. Crea un cliente de Stripe que se ejecute en el entorno de ejecución de Workers

Este paso solía confundir a todo el mundo, y vale la pena saber qué ha cambiado. La librería de Node de Stripe solía usar por defecto un transporte HTTP basado en node:https, que el entorno de ejecución de Workers no proporciona, por lo que la primera llamada a Stripe fallaba antes de llegar a su destino y tenías que pasar httpClient: Stripe.createFetchHttpClient() manualmente.

Las versiones actuales lo gestionan por sí mismas. El paquete stripe incluye una compilación dedicada para workers, seleccionada automáticamente mediante las condiciones de exportación worker y workerd que establece el entorno de ejecución de Workers, y en esa compilación, el cliente HTTP predeterminado ya es el cliente fetch.

Lo mismo ocurre con la criptografía: el proveedor predeterminado de la compilación de worker es SubtleCrypto.

Por lo tanto, el contenedor que aparece a continuación no establece ninguna opción de transporte:

// lib/stripe.ts
import Stripe from 'stripe'

// On the Workers runtime the `worker` export condition resolves the
// package to its worker build, whose defaults are already the fetch
// HTTP client and the SubtleCrypto provider. No httpClient override.
export function stripe(): Stripe {
  return new Stripe(process.env.STRIPE_SECRET_KEY!)
}

Si estás anclado a una versión principal antigua o heredas una base de código que pasa , déjalo: en las versiones actuales es redundante, no perjudicial. No lo añadas solo porque un tutorial diga que el SDK no puede funcionar de otra manera; eso ya no es cierto.httpClient: Stripe.createFetchHttpClient()

Sigue valiendo la pena envolver el cliente en una utilidad, por la sencilla razón de que te ofrece un único lugar donde leer la configuración. Leer desde mantiene el secreto en el lado del servidor; Webflow Cloud pone las variables de entorno a disposición de tu compilación y de la aplicación desplegada en tiempo de ejecución, por lo que la clave nunca llega al navegador.STRIPE_SECRET_KEYprocess.env

Guárdalo como un secreto en el panel de control de tu entorno para que permanezca cifrado y enmascarado.

3. Incorpora proveedores con Stripe Connect

Antes de que Stripe pueda pagar a un proveedor, necesita saber quién es y a dónde va su dinero. Stripe Connect se encarga de ello con una cuenta conectada y un flujo de incorporación alojado, para que nunca tengas que gestionar tú mismo los datos bancarios de un proveedor.

Creas una cuenta conectada para el proveedor, guardas su ID y le envías un enlace de un solo uso para que complete la incorporación en Stripe.

Fíjate en cómo se crea la cuenta, porque esta es la parte que la mayoría de los tutoriales siguen haciendo mal. El parámetro de Stripe está obsoleto; el comportamiento de la cuenta se configura ahora mediante propiedades de , que establecen quién paga las comisiones, quién asume las pérdidas y a qué panel de control tiene acceso el proveedor.type: 'express'controller

Pedir te da lo que antes significaba "una cuenta Express", sin el parámetro obsoleto.stripe_dashboard.type: 'express'

Crea :app/api/vendors/onboard/route.ts

// app/api/vendors/onboard/route.ts
import { NextResponse, type NextRequest } from 'next/server'
import { stripe } from '@/lib/stripe'
import { db } from '@/lib/db'

export async function POST(request: NextRequest) {
  const { vendorId } = (await request.json()) as { vendorId: string }
  const sql = db()
  const s = stripe()

  // Reuse an existing connected account if the vendor already started.
  const vendor = await sql
    .prepare('SELECT stripe_account_id FROM vendors WHERE id = ?')
    .bind(vendorId)
    .first<{ stripe_account_id: string | null }>()

  let accountId = vendor?.stripe_account_id ?? null

  // Otherwise create a connected account and save its ID against the vendor.
  if (!accountId) {
    const account = await s.accounts.create({
      // `type: 'express'` is deprecated. Configure the same behaviour
      // through controller properties instead.
      controller: {
        fees: { payer: 'application' },
        losses: { payments: 'application' },
        stripe_dashboard: { type: 'express' },
      },
      // `transfers` is the capability that makes a destination charge
      // legal. Without it the split payment has nowhere to go.
      capabilities: {
        card_payments: { requested: true },
        transfers: { requested: true },
      },
    })
    accountId = account.id
    await sql
      .prepare('UPDATE vendors SET stripe_account_id = ? WHERE id = ?')
      .bind(accountId, vendorId)
      .run()
  }

  // Return a single-use onboarding link the vendor opens on Stripe.
  const link = await s.accountLinks.create({
    account: accountId,
    refresh_url: `${process.env.APP_URL}/vendor/onboarding/refresh`,
    return_url: `${process.env.APP_URL}/vendor/dashboard`,
    type: 'account_onboarding',
  })

  return NextResponse.json({ url: link.url })
}

Redirige al proveedor al devuelto. Cuando vuelvan a tu , no lo tomes como prueba de nada. Volver a tu sitio solo significa que el flujo se inició y finalizó correctamente, no que Stripe haya recopilado toda la información o que la cuenta pueda recibir dinero. El webhook de en el paso seis es lo que cambia a verdadero, y el paso cinco se niega a realizar el cobro hasta que eso ocurra.urlreturn_urlaccount.updatedonboarded

Los enlaces de cuenta son de un solo uso y de corta duración, por lo que el controlador genera uno nuevo cada vez en lugar de almacenarlo.

4. Enumera los productos de cada proveedor desde la base de datos

Con los proveedores en la base de datos, la tienda puede mostrar lo que vende cada uno directamente desde tus propios datos, de modo que los listados nunca se desvíen de lo que realmente está a la venta. Como la lectura se ejecuta en un controlador de ruta, el navegador solo recibe los campos que decides devolver.

Crea :app/api/vendors/[id]/products/route.ts

// app/api/vendors/[id]/products/route.ts
import { NextResponse } from 'next/server'
import { db } from '@/lib/db'

export async function GET(
  _request: Request,
  { params }: { params: Promise<{ id: string }> }
) {
  const { id } = await params

  // Join through vendors so an un-onboarded vendor's products never
  // appear. Listing something nobody can pay for is worse than
  // listing nothing.
  const { results } = await db()
    .prepare(
      `SELECT p.id, p.title, p.price_cents
       FROM products p
       JOIN vendors v ON v.id = p.vendor_id
       WHERE p.vendor_id = ? AND p.active = 1 AND v.onboarded = 1`
    )
    .bind(id)
    .all()

  return NextResponse.json({ products: results })
}

El filtro mantiene los borradores privados sin necesidad de lógica en el frontend, el mismo instinto que quieres aplicar siempre que hay dinero de por medio: decide en el servidor, envía solo el resultado. Las imágenes de los productos son una buena opción para , así una cuadrícula de portadas grandes no ralentiza la página.active = 1

Ten en cuenta la promesa : en Next.js 15, que es el que ejecuta Webflow Cloud, los parámetros de ruta dinámica se esperan (await).params

5. Cobra a un cliente y divídelo con el proveedor

Este paso es lo que lo convierte en un marketplace. Cuando un cliente compra un producto, creas un cargo de destino de Stripe: el comprador paga a tu cuenta de plataforma, Stripe transfiere el saldo a la cuenta conectada del proveedor y redirige tu parte de la plataforma de vuelta a ti, todo en un solo pago.application_fee_amount

Crea :app/api/checkout/route.ts

// app/api/checkout/route.ts
import { NextResponse, type NextRequest } from 'next/server'
import { stripe } from '@/lib/stripe'
import { db } from '@/lib/db'

// The platform keeps 10% of every sale, in basis points.
const PLATFORM_FEE_BPS = 1000

export async function POST(request: NextRequest) {
  const { productId } = (await request.json()) as { productId: string }

  // Look up the product and its vendor's connected account server-side.
  const row = await db()
    .prepare(
      `SELECT p.id AS product_id, p.price_cents,
              v.id AS vendor_id, v.stripe_account_id, v.onboarded
       FROM products p
       JOIN vendors v ON v.id = p.vendor_id
       WHERE p.id = ? AND p.active = 1`
    )
    .bind(productId)
    .first<{
      product_id: string
      price_cents: number
      vendor_id: string
      stripe_account_id: string | null
      onboarded: number
    }>()

  // Gate on status, not presence. stripe_account_id is set the moment
  // the account is created, long before it can accept a charge.
  if (!row?.stripe_account_id || row.onboarded !== 1) {
    return NextResponse.json({ error: 'Vendor not payable' }, { status: 409 })
  }

  const fee = Math.round((row.price_cents * PLATFORM_FEE_BPS) / 10_000)

  const intent = await stripe().paymentIntents.create({
    amount: row.price_cents,
    currency: 'usd',
    application_fee_amount: fee,
    transfer_data: { destination: row.stripe_account_id },
    metadata: { product_id: row.product_id, vendor_id: row.vendor_id },
  })

  return NextResponse.json({ clientSecret: intent.client_secret })
}

Devuelve el a tu página de pago y confírmalo con Stripe.js en el navegador usando el Payment Element, que es la misma confirmación del lado del cliente que usarías para una tienda única. (Este es un flujo diferente al de Stripe Checkout, la página alojada, que no tiene un paso de confirmación de secreto de cliente de este tipo).client_secret

Una advertencia que afecta especialmente a los marketplaces: si tu plataforma y la cuenta del proveedor están en regiones diferentes, Stripe requiere que nombres a la cuenta conectada como el comerciante de liquidación con en el PaymentIntent.on_behalf_of

Las transferencias transfronterizas son compatibles entre EE. UU., Canadá, el Reino Unido, el EEE y Suiza; fuera de estas regiones, la plataforma y el proveedor deben compartir la misma. Es bueno saberlo antes de tener a tu primer proveedor internacional, no después.

Tanto el importe como la comisión se calculan en el servidor a partir del precio de la base de datos, nunca de una cifra enviada por el navegador, por lo que una solicitud manipulada no puede alterar lo que cobra el proveedor ni lo que tú conservas. Los campos llevan el producto y el proveedor hasta el webhook, donde finalmente se registra el pedido.metadata

6. Confirma el pedido pagado desde un webhook de Stripe

Una respuesta devuelta al navegador es una promesa, no una prueba. El pago aún puede fallar y el cliente puede cerrar la pestaña antes de que tu código reciba el resultado. Los webhooks de Stripe cierran esa brecha: Stripe llama a tu endpoint cuando el pago se realiza correctamente, y esa llamada es la que debes usar para registrar el pedido.client_secret

Crea :app/api/webhooks/stripe/route.ts

// app/api/webhooks/stripe/route.ts
import { NextResponse, type NextRequest } from 'next/server'
import Stripe from 'stripe'
import { stripe } from '@/lib/stripe'
import { db } from '@/lib/db'

export async function POST(request: NextRequest) {
  const body = await request.text()
  const signature = request.headers.get('stripe-signature') ?? ''

  let event: Stripe.Event
  try {
    // constructEventAsync, not constructEvent: verification runs on
    // SubtleCrypto, which is asynchronous, so the synchronous method
    // cannot be used here whatever else you configure. The worker
    // build already defaults to the SubtleCrypto provider, so there
    // is no provider argument to pass.
    event = await stripe().webhooks.constructEventAsync(
      body,
      signature,
      process.env.STRIPE_WEBHOOK_SECRET!
    )
  } catch {
    return NextResponse.json({ error: 'Invalid signature' }, { status: 400 })
  }

  if (event.type === 'payment_intent.succeeded') {
    const pi = event.data.object as Stripe.PaymentIntent

    // Not every payment_intent.succeeded came from this checkout.
    // A Dashboard payment or another feature arrives with no
    // metadata, and binding undefined into a NOT NULL column throws,
    // which Stripe then retries on its backoff schedule forever.
    if (!pi.metadata.product_id || !pi.metadata.vendor_id) {
      return NextResponse.json({ received: true })
    }

    // Stripe is the source of truth for the sale, not the browser.
    // OR IGNORE plus the UNIQUE constraint makes a duplicate delivery
    // a no-op rather than a second order.
    await db()
      .prepare(
        `INSERT OR IGNORE INTO orders
           (id, product_id, vendor_id, amount_cents,
            platform_fee_cents, stripe_payment_intent, status)
         VALUES (?, ?, ?, ?, ?, ?, 'paid')`
      )
      .bind(
        crypto.randomUUID(),
        pi.metadata.product_id,
        pi.metadata.vendor_id,
        pi.amount_received,
        pi.application_fee_amount ?? 0,
        pi.id
      )
      .run()
  }

  // The event that makes a vendor sellable. charges_enabled is the
  // field to trust, not the vendor having returned to your site.
  if (event.type === 'account.updated') {
    const account = event.data.object as Stripe.Account

    if (account.charges_enabled) {
      await db()
        .prepare('UPDATE vendors SET onboarded = 1 WHERE stripe_account_id = ?')
        .bind(account.id)
        .run()
    }
  }

  return NextResponse.json({ received: true })
}

Dos detalles hacen que esto sea fiable en Webflow Cloud. Verifica la firma con el método asíncrono en lugar del síncrono, ya que, en este entorno de ejecución, la verificación pasa por la Web Crypto API, que es asíncrona. Este es el único ajuste de Stripe que el entorno de ejecución de Workers todavía requiere.constructEventAsyncconstructEvent

Y el cuerpo se lee con un método específico antes de que cualquier otra cosa lo toque, ya que la firma se calcula sobre el payload original exacto. Apunta Stripe a esta URL en el panel de control y suscríbete a exactamente dos eventos: el primero y el segundo.request.text()payment_intent.succeededaccount.updated

Suscríbete solo a lo que vayas a gestionar, ya que cada tipo de evento adicional es tráfico que tu endpoint debe procesar y rechazar correctamente.

La rama de verificación es la que cierra el ciclo del paso tres. Stripe la envía a medida que avanza la verificación de un proveedor, y el momento en que esta se vuelve verdadera es cuando realmente pueden recibir pagos, que es lo que bloquea el paso cinco.account.updatedcharges_enabled

¿Qué es lo que hace que un marketplace de múltiples proveedores falle en Webflow Cloud?

La mayoría de los fallos se deben a un puñado de causas predecibles:

  • Una lectura de enlace de base de datos al cargar el módulo en lugar de dentro de una solicitud.
  • Un pago enviado a un proveedor cuyo proceso de registro no ha finalizado.
  • Un webhook verificado con el método síncrono o con un cuerpo ya analizado.
  • El cliente de Stripe resolviéndose a su versión de Node en lugar de a su versión para workers.

Cada uno suele fallar con un error genérico, por lo que los síntomas a continuación te ayudarán a identificar la causa.

La primera llamada a Stripe lanza un error o se agota el tiempo de espera tras el despliegue.

Este es el síntoma clásico de que el SDK se resuelve a su versión de Node en lugar de a la de worker, por lo que el cliente intenta un transporte que el entorno de ejecución no implementa. La llamada falla antes de llegar a Stripe, generalmente como un error de conexión o de módulo sin ningún código de estado de Stripe asociado.node:https

En las versiones actuales, la versión para worker se selecciona automáticamente, así que empieza por comprobar tu versión del SDK en lugar de recurrir a la vieja solución alternativa.stripe

Si estás en una versión reciente y sigues viendo esto, la condición de exportación no está llegando al resolvedor que empaqueta tu manejador, y pasar el parámetro explícitamente es la salida de emergencia que soluciona el problema.workerhttpClient: Stripe.createFetchHttpClient()

El webhook devuelve un error 400, o faltan todos los pedidos.

The signature check is failing, so the handler rejects real events. On the Workers runtime, this almost always means one of two things: you called the synchronous constructEvent instead of constructEventAsync, or you read and re-serialized the JSON body before verifying it.

La verificación de la firma está fallando, por lo que el controlador rechaza los eventos reales. En el entorno de ejecución de Workers, esto casi siempre significa una de dos cosas: llamaste al método síncronoawait stripe().webhooks.constructEventAsync(...)request.text()request.json()request.json(),

en lugar deSTRIPE_WEBHOOK_SECRET

, o leíste y volviste a serializar el cuerpo JSON antes de verificarlo.

getCloudflareContext() was called at the top level of a module, before Webflow Cloud attached the binding to the request. The binding reads as undefined, and the first query throws an exception.

Verifica congetCloudflareContext()db()bindingwrangler.jsonDBwrangler.json

y lee el cuerpo sin procesar con

en lugar de

. Una vez que el cuerpo ha pasado poronboardedstripe_account_id

, los bytes exactos que Stripe firmó desaparecen y no hay forma de reconstruirlos volviéndolos a convertir en cadena.onboarded = 1account.updatedcharges_enabled

Wrapping the payment and webhook handlers in Sentry error tracking surfaces these Stripe errors with a stack trace the first time they happen instead of as a silent failed sale.

Confirma que

coincide con el secreto de firma que aparece para ese punto de conexión específico en el panel de control de Stripe, ya que cada punto de conexión tiene el suyo propio.

A vendor dashboard is the most common next build. With orders already in SQLite, you can total each vendor's sales and fees and render a real earnings view, the kind of authenticated, data-driven screen covered in our real-time dashboard guide.

El enlace a la base de datos no está definido

If your catalog is single-seller rather than multi-vendor, you do not need Connect at all, and our guide to selling digital products covers that simpler build with Checkout Sessions.

se llamó en el nivel superior de un módulo, antes de que Webflow Cloud adjuntara el enlace a la solicitud. El enlace se lee como

Preguntas frecuentes

, y la primera consulta lanza una excepción.

You need a database for the transactional data. The Webflow CMS is a great fit for the storefront and the vendor and product content you want styled and indexed, but orders, connected-account IDs, and payout records belong in the SQLite binding, where they can be written from a webhook and queried on the fly. Many marketplaces run both: the CMS for display and SQLite for the money.

Llama a

Piensa en términos de propiedades del controlador en lugar de tipos de cuenta, ya que así es como Stripe lo modela ahora. El parámetro type está obsoleto, y lo que antes era "una cuenta Express" ahora es controller.stripe_dashboard.type: 'express' con las comisiones y pérdidas asignadas a tu plataforma, que es lo que utiliza esta guía.

Esa configuración suele encajar en un marketplace: Stripe gestiona el registro y ofrece a los vendedores un panel simplificado, mientras que tu plataforma controla el flujo de pagos y las comisiones. Los vendedores que deseen su propia cuenta y panel de Stripe completos se asignan al tipo de panel standard en su lugar. Ambos funcionan con cargos de destino, por lo que el código de pago no cambia en ninguno de los dos casos.

¿Funciona el SDK de Stripe en el entorno de ejecución Workers de Webflow Cloud?

Sí, y en las versiones actuales no necesita configuración de transporte. El paquete incluye una compilación para workers que el entorno de ejecución selecciona automáticamente, y esa compilación ya utiliza por defecto el cliente HTTP fetch y el proveedor SubtleCrypto.

Una cosa sí cambia: verifica los webhooks con constructEventAsync en lugar del constructEvent síncrono. Esto no depende de los valores predeterminados; SubtleCrypto es asíncrono por naturaleza, por lo que el método síncrono no puede utilizarlo, independientemente de tu configuración.

¿Cómo cobran los vendedores y cómo ven sus ganancias?

Con los cargos de destino, Stripe transfiere automáticamente el saldo de cada venta a la cuenta conectada del vendedor, menos tu application_fee_amount, y realiza los pagos según el calendario de la cuenta. Los vendedores pueden ver sus saldos y pagos a través del panel Express alojado en Stripe, al que accedes generando un enlace de inicio de sesión con accounts.createLoginLink, y puedes mostrar tu propio resumen de ganancias desde la tabla orders.

¿Puedo crear la tienda en el Diseñador de Webflow en lugar de en Next.js?

Sí. El Diseñador puede encargarse de todo lo que ve el cliente, mientras tu aplicación de Webflow Cloud gestiona el registro, el pago y los webhooks mediante Route Handlers para el front-end. Como una aplicación de Webflow Cloud se monta en una ruta base como /app, construye las URLs de solicitud desde tu basePath en lugar de codificar una barra diagonal inicial, para que las llamadas se resuelvan desde la raíz correcta.


Última actualización
September 4, 2026
Categoría

Artículos relacionados


verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logoreddit logothe new york times logoideo logoupwork logodiscord logo
verifone logomonday.com logospotify logoted logogreenhouse logoclear logocheckout.com logoreddit logothe new york times logoideo logoupwork logodiscord logo

Empieza gratis

Prueba Webflow todo el tiempo que quieras con nuestro plan Starter gratuito. Compra un plan de sitio de pago para publicar, alojar y desbloquear funciones adicionales.

Empieza, es gratis
Ver demostración

Prueba Webflow todo el tiempo que quieras con nuestro plan Starter gratuito. Compra un plan de sitio de pago para publicar, alojar y desbloquear funciones adicionales.