Skip to content

Servicio de Checkout con Stripe

Este servicio encapsula toda la lógica necesaria para crear una sesión de pago en Stripe. Se encuentra diseñado para funcionar dentro del entorno de Strapi y se invoca desde el controlador de checkout. Su objetivo es mantener la lógica separada, limpia y reutilizable.


src/api/checkout/services/stripe.ts


import Stripe from "stripe";
import {
DNI,
LABEL_DNI,
TYPE_TEXT,
CUSTOM,
AUTO,
REQUIRED,
PAYMENT_SAVE,
PAYMENT_FILTERS,
FUTURE_USSAGE,
} from "../../../constants/structures/collections/checkout";
import { selectStripeCrm } from "../../../utils/stripe-crm";
import { StripeCrmName } from "../../../type/stripe";
export default () => ({
async createCheckoutSession(
customer: Stripe.Customer,
payment_method_types: Stripe.Checkout.SessionCreateParams.PaymentMethodType[],
line_items: Stripe.Checkout.SessionCreateParams.LineItem[],
mode: Stripe.Checkout.SessionCreateParams.Mode,
success_url: string,
cancel_url: string,
payment_intent_data: Stripe.Checkout.SessionCreateParams.PaymentIntentData,
validVertical: string,
origin: StripeCrmName
): Promise<Stripe.Checkout.Session | undefined> {
const stripe = await selectStripeCrm(origin);
try {
const checkout = await stripe.checkout.sessions.create({
customer: customer.id,
custom_fields: [
{
key: DNI,
label: {
custom: LABEL_DNI,
type: CUSTOM,
},
type: TYPE_TEXT,
},
],
payment_method_types,
line_items,
mode,
success_url,
cancel_url,
payment_intent_data,
saved_payment_method_options: {
payment_method_save: PAYMENT_SAVE,
allow_redisplay_filters: PAYMENT_FILTERS,
},
payment_method_options: {
card: {
setup_future_usage: FUTURE_USSAGE,
},
},
automatic_tax: { enabled: true },
customer_update: { name: AUTO, address: AUTO },
billing_address_collection: REQUIRED,
allow_promotion_codes: true,
metadata: { vertical: validVertical },
});
return checkout;
} catch (error) {
console.error(error);
}
},
});

-Este es el servicio que se encarga de crear el checkout como tal


const stripe = await selectStripeCrm(origin);

Se inicializa una instancia de Stripe usando una clave secreta definida en las variables de entorno. Esta clave se extrae usando la función selectStripeCrm y enviando el origin


export default () => ({ ... })

Esta función devuelve un objeto con los métodos disponibles del servicio. Esto permite inyectar o instanciar el servicio según sea necesario.


async createCheckoutSession(
customer: Stripe.Customer,
payment_method_types: Stripe.Checkout.SessionCreateParams.PaymentMethodType[],
line_items: Stripe.Checkout.SessionCreateParams.LineItem[],
mode: Stripe.Checkout.SessionCreateParams.Mode,
success_url: string,
cancel_url: string,
payment_intent_data: Stripe.Checkout.SessionCreateParams.PaymentIntentData,
validVertical: string,
origin: StripeCrmName,
): Promise<Stripe.Checkout.Session | undefined>

Esta función es la encargada de crear la sesión de pago con todos los parámetros necesarios. Está fuertemente tipada usando los tipos del SDK de Stripe.

  • customer: objeto del cliente de Stripe.
  • payment_method_types: métodos de pago permitidos (por ejemplo: ['card']).
  • line_items: productos o servicios a pagar.
  • mode: modo de la sesión (payment, subscription, etc).
  • success_url: URL a redirigir tras pago exitoso.
  • cancel_url: URL si el usuario cancela.
  • payment_intent_data: metadatos y configuraciones del intent de pago.
  • validVertical: categoría del negocio, como ‘Hospitales’, ‘Veterinarias’, etc.

const checkout = await stripe.checkout.sessions.create({
customer: customer.id,
custom_fields: [
{
key: DNI,
label: {
custom: LABEL_DNI,
type: CUSTOM,
},
type: TYPE_TEXT,
},
],
payment_method_types,
line_items,
mode,
success_url,
cancel_url,
payment_intent_data,
saved_payment_method_options: {
payment_method_save: PAYMENT_SAVE,
allow_redisplay_filters: PAYMENT_FILTERS,
},
payment_method_options: {
card: {
setup_future_usage: FUTURE_USSAGE,
},
},
automatic_tax: { enabled: true },
customer_update: { name: AUTO, address: AUTO },
billing_address_collection: REQUIRED,
allow_promotion_codes: true,
metadata: { vertical: validVertical },
});
  • custom_fields: se agrega un campo adicional para solicitar el DNI, CURP, o similar, según lo requerido por el negocio.
  • saved_payment_method_options: permite guardar métodos de pago para uso futuro.
  • payment_method_options: configura opciones para tarjetas como el uso “off_session”, es decir que se almacene el metodo de pago para compras automaticas, esto unicamente para compras hechas con “Card”.
  • automatic_tax: activa el cálculo automático de impuestos según la ubicación del cliente.
  • customer_update: permite a Stripe actualizar automáticamente nombre y dirección del cliente si es necesario.
  • billing_address_collection: obliga al usuario a ingresar su dirección de facturación.
  • allow_promotion_codes: habilita el uso de cupones.
  • metadata: agrega el campo vertical para identificar a qué vertical pertenece la transacción.

} catch (error) {
console.error(error);
}

Cualquier error que ocurra durante la creación de la sesión se captura e imprime en consola. Esto ayuda a depurar errores sin interrumpir por completo el flujo del servidor.


A continuación, se muestra un ejemplo de cuerpo (payload) que puedes enviar en una solicitud POST para probar el endpoint de creación de sesión de checkout:

POST http://localhost:1337/api/create-checkout-session
{
"payment_method_types": ["card", "paypal"],
"mode": "payment",
"success_url": "https://edificiohospital.alebateducation.com/gracias/?message=purchase",
"cancel_url": "https://edificiohospital.alebateducation.com/carrito",
"payment_intent_data": {},
"origin": "Alebat",
"vertical": "Edificio Hospital",
"customer_email": "patricia.puerto@alebateducation.com",
"line_items": [
{
"price_data": {
"currency": "eur",
"product": "prod_Ryf8NItzQxisnM",
"unit_amount_decimal": 2000
},
"quantity": 1,
"adjustable_quantity": {
"enabled": false
}
}
],
"metadata": {
"laab_fetch": "[{\"id_stripe\":\"prod_QCTeVuDgvAZVer\",\"price\":100,\"discount_percentage\":10,\"SKU\":\"FOR-MA-AR-12\"}]",
"vertical": "Edificio Hospital",
"origin": "Alebat"
}
}
{
"payment_method_types": ["card", "paypal"],
"mode": "payment",
"success_url": "https://edificiohospital.alebateducation.com/gracias/?message=purchase",
"cancel_url": "https://edificiohospital.alebateducation.com/carrito",
"payment_intent_data": {},
"origin": "Inspiria",
"vertical": "Edificio Hospital",
"customer_email": "patricia.puerto@alebateducation.com",
"line_items": [
{
"price_data": {
"currency": "eur",
"product": "prod_S0cvoGuLErm7gQ",
"unit_amount_decimal": 2000
},
"quantity": 1,
"adjustable_quantity": {
"enabled": false
}
}
],
"metadata": {
"laab_fetch": "[{\"id_stripe\":\"prod_QCTeVuDgvAZVer\",\"price\":100,\"discount_percentage\":10,\"SKU\":\"FOR-MA-AR-12\"}]",
"vertical": "Edificio Hospital",
"origin": "Inspiria"
}
}