cms icon indicating copy to clipboard operation
cms copied to clipboard

Add purchases, payment information

Open hkirat opened this issue 5 months ago • 10 comments

Right now, a lot of the backend (user auth and course purchases) is deligated to appx We want to create a strategy where courses can be bought in house This will require some schema design so if you're thiniking of working on this please post the schema and approach first

hkirat avatar Mar 08 '24 11:03 hkirat

@hkirat .. will post soon ..

Rash-Hit avatar Mar 08 '24 11:03 Rash-Hit

Working on it @hkirat

devsargam avatar Mar 08 '24 11:03 devsargam

@hkirat, after some investigation, I've discovered that we're currently relying on an external API/service to verify whether a user has purchased the course or not. Your suggestion seems to be to bring this process in-house. Here's a rough approach I've outlined based on your statement. Please review and let me know if any adjustments are needed.

1).  We will add one more field in course model which will tell us ,

model Course {

 // Existing fields...

    inhouse  : Boolean   (we can use enum over here also , as u taught us ..)

 // Other fields...

}

2). We will add a purchase model in the db .. something like this ..

model Purchase {

 id        Int      @id @default(autoincrement())

 userId    String

 user      User     @relation(fields: [userId], references: [id])

 courseId  Int

 course    Course   @relation(fields: [courseId], references: [id])

 purchasedAt DateTime @default(now())

 .... (few more fields)

}

3). Wee will modify the name of UserPurchase model to something like ... UserCourses model which looks like this..

model UserCourses {

 user       User     @relation(fields: [userId], references: [id])

 userId     String

 course     Course   @relation(fields: [courseId], references: [id])

 courseId   Int

 assignedAt DateTime @default(now())

 @@id([userId, courseId])

}

4). We will add a payment model as well which looks something like this .

model Payment {

 id            Int      @id @default(autoincrement())

 purchaseId    Int

 purchase      Purchase @relation(fields: [purchaseId], references: [id])  (this is the new model above we have created .)

 method        String   // e.g., "Credit Card", "PayPal"

 amount        Float

 transactionId String

}

5).. I think by doing above these things we have to 100% change some of our application logic as well


6).  Lot of Testing and on spot changes will be required ..


7).  I am a beginner in this thing , so please consider that fact as well


@hkirat please have a look

Rash-Hit avatar Mar 08 '24 12:03 Rash-Hit

@hkirat, my approach would be. Assuming we are using razorpay for handeling course purchases. The following model should be fine:

model User {
  id             String          @id @default(cuid())
  name           String?
  email          String?         @unique
  phoneNumber    Int             @unique // Added

  transactions   Transaction[] // Added
}

// Added a model for razorpay
model Transaction {
  id                 String   @id @default(cuid())
  razorpay_paymet_id String   @unique
  razorpay_order_id  String   @unique
  razorpay_signature String
  purchasedAt        DateTime @default(now())

  purchasedCourse   Course @relation(fields: [purchasedCourseId], references: [id])
  purchasedCourseId Int

  purchasedBy   User   @relation(fields: [purchasedById], references: [id])
  purchasedById String
}

model Course {
  id             Int             @id @default(autoincrement())
  appxCourseId   Int
  discordRoleId  String
  title          String
  imageUrl       String
  description    String
  openToEveryone Boolean         @default(false)
  slug           String
  content        CourseContent[]
  purchasedBy    UserPurchases[]
  transactions   Transaction[] // Added
}
// Rest of the models

Endpoints: /singup for creating new accounts. Need to validate email or phonenumber to prevent spam /courses/:courseId/purchase for handling payments with razor pay

Still there are a lot of things that are ambiguous

  • Are we planning to handle CMS ourself?
  • How can we migrate all prior users from appx to this solution? Would love to clarify those and work on it

Happy to integrate if you think this approach sounds fine 🙇

devsargam avatar Mar 08 '24 13:03 devsargam

@hkirat, my approach would be. Assuming we are using razorpay for handeling course purchases. The following model should be fine:

model User {
  id             String          @id @default(cuid())
  name           String?
  email          String?         @unique
  phoneNumber    Int             @unique // Added

  transactions   Transaction[] // Added
}

// Added a model for razorpay
model Transaction {
  id                 String   @id @default(cuid())
  razorpay_paymet_id String   @unique
  razorpay_order_id  String   @unique
  razorpay_signature String
  purchasedAt        DateTime @default(now())

  purchasedCourse   Course @relation(fields: [purchasedCourseId], references: [id])
  purchasedCourseId Int

  purchasedBy   User   @relation(fields: [purchasedById], references: [id])
  purchasedById String
}

model Course {
  id             Int             @id @default(autoincrement())
  appxCourseId   Int
  discordRoleId  String
  title          String
  imageUrl       String
  description    String
  openToEveryone Boolean         @default(false)
  slug           String
  content        CourseContent[]
  purchasedBy    UserPurchases[]
  transactions   Transaction[] // Added
}
// Rest of the models

Endpoints: /singup for creating new accounts. Need to validate email or phonenumber to prevent spam /courses/:courseId/purchase for handling payments with razor pay

Still there are a lot of things that are ambiguous

  • Are we planning to handle CMS ourself?
  • How can we migrate all prior users from appx to this solution? Would love to clarify those and work on it

Happy to integrate if you think this approach sounds fine 🙇

How about removing transactions field from user and Course table and putting it in UserPurchases. It is refrenced in both user and course table and putting transaction in the userPurchase which is the link between user and course is more appropriate.

mumin-khan avatar Mar 09 '24 05:03 mumin-khan

@devsargam your approach looks fantastic Are u willing to implement it?

hkirat avatar Mar 09 '24 18:03 hkirat

@hkirat, yes absolutely can't wait to do it.

Could you please assign this to me?

devsargam avatar Mar 09 '24 19:03 devsargam

I am working on authentication system.

dhruvilmehta avatar Mar 10 '24 06:03 dhruvilmehta

@dhruvilmehta already raised a pr for that can you work on some other?

devsargam avatar Mar 10 '24 06:03 devsargam

// Define the User model model User { id String @id @default(cuid()) name String? email String @unique phoneNumber Int @unique transactions Transaction[] // User has many transactions }

// Define the Transaction model model Transaction { id String @id @default(cuid()) razorpay_payment_id String @unique razorpay_order_id String @unique razorpay_signature String purchasedAt DateTime @default(now())

purchasedCourse Course @relation(fields: [purchasedCourseId], references: [id]) purchasedCourseId Int purchasedBy User @relation(fields: [purchasedById], references: [id]) purchasedById String }

// Define the Course model model Course { id Int @id @default(autoincrement()) appxCourseId Int discordRoleId String title String imageUrl String description String openToEveryone Boolean @default(false) slug String content CourseContent[] purchasedBy UserPurchases[] transactions Transaction[] // Course has many transactions }

// Define the CourseContent model model CourseContent { id Int @id @default(autoincrement()) courseId Int content String // Define any other fields related to course content }

// Define the UserPurchases model model UserPurchases { id Int @id @default(autoincrement()) userId String courseId Int purchaseDate DateTime @default(now()) amount Float // Define any other fields related to user purchases }

Aryam2121 avatar Mar 10 '24 10:03 Aryam2121