trading-platform/docs/02-definicion-modulos/OQI-005-payments-stripe/especificaciones/ET-PAY-004-api.md
rckrdmrd a7cca885f0 feat: Major platform documentation and architecture updates
Changes include:
- Updated architecture documentation
- Enhanced module definitions (OQI-001 to OQI-008)
- ML integration documentation updates
- Trading strategies documentation
- Orchestration and inventory updates
- Docker configuration updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 05:33:35 -06:00

4.5 KiB

id title type status priority epic project version created_date updated_date
ET-PAY-004 API REST Payments Technical Specification Done Alta OQI-005 trading-platform 1.0.0 2025-12-05 2026-01-04

ET-PAY-004: API REST Payments

Epic: OQI-005 Pagos y Stripe Versión: 1.0 Fecha: 2025-12-05


1. Endpoints Payments

POST /api/v1/payments/intent

Crea Payment Intent para pago one-time

Request:

{
  "amount": 99.99,
  "payment_method_id": "pm_...",
  "description": "Premium course purchase"
}

Response 200:

{
  "success": true,
  "data": {
    "payment_intent_id": "pi_...",
    "client_secret": "pi_..._secret_...",
    "status": "requires_confirmation"
  }
}

GET /api/v1/payments

Lista pagos del usuario

Response 200:

{
  "success": true,
  "data": {
    "payments": [
      {
        "id": "uuid",
        "amount": 99.99,
        "status": "succeeded",
        "description": "Premium course",
        "created_at": "2025-01-20T10:00:00Z"
      }
    ]
  }
}

POST /api/v1/payments/:id/refund

Solicita reembolso (admin)

Request:

{
  "reason": "requested_by_customer",
  "amount": 99.99
}

2. Endpoints Subscriptions

POST /api/v1/subscriptions

Crea suscripción

Request:

{
  "price_id": "price_...",
  "payment_method_id": "pm_..."
}

GET /api/v1/subscriptions

Lista suscripciones activas


DELETE /api/v1/subscriptions/:id

Cancela suscripción

Query: ?immediate=false


3. Endpoints Payment Methods

POST /api/v1/payment-methods

Guarda método de pago

Request:

{
  "payment_method_id": "pm_..."
}

GET /api/v1/payment-methods

Lista métodos guardados


DELETE /api/v1/payment-methods/:id

Elimina método de pago


4. Implementation

// src/modules/payments/payment.controller.ts

export class PaymentController {
  async createPaymentIntent(req: Request, res: Response) {
    const { amount, payment_method_id, description } = req.body;
    const userId = req.user!.id;

    const result = await paymentService.createPaymentIntent({
      user_id: userId,
      amount,
      payment_method_id,
      description,
    });

    return successResponse(res, result, 200);
  }

  async getPayments(req: Request, res: Response) {
    const userId = req.user!.id;
    const { status, limit = 20, offset = 0 } = req.query;

    const payments = await paymentService.getPayments({
      user_id: userId,
      status,
      limit: Number(limit),
      offset: Number(offset),
    });

    return successResponse(res, payments, 200);
  }

  async requestRefund(req: Request, res: Response) {
    const { id } = req.params;
    const { reason, amount } = req.body;

    const refund = await paymentService.createRefund({
      payment_id: id,
      reason,
      amount,
    });

    return successResponse(res, refund, 200);
  }
}

5. Validations

// Zod schemas
export const createPaymentIntentSchema = z.object({
  amount: z.number().positive(),
  payment_method_id: z.string().min(1),
  description: z.string().optional(),
});

export const createSubscriptionSchema = z.object({
  price_id: z.string().startsWith('price_'),
  payment_method_id: z.string().min(1),
  trial_days: z.number().optional(),
});

export const refundSchema = z.object({
  reason: z.enum(['duplicate', 'fraudulent', 'requested_by_customer']),
  amount: z.number().positive().optional(),
});

6. Routes

// src/modules/payments/payment.routes.ts

const router = Router();

// Payments
router.post('/intent', authenticate, validate(createPaymentIntentSchema), controller.createPaymentIntent);
router.get('/', authenticate, controller.getPayments);
router.post('/:id/refund', authenticate, requireAdmin, validate(refundSchema), controller.requestRefund);

// Subscriptions
router.post('/subscriptions', authenticate, validate(createSubscriptionSchema), subscriptionController.create);
router.get('/subscriptions', authenticate, subscriptionController.list);
router.delete('/subscriptions/:id', authenticate, subscriptionController.cancel);

// Payment Methods
router.post('/payment-methods', authenticate, paymentMethodController.save);
router.get('/payment-methods', authenticate, paymentMethodController.list);
router.delete('/payment-methods/:id', authenticate, paymentMethodController.delete);
router.patch('/payment-methods/:id/default', authenticate, paymentMethodController.setDefault);

export default router;