Mail Modul überarbeitet, Korrekturen am PaymentService, neuer customerType seller

This commit is contained in:
2024-08-22 22:59:33 +02:00
parent b4609d07ba
commit 7a286e3519
16 changed files with 183 additions and 76 deletions

View File

@@ -14,7 +14,8 @@
"console": "integratedTerminal",
"env": {
"HOST_NAME": "localhost"
}
},
"preLaunchTask": "Start Stripe Listener"
},
{
"type": "node",
@@ -60,5 +61,30 @@
"sourceMaps": true,
"smartStep": true
}
],
"tasks": [
{
"label": "Start Stripe Listener",
"type": "shell",
"command": "stripe listen -e checkout.session.completed --forward-to http://localhost:3000/bizmatch/payment/webhook",
"isBackground": true,
"problemMatcher": [
{
"pattern": [
{
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": ".",
"endsPattern": "."
}
}
]
}
]
}

31
bizmatch-server/.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,31 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Start Stripe Listener",
"type": "shell",
"command": "stripe listen -e checkout.session.completed --forward-to http://localhost:3000/bizmatch/payment/webhook",
"problemMatcher": [],
"isBackground": true, // Task läuft im Hintergrund
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
}
},
{
"label": "Start Nest.js",
"type": "npm",
"script": "start:debug",
"isBackground": false,
"problemMatcher": [],
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
}
}
]
}

View File

@@ -2,7 +2,7 @@ import { boolean, char, doublePrecision, integer, jsonb, pgEnum, pgTable, serial
import { AreasServed, LicensedIn } from '../models/db.model';
export const PG_CONNECTION = 'PG_CONNECTION';
export const genderEnum = pgEnum('gender', ['male', 'female']);
export const customerTypeEnum = pgEnum('customerType', ['buyer', 'professional']);
export const customerTypeEnum = pgEnum('customerType', ['buyer', 'seller', 'professional']);
export const customerSubTypeEnum = pgEnum('customerSubType', ['broker', 'cpa', 'attorney', 'titleCompany', 'surveyor', 'appraiser']);
export const listingsCategoryEnum = pgEnum('listingsCategory', ['commercialProperty', 'business']);
export const subscriptionTypeEnum = pgEnum('subscriptionType', ['free', 'professional', 'broker']);
@@ -33,8 +33,6 @@ export const users = pgTable('users', {
longitude: doublePrecision('longitude'),
stripeCustomerId: text('stripeCustomerId'),
subscriptionId: text('subscriptionId'),
planActive: boolean('planActive').default(false),
planExpires: timestamp('planExpires'),
subscriptionPlan: subscriptionTypeEnum('subscriptionType'),
// embedding: vector('embedding', { dimensions: 1536 }),
});

View File

@@ -0,0 +1,14 @@
import { registerAs } from '@nestjs/config';
export default registerAs('mail', () => ({
host: 'email-smtp.us-east-2.amazonaws.com',
port: 587,
secure: false,
auth: {
user: process.env.AMAZON_USER,
pass: process.env.AMAZON_PASSWORD,
},
defaults: {
from: '"No Reply" <noreply@example.com>',
},
}));

View File

@@ -1,4 +1,5 @@
import { Body, Controller, Post } from '@nestjs/common';
import { User } from 'src/models/db.model';
import { ErrorResponse, MailInfo } from '../models/main.model';
import { MailService } from './mail.service.js';
@@ -13,4 +14,8 @@ export class MailController {
return this.mailService.sendRequest(mailInfo);
}
}
@Post('subscriptionConfirmation')
sendSubscriptionConfirmation(@Body() user: User): Promise<void | ErrorResponse> {
return this.mailService.sendSubscriptionConfirmation(user);
}
}

View File

@@ -13,33 +13,67 @@ import { MailController } from './mail.controller.js';
import { MailService } from './mail.service.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const user = process.env.amazon_user;
const password = process.env.amazon_password;
const user = process.env.AMAZON_USER;
const password = process.env.AMAZON_PASSWORD;
console.log('Amazon User:', process.env.AMAZON_USER);
console.log('Amazon Password:', process.env.AMAZON_PASSWORD);
@Module({
imports: [
DrizzleModule,
UserModule,
GeoModule,
MailerModule.forRoot({
transport: {
host: 'email-smtp.us-east-2.amazonaws.com',
secure: false,
port: 587,
auth: {
user: 'AKIAU6GDWVAQ2QNFLNWN',
pass: 'BDE9nZv/ARbpotim1mIOir52WgIbpSi9cv1oJoH8oEf7',
// ConfigModule.forFeature(mailConfig),
// MailerModule.forRoot({
// transport: {
// host: 'email-smtp.us-east-2.amazonaws.com',
// secure: false,
// port: 587,
// auth: {
// user: user, //'AKIAU6GDWVAQ2QNFLNWN',
// pass: password, //'BDE9nZv/ARbpotim1mIOir52WgIbpSi9cv1oJoH8oEf7',
// },
// },
// defaults: {
// from: '"No Reply" <noreply@example.com>',
// },
// template: {
// dir: join(__dirname, 'templates'),
// adapter: new HandlebarsAdapter({
// eq: function (a, b) {
// return a === b;
// },
// }),
// options: {
// strict: true,
// },
// },
// }),
MailerModule.forRootAsync({
useFactory: () => ({
transport: {
host: 'email-smtp.us-east-2.amazonaws.com',
secure: false,
port: 587,
auth: {
user: process.env.AMAZON_USER, //'AKIAU6GDWVAQ2QNFLNWN',
pass: process.env.AMAZON_PASSWORD, //'BDE9nZv/ARbpotim1mIOir52WgIbpSi9cv1oJoH8oEf7',
},
},
},
defaults: {
from: '"No Reply" <noreply@example.com>',
},
template: {
dir: join(__dirname, 'templates'),
adapter: new HandlebarsAdapter(), // or new PugAdapter() or new EjsAdapter()
options: {
strict: true,
defaults: {
from: '"No Reply" <noreply@example.com>',
},
},
template: {
dir: join(__dirname, 'templates'),
adapter: new HandlebarsAdapter({
eq: function (a, b) {
return a === b;
},
}),
options: {
strict: true,
},
},
}),
}),
],
providers: [MailService, UserService, FileService, GeoService],

View File

@@ -83,7 +83,7 @@ export class MailService {
}
async sendSubscriptionConfirmation(user: User): Promise<void> {
await this.mailerService.sendMail({
to: 'support@bizmatch.net',
to: user.email,
from: `"Bizmatch Support Team" <info@bizmatch.net>`,
subject: `Subscription Confirmation`,
//template: './inquiry', // `.hbs` extension is appended automatically

View File

@@ -17,18 +17,18 @@ export interface UserData {
hasCompanyLogo?: boolean;
licensedIn?: string[];
gender?: 'male' | 'female';
customerType?: 'buyer' | 'broker' | 'professional';
customerType?: 'buyer' | 'seller' | 'professional';
customerSubType?: 'broker' | 'cpa' | 'attorney' | 'titleCompany' | 'surveyor' | 'appraiser';
created?: Date;
updated?: Date;
}
export type Gender = 'male' | 'female';
export type CustomerType = 'buyer' | 'professional';
export type CustomerType = 'buyer' | 'seller' | 'professional';
export type CustomerSubType = 'broker' | 'cpa' | 'attorney' | 'titleCompany' | 'surveyor' | 'appraiser';
export type ListingsCategory = 'commercialProperty' | 'business';
export const GenderEnum = z.enum(['male', 'female']);
export const CustomerTypeEnum = z.enum(['buyer', 'professional']);
export const CustomerTypeEnum = z.enum(['buyer', 'seller', 'professional']);
export const SubscriptionTypeEnum = z.enum(['free', 'professional', 'broker']);
export const CustomerSubTypeEnum = z.enum(['broker', 'cpa', 'attorney', 'titleCompany', 'surveyor', 'appraiser']);
export const ListingsCategoryEnum = z.enum(['commercialProperty', 'business']);

View File

@@ -58,23 +58,19 @@ export class PaymentService {
quantity: 1,
},
],
success_url: 'http://localhost:4200/success',
cancel_url: 'http://localhost:4200/pricing',
success_url: `${process.env.WEB_HOST}/success`,
cancel_url: `${process.env.WEB_HOST}/pricing`,
// customer_email: checkout.email,
customer: customerId,
// customer_details:{
// name: checkout.name, // Hier wird der Name des Kunden übergeben
// },
shipping_address_collection: {
allowed_countries: ['US'],
},
client_reference_id: '1234',
client_reference_id: btoa(checkout.name),
locale: 'en',
subscription_data: {
trial_end: Math.floor(new Date().setMonth(new Date().getMonth() + 3) / 1000),
metadata: { plan: product.name },
},
metadata: { plan: product.name },
});
return session;
} else {
@@ -100,20 +96,11 @@ export class PaymentService {
});
user.stripeCustomerId = session.customer as string;
user.subscriptionId = session.subscription as string;
user.planActive = true;
//session.shipping_details ->
// "shipping_details": {
// "address": {
// "city": "Springfield",
// "country": "US",
// "line1": "West Maple Avenue South",
// "line2": null,
// "postal_code": "62704",
// "state": "IL"
// },
// "name": "Johnathan Miller"
// }
user.subscriptionPlan = session.amount_total === 4900 ? 'broker' : 'professional'; //session.metadata['subscriptionPlan'] as 'free' | 'professional' | 'broker';
user.customerType = 'professional';
if (session.metadata['plan'] === 'Broker Plan') {
user.customerSubType = 'broker';
}
user.subscriptionPlan = session.metadata['plan'] === 'Broker Plan' ? 'broker' : 'professional'; //session.metadata['subscriptionPlan'] as 'free' | 'professional' | 'broker';
this.userService.saveUser(user);
this.mailService.sendSubscriptionConfirmation(user);
}

View File

@@ -52,6 +52,7 @@ export class SelectOptionsService {
];
public customerTypes: Array<KeyValue> = [
{ name: 'Buyer', value: 'buyer' },
{ name: 'Commercial Property Seller', value: 'seller' },
{ name: 'Professional', value: 'professional' },
];
public customerSubTypes: Array<KeyValue> = [