Skip to content

Gestión de Pagos (Managing Payments)

La infraestructura de pagos de Yastubo está diseñada para manejar tanto la simplicidad de un pago único como la complejidad de suscripciones recurrentes y distribución de comisiones mediante Stripe Connect.

  • Pila de Pagos Híbrida: Soporte para One-time payments y Subscriptions con Stripe.
  • Modelo Marketplace (Connect): Gestión automática de comisiones para revendedores (resellers).
  • Confirmación Asíncrona: Uso de Webhooks para garantizar que el estado de la póliza sea coherente con la realidad bancaria.
  • Gestión de Cobros Manuales: Capacidad de registrar pagos fuera de Stripe (manuales) para mayor flexibilidad.

El sistema decide el tipo de pago basándose en la configuración del plan:

  • One-time: Utiliza PaymentIntents directamente.
  • Subscription: Crea un Price en Stripe vinculado a un producto, permitiendo cobros mensuales automáticos.

Para los socios comerciales (vendedores/revendedores), Yastubo utiliza Stripe Connect (Standard/Express). Cuando se crea una suscripción a través de un revendedor, se aplica una application_fee_percent (tasa de comisión) definida en el Company del socio.

Cada intento de pago genera un registro en la tabla Transaction. Este registro actúa como el nexo entre la póliza y los eventos de Stripe.

Fragmento de la lógica de creación de suscripciones (app/modules/payments/service.py):

@audited(action="SUBSCRIPTION_CREATED", entity="Policy")
async def create_subscription(
db: AsyncSession, stripe: StripeClient, data: CreateSubscriptionRequest
) -> Subscription:
# 1. Obtener la póliza y el espacio de trabajo (Company)
policy = await emission_service.get_policy(db, data.policy_id)
company = await get_company(db, policy.company_id)
# 2. Configurar Connect Account si es un revendedor
connect_account_id = company.stripe_connect_id if company.is_reseller else None
app_fee = float(company.commission_rate) if company.commission_rate > 0 else None
# 3. Crear suscripción en Stripe
stripe_sub = await stripe.create_subscription(
customer_id=policy.client.stripe_customer_id,
price_id=plan.stripe_price_id,
connect_account_id=connect_account_id,
application_fee_percent=app_fee,
metadata={"policy_id": str(policy.id)}
)
# 4. Persistir suscripción localmente
sub = Subscription(
policy_id=policy.id,
stripe_subscription_id=stripe_sub["id"],
status=stripe_sub["status"].upper(),
# ... otros campos
)
db.add(sub)
await db.commit()
return sub
  1. connect_account_id: Si está presente, Stripe sabe que el pago se procesa a nombre de un tercero, activando el flujo de Marketplace.
  2. application_fee_percent: Define qué porcentaje de la transacción retiene la plataforma Yastubo antes de liquidar al socio.
  3. metadata: Guardar el policy_id en Stripe es vital para que los Webhooks sepan qué póliza actualizar cuando llegue el evento invoice.paid.

[FLOW: El nodo “Cliente” con contenido “Ingresa tarjeta” se conecta al nodo “Stripe API” con contenido “Verificación 3DS”, indicando que si es exitoso se dispara el webhook “invoice.paid” hacia el backend, el cual transiciona la póliza de “PENDING_PAYMENT” a “ACTIVE”].