<?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: Shitanshu Jha</title>
    <description>The latest articles on DEV Community by Shitanshu Jha (@shitanshu686).</description>
    <link>https://dev.to/shitanshu686</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4089061%2Fdf0bb2f6-2ea8-4a39-acbf-b290296a5e68.jpg</url>
      <title>DEV Community: Shitanshu Jha</title>
      <link>https://dev.to/shitanshu686</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shitanshu686"/>
    <language>en</language>
    <item>
      <title>🚀 Building the ShopEase Admin Dashboard — Challenges, Solutions &amp; What I Learned By Shitanshu Jha</title>
      <dc:creator>Shitanshu Jha</dc:creator>
      <pubDate>Wed, 26 Aug 2026 06:26:59 +0000</pubDate>
      <link>https://dev.to/shitanshu686/building-the-shopease-admin-dashboard-challenges-solutions-what-i-learnedby-shitanshu-jha-25dp</link>
      <guid>https://dev.to/shitanshu686/building-the-shopease-admin-dashboard-challenges-solutions-what-i-learnedby-shitanshu-jha-25dp</guid>
      <description>&lt;p&gt;While developing ShopEase, my goal was not just to create a basic e-commerce website. I wanted to build it as a complete application while learning how real-world Java backend systems are designed.&lt;/p&gt;

&lt;p&gt;I am currently developing ShopEase as a full-stack e-commerce application using Java, Spring Boot, Spring Data JPA, Hibernate, MySQL, HTML, CSS and JavaScript.&lt;/p&gt;

&lt;p&gt;One of the major milestones in this journey was Module 23 — Admin Dashboard.&lt;/p&gt;

&lt;p&gt;The dashboard started as a simple admin page, but gradually became a proper management system for products, users, orders, order statuses and inventory.&lt;/p&gt;

&lt;p&gt;🛠️ What I Built&lt;/p&gt;

&lt;p&gt;The ShopEase Admin Dashboard currently provides:&lt;/p&gt;

&lt;p&gt;📊 Dashboard statistics&lt;br&gt;
📦 Product Management&lt;br&gt;
👥 User Management&lt;br&gt;
🛒 Order Management&lt;br&gt;
🔄 Order Status Management&lt;br&gt;
📋 Inventory Management&lt;br&gt;
⚠️ Low Stock Alerts&lt;br&gt;
❌ Out-of-Stock Alerts&lt;br&gt;
🕐 Recent Orders&lt;/p&gt;

&lt;p&gt;The dashboard communicates with my Spring Boot backend through REST APIs and retrieves the required data from MySQL using Spring Data JPA.&lt;/p&gt;

&lt;p&gt;😵 The Challenges I Faced&lt;/p&gt;

&lt;p&gt;Building the dashboard wasn't as straightforward as I initially expected.&lt;/p&gt;

&lt;p&gt;The biggest challenges were not creating the HTML cards or buttons. The difficult part was making sure that the frontend, backend, database and business logic were all connected correctly.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Calculating Dashboard Statistics&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Initially, the dashboard needed to display information such as:&lt;br&gt;
Total Products&lt;br&gt;
Total Users&lt;br&gt;
Total Orders&lt;br&gt;
Total Revenue&lt;/p&gt;

&lt;p&gt;The challenge was deciding where these values should actually come from.&lt;/p&gt;

&lt;p&gt;Instead of calculating everything on the frontend, I implemented the logic on the backend.&lt;/p&gt;

&lt;p&gt;For example, product and user counts are retrieved using repository operations:&lt;/p&gt;

&lt;p&gt;productRepository.count();&lt;br&gt;
userRepository.count();&lt;/p&gt;

&lt;p&gt;Similarly, total revenue required a database query that considers only confirmed orders.&lt;/p&gt;

&lt;p&gt;This taught me an important lesson:&lt;/p&gt;

&lt;p&gt;Dashboard statistics should come from reliable backend data rather than being calculated or trusted on the client side.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Implementing Inventory Alerts&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One of the more interesting parts was implementing inventory monitoring.&lt;/p&gt;

&lt;p&gt;I wanted the dashboard to show:&lt;/p&gt;

&lt;p&gt;Low Stock&lt;br&gt;
Out of Stock&lt;/p&gt;

&lt;p&gt;I implemented repository queries such as:&lt;/p&gt;

&lt;p&gt;long lowStockProducts =&lt;br&gt;
        productRepository.countByStockBetween(1, 10);&lt;/p&gt;

&lt;p&gt;long outOfStockProducts =&lt;br&gt;
        productRepository.countByStock(0);&lt;/p&gt;

&lt;p&gt;This allowed the backend to directly determine the inventory status.&lt;/p&gt;

&lt;p&gt;The dashboard could then display something like:&lt;/p&gt;

&lt;p&gt;⚠️ Low Stock       13&lt;/p&gt;

&lt;p&gt;❌ Out of Stock     1&lt;/p&gt;

&lt;p&gt;This was a good example of how a simple UI feature actually requires proper backend and database logic behind it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fetching Recent Orders&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Another requirement was displaying the latest orders on the Admin Dashboard.&lt;/p&gt;

&lt;p&gt;Instead of returning every order and filtering it on the frontend, I created a repository-level query to retrieve recent orders.&lt;/p&gt;

&lt;p&gt;The backend then converts the Order entities into a dedicated DTO:&lt;/p&gt;

&lt;p&gt;AdminRecentOrderDTO&lt;/p&gt;

&lt;p&gt;The response contains information such as:&lt;/p&gt;

&lt;p&gt;Order ID&lt;br&gt;
Customer name&lt;br&gt;
Total amount&lt;br&gt;
Order status&lt;br&gt;
Order creation time&lt;/p&gt;

&lt;p&gt;This helped me understand why DTOs are useful when exposing database entities through APIs.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connecting Everything Through a Dashboard Service&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I didn't want the controller to contain all the dashboard business logic.&lt;/p&gt;

&lt;p&gt;So I created:&lt;/p&gt;

&lt;p&gt;AdminDashboardService&lt;/p&gt;

&lt;p&gt;The service is responsible for collecting:&lt;/p&gt;

&lt;p&gt;Products&lt;br&gt;
Users&lt;br&gt;
Orders&lt;br&gt;
Revenue&lt;br&gt;
Inventory&lt;br&gt;
Recent Orders&lt;/p&gt;

&lt;p&gt;and combining them into:&lt;/p&gt;

&lt;p&gt;AdminDashboardResponseDTO&lt;/p&gt;

&lt;p&gt;This gave me a much cleaner architecture:&lt;/p&gt;

&lt;p&gt;Frontend&lt;br&gt;
   ↓&lt;br&gt;
Controller&lt;br&gt;
   ↓&lt;br&gt;
Service&lt;br&gt;
   ↓&lt;br&gt;
Repository&lt;br&gt;
   ↓&lt;br&gt;
MySQL&lt;/p&gt;

&lt;p&gt;Working through this helped me understand the importance of separating responsibilities instead of putting everything inside one class.&lt;/p&gt;

&lt;p&gt;🐛 Debugging Was a Major Part of the Work&lt;/p&gt;

&lt;p&gt;One thing I learned while developing ShopEase is that writing code is only half the job.&lt;/p&gt;

&lt;p&gt;A lot of my time went into debugging.&lt;/p&gt;

&lt;p&gt;For example, I encountered issues where repository methods were not recognized correctly, constructors didn't match DTO parameters, and entity fields differed from what the service expected.&lt;/p&gt;

&lt;p&gt;There were also situations where the dashboard displayed incorrect inventory numbers.&lt;/p&gt;

&lt;p&gt;Instead of randomly changing code, I started checking the complete flow:&lt;/p&gt;

&lt;p&gt;Database&lt;br&gt;
   ↓&lt;br&gt;
Repository&lt;br&gt;
   ↓&lt;br&gt;
Service&lt;br&gt;
   ↓&lt;br&gt;
DTO&lt;br&gt;
   ↓&lt;br&gt;
Controller&lt;br&gt;
   ↓&lt;br&gt;
API Response&lt;br&gt;
   ↓&lt;br&gt;
Frontend&lt;/p&gt;

&lt;p&gt;That approach made debugging much easier.&lt;/p&gt;

&lt;p&gt;📊 Testing the Dashboard&lt;/p&gt;

&lt;p&gt;After implementing the features, I tested the dashboard with actual application data.&lt;/p&gt;

&lt;p&gt;For example, the backend returned dashboard information similar to:&lt;/p&gt;

&lt;p&gt;Total Products: 58&lt;br&gt;
Total Users: 9&lt;br&gt;
Total Orders: 21&lt;br&gt;
Total Revenue: 7798&lt;br&gt;
Low Stock Products: 13&lt;br&gt;
Out of Stock Products: 1&lt;/p&gt;

&lt;p&gt;I also tested inventory changes by changing product stock values in the database and verifying that the dashboard updated accordingly.&lt;/p&gt;

&lt;p&gt;This helped confirm that the values weren't hardcoded and were actually coming from the database.&lt;/p&gt;

&lt;p&gt;🔐 Admin-Specific Functionality&lt;/p&gt;

&lt;p&gt;Another important part was making sure that administrative functionality was separated from normal user functionality.&lt;/p&gt;

&lt;p&gt;ShopEase already has role-based behavior for:&lt;/p&gt;

&lt;p&gt;USER&lt;br&gt;
ADMIN&lt;/p&gt;

&lt;p&gt;The Admin Dashboard is therefore intended for administrative operations such as:&lt;/p&gt;

&lt;p&gt;Managing products&lt;br&gt;
Managing users&lt;br&gt;
Managing orders&lt;br&gt;
Updating order status&lt;br&gt;
Monitoring inventory&lt;/p&gt;

&lt;p&gt;This made me think more seriously about authorization and access control, rather than treating an admin page as just another frontend page.&lt;/p&gt;

&lt;p&gt;🚀 From Admin Page to Production-Ready Module&lt;/p&gt;

&lt;p&gt;The biggest takeaway from this module is that a dashboard isn't just a collection of cards.&lt;/p&gt;

&lt;p&gt;A proper admin dashboard requires:&lt;/p&gt;

&lt;p&gt;UI&lt;br&gt;
+&lt;br&gt;
REST APIs&lt;br&gt;
+&lt;br&gt;
Business Logic&lt;br&gt;
+&lt;br&gt;
Database Queries&lt;br&gt;
+&lt;br&gt;
DTOs&lt;br&gt;
+&lt;br&gt;
Validation&lt;br&gt;
+&lt;br&gt;
Authorization&lt;br&gt;
+&lt;br&gt;
Error Handling&lt;br&gt;
+&lt;br&gt;
Testing&lt;/p&gt;

&lt;p&gt;That is what made this module much more valuable for me than simply designing an admin interface.&lt;/p&gt;

&lt;p&gt;🧠 What I Learned&lt;/p&gt;

&lt;p&gt;While working on this module, I learned and practiced:&lt;/p&gt;

&lt;p&gt;Spring Boot service-layer architecture&lt;br&gt;
Spring Data JPA repository queries&lt;br&gt;
DTO-based API responses&lt;br&gt;
Database aggregation&lt;br&gt;
Inventory management logic&lt;br&gt;
Order management&lt;br&gt;
Role-based functionality&lt;br&gt;
Debugging backend/frontend integration&lt;br&gt;
API testing&lt;br&gt;
Separating business logic from controllers&lt;br&gt;
Designing features around actual application data&lt;/p&gt;

&lt;p&gt;More importantly, I learned that production-ready development is mostly about handling the problems that appear between different parts of the system.&lt;/p&gt;

&lt;p&gt;👨‍💻 About Me&lt;/p&gt;

&lt;p&gt;I'm Shitanshu Jha, a BCA student and developer currently building ShopEase as a hands-on project to strengthen my skills in Java backend and full-stack development.&lt;/p&gt;

&lt;p&gt;Instead of only learning technologies theoretically, I'm trying to understand them by building a complete application step by step.&lt;/p&gt;

&lt;p&gt;With ShopEase, I'm working with:&lt;/p&gt;

&lt;p&gt;Java&lt;br&gt;
Spring Boot&lt;br&gt;
Spring MVC&lt;br&gt;
Spring Data JPA&lt;br&gt;
Hibernate&lt;br&gt;
MySQL&lt;br&gt;
REST APIs&lt;br&gt;
JWT&lt;br&gt;
Spring Security&lt;br&gt;
HTML&lt;br&gt;
CSS&lt;br&gt;
JavaScript&lt;br&gt;
Git &amp;amp; GitHub&lt;br&gt;
Postman&lt;/p&gt;

&lt;p&gt;ShopEase is still an ongoing project, and I'm continuing to improve it module by module.&lt;/p&gt;

&lt;p&gt;The objective isn't simply to finish another college project.&lt;/p&gt;

&lt;p&gt;I'm using ShopEase to understand how real software is designed, debugged, tested and gradually made production-ready.&lt;/p&gt;

&lt;p&gt;🚀 What's Next?&lt;/p&gt;

&lt;p&gt;With the Admin Dashboard completed, ShopEase has moved into Phase 6 — Production Ready.&lt;/p&gt;

&lt;p&gt;The next focus is improving the application's production-level capabilities, including:&lt;/p&gt;

&lt;p&gt;Logging&lt;br&gt;
Better error tracking&lt;br&gt;
Reliability&lt;br&gt;
Security improvements&lt;br&gt;
Performance&lt;br&gt;
Deployment considerations&lt;/p&gt;

&lt;p&gt;There is still a lot to build, but every module is teaching me something that a tutorial alone couldn't.&lt;/p&gt;

&lt;p&gt;ShopEase is not finished yet — and that's the point.&lt;/p&gt;

&lt;h1&gt;
  
  
  Java
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Spring Boot
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Backend Development
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Full Stack Development
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Web Development
&lt;/h1&gt;

</description>
      <category>backend</category>
      <category>database</category>
      <category>java</category>
      <category>springboot</category>
    </item>
    <item>
      <title>I Integrated Razorpay Payments into My Java Spring Boot E-Commerce Project — Challenges, Bugs, and What I Learned</title>
      <dc:creator>Shitanshu Jha</dc:creator>
      <pubDate>Sun, 23 Aug 2026 12:13:24 +0000</pubDate>
      <link>https://dev.to/shitanshu686/i-integrated-razorpay-payments-into-my-java-spring-boot-e-commerce-project-challenges-bugs-and-21f3</link>
      <guid>https://dev.to/shitanshu686/i-integrated-razorpay-payments-into-my-java-spring-boot-e-commerce-project-challenges-bugs-and-21f3</guid>
      <description>&lt;p&gt;&lt;strong&gt;💳 Integrating Razorpay Payment Gateway into My Java Spring Boot E-Commerce Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Building an e-commerce application is not just about displaying products and adding them to a cart.&lt;/p&gt;

&lt;p&gt;At some point, the application needs to handle one of the most important parts of the entire flow:&lt;/p&gt;

&lt;p&gt;Payments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F472kl5kbjc5gcjjfz693.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F472kl5kbjc5gcjjfz693.png" alt=" " width="800" height="443"&gt;&lt;/a&gt;&lt;br&gt;
While working on my ShopEase, a full-stack e-commerce application built with Java Spring Boot, MySQL, JavaScript and JWT authentication, I recently implemented Razorpay Test Mode payments.&lt;/p&gt;

&lt;p&gt;The implementation looked straightforward at first:&lt;br&gt;
Checkout&lt;br&gt;
   ↓&lt;br&gt;
Create Order&lt;br&gt;
   ↓&lt;br&gt;
Create Razorpay Order&lt;br&gt;
   ↓&lt;br&gt;
Open Razorpay Checkout&lt;br&gt;
   ↓&lt;br&gt;
Verify Payment&lt;br&gt;
   ↓&lt;br&gt;
Confirm Order&lt;br&gt;
But in practice, there were several problems that I had to debug and solve.&lt;/p&gt;

&lt;p&gt;This post documents what I actually implemented, the problems I faced, and what I learned from them.&lt;/p&gt;

&lt;p&gt;🛒 About ShopEase&lt;/p&gt;

&lt;p&gt;ShopEase is my full-stack e-commerce project.&lt;/p&gt;

&lt;p&gt;Tech Stack&lt;/p&gt;

&lt;p&gt;Frontend&lt;/p&gt;

&lt;p&gt;HTML&lt;br&gt;
CSS&lt;br&gt;
JavaScript&lt;br&gt;
Fetch API&lt;br&gt;
LocalStorage&lt;/p&gt;

&lt;p&gt;Backend&lt;/p&gt;

&lt;p&gt;Java&lt;br&gt;
Spring Boot&lt;br&gt;
Spring MVC&lt;br&gt;
Spring Data JPA&lt;br&gt;
Hibernate&lt;br&gt;
Spring Security&lt;br&gt;
JWT&lt;br&gt;
BCrypt&lt;/p&gt;

&lt;p&gt;Database&lt;/p&gt;

&lt;p&gt;MySQL&lt;/p&gt;

&lt;p&gt;Payment Gateway&lt;/p&gt;

&lt;p&gt;Razorpay&lt;/p&gt;

&lt;p&gt;Tools&lt;/p&gt;

&lt;p&gt;Eclipse&lt;br&gt;
Postman&lt;br&gt;
XAMPP&lt;br&gt;
Git&lt;br&gt;
GitHub&lt;/p&gt;

&lt;p&gt;Before implementing payments, I already had:&lt;/p&gt;

&lt;p&gt;User authentication&lt;br&gt;
JWT authorization&lt;br&gt;
Product system&lt;br&gt;
Shopping cart&lt;br&gt;
Wishlist&lt;br&gt;
Checkout&lt;br&gt;
Order creation&lt;br&gt;
Order history&lt;/p&gt;

&lt;p&gt;So the next logical step was integrating payments.&lt;/p&gt;

&lt;p&gt;🎯 What I Wanted to Build&lt;/p&gt;

&lt;p&gt;I didn't want Razorpay to simply open a payment popup.&lt;/p&gt;

&lt;p&gt;I wanted a complete payment lifecycle.&lt;/p&gt;

&lt;p&gt;The final architecture became:&lt;br&gt;
User&lt;br&gt;
 ↓&lt;br&gt;
Cart&lt;br&gt;
 ↓&lt;br&gt;
Checkout&lt;br&gt;
 ↓&lt;br&gt;
POST /orders&lt;br&gt;
 ↓&lt;br&gt;
ShopEase Order Created&lt;br&gt;
 ↓&lt;br&gt;
POST /payments/create&lt;br&gt;
 ↓&lt;br&gt;
Razorpay Order Created&lt;br&gt;
 ↓&lt;br&gt;
Razorpay Checkout&lt;br&gt;
 ↓&lt;br&gt;
Payment&lt;br&gt;
 ├── SUCCESS&lt;br&gt;
 │      ↓&lt;br&gt;
 │   Verify Signature&lt;br&gt;
 │      ↓&lt;br&gt;
 │   Payment = SUCCESS&lt;br&gt;
 │      ↓&lt;br&gt;
 │   Order = CONFIRMED&lt;br&gt;
 │      ↓&lt;br&gt;
 │   Cart Cleared&lt;br&gt;
 │&lt;br&gt;
 └── FAILURE&lt;br&gt;
        ↓&lt;br&gt;
     Payment = FAILED&lt;br&gt;
        ↓&lt;br&gt;
     Order = PENDING&lt;br&gt;
        ↓&lt;br&gt;
     Cart Preserved&lt;br&gt;
This distinction between ShopEase Order and Razorpay Order was one of the most important concepts I learned during the implementation.&lt;/p&gt;

&lt;p&gt;🧩 Step 1 — Creating a Razorpay Order&lt;/p&gt;

&lt;p&gt;I created a backend endpoint:&lt;br&gt;
POST /payments/create&lt;br&gt;
The frontend sends:&lt;/p&gt;

&lt;p&gt;orderId&lt;br&gt;
amount&lt;/p&gt;

&lt;p&gt;The backend first finds the ShopEase order.&lt;/p&gt;

&lt;p&gt;Then I validate that the payment amount matches the actual order amount.&lt;/p&gt;

&lt;p&gt;if (!order.getTotalAmount().equals(amount)) {&lt;br&gt;
    throw new RuntimeException(&lt;br&gt;
        "Payment amount does not match order amount"&lt;br&gt;
    );&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;I then convert the amount into paise:&lt;/p&gt;

&lt;p&gt;int amountInPaise =&lt;br&gt;
        (int) Math.round(amount * 100);&lt;/p&gt;

&lt;p&gt;and create the Razorpay order.&lt;/p&gt;

&lt;p&gt;The Razorpay order ID is then stored in my Payment entity.&lt;/p&gt;

&lt;p&gt;This gives me a relationship like:&lt;/p&gt;

&lt;p&gt;ShopEase Order&lt;br&gt;
      ↓&lt;br&gt;
Payment&lt;br&gt;
      ↓&lt;br&gt;
Razorpay Order ID&lt;br&gt;
🔐 Step 2 — Payment Verification&lt;/p&gt;

&lt;p&gt;One of the most important parts of the integration was payment verification.&lt;/p&gt;

&lt;p&gt;After successful payment, Razorpay provides:&lt;/p&gt;

&lt;p&gt;razorpay_order_id&lt;br&gt;
razorpay_payment_id&lt;br&gt;
razorpay_signature&lt;/p&gt;

&lt;p&gt;I send these values to:&lt;/p&gt;

&lt;p&gt;POST /payments/verify&lt;/p&gt;

&lt;p&gt;The backend constructs the signature payload:&lt;/p&gt;

&lt;p&gt;String payload =&lt;br&gt;
        razorpayOrderId&lt;br&gt;
        + "|"&lt;br&gt;
        + razorpayPaymentId;&lt;/p&gt;

&lt;p&gt;Then I verify the signature using the Razorpay secret:&lt;/p&gt;

&lt;p&gt;Utils.verifySignature(&lt;br&gt;
    payload,&lt;br&gt;
    razorpaySignature,&lt;br&gt;
    System.getenv("RAZORPAY_KEY_SECRET")&lt;br&gt;
);&lt;/p&gt;

&lt;p&gt;I deliberately kept the secret on the backend instead of exposing it in JavaScript.&lt;/p&gt;

&lt;p&gt;🐛 Challenge 1 — Order ID Was Missing&lt;/p&gt;

&lt;p&gt;This was one of the first real bugs I encountered.&lt;/p&gt;

&lt;p&gt;The frontend initially expected the order response to directly contain the order ID.&lt;/p&gt;

&lt;p&gt;But my backend response was wrapped inside my standard:&lt;/p&gt;

&lt;p&gt;ApiResponse&lt;/p&gt;

&lt;p&gt;The actual response structure was effectively:&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
  "success": true,&lt;br&gt;
  "message": "Order placed successfully",&lt;br&gt;
  "data": {&lt;br&gt;
    "orderId": 14,&lt;br&gt;
    "totalAmount": 4299&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;My frontend initially wasn't extracting the nested data correctly.&lt;/p&gt;

&lt;p&gt;This resulted in:&lt;/p&gt;

&lt;p&gt;Order created but Order ID was not received.&lt;/p&gt;

&lt;p&gt;I debugged it by printing the raw response:&lt;/p&gt;

&lt;p&gt;console.log(&lt;br&gt;
    "RAW ORDER RESPONSE:",&lt;br&gt;
    JSON.stringify(order, null, 2)&lt;br&gt;
);&lt;/p&gt;

&lt;p&gt;The response showed me that I was reading the wrong level of the JSON structure.&lt;/p&gt;

&lt;p&gt;I fixed the API layer so that placeOrder() returns:&lt;/p&gt;

&lt;p&gt;return {&lt;br&gt;
    orderId: order.orderId,&lt;br&gt;
    totalAmount: order.totalAmount&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;This was a good reminder that frontend/backend integration bugs are often response-contract bugs, not business-logic bugs.&lt;/p&gt;

&lt;p&gt;🐛 Challenge 2 — Razorpay Was Not Opening Reliably&lt;/p&gt;

&lt;p&gt;Another confusing problem was that Razorpay sometimes didn't open when I clicked Place Order from the cart flow.&lt;/p&gt;

&lt;p&gt;But when I manually opened Checkout.html, it worked.&lt;/p&gt;

&lt;p&gt;I initially suspected Razorpay itself.&lt;/p&gt;

&lt;p&gt;The actual problem was in my application flow and state handling around the cart/checkout page.&lt;/p&gt;

&lt;p&gt;I traced the complete flow instead of assuming the payment gateway was broken:&lt;/p&gt;

&lt;p&gt;Cart&lt;br&gt;
 ↓&lt;br&gt;
Checkout&lt;br&gt;
 ↓&lt;br&gt;
Create Order&lt;br&gt;
 ↓&lt;br&gt;
Create Razorpay Order&lt;br&gt;
 ↓&lt;br&gt;
Open Razorpay&lt;/p&gt;

&lt;p&gt;This debugging process helped me separate:&lt;/p&gt;

&lt;p&gt;application bugs&lt;/p&gt;

&lt;p&gt;from&lt;/p&gt;

&lt;p&gt;payment gateway bugs.&lt;/p&gt;

&lt;p&gt;That distinction saved a lot of time.&lt;/p&gt;

&lt;p&gt;🐛 Challenge 3 — Payment Failed But Database Still Had CREATED&lt;/p&gt;

&lt;p&gt;This was a more important backend problem.&lt;/p&gt;

&lt;p&gt;When a Razorpay payment failed, I initially had a record like:&lt;/p&gt;

&lt;p&gt;Payment&lt;br&gt;
Status = CREATED&lt;/p&gt;

&lt;p&gt;even though the user had already failed the payment.&lt;/p&gt;

&lt;p&gt;That meant my database wasn't representing the actual payment state.&lt;/p&gt;

&lt;p&gt;I implemented a failure endpoint:&lt;/p&gt;

&lt;p&gt;POST /payments/fail&lt;/p&gt;

&lt;p&gt;and added logic to update the payment:&lt;/p&gt;

&lt;p&gt;payment.setStatus(&lt;br&gt;
    PaymentStatus.FAILED&lt;br&gt;
);&lt;/p&gt;

&lt;p&gt;paymentRepository.save(payment);&lt;/p&gt;

&lt;p&gt;The frontend listens for Razorpay's failure event:&lt;/p&gt;

&lt;p&gt;razorpay.on(&lt;br&gt;
    "payment.failed",&lt;br&gt;
    async function(response) {&lt;br&gt;
        ...&lt;br&gt;
    }&lt;br&gt;
);&lt;/p&gt;

&lt;p&gt;and records the failure on the backend.&lt;/p&gt;

&lt;p&gt;After that, my database correctly reflected:&lt;/p&gt;

&lt;p&gt;Payment → FAILED&lt;br&gt;
🐛 Challenge 4 — Failed Payment Was Clearing My Cart&lt;/p&gt;

&lt;p&gt;This was probably the most important business-logic issue I encountered.&lt;/p&gt;

&lt;p&gt;Initially, the order creation flow deleted cart items immediately after creating the order.&lt;/p&gt;

&lt;p&gt;That produced this problem:&lt;/p&gt;

&lt;p&gt;Cart&lt;br&gt;
 ↓&lt;br&gt;
Create Order&lt;br&gt;
 ↓&lt;br&gt;
Cart deleted ❌&lt;br&gt;
 ↓&lt;br&gt;
Payment&lt;br&gt;
 ↓&lt;br&gt;
Payment FAILED&lt;/p&gt;

&lt;p&gt;Now the customer had paid nothing, but their cart was already empty.&lt;/p&gt;

&lt;p&gt;That's bad e-commerce behavior.&lt;/p&gt;

&lt;p&gt;✅ The Solution — Clear Cart Only After Successful Payment&lt;/p&gt;

&lt;p&gt;I changed the flow so that creating an order does not immediately delete the cart.&lt;/p&gt;

&lt;p&gt;Instead:&lt;/p&gt;

&lt;p&gt;Order Created&lt;br&gt;
 ↓&lt;br&gt;
Payment Created&lt;br&gt;
 ↓&lt;br&gt;
Razorpay Payment&lt;/p&gt;

&lt;p&gt;Only after successful payment verification:&lt;/p&gt;

&lt;p&gt;Payment SUCCESS&lt;br&gt;
 ↓&lt;br&gt;
Order CONFIRMED&lt;br&gt;
 ↓&lt;br&gt;
Cart Cleared&lt;/p&gt;

&lt;p&gt;The backend finds the user's cart:&lt;/p&gt;

&lt;p&gt;Cart cart =&lt;br&gt;
        cartRepository&lt;br&gt;
        .findByUser(order.getUser())&lt;br&gt;
        .orElse(null);&lt;/p&gt;

&lt;p&gt;Then retrieves its items:&lt;/p&gt;

&lt;p&gt;List cartItems =&lt;br&gt;
        cartItemRepository&lt;br&gt;
        .findByCart(cart);&lt;/p&gt;

&lt;p&gt;and deletes them only after successful payment.&lt;/p&gt;

&lt;p&gt;This gives the correct behavior:&lt;/p&gt;

&lt;p&gt;Successful payment&lt;br&gt;
Payment = SUCCESS&lt;br&gt;
Order = CONFIRMED&lt;br&gt;
Cart = EMPTY&lt;br&gt;
Failed payment&lt;br&gt;
Payment = FAILED&lt;br&gt;
Order = PENDING&lt;br&gt;
Cart = PRESERVED&lt;br&gt;
🧠 Challenge 5 — Java Method/Brace Error&lt;/p&gt;

&lt;p&gt;While modifying PaymentService, I also introduced a simple but annoying Java structure error.&lt;/p&gt;

&lt;p&gt;I accidentally placed:&lt;/p&gt;

&lt;p&gt;markPaymentAsFailed()&lt;/p&gt;

&lt;p&gt;inside:&lt;/p&gt;

&lt;p&gt;verifyPayment()&lt;/p&gt;

&lt;p&gt;because a closing brace was missing.&lt;/p&gt;

&lt;p&gt;The compiler then highlighted:&lt;/p&gt;

&lt;p&gt;return true;&lt;/p&gt;

&lt;p&gt;which initially made it look like return true itself was the problem.&lt;/p&gt;

&lt;p&gt;The actual issue was the method structure.&lt;/p&gt;

&lt;p&gt;The correct structure is:&lt;/p&gt;

&lt;p&gt;verifyPayment() {&lt;br&gt;
    ...&lt;br&gt;
    return true;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;markPaymentAsFailed() {&lt;br&gt;
    ...&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;This was a small bug, but it reinforced an important debugging lesson:&lt;/p&gt;

&lt;p&gt;When Java highlights a perfectly valid line, don't automatically assume that line is the real problem. Check the surrounding structure first.&lt;/p&gt;

&lt;p&gt;🔄 Final Payment Flow&lt;/p&gt;

&lt;p&gt;After fixing these issues, the complete flow became:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             SHOP EASE
                 │
               Cart
                 │
             Checkout
                 │
          Create Order
                 │
          MySQL Order
                 │
      Create Razorpay Order
                 │
         Razorpay Checkout
             /       \
            /         \
       SUCCESS       FAILURE
          │              │
   Verify Signature      │
          │              │
    Payment SUCCESS  Payment FAILED
          │              │
   Order CONFIRMED   Order PENDING
          │              │
     Clear Cart     Keep Cart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;🧪 Testing&lt;/p&gt;

&lt;p&gt;I tested both important scenarios.&lt;/p&gt;

&lt;p&gt;Successful Payment&lt;/p&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;Order ID: 20&lt;br&gt;
Status: CONFIRMED&lt;br&gt;
Total: ₹3499&lt;br&gt;
Payment: SUCCESS&lt;br&gt;
Cart: Cleared&lt;br&gt;
Failed Payment&lt;/p&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;Payment: FAILED&lt;br&gt;
Order: PENDING&lt;br&gt;
Cart: Preserved&lt;/p&gt;

&lt;p&gt;This was important because testing only successful payments would have hidden the cart-loss bug.&lt;/p&gt;

&lt;p&gt;🔒 Security Considerations&lt;/p&gt;

&lt;p&gt;I also made sure that sensitive payment information wasn't trusted blindly from the frontend.&lt;/p&gt;

&lt;p&gt;The backend:&lt;/p&gt;

&lt;p&gt;Validates the order amount&lt;br&gt;
Creates the Razorpay order&lt;br&gt;
Stores the Razorpay order ID&lt;br&gt;
Verifies the Razorpay signature&lt;br&gt;
Keeps the Razorpay secret on the backend&lt;br&gt;
Updates payment status on the backend&lt;br&gt;
Updates order status only after successful verification&lt;/p&gt;

&lt;p&gt;The frontend is responsible for initiating the checkout experience, but the backend is responsible for trusting and recording the payment result.&lt;/p&gt;

&lt;p&gt;📚 What I Learned&lt;/p&gt;

&lt;p&gt;The biggest lesson wasn't actually how to call the Razorpay API.&lt;/p&gt;

&lt;p&gt;It was understanding that payment integration is a state-management problem.&lt;/p&gt;

&lt;p&gt;A payment can move through states like:&lt;/p&gt;

&lt;p&gt;CREATED&lt;br&gt;
   ↓&lt;br&gt;
SUCCESS&lt;/p&gt;

&lt;p&gt;or:&lt;/p&gt;

&lt;p&gt;CREATED&lt;br&gt;
   ↓&lt;br&gt;
FAILED&lt;/p&gt;

&lt;p&gt;And the order has its own state:&lt;/p&gt;

&lt;p&gt;PENDING&lt;br&gt;
   ↓&lt;br&gt;
CONFIRMED&lt;/p&gt;

&lt;p&gt;These states need to remain consistent.&lt;/p&gt;

&lt;p&gt;I also learned:&lt;/p&gt;

&lt;p&gt;Never clear a cart before payment succeeds.&lt;br&gt;
Always verify payment on the backend.&lt;br&gt;
Don't expose payment secrets in frontend code.&lt;br&gt;
Debug the complete frontend → API → service → database flow.&lt;br&gt;
API response structure matters as much as business logic.&lt;br&gt;
Always test failure scenarios, not just the happy path.&lt;br&gt;
Payment integration is tightly connected to order and cart state.&lt;br&gt;
🚀 What's Next?&lt;/p&gt;

&lt;p&gt;Razorpay completes another major part of ShopEase.&lt;/p&gt;

&lt;p&gt;The next areas I want to work on are:&lt;/p&gt;

&lt;p&gt;Admin Dashboard&lt;br&gt;
User Management&lt;br&gt;
Inventory Management&lt;br&gt;
Automated Testing&lt;br&gt;
Pagination&lt;br&gt;
Sorting&lt;br&gt;
Advanced Search&lt;br&gt;
Docker&lt;br&gt;
CI/CD&lt;br&gt;
Deployment&lt;/p&gt;

&lt;p&gt;Eventually, I want to take ShopEase from a learning project toward a more production-oriented architecture.&lt;/p&gt;

&lt;p&gt;🎯 Final Thoughts&lt;/p&gt;

&lt;p&gt;Implementing Razorpay wasn't just about adding a payment popup.&lt;/p&gt;

&lt;p&gt;The real challenge was making sure that:&lt;/p&gt;

&lt;p&gt;Payment&lt;br&gt;
   ↕&lt;br&gt;
Order&lt;br&gt;
   ↕&lt;br&gt;
Cart&lt;/p&gt;

&lt;p&gt;all remain consistent.&lt;/p&gt;

&lt;p&gt;The bugs I encountered—missing order IDs, incorrect response handling, failed payment state, cart deletion and Java method structure issues—were actually more valuable than simply getting the first successful payment.&lt;/p&gt;

&lt;p&gt;That's what made this implementation useful as a development experience.&lt;/p&gt;

&lt;p&gt;ShopEase now has a complete tested payment flow using Razorpay Test Mode, with backend verification, payment status tracking, order confirmation, failure handling and correct cart behavior.&lt;br&gt;
ShopEase -Shitanshu Jha&lt;/p&gt;

&lt;h1&gt;
  
  
  java #springboot #razorpay #ecommerce #webdev
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>Building ShopEase: My Journey From a Basic E-Commerce App to a Spring Boot Backend</title>
      <dc:creator>Shitanshu Jha</dc:creator>
      <pubDate>Sat, 22 Aug 2026 02:33:38 +0000</pubDate>
      <link>https://dev.to/shitanshu686/building-shopease-my-journey-from-a-basic-e-commerce-app-to-a-spring-boot-backend-4bah</link>
      <guid>https://dev.to/shitanshu686/building-shopease-my-journey-from-a-basic-e-commerce-app-to-a-spring-boot-backend-4bah</guid>
      <description>&lt;p&gt;Building ShopEase: My Journey From a Basic E-Commerce App to a Spring Boot Backend&lt;/p&gt;

&lt;p&gt;By Shitanshu Jha&lt;/p&gt;

&lt;p&gt;**👋 Hi, I'm Shitanshu Jha&lt;/p&gt;

&lt;p&gt;I'm a BCA student and Java Developer focused on backend development and building real-world applications with Java, Spring Boot, REST APIs, MySQL, and Spring Security.**&lt;/p&gt;

&lt;p&gt;I'm currently pursuing my Bachelor of Computer Applications at Guru Gobind Singh Indraprastha University (GGSIPU). While learning software development, I wanted to move beyond small practice programs and understand how a complete application is actually designed, connected, secured, tested, and developed over time.&lt;/p&gt;

&lt;p&gt;That's what led me to build ShopEase.&lt;/p&gt;

&lt;p&gt;ShopEase is a full-stack e-commerce application that I'm developing module by module, starting from basic product management and gradually adding authentication, authorization, cart management, wishlist, checkout, orders, and payment integration. The project currently has a Java/Spring Boot backend, JavaScript frontend, MySQL database, JWT authentication, role-based authorization, and several integrated modules.**&lt;/p&gt;

&lt;p&gt;How I built and evolved a full-stack e-commerce application using Java, Spring Boot, MySQL, JavaScript, JWT authentication, and REST APIs.&lt;br&gt;
When I started building ShopEase, my goal wasn't to create a perfect e-commerce application from day one.&lt;/p&gt;

&lt;p&gt;I wanted to understand what actually happens behind a real application — how the frontend communicates with a backend, how data is stored, how authentication works, how users are authorized, and how different features come together into one system.&lt;/p&gt;

&lt;p&gt;ShopEase started as an e-commerce project and gradually evolved into a much larger full-stack application.&lt;/p&gt;

&lt;p&gt;Today, it has a Java + Spring Boot backend, a JavaScript frontend, MySQL database integration, JWT authentication, role-based authorization, persistent cart and wishlist functionality, checkout and order management, validation, DTOs, and centralized exception handling.&lt;br&gt;
🛠️ Tech Stack&lt;br&gt;
Frontend&lt;br&gt;
HTML&lt;br&gt;
CSS&lt;br&gt;
JavaScript&lt;br&gt;
Fetch API&lt;br&gt;
LocalStorage&lt;br&gt;
Backend&lt;br&gt;
Java&lt;br&gt;
Spring Boot&lt;br&gt;
Spring MVC&lt;br&gt;
Spring Data JPA&lt;br&gt;
Hibernate&lt;br&gt;
Spring Security&lt;br&gt;
JWT&lt;br&gt;
BCrypt&lt;br&gt;
Jakarta Validation&lt;br&gt;
Database&lt;br&gt;
MySQL&lt;br&gt;
Tools&lt;br&gt;
Eclipse&lt;br&gt;
Postman&lt;br&gt;
XAMPP&lt;br&gt;
Git&lt;br&gt;
GitHub&lt;br&gt;
🏗️ The Architecture&lt;/p&gt;

&lt;p&gt;The basic architecture of ShopEase looks like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                ShopEase
                   │
      ┌────────────┴────────────┐
      │                         │
  FRONTEND                   BACKEND
      │                         │
HTML / CSS / JS            Spring Boot
      │                         │
  Fetch API               Spring MVC
      │                         │
   api.js               Spring Security
      │                         │
      └────── REST API ─────────┘
                   │
                  JWT
                   │
                 MySQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The frontend communicates with the Spring Boot backend through REST APIs, while authentication is handled using JWT.&lt;/p&gt;

&lt;p&gt;📦 1. Building the Product System&lt;/p&gt;

&lt;p&gt;The product module was one of the first major parts of ShopEase.&lt;/p&gt;

&lt;p&gt;On the frontend, I implemented product cards containing information such as:&lt;/p&gt;

&lt;p&gt;Product image&lt;br&gt;
Name&lt;br&gt;
Brand&lt;br&gt;
Description&lt;br&gt;
Price&lt;br&gt;
Old price&lt;br&gt;
Discount&lt;br&gt;
Rating&lt;br&gt;
Stock status&lt;br&gt;
Add to cart&lt;br&gt;
View details&lt;/p&gt;

&lt;p&gt;On the backend, the product system includes:&lt;/p&gt;

&lt;p&gt;Product Entity&lt;br&gt;
Repository&lt;br&gt;
Service&lt;br&gt;
Controller&lt;br&gt;
MySQL integration&lt;br&gt;
JPA/Hibernate&lt;br&gt;
CRUD operations&lt;br&gt;
DTOs&lt;br&gt;
Validation&lt;br&gt;
Exception handling&lt;/p&gt;

&lt;p&gt;The main REST APIs are:&lt;/p&gt;

&lt;p&gt;GET    /products&lt;br&gt;
GET    /products/{id}&lt;br&gt;
POST   /products&lt;br&gt;
PUT    /products/{id}&lt;br&gt;
DELETE /products/{id}&lt;/p&gt;

&lt;p&gt;The data flows from the frontend through the Fetch API to the controller, service, repository and finally MySQL before returning a JSON response to the frontend.&lt;/p&gt;

&lt;p&gt;🔐 2. Authentication with Spring Security and JWT&lt;/p&gt;

&lt;p&gt;This was one of the more important parts of the project.&lt;/p&gt;

&lt;p&gt;I implemented:&lt;/p&gt;

&lt;p&gt;User registration&lt;br&gt;
Login&lt;br&gt;
BCrypt password encoding&lt;br&gt;
JWT generation&lt;br&gt;
JWT validation&lt;br&gt;
JWT authentication filter&lt;br&gt;
Protected APIs&lt;br&gt;
Role-based authorization&lt;/p&gt;

&lt;p&gt;The login flow looks like:&lt;/p&gt;

&lt;p&gt;Login Form&lt;br&gt;
    ↓&lt;br&gt;
POST /users/login&lt;br&gt;
    ↓&lt;br&gt;
UserService&lt;br&gt;
    ↓&lt;br&gt;
BCrypt Verification&lt;br&gt;
    ↓&lt;br&gt;
JWT Generation&lt;br&gt;
    ↓&lt;br&gt;
Token Response&lt;br&gt;
    ↓&lt;br&gt;
LocalStorage&lt;/p&gt;

&lt;p&gt;For protected requests, the frontend automatically sends:&lt;/p&gt;

&lt;p&gt;Authorization: Bearer &lt;/p&gt;

&lt;p&gt;The backend then validates the JWT through the authentication filter and Spring Security context.&lt;/p&gt;

&lt;p&gt;👥 3. Role-Based Authorization&lt;/p&gt;

&lt;p&gt;I didn't want authentication to simply mean “the user is logged in.”&lt;/p&gt;

&lt;p&gt;Different users should have different permissions.&lt;/p&gt;

&lt;p&gt;ShopEase currently has USER and ADMIN roles.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;USER&lt;br&gt;
 ↓&lt;br&gt;
Protected API&lt;br&gt;
 ↓&lt;br&gt;
Unauthorized operation&lt;br&gt;
 ↓&lt;br&gt;
403 Forbidden&lt;/p&gt;

&lt;p&gt;while:&lt;/p&gt;

&lt;p&gt;ADMIN&lt;br&gt;
 ↓&lt;br&gt;
Protected Admin API&lt;br&gt;
 ↓&lt;br&gt;
Allowed&lt;/p&gt;

&lt;p&gt;This is used for operations such as product and specification management.&lt;/p&gt;

&lt;p&gt;🛒 4. Building a Persistent Shopping Cart&lt;/p&gt;

&lt;p&gt;The cart was where the frontend and backend really started behaving like one application.&lt;/p&gt;

&lt;p&gt;The backend contains:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 ↓&lt;br&gt;
Cart&lt;br&gt;
 ↓&lt;br&gt;
CartItem&lt;br&gt;
 ↓&lt;br&gt;
Product&lt;/p&gt;

&lt;p&gt;The cart supports:&lt;/p&gt;

&lt;p&gt;Add product&lt;br&gt;
View cart&lt;br&gt;
Update quantity&lt;br&gt;
Remove item&lt;br&gt;
Stock validation&lt;br&gt;
Quantity validation&lt;br&gt;
Subtotal&lt;br&gt;
Total&lt;br&gt;
Total item count&lt;/p&gt;

&lt;p&gt;The APIs are:&lt;/p&gt;

&lt;p&gt;POST   /cart&lt;br&gt;
GET    /cart&lt;br&gt;
PUT    /cart/{itemId}&lt;br&gt;
DELETE /cart/{itemId}&lt;/p&gt;

&lt;p&gt;The important part was making the cart persistent.&lt;/p&gt;

&lt;p&gt;If a user adds a product, logs out, and later logs in again, the cart is restored from the database instead of being lost.&lt;/p&gt;

&lt;p&gt;🤍 5. Adding Wishlist Functionality&lt;/p&gt;

&lt;p&gt;After the cart, I implemented a user-specific persistent wishlist.&lt;/p&gt;

&lt;p&gt;The backend provides:&lt;/p&gt;

&lt;p&gt;POST   /wishlist/{productId}&lt;br&gt;
GET    /wishlist&lt;br&gt;
DELETE /wishlist/{itemId}&lt;/p&gt;

&lt;p&gt;The frontend includes:&lt;/p&gt;

&lt;p&gt;Wishlist button&lt;br&gt;
Wishlist count&lt;br&gt;
Wishlist drawer&lt;br&gt;
Product cards&lt;br&gt;
Add/remove functionality&lt;br&gt;
Wishlist state synchronization&lt;br&gt;
Empty wishlist UI&lt;/p&gt;

&lt;p&gt;I also added duplicate-product handling and ownership validation.&lt;/p&gt;

&lt;p&gt;The wishlist module is currently fully integrated and tested.&lt;/p&gt;

&lt;p&gt;🧾 6. DTOs, Validation and Exception Handling&lt;/p&gt;

&lt;p&gt;As the project became bigger, I realized that directly exposing entities through APIs wasn't a good approach.&lt;/p&gt;

&lt;p&gt;So I introduced DTOs such as:&lt;/p&gt;

&lt;p&gt;ProductRequestDTO&lt;br&gt;
ProductResponseDTO&lt;/p&gt;

&lt;p&gt;UserRequestDTO&lt;br&gt;
UserResponseDTO&lt;/p&gt;

&lt;p&gt;LoginRequestDTO&lt;br&gt;
LoginResponseDTO&lt;/p&gt;

&lt;p&gt;AddToCartRequestDTO&lt;br&gt;
UpdateCartItemDTO&lt;/p&gt;

&lt;p&gt;CartItemResponseDTO&lt;br&gt;
CartResponseDTO&lt;/p&gt;

&lt;p&gt;The purpose was to separate the API layer from the entity layer and control exactly what data enters and leaves the application.&lt;/p&gt;

&lt;p&gt;I also implemented Jakarta Validation with annotations such as:&lt;/p&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/notblank"&gt;@notblank&lt;/a&gt;&lt;br&gt;
@NotNull&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/positive"&gt;@positive&lt;/a&gt;&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/min"&gt;@min&lt;/a&gt;&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/max"&gt;@max&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and created a centralized GlobalExceptionHandler for validation, authentication, product, stock and cart-related errors.&lt;/p&gt;

&lt;p&gt;🧾 7. Checkout and Orders&lt;/p&gt;

&lt;p&gt;The project has now moved beyond just shopping-cart functionality.&lt;/p&gt;

&lt;p&gt;Checkout and order management are implemented and tested.&lt;/p&gt;

&lt;p&gt;The current flow is:&lt;/p&gt;

&lt;p&gt;USER&lt;br&gt;
 ↓&lt;br&gt;
Cart&lt;br&gt;
 ↓&lt;br&gt;
Checkout&lt;br&gt;
 ↓&lt;br&gt;
POST /orders&lt;br&gt;
 ↓&lt;br&gt;
Order Success&lt;br&gt;
 ↓&lt;br&gt;
Order Details&lt;br&gt;
 ↓&lt;br&gt;
My Orders&lt;br&gt;
 ↓&lt;br&gt;
Order History&lt;/p&gt;

&lt;p&gt;The backend supports:&lt;/p&gt;

&lt;p&gt;POST /orders&lt;br&gt;
GET  /orders&lt;br&gt;
GET  /orders/{id}&lt;/p&gt;

&lt;p&gt;It also handles user-specific order history and order-status transitions.&lt;/p&gt;

&lt;p&gt;🚧 What's Next?&lt;/p&gt;

&lt;p&gt;The next major target is payment integration.&lt;/p&gt;

&lt;p&gt;I'm currently planning the Razorpay integration around:&lt;/p&gt;

&lt;p&gt;Payment order creation&lt;br&gt;
Payment verification&lt;br&gt;
Payment status handling&lt;br&gt;
Order-payment integration&lt;br&gt;
Successful payment handling&lt;br&gt;
Failed payment handling&lt;br&gt;
Payment security&lt;br&gt;
Payment testing&lt;/p&gt;

&lt;p&gt;The frontend will also have payment initiation and success/failure handling.&lt;/p&gt;

&lt;p&gt;After that, the longer-term roadmap includes production hardening, automated testing, Docker, CI/CD, deployment, and eventually more advanced architecture such as microservices and event-driven communication.&lt;/p&gt;

&lt;p&gt;🧠 What I'm Learning From ShopEase&lt;/p&gt;

&lt;p&gt;The biggest thing I've learned from this project is that building a real application is very different from writing isolated code.&lt;/p&gt;

&lt;p&gt;A feature isn't finished when the Java class compiles.&lt;/p&gt;

&lt;p&gt;It has to go through a complete workflow:&lt;/p&gt;

&lt;p&gt;Backend Development&lt;br&gt;
        ↓&lt;br&gt;
API Testing&lt;br&gt;
        ↓&lt;br&gt;
Frontend Development&lt;br&gt;
        ↓&lt;br&gt;
API Integration&lt;br&gt;
        ↓&lt;br&gt;
Full Feature Testing&lt;br&gt;
        ↓&lt;br&gt;
Bug Fixing&lt;br&gt;
        ↓&lt;br&gt;
Git Commit&lt;br&gt;
        ↓&lt;br&gt;
Git Push&lt;/p&gt;

&lt;p&gt;That process has become an important part of how I'm developing ShopEase.&lt;/p&gt;

&lt;p&gt;🚀 What's Next for ShopEase?&lt;/p&gt;

&lt;p&gt;The final goal is to take ShopEase from a learning project toward a production-oriented full-stack e-commerce application.&lt;/p&gt;

&lt;p&gt;The long-term architecture is planned around:&lt;/p&gt;

&lt;p&gt;Frontend&lt;br&gt;
   ↓&lt;br&gt;
Spring Boot Backend&lt;br&gt;
   ↓&lt;br&gt;
MySQL&lt;br&gt;
   ↓&lt;br&gt;
JWT Authentication&lt;br&gt;
   ↓&lt;br&gt;
Role-Based Authorization&lt;br&gt;
   ↓&lt;br&gt;
Cart + Wishlist&lt;br&gt;
   ↓&lt;br&gt;
Checkout&lt;br&gt;
   ↓&lt;br&gt;
Orders&lt;br&gt;
   ↓&lt;br&gt;
Payment&lt;br&gt;
   ↓&lt;br&gt;
Admin Dashboard&lt;br&gt;
   ↓&lt;br&gt;
Inventory&lt;br&gt;
   ↓&lt;br&gt;
Testing&lt;br&gt;
   ↓&lt;br&gt;
Docker&lt;br&gt;
   ↓&lt;br&gt;
CI/CD&lt;br&gt;
   ↓&lt;br&gt;
Cloud Deployment&lt;/p&gt;

&lt;p&gt;The project is being developed module by module, with backend development, frontend integration, testing and Git commits forming the development workflow&lt;/p&gt;

&lt;p&gt;ShopEase is still a work in progress.&lt;/p&gt;

&lt;p&gt;I'm not trying to rush toward calling it “production-ready.” There are still important areas left to build, including payment integration, automated testing, Docker, CI/CD, deployment and production hardening.&lt;/p&gt;

&lt;p&gt;For me, that's actually the point of the project.&lt;/p&gt;

&lt;p&gt;I'm using ShopEase to understand how a real full-stack application grows from individual features into a complete system — one module at a time.&lt;/p&gt;

&lt;p&gt;GitHub: github.com/Shitanshu686&lt;br&gt;
Portfolio: shitanshu686.github.io/ShitanshuJhaaaa/&lt;br&gt;
LinkedIn: linkedin.com/in/shitanshu-jha-738012342/&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5cmnitwrzp8sw07n73k0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5cmnitwrzp8sw07n73k0.png" alt=" " width="799" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>backend</category>
    </item>
  </channel>
</rss>
