<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ahmed Ben Bettaieb</title>
    <description>The latest articles on DEV Community by Ahmed Ben Bettaieb (@ahmedbenbettaieb).</description>
    <link>https://dev.to/ahmedbenbettaieb</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F856108%2Fae5fb5f3-58dd-4b92-9a39-402f3ddd49dc.png</url>
      <title>DEV Community: Ahmed Ben Bettaieb</title>
      <link>https://dev.to/ahmedbenbettaieb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ahmedbenbettaieb"/>
    <language>en</language>
    <item>
      <title>How to Configure Laravel Reverb with Nginx in Production</title>
      <dc:creator>Ahmed Ben Bettaieb</dc:creator>
      <pubDate>Mon, 13 Apr 2026 09:34:50 +0000</pubDate>
      <link>https://dev.to/ahmedbenbettaieb/how-to-configure-laravel-reverb-with-nginx-in-production-1870</link>
      <guid>https://dev.to/ahmedbenbettaieb/how-to-configure-laravel-reverb-with-nginx-in-production-1870</guid>
      <description>&lt;p&gt;Real-time WebSocket communication in Laravel has never been easier thanks to Laravel Reverb — a first-party WebSocket server that integrates seamlessly with Laravel's broadcasting system. In this guide, I'll walk you through everything needed to get Reverb running behind Nginx in production, including the gotchas that cost me hours of debugging.&lt;/p&gt;

&lt;p&gt;What We're Building&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser (wss://yourdomain.com/app/...)
        ↓
    Nginx :443  ← handles SSL termination
        ↓
  Reverb :8080  ← internal only, managed by Supervisor

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nginx handles all public traffic (HTTP/HTTPS), and Reverb runs quietly on an internal port — never exposed directly to the internet.&lt;/p&gt;

&lt;p&gt;Prerequisites&lt;/p&gt;

&lt;p&gt;Laravel 10+ application already running on Nginx&lt;br&gt;
PHP 8.2+&lt;br&gt;
Node.js &amp;amp; npm&lt;br&gt;
SSL certificate (Let's Encrypt recommended)&lt;br&gt;
Supervisor installed (sudo apt-get install supervisor -y)&lt;/p&gt;

&lt;p&gt;Step 1: Install Laravel Reverb&lt;br&gt;
&lt;code&gt;php artisan install:broadcasting&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Answer yes to all prompts. This installs the Reverb PHP package along with Laravel Echo and pusher-js on the frontend.&lt;/p&gt;

&lt;p&gt;Step 2: Configure Your .env&lt;br&gt;
This is where most people get it wrong. Here's what matters:&lt;br&gt;
For HTTPS (production with domain)&lt;/p&gt;

&lt;p&gt;`BROADCAST_CONNECTION=reverb&lt;br&gt;
QUEUE_CONNECTION=sync&lt;/p&gt;

&lt;p&gt;REVERB_APP_ID=your-app-id&lt;br&gt;
REVERB_APP_KEY=your-app-key&lt;br&gt;
REVERB_APP_SECRET=your-app-secret&lt;br&gt;
REVERB_HOST="yourdomain.com"&lt;br&gt;
REVERB_PORT=443&lt;br&gt;
REVERB_SCHEME=https&lt;/p&gt;
&lt;h1&gt;
  
  
  Internal server config (Reverb listens on this port)
&lt;/h1&gt;

&lt;p&gt;REVERB_SERVER_HOST=127.0.0.1&lt;br&gt;
REVERB_SERVER_PORT=8080&lt;/p&gt;

&lt;p&gt;VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"&lt;br&gt;
VITE_REVERB_HOST="${REVERB_HOST}"&lt;br&gt;
VITE_REVERB_PORT="${REVERB_PORT}"&lt;br&gt;
VITE_REVERB_SCHEME="${REVERB_SCHEME}"`&lt;/p&gt;

&lt;p&gt;For HTTP (development / IP-based server)&lt;br&gt;
`BROADCAST_CONNECTION=reverb&lt;br&gt;
QUEUE_CONNECTION=sync&lt;/p&gt;

&lt;p&gt;REVERB_APP_ID=your-app-id&lt;br&gt;
REVERB_APP_KEY=your-app-key&lt;br&gt;
REVERB_APP_SECRET=your-app-secret&lt;br&gt;
REVERB_HOST="your-server-ip"&lt;br&gt;
REVERB_PORT=80&lt;br&gt;
REVERB_SCHEME=http&lt;/p&gt;

&lt;p&gt;REVERB_SERVER_HOST=127.0.0.1&lt;br&gt;
REVERB_SERVER_PORT=8080&lt;/p&gt;

&lt;p&gt;VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"&lt;br&gt;
VITE_REVERB_HOST="${REVERB_HOST}"&lt;br&gt;
VITE_REVERB_PORT="${REVERB_PORT}"&lt;br&gt;
VITE_REVERB_SCHEME="${REVERB_SCHEME}"`&lt;/p&gt;

&lt;p&gt;⚠️ Common mistake: Don't forget QUEUE_CONNECTION=sync. Without it, broadcast events may never fire even though everything else looks correct.&lt;/p&gt;

&lt;p&gt;Step 3: Configure Nginx&lt;br&gt;
Add the WebSocket proxy blocks to your Nginx server block before location `server {&lt;br&gt;
    listen 443 ssl;&lt;br&gt;
    server_name yourdomain.com;&lt;br&gt;
    root /var/www/your-app/public;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

# WebSocket proxy for Reverb
location /app {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
    proxy_pass http://127.0.0.1:8080;
}

location /apps {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
    proxy_pass http://127.0.0.1:8080;
}

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

location ~ /\.ht {
    deny all;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h1&gt;
  
  
  Redirect HTTP to HTTPS
&lt;/h1&gt;

&lt;p&gt;server {&lt;br&gt;
    listen 80;&lt;br&gt;
    server_name yourdomain.com;&lt;br&gt;
    return 301 https://$host$request_uri;&lt;br&gt;
}`&lt;/p&gt;

&lt;p&gt;Test and reload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nginx &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload nginx
&lt;span class="c"&gt;# OR for Bitnami:&lt;/span&gt;
&lt;span class="nb"&gt;sudo&lt;/span&gt; /opt/bitnami/nginx/sbin/nginx &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;span class="nb"&gt;sudo&lt;/span&gt; /opt/bitnami/ctlscript.sh restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4: Keep Reverb Running with Supervisor&lt;br&gt;
Without Supervisor, Reverb dies the moment your SSH session closes.&lt;br&gt;
sudo nano /etc/supervisor/conf.d/reverb.conf&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[program:reverb]&lt;br&gt;
process_name=%(program_name)s&lt;br&gt;
command=php /var/www/your-app/artisan reverb:start --host=127.0.0.1 --port=8080 --no-interaction&lt;br&gt;
autostart=true&lt;br&gt;
autorestart=true&lt;br&gt;
user=www-data&lt;br&gt;
redirect_stderr=true&lt;br&gt;
stdout_logfile=/var/www/your-app/storage/logs/reverb.log&lt;br&gt;
stopwaitsecs=3600&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Activate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;supervisorctl reread
&lt;span class="nb"&gt;sudo &lt;/span&gt;supervisorctl update
&lt;span class="nb"&gt;sudo &lt;/span&gt;supervisorctl start reverb
&lt;span class="nb"&gt;sudo &lt;/span&gt;supervisorctl status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;reverb    RUNNING   pid 12345, uptime 0:00:05

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 5: Clear Cache &amp;amp; Rebuild Frontend&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /var/www/your-app

php artisan config:clear
php artisan cache:clear

npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 6: Verify Everything Works&lt;br&gt;
Check Reverb is listening internally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ss &lt;span class="nt"&gt;-tlnp&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;8080
&lt;span class="c"&gt;# Should show: LISTEN 0 ... 127.0.0.1:8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test the WebSocket connection using piehost.com/websocket-tester:&lt;/p&gt;

&lt;p&gt;URL: wss://yourdomain.com/app/your-app-key&lt;br&gt;
Click Connect → should say Connection established&lt;/p&gt;

&lt;p&gt;Subscribe to a channel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pusher:subscribe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"channel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"my-channel"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fire a test broadcast from tinker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:event TestBroadcast
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;php artisan make:event TestBroadcast&lt;/p&gt;

&lt;p&gt;Edit app/Events/TestBroadcast.php:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Events&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Broadcasting\Channel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Contracts\Broadcasting\ShouldBroadcast&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestBroadcast&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ShouldBroadcast&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;broadcastOn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'my-channel'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;broadcastAs&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'test.event'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;broadcastWith&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Hello from Reverb!'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
php artisan tinker
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; event&lt;span class="o"&gt;(&lt;/span&gt;new &lt;span class="se"&gt;\A&lt;/span&gt;pp&lt;span class="se"&gt;\E&lt;/span&gt;vents&lt;span class="se"&gt;\T&lt;/span&gt;estBroadcast&lt;span class="o"&gt;())&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the message arrive in the WebSocket tester instantly. ✅&lt;/p&gt;

&lt;p&gt;Summary&lt;br&gt;
The key things that make Reverb work behind Nginx:&lt;/p&gt;

&lt;p&gt;Nginx proxies /app and /apps paths to Reverb's internal port&lt;br&gt;
REVERB_HOST = your public domain (what the browser uses)&lt;br&gt;
REVERB_SERVER_PORT = internal port Reverb listens on (8080)&lt;br&gt;
QUEUE_CONNECTION=sync = ensures broadcasts fire immediately&lt;br&gt;
Supervisor = keeps Reverb alive permanently&lt;/p&gt;

&lt;p&gt;Happy broadcasting! 🚀&lt;/p&gt;

</description>
      <category>devops</category>
      <category>laravel</category>
      <category>php</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Create custom connect and transfer money stripe for non registered countries</title>
      <dc:creator>Ahmed Ben Bettaieb</dc:creator>
      <pubDate>Thu, 15 Jun 2023 14:19:26 +0000</pubDate>
      <link>https://dev.to/ahmedbenbettaieb/create-custom-connect-and-transfer-money-stripe-for-non-registered-countries-3o9m</link>
      <guid>https://dev.to/ahmedbenbettaieb/create-custom-connect-and-transfer-money-stripe-for-non-registered-countries-3o9m</guid>
      <description>&lt;p&gt;Hello, &lt;br&gt;
Through this post I will show how to create a stripe account and make a connect , and transfer money to the connect  using node js (express  with typescript) .&lt;br&gt;
Assuming that your node js project is setup. &lt;br&gt;
first of all you need to create a stripe account (in estonia) :&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=vEbD8SQg5So&amp;amp;ab_channel=DistroTechnologies"&gt;https://www.youtube.com/watch?v=vEbD8SQg5So&amp;amp;ab_channel=DistroTechnologies&lt;/a&gt;&lt;br&gt;
follow this video .&lt;br&gt;
after creating the stripe account you will get your publishable key and secret key , copy  them and put them in .env file .&lt;br&gt;
then run this command :&lt;br&gt;
&lt;code&gt;npm install stripe @types/stripe&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;then make a user model (mongoose) :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`import { Schema, Document, model } from 'mongoose';

// Define the User interface
interface IUser extends Document {
  name: string;
  email: string;
  birthDate: Date;
  accountId: string;
  password: string;
}

// Define the User schema
const UserSchema = new Schema&amp;lt;IUser&amp;gt;({
  name: { type: String, required: true },
  email: { type: String, required: true },
  birthDate: { type: Date, required: true },
  accountId: { type: String, required: true },
  password: { type: String, required: true },
});

// Create and export the User model
const User = model&amp;lt;IUser&amp;gt;('User', UserSchema);
export default User;`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and make sure to make an authMiddleware to verify that the user is authenticated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`import { Request, Response, NextFunction } from "express";
import jwt from "jsonwebtoken";
import dotenv from "dotenv";
dotenv.config();

const authMiddleware = (
  req: Request,
  res: Response,
  next: NextFunction
) =&amp;gt; {
  try {
    const token = req.headers["authorization"]?.split(" ")[1];

    if (!token &amp;amp;&amp;amp; !process.env.JWT_SECRET) {
      // Token does not exist or JWT_SECRET is not set in the environment variables
      console.log("Token does not exist");
      return res.status(401).send({
        message: "Authentication failed!",
        success: false,
      });
    } else {
      jwt.verify(
        token as string,
        process.env.JWT_SECRET as string,
        (err, decoded: any) =&amp;gt; {
          // Verifying the token
          console.log("Verifying token");
          if (err) {
            // Error occurred during token verification
            console.log(err);
            return res.status(401).send({
              message: "JWT verification failed!",
              success: false,
            });
          } else {
            // Token is valid, extracting the user ID from the decoded token and attaching it to the request body
            (req.body as any).userId = (decoded as any)._id;
            next();
          }
        }
      );
    }
  } catch (error: any) {
    // Catching any other errors that might occur
    console.log(error.message);
    return res.status(401).send({
      message: "Authentication failed",
      success: false,
    });
  }
};

export default authMiddleware;`

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then create a folder named routes and under this folder we will create a file named paymentRoute.ts, first of all :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`
//we import the stripe secret key and the public key from .env

const secret: string | undefined = process.env.STRIPE_SECRETKEY;
const publicKey: string | undefined = process.env.STRIPE_PUBLISHABLEKEY;

if (!secret) {
  throw new Error("Stripe secret key not found in environment variables.");
}

// Creating a new instance of the Stripe API using the secret key
const stripe = new Stripe(secret, {
  apiVersion: "2022-11-15",
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;after creating a new instance of stripe  ,we pass to creating the connect ,&lt;br&gt;
first  we create the custom connect  (assuming that the user is already defined ):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.post(
  "/create-stripe-account",
  authMiddleware,
  async (req: Request, res: Response) =&amp;gt; {
    try {
      const user = await User.findOne({ _id: req.body.userId });

      if (user) {
        if (!user.accountId) {
          // Creating a custom Stripe account for the user
          const accountParams: Stripe.AccountCreateParams = {
            country: "EE",
            type: "custom",
            business_type: "individual",
            email: user.email,
            capabilities: {
              card_payments: {
                requested: true,
              },
              transfers: {
                requested: true,
              },
            },
          };

          const account = await stripe.accounts.create(accountParams);

          // Saving the account ID to the user document
          user.accountId = account.id;
          await user.save();

          res.status(200).json({ data: account, success: true });
        } else {
          res
            .status(200)
            .json({ message: "You already have an account", success: false });
        }
      } else {
        res.status(404).json({ message: "User not found" });
      }
    } catch (error) {
      res.status(200).json("Something went wrong");
    }
  }
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if you access to your stripe account ,you will find a new connect but it is restricted .&lt;br&gt;
so , we must update the account using this route :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.put(
  "/update-stripe-account",
  authMiddleware,
  async (req: Request, res: Response) =&amp;gt; {
    try {
      const user = await User.findOne({ _id: req.body.userId });
      if (user) {
        const { firstName, lastName, email, accountId } = user;
        const birthDateString = user.birthDate; // Assuming `user.birthDate` is defined

        if (birthDateString) {
          const dateObj = new Date(birthDateString);

          const day = dateObj.getDate();
          const month = dateObj.getMonth() + 1; // Month is zero-based, so we add 1 to get the correct month
          const year = dateObj.getFullYear();



          const { city, line, postalCode, state, ipAddress, phone ,url,} = req.body;
          const date = Math.floor(Date.now() / 1000);

          const stripeAccount = await stripe.accounts.update(accountId, {
            business_type: "individual",
            settings: {
              payouts: {
                schedule: {
                  interval: "manual" as any,
                },
              },
            },
            email,

            individual: {
              first_name: firstName,
              last_name: lastName,
              email: email,
              maiden_name: firstName + " " + lastName,
              phone: phone,
              address: {
                city,
                line1: line,
                line2: line,
                postal_code: postalCode,
                state,
              },
              dob: {
                day,
                month,
                year,
              },
            },

            business_profile: {
              mcc: "7372",

              url: url,
              product_description:
                "Description of the business's products or services",
            },
            tos_acceptance: {
              date: date,
              ip: ipAddress,
            },
          });
          res.status(200).send({
            success: true,
            data: stripeAccount,
            message: "account updated successfully",
          });
        } else {
          res.status(404).send({
            message:
              "You should update your profile and add the missing information",
            success: false,
          });
        }
      }
    } catch (error) {
      console.log(error);
      res.status(500).json({ message: "something went wrong" });
    }
  }
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MCC stands for Merchant Category Code. It is a four-digit code used to categorize businesses based on the products or services they provide.  you can find mored details in this doc &lt;a href="https://stripe.com/docs/connect/setting-mcc"&gt;https://stripe.com/docs/connect/setting-mcc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;now we should add a payout method , this is the route for adding payout method :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.post(
  "/add-payout-method",
  authMiddleware,
  async (req: Request, res: Response) =&amp;gt; {
    try {
      const user = await User.findOne({ _id: req.body.userId });
      if (user) {
        const accountId = user.accountId;
        const { accountType, accountDetails } = req.body;
        const account_holder_name = `${user.firstName} ${user.lastName}`;

        // Create a bank account or debit card token
        let externalAccountToken;
        if (accountType === "bank") {
          externalAccountToken = await stripe.tokens.create({
            bank_account: {
              country: "EE",
              currency: "eur",
              account_holder_name: account_holder_name,
              account_holder_type: "individual",
              account_number: accountDetails.accountNumber,
            },
          });
        } else if (accountType === "card") {
          externalAccountToken = await stripe.tokens.create({
            card: {
              number: accountDetails.cardNumber,
              exp_month: accountDetails.expMonth,
              exp_year: accountDetails.expYear,
              cvc: accountDetails.cvc,
              currency: "eur",
            },
          });

          const externalAccount = await stripe.accounts.createExternalAccount(
            accountId,
            {
              external_account: externalAccountToken.id,
            }
          );

          await stripe.accounts.update(accountId, {
            capabilities: {
              transfers: { requested: true },
            },
          });
        } else {
          return res.status(400).json({ message: "Invalid account type" });
        }

        // Associate the bank account or debit card with the Stripe account
        await stripe.accounts.createExternalAccount(accountId, {
          external_account: externalAccountToken.id,
        });

        res
          .status(200)
          .json({ success: true, message: "Payout method added successfully" });
      } else {
        res.status(404).json({ message: "User not found" });
      }
    } catch (error) {
      res.status(500).json({ error });
    }
  }
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;test this route with this json file :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "accountType": "bank",
  "accountDetails": {
    "accountNumber": "EE382200221020145685"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;after adding payout method now the custom connect is ready to receive money  , this is the route for making transfer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.post("/transaction/:contractId", authMiddleware, async (req, res) =&amp;gt; {
  try {
    const user = await User.findOne({ _id: req.body.userId });

    const contract = await Contract.findOne({
      _id: req.params.contractId,
    });
    if (user &amp;amp;&amp;amp; contract) {
      const paymentIntent = await stripe.paymentIntents.create(
        {
          amount: contract.price,
          currency: "eur",
          automatic_payment_methods: {
            enabled: true,
          },
        },
        {
          stripeAccount: user.accountId,
        }
      );

      console.log("user and contract found");
      const freelancerTransfer = await stripe.transfers.create({
        amount: contract.price*99,
        currency: "eur",
        destination: user.accountId,
      });


      user.unSeenNotifications.push(
        "your transaction is  created successfully"
      );
      user.save();

      res.status(200).json({
        message: "Transfer created successfully",

      });
    } else {
      res.status(404).json({ message: "User or contract not found" });
    }
  } catch (error) {
    res.status(500).json({ error });
  }
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for my project , the amount was taken from the contract price .&lt;br&gt;
after making the the last route and test it with postman  ,and we can access to our stripe dashboard :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J_P4Gynv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5lrn1ptmwny73bzk6f00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J_P4Gynv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5lrn1ptmwny73bzk6f00.png" alt="Dashboard" width="800" height="113"&gt;&lt;/a&gt;&lt;br&gt;
we see that the connect has received his money and he is ready to payout.&lt;/p&gt;

&lt;p&gt;Note:I'm speaking for test mode&lt;/p&gt;

&lt;p&gt;That's it , I wish  it was helpful !&lt;br&gt;
I'm waiting for  your feedbacks&lt;/p&gt;

</description>
    </item>
    <item>
      <title>TypeError: this.userRepository.signUp is not a function</title>
      <dc:creator>Ahmed Ben Bettaieb</dc:creator>
      <pubDate>Mon, 24 Oct 2022 22:47:04 +0000</pubDate>
      <link>https://dev.to/ahmedbenbettaieb/typeerror-thisuserrepositorysignup-is-not-a-function-47cm</link>
      <guid>https://dev.to/ahmedbenbettaieb/typeerror-thisuserrepositorysignup-is-not-a-function-47cm</guid>
      <description>&lt;p&gt;I'm new on nest js and I encountered this error while developping login service ``import { Injectable } from '@nestjs/common';&lt;br&gt;
import { UserRepository } from './user.repository';&lt;br&gt;
import { InjectRepository } from '@nestjs/typeorm';&lt;br&gt;
import { AuthSignUpDto } from './dto/auth-signup.dto';&lt;/p&gt;

&lt;p&gt;@Injectable()&lt;br&gt;
export class AuthService {&lt;br&gt;
  constructor(&lt;br&gt;
    @InjectRepository(UserRepository)&lt;br&gt;
    private userRepository: UserRepository,&lt;br&gt;
  ) {}&lt;br&gt;
  async signUp(authSignUpDto: AuthSignUpDto): Promise {&lt;br&gt;
    return this.userRepository.signUp(authSignUpDto)&lt;br&gt;
  }&lt;br&gt;
}&lt;code&gt;&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

</description>
      <category>nestjs</category>
    </item>
    <item>
      <title>Route is not working</title>
      <dc:creator>Ahmed Ben Bettaieb</dc:creator>
      <pubDate>Sun, 01 May 2022 14:07:01 +0000</pubDate>
      <link>https://dev.to/ahmedbenbettaieb/route-is-not-working-4llk</link>
      <guid>https://dev.to/ahmedbenbettaieb/route-is-not-working-4llk</guid>
      <description>&lt;p&gt;I'am working on a full stach web site using spring and angular  but the routes are not working &lt;br&gt;
this is the spring boot application code to  search category by ID &lt;br&gt;
 &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gskC8x39--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ue2atxt5lvo5m43d2x23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gskC8x39--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ue2atxt5lvo5m43d2x23.png" alt="Image description" width="800" height="133"&gt;&lt;/a&gt;&lt;br&gt;
and here is the routes &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S84WK5si--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ye90xky84mudlpg50rt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S84WK5si--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ye90xky84mudlpg50rt.png" alt="Image description" width="664" height="230"&gt;&lt;/a&gt;&lt;br&gt;
and this is the product service  class and the his urls &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ofPa32xS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kor1myrl3ykee394xv1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ofPa32xS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kor1myrl3ykee394xv1z.png" alt="Image description" width="800" height="346"&gt;&lt;/a&gt;&lt;br&gt;
and this is the product list component &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---EHohXv_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igixvjg0mkc14qnx5fxe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---EHohXv_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igixvjg0mkc14qnx5fxe.png" alt="Image description" width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
