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

237 lines
4.5 KiB
Markdown

---
id: "ET-PAY-004"
title: "API REST Payments"
type: "Technical Specification"
status: "Done"
priority: "Alta"
epic: "OQI-005"
project: "trading-platform"
version: "1.0.0"
created_date: "2025-12-05"
updated_date: "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:**
```json
{
"amount": 99.99,
"payment_method_id": "pm_...",
"description": "Premium course purchase"
}
```
**Response 200:**
```json
{
"success": true,
"data": {
"payment_intent_id": "pi_...",
"client_secret": "pi_..._secret_...",
"status": "requires_confirmation"
}
}
```
---
### GET `/api/v1/payments`
Lista pagos del usuario
**Response 200:**
```json
{
"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:**
```json
{
"reason": "requested_by_customer",
"amount": 99.99
}
```
---
## 2. Endpoints Subscriptions
### POST `/api/v1/subscriptions`
Crea suscripción
**Request:**
```json
{
"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:**
```json
{
"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
```typescript
// 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
```typescript
// 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
```typescript
// 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;
```