برنامه نویسی

برای تنظیم Flutterwave با TypeScript، Express.js، Sequelize و PostgreSQL به کمک نیاز دارید

Summarize this content to 400 words in Persian Lang
سلام انجمن DEV،

من در حال حاضر روی ادغام Flutterwave در برنامه خود کار می کنم که با TypeScript، Express.js، Sequelize و PostgreSQL ساخته شده است. با این حال، من با چند چالش روبرو بوده ام و از هر گونه راهنمایی یا منبعی که می توانید به اشتراک بگذارید قدردانی می کنم.

در اینجا خلاصه ای از کارهایی است که من تاکنون انجام داده ام:

بسته flutterwave-node-v3 را نصب کردم و آن را با کلیدهای عمومی و مخفی خود پیکربندی کردم.
توابع TypeScript را برای مقداردهی اولیه و تأیید پرداخت ایجاد کرد.
از Sequelize برای مدل سازی جداول پایگاه داده من (به عنوان مثال، بلیط ها و رویدادها) استفاده کرد.

مشکلات پیش آمده:الف هنگام تماس با flw.initializePayment، این خطا را دریافت می کنم:TypeError: initializePayment یک تابع نیست.ب افزودن پشتیبانی TypeScript دشوار است زیرا هیچ نوع رسمی TypeScript برای flutterwave-node-v3 وجود ندارد و نوشتن اعلان‌های نوع سفارشی مشکل را حل نکرده است.ج برای درک بهترین روش‌ها برای رسیدگی به تماس‌های ناهمزمان و به‌روزرسانی وضعیت رویداد و بلیط در پایگاه داده به کمک نیاز دارید.

آنچه من امتحان کرده ام:

// src/types/flutterwave-node-v3.d.ts
declare module ‘flutterwave-node-v3’ {
// TypeScript interfaces for the Flutterwave response and request types
export interface PaymentInitiateResponse {
status: string;
message: string;
data: {
link: string;
};
}

export interface TransactionVerifyResponse {
status: string;
message: string;
data: {
tx_ref: string;
flw_ref: string;
currency: string;
status: string;
};
}

export interface Flutterwave {
initializePayment(
payload: {
tx_ref: string;
amount: number;
currency: string;
redirect_url: string;
customer: {
email: string;
};
}
): Promise;

TransactionVerify(
payload: { id: string }
): Promise;
}

const Flutterwave: new (publicKey: string, secretKey: string) => Flutterwave;
export = Flutterwave;
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

import Flutterwave from “flutterwave-node-v3”;
import { FLWPUBK, FLWSECK } from “../config”;

const flw = new Flutterwave(FLWPUBK, FLWSECK);

export const initiatePayment = async (payload: {
tx_ref: string;
amount: number;
currency: string;
email: string;
redirect_url: string;
}) => {
try {
const response = await flw.Charge.card({
tx_ref: payload.tx_ref,
amount: payload.amount,
currency: payload.currency,
redirect_url: payload.redirect_url,
customer: {
email: payload.email,
},
payment_options: “card”, // Optional: specify payment options
});

if (response.status === “success”) {
return response.meta.authorization.redirect; // Payment link
} else {
throw new Error(response.message || “Failed to initiate payment.”);
}
} catch (error) {
console.error(“Payment initiation error:”, error);
throw new Error(“Failed to initiate payment.”);
}
};
export const verifyPayment = async (transactionId: string) => {
try {
const response = await flw.Transaction.verify({ id: transactionId });

if (response.status === “success”) {
return response.data;
} else {
throw new Error(“Payment verification failed.”);
}
} catch (error) {
console.error(“Payment verification error:”, error);
throw new Error(“Failed to verify payment.”);
}
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

`import { Request, Response } from “express”;وارد کردن { EventAttribute, EventInstance } از “../models/eventModel”;وارد کردن { TicketAttribute, TicketInstance } از “../models/ticketModel”;وارد کردن { v4 به عنوان uuidv4 } از “uuid”;وارد کردن { JwtPayload } از “jsonwebtoken”;وارد کردن QRCode از “qrcode”؛وارد کردن { NotificationInstance } از “../models/notificationModel”؛وارد کردن { initiatePayment, verifyPayment } از “../interface/payment.dto”;وارد کردن { BASE_URL, FRONTEND_URL } از “../config”؛وارد کردن {UserAttribute, UserInstance } از “../models/userModel”;

صادرات هزینه خرید بلیط = ناهمگام (درخواست: JwtPayload،پاسخ: پاسخ): قول => {const userId = req.user;const { eventId } = req.params;const { ticketType,currency } = req.body;

سعی کن {const user = (انتظار UserInstance.findOne({کجا: { id: userId }،})) به عنوان UserAttribute ناشناخته.اگر (! کاربر) {return res.status(404).json({ خطا: “کاربر پیدا نشد” });}

const event = (await EventInstance.findOne({
where: { id: eventId },
})) as unknown as EventAttribute;
if (!event) {
return res.status(404).json({ error: “Event not found” });
}

if (new Date() > new Date(event.date)) {
return res
.status(400)
.json({ error: “Cannot purchase tickets for expired events” });
}

const ticketPrice = event.ticketType[ticketType];
if (!ticketPrice) {
return res.status(400).json({ error: “Invalid ticket type” });
}

const ticketId = uuidv4();

const qrCodeData = {
ticketId,
userId,
eventId: event.id,
ticketType,
price: ticketPrice,
purchaseDate: new Date(),
};
const qrCode = await QRCode.toDataURL(JSON.stringify(qrCodeData));

const newTicket = await TicketInstance.create({
id: ticketId,
eventId: event.id,
userId,
ticketType,
price: ticketPrice,
purchaseDate: new Date(),
qrCode,
paid: false,
currency,
validationStatus: “Invalid”,
}) as unknown as TicketAttribute;

const notification = await NotificationInstance.create({
id: uuidv4(),
title: “Ticket Purchase Successful”,
message: `You have successfully purchased a ${ticketType} ticket for the event ${event.title}.`,
userId,
isRead: false,
});

const paymentLink = await initiatePayment({
tx_ref: newTicket.id,
amount: newTicket.price,
currency: newTicket.currency,
email: user.email,
redirect_url: `${BASE_URL}/tickets/callback`,
});

return res.status(201).json({
message: “Ticket created successfully”,
paymentLink,
ticket: newTicket,
});

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

} catch (خطا: هر) {Result Resوضعیت .(500).json({ خطا: “خرید بلیط انجام نشد”، جزئیات: error.message });}};

صادرات هزینه پرداخت تأیید = ناهمگام (درخواست: JwtPayload،پاسخ: پاسخ): قول => {const {transaction_id, tx_ref } = req.query;

سعی کن {// بررسی پرداختconst paymentData = await verifyPayment(transaction_id as string);

if (paymentData.tx_ref === tx_ref) {
await TicketInstance.update(
{
paid: true,
validationStatus: “Valid”,
flwRef: paymentData.flw_ref,
currency: paymentData.currency,
},
{
where: { id: tx_ref },
}
);

const ticket = (await TicketInstance.findOne({
where: { id: tx_ref },
})) as unknown as TicketAttribute;
const event = (await EventInstance.findOne({
where: { id: ticket?.eventId },
})) as unknown as EventAttribute;

if (event) {
if (event.quantity <= 0) {
throw new Error(“Event is sold out”);
}

await EventInstance.update(
{
quantity: event.quantity – 1,
sold: event.sold + 1,
},
{ where: { id: ticket?.eventId } }
);
}

res.redirect(`${FRONTEND_URL}/payment-success`);
} else {
throw new Error(“Transaction reference mismatch”);
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

} catch (خطا) {console.error(error);res.redirect(${FRONTEND_URL}/payment-failed)}};`

جزئیات پشته فناوری:

چارچوب Backend: Express.js
ORM: دنباله دار کردن
پایگاه داده: PostgreSQL
زبان: TypeScript

سوالات:

آیا کسی با موفقیت Flutterwave را در پروژه TypeScript + Express.js ادغام کرده است؟
آیا اعلان‌های نوع پشتیبانی شده توسط جامعه یا رویکردهای بهتری برای استفاده از این بسته وجود دارد؟
بهترین راه برای رسیدگی به callbacktransaction_id برای تأیید پرداخت‌ها و به‌روزرسانی سوابق پایگاه داده چیست؟

اگر با مشکلات مشابهی مواجه شده اید یا پیشنهادهایی دارید (مقالات، آموزش های یوتیوب یا مخازن GitHub)، از کمک شما بسیار سپاسگزارم.

پیشاپیش متشکرم 🚀

سلام انجمن DEV،

من در حال حاضر روی ادغام Flutterwave در برنامه خود کار می کنم که با TypeScript، Express.js، Sequelize و PostgreSQL ساخته شده است. با این حال، من با چند چالش روبرو بوده ام و از هر گونه راهنمایی یا منبعی که می توانید به اشتراک بگذارید قدردانی می کنم.

در اینجا خلاصه ای از کارهایی است که من تاکنون انجام داده ام:

  1. بسته flutterwave-node-v3 را نصب کردم و آن را با کلیدهای عمومی و مخفی خود پیکربندی کردم.
  2. توابع TypeScript را برای مقداردهی اولیه و تأیید پرداخت ایجاد کرد.
  3. از Sequelize برای مدل سازی جداول پایگاه داده من (به عنوان مثال، بلیط ها و رویدادها) استفاده کرد.

مشکلات پیش آمده:
الف هنگام تماس با flw.initializePayment، این خطا را دریافت می کنم:
TypeError: initializePayment یک تابع نیست.
ب افزودن پشتیبانی TypeScript دشوار است زیرا هیچ نوع رسمی TypeScript برای flutterwave-node-v3 وجود ندارد و نوشتن اعلان‌های نوع سفارشی مشکل را حل نکرده است.
ج برای درک بهترین روش‌ها برای رسیدگی به تماس‌های ناهمزمان و به‌روزرسانی وضعیت رویداد و بلیط در پایگاه داده به کمک نیاز دارید.

آنچه من امتحان کرده ام:

// src/types/flutterwave-node-v3.d.ts
declare module 'flutterwave-node-v3' {
    // TypeScript interfaces for the Flutterwave response and request types
    export interface PaymentInitiateResponse {
      status: string;
      message: string;
      data: {
        link: string;
      };
    }

    export interface TransactionVerifyResponse {
      status: string;
      message: string;
      data: {
        tx_ref: string;
        flw_ref: string;
        currency: string;
        status: string;
      };
    }

    export interface Flutterwave {
      initializePayment(
        payload: {
          tx_ref: string;
          amount: number;
          currency: string;
          redirect_url: string;
          customer: {
            email: string;
          };
        }
      ): Promise;

      TransactionVerify(
        payload: { id: string }
      ): Promise;
    }

    const Flutterwave: new (publicKey: string, secretKey: string) => Flutterwave;
    export = Flutterwave;
  }

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

import Flutterwave from "flutterwave-node-v3";
import { FLWPUBK, FLWSECK } from "../config";

const flw = new Flutterwave(FLWPUBK, FLWSECK);

export const initiatePayment = async (payload: {
  tx_ref: string;
  amount: number;
  currency: string;
  email: string;
  redirect_url: string;
}) => {
  try {
    const response = await flw.Charge.card({
      tx_ref: payload.tx_ref,
      amount: payload.amount,
      currency: payload.currency,
      redirect_url: payload.redirect_url,
      customer: {
        email: payload.email,
      },
      payment_options: "card", // Optional: specify payment options
    });

    if (response.status === "success") {
      return response.meta.authorization.redirect; // Payment link
    } else {
      throw new Error(response.message || "Failed to initiate payment.");
    }
  } catch (error) {
    console.error("Payment initiation error:", error);
    throw new Error("Failed to initiate payment.");
  }
};
export const verifyPayment = async (transactionId: string) => {
  try {
    const response = await flw.Transaction.verify({ id: transactionId });

    if (response.status === "success") {
      return response.data;
    } else {
      throw new Error("Payment verification failed.");
    }
  } catch (error) {
    console.error("Payment verification error:", error);
    throw new Error("Failed to verify payment.");
  }
};

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

`
import { Request, Response } from “express”;
وارد کردن { EventAttribute, EventInstance } از “../models/eventModel”;
وارد کردن { TicketAttribute, TicketInstance } از “../models/ticketModel”;
وارد کردن { v4 به عنوان uuidv4 } از “uuid”;
وارد کردن { JwtPayload } از “jsonwebtoken”;
وارد کردن QRCode از “qrcode”؛
وارد کردن { NotificationInstance } از “../models/notificationModel”؛
وارد کردن { initiatePayment, verifyPayment } از “../interface/payment.dto”;
وارد کردن { BASE_URL, FRONTEND_URL } از “../config”؛
وارد کردن {UserAttribute, UserInstance } از “../models/userModel”;

صادرات هزینه خرید بلیط = ناهمگام (
درخواست: JwtPayload،
پاسخ: پاسخ
): قول => {
const userId = req.user;
const { eventId } = req.params;
const { ticketType,currency } = req.body;

سعی کن {
const user = (انتظار UserInstance.findOne({
کجا: { id: userId }،
})) به عنوان UserAttribute ناشناخته.
اگر (! کاربر) {
return res.status(404).json({ خطا: “کاربر پیدا نشد” });
}

const event = (await EventInstance.findOne({
  where: { id: eventId },
})) as unknown as EventAttribute;
if (!event) {
  return res.status(404).json({ error: "Event not found" });
}

if (new Date() > new Date(event.date)) {
  return res
    .status(400)
    .json({ error: "Cannot purchase tickets for expired events" });
}

const ticketPrice = event.ticketType[ticketType];
if (!ticketPrice) {
  return res.status(400).json({ error: "Invalid ticket type" });
}

const ticketId = uuidv4();

const qrCodeData = {
  ticketId,
  userId,
  eventId: event.id,
  ticketType,
  price: ticketPrice,
  purchaseDate: new Date(),
};
const qrCode = await QRCode.toDataURL(JSON.stringify(qrCodeData));

const newTicket = await TicketInstance.create({
  id: ticketId,
  eventId: event.id,
  userId,
  ticketType,
  price: ticketPrice,
  purchaseDate: new Date(),
  qrCode,
  paid: false,
  currency,
  validationStatus: "Invalid",
}) as unknown as TicketAttribute;

const notification = await NotificationInstance.create({
  id: uuidv4(),
  title: "Ticket Purchase Successful",
  message: `You have successfully purchased a ${ticketType} ticket for the event ${event.title}.`,
  userId,
  isRead: false,
});

const paymentLink = await initiatePayment({
  tx_ref: newTicket.id,
  amount: newTicket.price,
  currency: newTicket.currency,
  email: user.email,
  redirect_url: `${BASE_URL}/tickets/callback`,
});

return res.status(201).json({
  message: "Ticket created successfully",
  paymentLink,
  ticket: newTicket,
});
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

} catch (خطا: هر) {
Result Res
وضعیت .(500)
.json({ خطا: “خرید بلیط انجام نشد”، جزئیات: error.message });
}
};

صادرات هزینه پرداخت تأیید = ناهمگام (
درخواست: JwtPayload،
پاسخ: پاسخ
): قول => {
const {transaction_id, tx_ref } = req.query;

سعی کن {
// بررسی پرداخت
const paymentData = await verifyPayment(transaction_id as string);

if (paymentData.tx_ref === tx_ref) {
  await TicketInstance.update(
    {
      paid: true,
      validationStatus: "Valid",
      flwRef: paymentData.flw_ref,
      currency: paymentData.currency,
    },
    {
      where: { id: tx_ref },
    }
  );

  const ticket = (await TicketInstance.findOne({
    where: { id: tx_ref },
  })) as unknown as TicketAttribute;
  const event = (await EventInstance.findOne({
    where: { id: ticket?.eventId },
  })) as unknown as EventAttribute;

  if (event) {
    if (event.quantity <= 0) {
      throw new Error("Event is sold out");
    }

    await EventInstance.update(
      {
        quantity: event.quantity - 1,
        sold: event.sold + 1,
      },
      { where: { id: ticket?.eventId } }
    );
  }

  res.redirect(`${FRONTEND_URL}/payment-success`);
} else {
  throw new Error("Transaction reference mismatch");
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

} catch (خطا) {
console.error(error);
res.redirect(${FRONTEND_URL}/payment-failed)
}
};`

جزئیات پشته فناوری:

  • چارچوب Backend: Express.js
  • ORM: دنباله دار کردن
  • پایگاه داده: PostgreSQL
  • زبان: TypeScript

سوالات:

  1. آیا کسی با موفقیت Flutterwave را در پروژه TypeScript + Express.js ادغام کرده است؟
  2. آیا اعلان‌های نوع پشتیبانی شده توسط جامعه یا رویکردهای بهتری برای استفاده از این بسته وجود دارد؟
  3. بهترین راه برای رسیدگی به callbacktransaction_id برای تأیید پرداخت‌ها و به‌روزرسانی سوابق پایگاه داده چیست؟

اگر با مشکلات مشابهی مواجه شده اید یا پیشنهادهایی دارید (مقالات، آموزش های یوتیوب یا مخازن GitHub)، از کمک شما بسیار سپاسگزارم.

پیشاپیش متشکرم 🚀

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا