Spaces:
Running
Running
Download src/models/Order.js from AndreaNotes1/auth-app-api: direct link, hf CLI and curl.
- Browser
- Download file 4.37 kB
-
https://huggingface.co/spaces/AndreaNotes1/auth-app-api/resolve/main/src/models/Order.js
- Command line
-
hf download hf://spaces/AndreaNotes1/auth-app-api/src/models/Order.js
-
curl -L -o Order.js https://huggingface.co/spaces/AndreaNotes1/auth-app-api/resolve/main/src/models/Order.js
4.37 kB
| const mongoose = require("mongoose"); | |
| const { encryptField, decryptField, hmacIndex } = require("../utils/crypto"); | |
| const PAYMENT_METHODS = ["bank_wire", "payoneer", "payoneer_checkout", "voucher"]; | |
| const ORDER_STATUSES = ["pending_payment", "awaiting_confirmation", "confirmed", "rejected", "cancelled"]; | |
| const orderSchema = new mongoose.Schema( | |
| { | |
| orderNumber: { type: String, required: true, unique: true, index: true }, | |
| user: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true, index: true }, | |
| course: { type: mongoose.Schema.Types.ObjectId, ref: "Course", required: true }, | |
| // Snapshot of course price/title at time of purchase so historical | |
| // orders remain accurate even if the course is later edited. | |
| courseTitleSnapshot: { type: String, required: true }, | |
| amount: { type: Number, required: true, min: 0 }, | |
| currency: { type: String, default: "USD" }, | |
| paymentMethod: { type: String, enum: PAYMENT_METHODS, required: true }, | |
| // Set only when paymentMethod === "voucher": the voucher whose | |
| // redemption produced this (free, pre-confirmed) order. | |
| voucher: { type: mongoose.Schema.Types.ObjectId, ref: "Voucher", default: null, index: true }, | |
| // --- Automated Payoneer Checkout fields (paymentMethod === | |
| // "payoneer_checkout" only). Populated when the checkout session is | |
| // created and used to (a) match an incoming webhook back to this | |
| // order, and (b) show the buyer a clear tax breakdown before they're | |
| // sent to Payoneer to actually pay. --- | |
| providerSessionId: { type: String, default: null, index: true }, | |
| providerCheckoutUrl: { type: String, default: null }, | |
| taxAmount: { type: Number, default: 0, min: 0 }, | |
| taxCurrency: { type: String, default: null }, | |
| // Sensitive: encrypted at rest with AES-256-GCM. Never returned by | |
| // default queries (select: false) and never logged in plaintext. | |
| // paymentReferenceIndex is a keyed HMAC used only to detect | |
| // duplicate submissions without ever decrypting. | |
| paymentReferenceEncrypted: { type: String, default: null, select: false }, | |
| paymentReferenceIndex: { type: String, default: null, index: true }, | |
| payerNoteEncrypted: { type: String, default: null, select: false }, | |
| status: { type: String, enum: ORDER_STATUSES, default: "pending_payment", index: true }, | |
| confirmedBy: { type: mongoose.Schema.Types.ObjectId, ref: "User", default: null }, | |
| confirmedAt: { type: Date, default: null }, | |
| rejectionReason: { type: String, default: null }, | |
| confirmationEmailSentAt: { type: Date, default: null }, | |
| }, | |
| { timestamps: true } | |
| ); | |
| // --- Helpers to write/read the encrypted payment reference safely --- | |
| orderSchema.methods.setPaymentReference = function setPaymentReference(plainReference) { | |
| this.paymentReferenceEncrypted = encryptField(plainReference); | |
| this.paymentReferenceIndex = hmacIndex(plainReference); | |
| }; | |
| orderSchema.methods.getPaymentReference = function getPaymentReference() { | |
| return decryptField(this.paymentReferenceEncrypted); | |
| }; | |
| orderSchema.methods.setPayerNote = function setPayerNote(note) { | |
| this.payerNoteEncrypted = encryptField(note); | |
| }; | |
| orderSchema.methods.getPayerNote = function getPayerNote() { | |
| return decryptField(this.payerNoteEncrypted); | |
| }; | |
| orderSchema.methods.toPublicJSON = function toPublicJSON({ includeSensitive = false } = {}) { | |
| const json = { | |
| id: this._id, | |
| orderNumber: this.orderNumber, | |
| course: this.course, | |
| courseTitleSnapshot: this.courseTitleSnapshot, | |
| amount: this.amount, | |
| currency: this.currency, | |
| taxAmount: this.taxAmount, | |
| taxCurrency: this.taxCurrency, | |
| totalAmount: this.amount + (this.taxAmount || 0), | |
| paymentMethod: this.paymentMethod, | |
| voucher: this.voucher || undefined, | |
| providerCheckoutUrl: this.providerCheckoutUrl, | |
| status: this.status, | |
| confirmedAt: this.confirmedAt, | |
| rejectionReason: this.rejectionReason, | |
| createdAt: this.createdAt, | |
| }; | |
| if (includeSensitive) { | |
| json.paymentReference = this.getPaymentReference(); | |
| json.payerNote = this.getPayerNote(); | |
| } | |
| return json; | |
| }; | |
| module.exports = mongoose.model("Order", orderSchema); | |
| module.exports.PAYMENT_METHODS = PAYMENT_METHODS; | |
| module.exports.ORDER_STATUSES = ORDER_STATUSES; | |