mirror of
https://github.com/PretendoNetwork/website.git
synced 2026-09-29 20:16:47 -05:00
Stripe start create subscription
This commit is contained in:
25
src/database.js
Normal file
25
src/database.js
Normal file
@@ -0,0 +1,25 @@
|
||||
const mongoose = require('mongoose');
|
||||
const PNIDSchema = require('./schema/pnid');
|
||||
const config = require('../config.json');
|
||||
|
||||
const accountServerConfig = config.database.account;
|
||||
const accountServerURI = `mongodb://${accountServerConfig.address}:${accountServerConfig.port}/${accountServerConfig.database_name}`;
|
||||
let accountServerDBConnection;
|
||||
let PNID;
|
||||
|
||||
async function connect() {
|
||||
accountServerDBConnection = await mongoose.createConnection(accountServerURI, accountServerConfig.options);
|
||||
accountServerDBConnection.on('error', console.error.bind(console, 'Mongoose connection error:'));
|
||||
accountServerDBConnection.on('close', () => {
|
||||
accountServerDBConnection.removeAllListeners();
|
||||
});
|
||||
|
||||
PNID = accountServerDBConnection.model('PNID', PNIDSchema);
|
||||
|
||||
module.exports.PNID = PNID;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
connect,
|
||||
PNID
|
||||
};
|
||||
@@ -1,10 +1,15 @@
|
||||
const { Router } = require('express');
|
||||
const express = require('express');
|
||||
const crypto = require('crypto');
|
||||
const DiscordOauth2 = require('discord-oauth2');
|
||||
const { v4: uuidv4 } = require('uuid');
|
||||
const AdmZip = require('adm-zip');
|
||||
const Stripe = require('stripe');
|
||||
const database = require('../database');
|
||||
const util = require('../util');
|
||||
const config = require('../../config.json');
|
||||
|
||||
const { Router } = express;
|
||||
const stripe = new Stripe(config.stripe.secret_key);
|
||||
const router = new Router();
|
||||
const aesKey = Buffer.from(config.aes_key, 'hex');
|
||||
|
||||
@@ -494,4 +499,150 @@ router.get('/miieditor', async (request, response) => {
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/upgrade', async (request, response) => {
|
||||
// Verify the user is logged in
|
||||
if (!request.cookies.access_token || !request.cookies.refresh_token || !request.cookies.ph) {
|
||||
return response.redirect('/account/login');
|
||||
}
|
||||
|
||||
const renderData = {
|
||||
layout: 'main',
|
||||
locale: util.getLocale(request.locale.region, request.locale.language),
|
||||
localeString: request.locale.toString(),
|
||||
error: request.cookies.error
|
||||
};
|
||||
|
||||
const { data: prices } = await stripe.prices.list();
|
||||
const { data: products } = await stripe.products.list();
|
||||
|
||||
renderData.tiers = products.filter(product => product.active).map(product => {
|
||||
const price = prices.find(price => price.product === product.id);
|
||||
|
||||
return {
|
||||
price_id: price.id,
|
||||
thumbnail: product.images[0],
|
||||
name: product.name,
|
||||
description: product.description,
|
||||
price: (price.unit_amount / 100).toLocaleString('en-US', { style: 'currency', currency: 'USD' }),
|
||||
};
|
||||
});
|
||||
|
||||
response.render('account/upgrade', renderData);
|
||||
});
|
||||
|
||||
router.post('/checkout/:priceId', async (request, response) => {
|
||||
// Verify the user is logged in
|
||||
if (!request.cookies.access_token || !request.cookies.refresh_token || !request.cookies.ph) {
|
||||
return response.redirect('/account/login');
|
||||
}
|
||||
|
||||
// Attempt to get user data
|
||||
let apiResponse = await util.apiGetRequest('/v1/user', {
|
||||
'Authorization': `${request.cookies.token_type} ${request.cookies.access_token}`
|
||||
});
|
||||
|
||||
if (apiResponse.statusCode !== 200) {
|
||||
// Assume expired, refresh and retry request
|
||||
apiResponse = await util.apiPostGetRequest('/v1/login', {}, {
|
||||
refresh_token: request.cookies.refresh_token,
|
||||
grant_type: 'refresh_token'
|
||||
});
|
||||
|
||||
if (apiResponse.statusCode !== 200) {
|
||||
return response.redirect('/account/login');
|
||||
}
|
||||
|
||||
const tokens = apiResponse.body;
|
||||
|
||||
response.cookie('refresh_token', tokens.refresh_token, { domain: '.pretendo.network' });
|
||||
response.cookie('access_token', tokens.access_token, { domain: '.pretendo.network' });
|
||||
response.cookie('token_type', tokens.token_type, { domain: '.pretendo.network' });
|
||||
|
||||
apiResponse = await util.apiGetRequest('/v1/user', {
|
||||
'Authorization': `${tokens.token_type} ${tokens.access_token}`
|
||||
});
|
||||
}
|
||||
|
||||
// If still failed, something went horribly wrong
|
||||
if (apiResponse.statusCode !== 200) {
|
||||
return response.redirect('/account/login');
|
||||
}
|
||||
|
||||
// Set user account info to render data
|
||||
const account = apiResponse.body;
|
||||
const pid = account.pid;
|
||||
|
||||
let customer;
|
||||
const { data: searchResults } = await await stripe.customers.search({
|
||||
query: `metadata['pnid_pid']:'${pid}'`
|
||||
});
|
||||
|
||||
if (searchResults.length !== 0) {
|
||||
customer = searchResults[0];
|
||||
} else {
|
||||
customer = await stripe.customers.create({
|
||||
metadata: {
|
||||
pnid_pid: pid
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const priceId = request.params.priceId;
|
||||
|
||||
const session = await stripe.checkout.sessions.create({
|
||||
line_items: [
|
||||
{
|
||||
price: priceId,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
customer: customer.id,
|
||||
mode: 'subscription',
|
||||
success_url: `${config.http.base_url}/account?upgrade_success=true`,
|
||||
cancel_url: `${config.http.base_url}/account?upgrade_success=false`
|
||||
});
|
||||
|
||||
response.redirect(303, session.url);
|
||||
});
|
||||
|
||||
router.post('/stripe-wh', express.raw({ type: 'application/json' }), async (request, response) => {
|
||||
const stripeSignature = request.headers['stripe-signature'];
|
||||
let event;
|
||||
|
||||
try {
|
||||
event = stripe.webhooks.constructEvent(request.body, stripeSignature, config.stripe.webhook_secret);
|
||||
} catch (err) {
|
||||
return response.status(400).send(`Webhook Error: ${err.message}`);
|
||||
}
|
||||
|
||||
if (event.type === 'customer.subscription.updated' || event.type === 'customer.subscription.deleted') {
|
||||
const subscription = event.data.object;
|
||||
const product = await stripe.products.retrieve(subscription.plan.product);
|
||||
const customer = await stripe.customers.retrieve(subscription.customer);
|
||||
const pid = Number(customer.metadata.pnid_pid);
|
||||
const pnid = await database.PNID.findOne({ pid });
|
||||
|
||||
if (product.metadata.beta === 'true') {
|
||||
switch (subscription.status) {
|
||||
case 'active':
|
||||
pnid.access_level = 1;
|
||||
break;
|
||||
|
||||
case 'canceled': // Subscription was cancled
|
||||
case 'unpaid': // User missed too many payments
|
||||
pnid.access_level = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
await pnid.save();
|
||||
}
|
||||
}
|
||||
|
||||
response.json({ received: true });
|
||||
});
|
||||
|
||||
|
||||
module.exports = router;
|
||||
13
src/schema/pnid.js
Normal file
13
src/schema/pnid.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const { Schema } = require('mongoose');
|
||||
|
||||
// Only define what we will be using
|
||||
const PNIDSchema = new Schema({
|
||||
pid: {
|
||||
type: Number,
|
||||
unique: true
|
||||
},
|
||||
server_access_level: String,
|
||||
access_level: Number,
|
||||
});
|
||||
|
||||
module.exports = PNIDSchema;
|
||||
@@ -6,6 +6,7 @@ const morgan = require('morgan');
|
||||
const expressLocale = require('express-locale');
|
||||
const cookieParser = require('cookie-parser');
|
||||
const logger = require('./logger');
|
||||
const database = require('./database');
|
||||
const util = require('./util');
|
||||
const config = require('../config.json');
|
||||
|
||||
@@ -156,6 +157,8 @@ app.engine('handlebars', handlebars({
|
||||
app.set('view engine', 'handlebars');
|
||||
|
||||
logger.info('Starting server');
|
||||
app.listen(port, () => {
|
||||
logger.success(`Server listening on http://localhost:${port}`);
|
||||
database.connect().then(() => {
|
||||
app.listen(port, () => {
|
||||
logger.success(`Server listening on http://localhost:${port}`);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user