From 2beda1232ae6a8f5942fb78065ee31206239daed Mon Sep 17 00:00:00 2001 From: Matteus Date: Sun, 5 Dec 2021 22:08:05 +0100 Subject: [PATCH 1/5] Added `.env.example` --- .env.example | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..bb4fdc2 --- /dev/null +++ b/.env.example @@ -0,0 +1,68 @@ +# Secret JWT token for authentication, don't share this with anyone. +JWT_ACCESS_TOKEN= + +# If in debug mode or note +DEBUG= + +# The mongo database uri to use, if not set it will use the default: mongodb://localhost/cpg +MONGO_URI= + +# The domain to use for the api, if not set it will use the default: localhost +# Needs to look like: https://domain.com +DOMAIN= + +# http or https, default: http +HTTP_SCHEMA= + +# Session secret key for cookies +SESSION_SECRET= + +# Which port to run on, default 8080 +PORT= + +# If you use OsTicket you can configure it here +# (optional) +OSTICKET_URL= +OSTICKET_API_KEY= + +# If you have "swish" (Swedish company), you can use your number here for CPG +# (optional) +SWISH_PAYEE_NUMBER= + +# Paypal credentials (optional) +PAYPAL_CLIENT_ID= +PAYPAL_CLIENT_SECRET= + +# Stripe credentials +# (optional) +STRIPE_SK_LIVE= +STRIPE_SK_PUBLIC= +STRIPE_WEBHOOK_SECRET= + +# This is a solution that will be probably removed in the near future +# but for the invoices adding these would be recommended. +COMPANY_NAME= +COMPANY_ADDRESS= +COMPANY_ZIP= +COMPANY_CITY= +COMPANY_COUNTRY= +COMPANY_PHONE= +COMPANY_EMAIL= +COMPANY_VAT= +COMPANY_CURRENCY= +COMPANY_LOGO_URL= +COMPANY_TAX_REGISTERED= +COMPANY_WEBSITE= + +# For invoice you can add a template +# (optional) +PDF_TEMPLATE_URL= + +# Plugins for CPG +# NOTE: Plugins can require different env variables to be set. +# (optional) +PLUGINS="[]" + +# For the webhook, you add a secret to know the webhook is from CPG +# (optional) +WEBHOOK_SECRET= \ No newline at end of file From 121c79c40bb666c10634926441f5707c02d46d21 Mon Sep 17 00:00:00 2001 From: Matteus Date: Sun, 5 Dec 2021 22:18:11 +0100 Subject: [PATCH 2/5] Modified `.env.example` --- .env.example | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index bb4fdc2..5f78de8 100644 --- a/.env.example +++ b/.env.example @@ -2,6 +2,7 @@ JWT_ACCESS_TOKEN= # If in debug mode or note +# (optional) DEBUG= # The mongo database uri to use, if not set it will use the default: mongodb://localhost/cpg @@ -9,15 +10,18 @@ MONGO_URI= # The domain to use for the api, if not set it will use the default: localhost # Needs to look like: https://domain.com +# (optional) DOMAIN= # http or https, default: http +# (optional) HTTP_SCHEMA= # Session secret key for cookies SESSION_SECRET= # Which port to run on, default 8080 +# (optional) PORT= # If you use OsTicket you can configure it here @@ -29,7 +33,8 @@ OSTICKET_API_KEY= # (optional) SWISH_PAYEE_NUMBER= -# Paypal credentials (optional) +# Paypal credentials +# (optional) PAYPAL_CLIENT_ID= PAYPAL_CLIENT_SECRET= From 9b131d0d6ecedeb4dcc0a2421391a6762f086093 Mon Sep 17 00:00:00 2001 From: Matteus Date: Sun, 5 Dec 2021 22:18:20 +0100 Subject: [PATCH 3/5] Modified `README.md` --- README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/README.md b/README.md index 81bacd3..8d24f95 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,41 @@ # ⭐ | CPG-API CPG-API is being used to create products, invoices, orders, transactions and payments for customers, to grow your business. +# 🧰 | Setup +Setting up `CPG` can be done in various of ways, but by the far easiet is by using `Docker`. +You can pull the latest `docker` image from `tolfixorg/cpg:latest` from `DockerHub`. + +`CPG` also needs `env` vars added, which you can find some documents from [`.env.example`](), those added with `(optional)` can be ignored if you don't feel the need of them, but the others are required to make `CPG` functional. + +## Installing +`CPG` requires the following +* Node.js +* Typescript - 4.3.5 +* MongoDB +* Git + +1. Clone repository +```txt +git clone https://github.com/Tolfix/CPG-API +``` +2. Install dependencies +```txt +npm install +``` +3. Install `TypeScript` +```txt +npm install -g typescript@4.3.5 +``` +## Building +`CPG` is built from `TypeScript`, thus simple run it by using the compiler. +```txt +tsc -b +npm run build +``` + +## Running +You can run `CPG` by using `npm run start` or `node ./build/Main.js`. +Would recommend to use `pm2`. # 🎨 | Plugins Plugins allows you to install others features to CPG. Be aware it can be `dangerous` due to plugins get accessed to alot, you can trust `Tolfix` owns plugins, or plugins you created yourself, otherwise there is no guarantee. From f6f5e0f5470caed54aa849a8dff298a2cb45250c Mon Sep 17 00:00:00 2001 From: Matteus Date: Mon, 6 Dec 2021 16:33:29 +0100 Subject: [PATCH 4/5] Added `v2/customers/my/orders/:id/cancel` --- src/Routes/v2/Customers/Customers.config.ts | 50 ++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/Routes/v2/Customers/Customers.config.ts b/src/Routes/v2/Customers/Customers.config.ts index 1050622..f46524c 100644 --- a/src/Routes/v2/Customers/Customers.config.ts +++ b/src/Routes/v2/Customers/Customers.config.ts @@ -1,7 +1,7 @@ import { Application, Router } from "express"; import EnsureAdmin from "../../../Middlewares/EnsureAdmin"; import CustomerController from "./Customers.controller"; -import { Full_Domain, JWT_Access_Token } from "../../../Config"; +import { Full_Domain, GetSMTPEmails, JWT_Access_Token } from "../../../Config"; import jwt from "jsonwebtoken"; import bcrypt from "bcryptjs"; import { APIError, APISuccess } from "../../../Lib/Response"; @@ -138,6 +138,54 @@ export default class CustomerRouter return APISuccess(order)(res); }); + this.router.get("/my/orders/:id/cancel", EnsureAuth(), async (req, res) => { + const orderId = req.params.id; + + if(!orderId) + return APIError(`Invalid invoice id`)(res); + + const customer = await CustomerModel.findOne({ + // @ts-ignore + id: req.customer.id + }); + + if(!customer) + return APIError(`Unable to find customer`)(res); + + const order = await OrderModel.findOne({ + $or: [ + { + customer_uid: customer.uid, + }, + { + customer_uid: customer.id, + }, + ], + id: orderId, + }); + + if(!order) + return APIError(`Unable to find order`)(res); + + order.order_status = "cancelled"; + await order.save(); + + GetSMTPEmails().then(emails => { + for(const email of emails) + { + SendEmail(email, `Order Cancelled #${order.id}`, { + isHTML: true, + body: ` +

Order Cancelled

+

Order #${order.id} has been cancelled

+ `, + }); + } + }); + + return APISuccess("Order cancelled.")(res); + }); + this.router.post("/my/reset-password", async (req, res) => { const email = req.body.email; const customer = await CustomerModel.findOne({ "personal.email": email }); From c32ab0e0b1006b7722ca101cb1c7ebb7f1c5c163 Mon Sep 17 00:00:00 2001 From: Matteus Date: Tue, 7 Dec 2021 20:08:03 +0100 Subject: [PATCH 5/5] Modified `orders/place` --- src/Routes/v2/Orders/Orders.config.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Routes/v2/Orders/Orders.config.ts b/src/Routes/v2/Orders/Orders.config.ts index 50e3380..319c15d 100644 --- a/src/Routes/v2/Orders/Orders.config.ts +++ b/src/Routes/v2/Orders/Orders.config.ts @@ -11,7 +11,7 @@ import dateFormat from "date-and-time"; import nextRecycleDate from "../../../Lib/Dates/DateCycle"; import { createInvoiceFromOrder } from "../../../Lib/Orders/newInvoice"; import { idOrder } from "../../../Lib/Generator"; -import { Company_Name, Full_Domain } from "../../../Config"; +import { Company_Name, Full_Domain, Swish_Payee_Number } from "../../../Config"; import { sendInvoiceEmail } from "../../../Lib/Invoices/SendEmail"; import EnsureAuth from "../../../Middlewares/EnsureAuth"; import { IOrder } from "../../../Interfaces/Orders"; @@ -20,6 +20,7 @@ import { SendEmail } from "../../../Email/Send"; import NewOrderCreated from "../../../Email/Templates/Orders/NewOrderCreated"; import { IConfigurableOptions } from "../../../Interfaces/ConfigurableOptions"; import { CreatePaymentIntent } from "../../../Payments/Stripe"; +import { createSwishQRCode } from "../../../Payments/Swish"; async function createOrder(customer: ICustomer, products: Array<{ product_id: IProduct["id"], @@ -266,6 +267,9 @@ export default class OrderRoute if(payment_method === "credit_card") return APISuccess(`${Full_Domain}/v2/stripe/pay/${invoice.uid}`)(res); + if(payment_method === "swish" && Swish_Payee_Number) + return APISuccess(`data:image/png;base64,${await createSwishQRCode(Swish_Payee_Number, (invoice.amount)+(invoice.amount)*(invoice.tax_rate/100), `Invoice ${invoice.id}`)}`)(res); + return APISuccess(`Invoice sent.`)(res); });