feat: agregar envío de correos electrónicos para planes aprobados y mejorar el formato de fecha y monto
This commit is contained in:
@@ -6,6 +6,9 @@ import dayjs from "dayjs";
|
||||
import PlanPaymentsList from "../../Models/PlanPayments/PlanPayments";
|
||||
import { IPlanSuscriptionDocument } from "../../Models/PlanSubscriptions/PlanSubscriptions.Adapter.Mongoose";
|
||||
import { VerifyPendingPlanPaymentResponse } from "../../Models/PlanSubscriptions/PlanSubscriptions.interface";
|
||||
import PlansList from "../../Models/Plans/Plans";
|
||||
import UserList from "../../Models/Users/Users";
|
||||
import { NotificationsManager } from "../../Models/Notifications/Notifications";
|
||||
|
||||
type MercadoPagoPaymentData = {
|
||||
id: string | number;
|
||||
@@ -41,6 +44,66 @@ type MercadoPagoPaymentVerification = {
|
||||
const REJECTED_PAYMENT_STATUSES = ["rejected", "cancelled", "failed"];
|
||||
|
||||
export class MercadoPagoWebhookService {
|
||||
private formatTemplateDate(date: Date): string {
|
||||
return new Intl.DateTimeFormat("es-AR", {
|
||||
day: "2-digit",
|
||||
month: "2-digit",
|
||||
year: "numeric",
|
||||
}).format(date);
|
||||
}
|
||||
|
||||
private formatTemplateAmount(amount: number): string {
|
||||
return new Intl.NumberFormat("es-AR", {
|
||||
style: "currency",
|
||||
currency: "ARS",
|
||||
}).format(amount);
|
||||
}
|
||||
|
||||
private async sendApprovedPaidPlanEmail(
|
||||
subscription: IPlanSuscriptionDocument,
|
||||
paymentData: MercadoPagoPaymentData,
|
||||
userId: string,
|
||||
approvedAt: Date,
|
||||
periodStart: Date
|
||||
): Promise<void> {
|
||||
try {
|
||||
const plan = await PlansList.findOne({ _id: String(subscription.planId) });
|
||||
|
||||
if (plan.price <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const user = await UserList.users.findOne({ _id: userId });
|
||||
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
|
||||
await NotificationsManager.sendEmail({
|
||||
email: user.email,
|
||||
templateId: "6a85ebb1323720a53d0cfd3f",
|
||||
context: {
|
||||
username: user.firstName || user.email,
|
||||
nombre_plan: plan.name,
|
||||
importe: this.formatTemplateAmount(paymentData.transaction_amount || 0),
|
||||
fecha_pago: this.formatTemplateDate(approvedAt),
|
||||
periodo_desde: this.formatTemplateDate(periodStart),
|
||||
periodo_hasta: this.formatTemplateDate(subscription.endDate),
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
if (axios.isAxiosError(e)) {
|
||||
console.error("Error enviando email de pago de plan aprobado:", {
|
||||
status: e.response?.status,
|
||||
data: e.response?.data,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.error("Error enviando email de pago de plan aprobado:", e);
|
||||
}
|
||||
}
|
||||
|
||||
public async handleWebhook(body: any): Promise<void> {
|
||||
await connect(`${process.env.DATABASE_CONNECTION}`);
|
||||
|
||||
@@ -300,6 +363,9 @@ export class MercadoPagoWebhookService {
|
||||
const periodStart = isExtensionPayment && dayjs(subscription.endDate).isAfter(approvedAt)
|
||||
? subscription.endDate
|
||||
: approvedAt;
|
||||
const transactionId = String(paymentData.id);
|
||||
const existingPayments = await PlanPaymentsList.find({ transactionId });
|
||||
const shouldSendApprovedPaymentEmail = existingPayments.length === 0;
|
||||
|
||||
if (isUpgradePayment && subscription.pendingPaymentPlanId) {
|
||||
subscription.planId = subscription.pendingPaymentPlanId;
|
||||
@@ -342,8 +408,12 @@ export class MercadoPagoWebhookService {
|
||||
paymentDate: approvedAt,
|
||||
paymentMethod: paymentData.payment_method_id || paymentData.payment_type_id || "mercadopago",
|
||||
status: "completed",
|
||||
transactionId: String(paymentData.id),
|
||||
transactionId,
|
||||
});
|
||||
|
||||
if (shouldSendApprovedPaymentEmail) {
|
||||
await this.sendApprovedPaidPlanEmail(subscription, paymentData, userId, approvedAt, periodStart);
|
||||
}
|
||||
}
|
||||
|
||||
private async applyRejectedPayment(
|
||||
|
||||
Reference in New Issue
Block a user