Marketplace móvil para negocios locales mexicanos. Estructura inicial: - apps/backend (NestJS API) - apps/frontend (React Web) - apps/mobile (Expo/React Native) - apps/mcp-server (Claude MCP Server) - apps/whatsapp-service (WhatsApp Business API) - database/ (PostgreSQL DDL) - docs/ (Documentación) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
160 lines
5.7 KiB
JavaScript
160 lines
5.7 KiB
JavaScript
"use strict";
|
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
};
|
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
};
|
|
var StripeService_1;
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.StripeService = void 0;
|
|
const common_1 = require("@nestjs/common");
|
|
const config_1 = require("@nestjs/config");
|
|
const stripe_1 = require("stripe");
|
|
let StripeService = StripeService_1 = class StripeService {
|
|
constructor(configService) {
|
|
this.configService = configService;
|
|
this.logger = new common_1.Logger(StripeService_1.name);
|
|
const secretKey = this.configService.get('STRIPE_SECRET_KEY');
|
|
if (!secretKey) {
|
|
this.logger.warn('STRIPE_SECRET_KEY not configured - billing features disabled');
|
|
return;
|
|
}
|
|
this.stripe = new stripe_1.default(secretKey);
|
|
}
|
|
ensureStripe() {
|
|
if (!this.stripe) {
|
|
throw new Error('Stripe not configured');
|
|
}
|
|
}
|
|
async createCustomer(params) {
|
|
this.ensureStripe();
|
|
return this.stripe.customers.create({
|
|
email: params.email,
|
|
phone: params.phone,
|
|
name: params.name,
|
|
metadata: {
|
|
tenantId: params.tenantId,
|
|
},
|
|
});
|
|
}
|
|
async getCustomer(customerId) {
|
|
this.ensureStripe();
|
|
try {
|
|
const customer = await this.stripe.customers.retrieve(customerId);
|
|
return customer.deleted ? null : customer;
|
|
}
|
|
catch (error) {
|
|
return null;
|
|
}
|
|
}
|
|
async createSubscription(params) {
|
|
this.ensureStripe();
|
|
const subscriptionParams = {
|
|
customer: params.customerId,
|
|
items: [{ price: params.priceId }],
|
|
payment_behavior: 'default_incomplete',
|
|
payment_settings: {
|
|
save_default_payment_method: 'on_subscription',
|
|
},
|
|
expand: ['latest_invoice.payment_intent'],
|
|
};
|
|
if (params.trialDays) {
|
|
subscriptionParams.trial_period_days = params.trialDays;
|
|
}
|
|
return this.stripe.subscriptions.create(subscriptionParams);
|
|
}
|
|
async cancelSubscription(subscriptionId) {
|
|
this.ensureStripe();
|
|
return this.stripe.subscriptions.cancel(subscriptionId);
|
|
}
|
|
async getSubscription(subscriptionId) {
|
|
this.ensureStripe();
|
|
try {
|
|
return await this.stripe.subscriptions.retrieve(subscriptionId);
|
|
}
|
|
catch (error) {
|
|
return null;
|
|
}
|
|
}
|
|
async updateSubscription(subscriptionId, params) {
|
|
this.ensureStripe();
|
|
return this.stripe.subscriptions.update(subscriptionId, params);
|
|
}
|
|
async createPaymentIntent(params) {
|
|
this.ensureStripe();
|
|
return this.stripe.paymentIntents.create({
|
|
amount: params.amount,
|
|
currency: 'mxn',
|
|
customer: params.customerId,
|
|
metadata: params.metadata || {},
|
|
automatic_payment_methods: {
|
|
enabled: true,
|
|
},
|
|
});
|
|
}
|
|
async createCheckoutSession(params) {
|
|
this.ensureStripe();
|
|
return this.stripe.checkout.sessions.create({
|
|
customer: params.customerId,
|
|
mode: params.mode,
|
|
line_items: [{ price: params.priceId, quantity: 1 }],
|
|
success_url: params.successUrl,
|
|
cancel_url: params.cancelUrl,
|
|
metadata: params.metadata || {},
|
|
locale: 'es',
|
|
payment_method_types: params.mode === 'subscription'
|
|
? ['card']
|
|
: ['card', 'oxxo'],
|
|
});
|
|
}
|
|
async createPortalSession(params) {
|
|
this.ensureStripe();
|
|
return this.stripe.billingPortal.sessions.create({
|
|
customer: params.customerId,
|
|
return_url: params.returnUrl,
|
|
});
|
|
}
|
|
constructWebhookEvent(payload, signature, webhookSecret) {
|
|
this.ensureStripe();
|
|
return this.stripe.webhooks.constructEvent(payload, signature, webhookSecret);
|
|
}
|
|
async createProduct(params) {
|
|
this.ensureStripe();
|
|
return this.stripe.products.create({
|
|
name: params.name,
|
|
description: params.description,
|
|
metadata: params.metadata || {},
|
|
});
|
|
}
|
|
async createPrice(params) {
|
|
this.ensureStripe();
|
|
const priceParams = {
|
|
product: params.productId,
|
|
unit_amount: params.unitAmount,
|
|
currency: 'mxn',
|
|
metadata: params.metadata || {},
|
|
};
|
|
if (params.recurring) {
|
|
priceParams.recurring = params.recurring;
|
|
}
|
|
return this.stripe.prices.create(priceParams);
|
|
}
|
|
async listInvoices(customerId, limit = 10) {
|
|
this.ensureStripe();
|
|
const invoices = await this.stripe.invoices.list({
|
|
customer: customerId,
|
|
limit,
|
|
});
|
|
return invoices.data;
|
|
}
|
|
};
|
|
exports.StripeService = StripeService;
|
|
exports.StripeService = StripeService = StripeService_1 = __decorate([
|
|
(0, common_1.Injectable)(),
|
|
__metadata("design:paramtypes", [config_1.ConfigService])
|
|
], StripeService);
|
|
//# sourceMappingURL=stripe.service.js.map
|