const Schema = require('mongoose').Schema; const SubStatus = Object.freeze({ ACTIVE: "active", PAST_DUE: "past_due", UNPAID: "unpaid", CANCELED: "canceled", INCOMPLETE: "incomplete", INCOMPLETE_EXPIRED: "incomplete_expired", TRIALING: "trialing", PAUSED: "paused" }); const InvStatus = Object.freeze({ DRAFT: 'draft', OPEN: 'open', PAID: 'paid', UNCOLLECTIBLE: 'uncollectible', VOID: 'void' }); const ChrgStatus = Object.freeze({ SUCCEEDED: 'succeeded', PENDING: 'pending', FAILED: 'failed' }); const SubType = Object.freeze({ PACKAGE: "package", ADDON: "addon" }); const RecurType = Object.freeze({ MONTH: "month", YEAR: "year", WEEK: "week", day: "day" }); const AutoTaxStatus = Object.freeze({ SUPPORTED: 'supported', NOT_COLLECTING: 'not_collecting' }); const SubFields = Object.freeze({ ID: 'id', METADATA: 'metadata', TYPE: 'type', PRICE: 'price', QUANTITY: 'quantity', TIER: 'tier', MAX_VEHICLES: 'maxVehicles', // Custom, only use in metadata MAX_ACRES: 'maxAcres', // Custom, only use in metadata LEVEL: 'level', STATUS: 'status', TAX: 'tax', REFUNDED: 'refunded', LIMIT: 'limit', DEFAULT_PAYMENT_METHOD: 'default_payment_method', DEFAULT_SOURCE: 'default_source', NAME: 'name', BILLING_DETAILS: 'billing_details', // PM Object's billing_details 'CARD': 'card', EXP_MONTH: 'exp_month', EXP_YEAR: 'exp_year' }); const Events = Object.freeze({ CUST_SUB_TRIAL_WILL_END: 'customer.subscription.trial_will_end', CUST_SUB_DELETED: "customer.subscription.deleted", CUST_SUB_CREATED: "customer.subscription.created", CUST_SUB_UPDATED: "customer.subscription.updated", INV_UPCOMING: 'invoice.upcoming', INV_PAID: "invoice.paid", INV_PM_SUCCEEDED: "invoice.payment_succeeded", INV_PM_FAILED: "invoice.payment_failed", INV_FIN_FAILED: "invoice.finalization_failed", INV_PM_ACT_REQUIRED: "invoice.payment_action_required", CHARGE_RFD_UPDATED: "charge.refund.updated", CHARGE_SUCCEEDED: "charge.succeeded" }); function isTaxableCountry(country) { return country && country == 'CA'; } function isValidTaxStatus(status) { return [AutoTaxStatus.SUPPORTED, AutoTaxStatus.NOT_COLLECTING].includes(status); } function isFinalSubStatus(status) { return [SubStatus.CANCELED, SubStatus.INCOMPLETE_EXPIRED].includes(status); } /* Subscription information [ { id: subscription id, type: 'PACKAGE'/'ADDON', status: subscription status, // Need to handle user action when value other than 'active', especially 'incomplete' for user actions periodStart: subscription current_period_start, periodEnd: subscription current_period_end, items: [ price: 'lookup_key', quantity: '' // optional for package or can be 1 ], } ] */ const subscriptionSchema = new Schema({ id: String, type: { type: String, enum: { values: Object.values(SubType), message: '{VALUE} for subscription \'type\' is not supported' } }, status: { type: String, enum: { values: Object.values(SubStatus), message: '{VALUE} for subscription \'status\' is not supported' } }, periodStart: Number, periodEnd: Number, items: [ { price: String, quantity: { type: Number, required: false, min: [1, 'quantity must be at least 1'], max: [100, 'quantity must be at max of 100'] }, metadata: Schema.Types.Mixed } ], // billing cycles: monthly, yearly, quarterly, etc. recurring: { interval: { type: String, enum: { values: Object.values(RecurType), message: '{VALUE} for subscription \'recurring\' is not supported' } }, intervalCount: { type: Number, default: 1 } }, cancelAtPeriodEnd: Boolean, trialEnd: Number }); module.exports = { subscriptionSchema, SubStatus, SubType, SubFields, Events, InvStatus, ChrgStatus, isTaxableCountry, AutoTaxStatus, isValidTaxStatus, isFinalSubStatus }