Created
September 14, 2020 16:35
-
-
Save cptiwari20/836e7875d38dd4965faeb14fb8f3a4ad to your computer and use it in GitHub Desktop.
Handle Thrivecart events in Node.js Expressjs API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const Subscriptions = require("../models/subscriptions"); //Any Subscription Model | |
| const Users = require("../models/users"); // User Model | |
| const Plans = require("../models/plans"); // Plans Model | |
| const Payments = require('../models/payments') | |
| const { send: sendMail } = require('../services/smtp'); | |
| const { generatePassword, getExpiryDate } = require('../utils/helpers'); | |
| let thrivecart_secret = process.env.THRIVECART_SECRET; //Add your API Secret in .env file | |
| const thriveCartWebhook = async (req, res, next) => { | |
| const subscriptionData = req.body | |
| const { | |
| customer, | |
| order_id, | |
| customer_id, | |
| base_product, order | |
| } = subscriptionData | |
| console.log('the thrivecart webhook request data =>', subscriptionData) | |
| try { | |
| if(subscriptionData.thrivecart_secret === thrivecart_secret){ | |
| switch (req.body.event) { | |
| case 'order.success': | |
| // Find if existing User (this data is Optional You can add a passthrough inside the plan URL) | |
| const userId = customer.passthrough ? customer.passthrough.userId : undefined | |
| // check the event whether the subscription is available or not | |
| const subscription = await Subscriptions.findOne({ order_id, customer_id }) | |
| if(!!subscription) return await createSubscriptionPayment({subscriptionData}, res) //create a new payment | |
| if (userId) { | |
| const user = await Users.findById(userId); | |
| if(!user){ //if failed to find user | |
| const existingUser = await Users.findOne({email: customer.email}); //then find using email | |
| if (existingUser) { // if email exists | |
| return await findUserAndSubscribe({ user: existingUser, subscriptionData }, res) | |
| }else{ // email doesn't exist | |
| return await createUserAndSubscribe({ subscriptionData }, res) | |
| } | |
| } | |
| return await findUserAndSubscribe({ user, subscriptionData }, res) | |
| } else { | |
| // If no existing User | |
| // Check if users email already exists | |
| const existingUser = await Users.findOne({email: customer.email}); | |
| if (existingUser) { | |
| return await findUserAndSubscribe({ user: existingUser, subscriptionData }, res) | |
| }else{ | |
| return await createUserAndSubscribe({ subscriptionData }, res) | |
| } | |
| } | |
| case 'order.subscription_payment': | |
| return await createSubscriptionPayment({subscriptionData}, res) | |
| case 'order.subscription_cancelled': | |
| return await updateSubscription({ | |
| subscriptionData, | |
| status: 'cancelled', | |
| message: 'Subscription cancelled!' | |
| }, res) | |
| case 'order.subscription_paused': | |
| return await updateSubscription({ | |
| subscriptionData, | |
| status: 'paused', | |
| message: 'Subscription paused!' | |
| }, res) | |
| case 'order.subscription_resumed': | |
| return await updateSubscription({ | |
| subscriptionData, | |
| status: 'live', | |
| message: 'Subscription resumed!' | |
| }, res) | |
| case 'order.refund': | |
| return await updateSubscription({ | |
| subscriptionData, | |
| status: 'refunded', | |
| message: 'Subscription updated!' | |
| }, res) | |
| case 'order.rebill_failed': | |
| return await updateSubscription({ | |
| subscriptionData, | |
| status: 'rebill_failed', | |
| message: 'Subscription updated!' | |
| }, res) | |
| default: | |
| // const subscription = await Subscriptions.findOne({ order_id, customer_id }) | |
| // await subscription.updateOne( | |
| // { | |
| // $set: { | |
| // ...subscriptionData | |
| // } | |
| // } | |
| // ) | |
| console.log('Event recieved but nothing updated!') | |
| return res.status(200).json({ status: false, message: 'Event recieved but nothing updated!' }) | |
| } | |
| }else{ | |
| console.log('Getting data from unknown source!') | |
| res.status(403).json({status: false, message: 'Getting data from unknown source.'}) | |
| } | |
| } catch (error) { | |
| console.log(error) | |
| return res.status(500).json({ status: false, message: error.message, error }) | |
| } | |
| } | |
| const findUserAndSubscribe = async ({ user, subscriptionData }, res) => { | |
| const { base_product, order, customer } = subscriptionData | |
| try { | |
| const plan = await Plans.findOne({ product: base_product }) | |
| if (!plan) res.status(400).json({ status: false, message: 'Plan not found.' }) | |
| const subscription = new Subscriptions({ | |
| ...subscriptionData, | |
| user: user._id, | |
| plan: plan._id, | |
| amount: order.total_str, | |
| product: base_product, | |
| payment_method: order.processor, | |
| email_id: customer.email, | |
| customer_details: customer, | |
| interval: plan.interval.billing_period, | |
| starts_at: new Date(subscriptionData.order_date), | |
| expiry_date: getExpiryDate(plan.interval.billing_period, new Date(subscriptionData.order_date)) | |
| }) | |
| const createdSubscription = await subscription.save() | |
| user.subscriptions = [...user.subscriptions, createdSubscription._id], | |
| user.thrivecart_customer_id = subscriptionData.customer_id | |
| const payment = await new Payments({ | |
| ...subscriptionData, | |
| user: user._id, | |
| plan: plan._id, | |
| subscription: createdSubscription._id, | |
| amount: order.total_str, | |
| payment_method: order.processor, | |
| }).save(); | |
| // console.log('Existing uSer',{user}) | |
| await user.save() | |
| res.status(200).json({ status: true, message: 'Plan has been subscribed Successfully!' }) | |
| } catch (error) { | |
| res.status(500).json({ status: false, message: error.message}) | |
| } | |
| } | |
| const createUserAndSubscribe = async ({ subscriptionData, hostedpage }, res) => { | |
| try { | |
| const { customer, base_product, order } = subscriptionData | |
| const plan = await Plans.findOne({ product: base_product }) | |
| if (!plan) res.status(400).json({ status: false, message: 'Plan not found.' }) | |
| const { first_name, last_name, email, address } = customer | |
| let addressUpdated = "" | |
| if (address) { | |
| addressUpdated = Object.values(address).join(', '); | |
| } | |
| const password = generatePassword() | |
| const user = new Users({ | |
| first_name, | |
| last_name, | |
| email, | |
| password, | |
| address: addressUpdated, | |
| }) | |
| const createdUser = await user.save() | |
| const subscription = new Subscriptions({ | |
| ...subscriptionData, | |
| user: user._id, | |
| plan: plan._id, | |
| amount: order.total_str, | |
| product: base_product, | |
| payment_method: order.processor, | |
| email_id: customer.email, | |
| customer_details: customer, | |
| interval: plan.interval.billing_period, | |
| starts_at: new Date(subscriptionData.order_date), | |
| expiry_date: getExpiryDate(plan.interval.billing_period, new Date(subscriptionData.order_date)) | |
| }) | |
| const createdSubscription = await subscription.save() | |
| createdUser.subscriptions = [...user.subscriptions, createdSubscription._id], | |
| createdUser.thrivecart_customer_id = customer.id | |
| await createdUser.save() | |
| const payment = await new Payments({ | |
| ...subscriptionData, | |
| user: createdUser._id, | |
| plan: plan._id, | |
| subscription: createdSubscription._id, | |
| amount: order.total_str, | |
| payment_method: order.processor, | |
| }).save(); | |
| return res.status(200).json({ status: true, message: 'New user has been registered with a new subscription!' }) | |
| } catch (error) { | |
| res.status(500).json({ status: false, message: error.message }) | |
| } | |
| } | |
| const updateSubscription = async ({ subscriptionData, status, message }, res) => { | |
| const subscription = await Subscriptions.findOne({ | |
| order_id: subscriptionData.order_id, | |
| customer_id: subscriptionData.customer_id | |
| }) | |
| await subscription.updateOne( | |
| { | |
| $set: { | |
| updated_at: new Date().now, | |
| status: status, | |
| } | |
| } | |
| ); | |
| return res.status(200).json({ status: true, message }) | |
| } | |
| const createSubscriptionPayment = async ({subscriptionData}, res) => { | |
| const {order_id, customer_id, order } = subscriptionData | |
| try{ | |
| const subscription = await Subscriptions.findOne({ order_id, customer_id }); | |
| if(!subscription) return res.status(400).json({ status: false, message: 'No subscription found!' }) | |
| const resp = await subscription.updateOne( | |
| { | |
| $set: { | |
| updated_at: new Date().now, | |
| status: 'live', | |
| expiry_date: getExpiryDate(subscription.interval, new Date()) | |
| } | |
| }, | |
| { runValidators: true } | |
| ); | |
| const payment = await new Payments({ | |
| ...subscriptionData, | |
| user: subscription.user, | |
| plan: subscription.plan, | |
| subscription: subscription._id, | |
| amount: order.total_str, | |
| payment_method: order.processor, | |
| }) | |
| const createdPayment = await payment.save() | |
| console.log(createdPayment) | |
| return res.status(200).json({ status: true, message: 'Subscription Payment created' }) | |
| } catch (error) { | |
| console.log(error) | |
| res.status(500).json({ status: false, message: error.message }) | |
| } | |
| } | |
| module.exports = { | |
| thriveCartWebhook | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment