diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java
index 7b109f07bdc6802bc0610d171e20a5ffa510f0a0..7750bd29c848fcfa71e746448891caa9a4546d45 100644
--- a/src/main/java/org/example/Main.java
+++ b/src/main/java/org/example/Main.java
@@ -2,15 +2,15 @@ package org.example;
 
 import javax.xml.ws.Endpoint;
 
-import org.example.service.ChallengeServiceImpl;
-import org.example.service.TopupServiceImpl;
-import org.example.service.restCodeServiceImpl;
+import org.example.service.*;
 
 public class Main {
     public static void main(String[] args) {
         try {
             Endpoint.publish("http://0.0.0.0:8081/topup", new TopupServiceImpl());
             Endpoint.publish("http://0.0.0.0:8081/code", new restCodeServiceImpl());
+            Endpoint.publish("http://0.0.0.0:8081/buyProduct", new buyProductServiceImpl());
+            Endpoint.publish("http://0.0.0.0:8081/checkCode", new checkCodeServiceImpl());
             
             System.out.println("Server started");
         } catch (Exception e) {
diff --git a/src/main/java/org/example/service/TopupServiceImpl.java b/src/main/java/org/example/service/TopupServiceImpl.java
index d093b10ef0afc721a0aa4af16cc157ab78f04938..2a58258ebb0707cb852cdc25f0a151739269c8d2 100644
--- a/src/main/java/org/example/service/TopupServiceImpl.java
+++ b/src/main/java/org/example/service/TopupServiceImpl.java
@@ -69,7 +69,7 @@ public class TopupServiceImpl implements TopupService {
         System.out.println(restId);
         System.out.println(balance);
         try {
-            String query = "UPDATE currency SET uang = uang + ? WHERE user_id = ?";
+            String query = "UPDATE soap_connector SET uang = uang + ? WHERE user_id_Rest = ?";
             PreparedStatement preparedStatement = connection.prepareStatement(query);
             preparedStatement.setInt(1, balance); 
             preparedStatement.setInt(2, restId);
diff --git a/src/main/java/org/example/service/buyProductService.java b/src/main/java/org/example/service/buyProductService.java
new file mode 100644
index 0000000000000000000000000000000000000000..66f896c6f5582169b58bc45111040a58c433d5af
--- /dev/null
+++ b/src/main/java/org/example/service/buyProductService.java
@@ -0,0 +1,5 @@
+package org.example.service;
+
+public interface buyProductService {
+	public int buyProduct (int restId, int productId, int quantity, int balance);
+}
diff --git a/src/main/java/org/example/service/buyProductServiceImpl.java b/src/main/java/org/example/service/buyProductServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca150d7dda4e9c9574c08529710fc031efc8a775
--- /dev/null
+++ b/src/main/java/org/example/service/buyProductServiceImpl.java
@@ -0,0 +1,124 @@
+
+package org.example.service;
+
+import javax.annotation.Resource;
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.xml.ws.WebServiceContext;
+import javax.xml.ws.handler.MessageContext;
+import com.sun.net.httpserver.HttpExchange;
+import java.sql.PreparedStatement;
+
+import com.sun.xml.internal.ws.developer.JAXWSProperties;
+import org.example.model.Challenge;
+import org.example.model.ChallengeDAOImpl;
+import org.example.core.Database;
+import org.example.model.Log;
+import org.w3c.dom.Element;
+import java.security.Principal;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+
+@WebService
+public class buyProductServiceImpl implements buyProductService {
+
+    @Resource
+    public WebServiceContext wsContext;
+
+   public Boolean checkApiKey() {
+       String[] API_KEYS = { "RestClient" , "PHPClient" };
+       MessageContext msgContext = wsContext.getMessageContext();
+       HttpExchange httpExchange = (HttpExchange) msgContext.get("com.sun.xml.internal.ws.http.exchange");
+       String apiKey = httpExchange.getRequestHeaders().getFirst("X-API-Key");
+       if (apiKey == null) {
+         return false;
+       } else if (apiKey.equals(API_KEYS[0]) || apiKey.equals(API_KEYS[1])) {
+         return true;
+       } else {
+         return false;
+       }
+   }
+
+   public void log(String description) {
+    try {
+        MessageContext msgContext = wsContext.getMessageContext();
+        HttpExchange httpExchange = (HttpExchange) msgContext.get("com.sun.xml.internal.ws.http.exchange");
+        String ip = httpExchange.getRemoteAddress().getAddress().getHostAddress();
+        String endpoint = httpExchange.getRequestURI().toString();
+        System.out.println(ip);
+        System.out.println(endpoint);
+        Log log = new Log();
+        String apiKey = httpExchange.getRequestHeaders().getFirst("X-API-Key");
+        String desc = apiKey + ": " + description;
+       log.InsertLog(desc, ip, endpoint);
+    } catch (Exception e) {
+       System.out.println("Internal Server Error: " + e.getMessage());
+    }
+}
+
+    @WebMethod
+    @Override
+    public int buyProduct(int restId, int productId, int quantity, int balance) {
+        if (!checkApiKey()) {
+            return 0;
+        }
+        Database db = new Database();
+        Connection connection = db.getConnection();
+        System.out.println(restId);
+        System.out.println(balance);
+        try {
+            connection.setAutoCommit(false);
+            String balanceQuery = "SELECT uang FROM soap_connector WHERE user_id_Rest = ?";
+            PreparedStatement balanceStatement = connection.prepareStatement(balanceQuery);
+            balanceStatement.setInt(1, restId);
+            ResultSet balanceResult = balanceStatement.executeQuery();
+
+            int currentBalance = 0;
+            if (balanceResult.next()) {
+                currentBalance = balanceResult.getInt("uang");
+            }
+            if (currentBalance < balance) {
+                balanceResult.close();
+                balanceStatement.close();
+                connection.close();
+                return 0;
+            }
+            
+            String updateQuery = "UPDATE soap_connector SET uang = uang - ? WHERE user_id_Rest = ?";
+            PreparedStatement updateStatement = connection.prepareStatement(updateQuery);
+            updateStatement.setInt(1, balance);
+            updateStatement.setInt(2, restId);
+            int rowsAffected = updateStatement.executeUpdate();
+
+
+            String historyInsertQuery = "INSERT INTO history (user_id, product_id, quantity) VALUES (?, ?, ?)";
+            PreparedStatement historyInsertStatement = connection.prepareStatement(historyInsertQuery);
+            historyInsertStatement.setInt(1, restId); 
+            historyInsertStatement.setInt(2, productId); 
+            historyInsertStatement.setInt(3, quantity); 
+
+            int rowsInserted = historyInsertStatement.executeUpdate();
+            historyInsertStatement.close();
+
+            balanceResult.close();
+            balanceStatement.close();
+            updateStatement.close();
+            connection.commit();
+            // connection.close();
+            
+            log("buying product " + productId + " user id " + restId + " quantity " + quantity + " and total " + balance);
+            
+            return 1;
+            
+        } catch (SQLException e) {
+            e.printStackTrace();
+            log("Error when buying product " + productId + " user id " + restId + " quantity " + quantity + " and total " + balance);
+            return -1;
+        } 
+    }
+
+    
+}
\ No newline at end of file
diff --git a/src/main/java/org/example/service/checkCodeService.java b/src/main/java/org/example/service/checkCodeService.java
new file mode 100644
index 0000000000000000000000000000000000000000..360ff40500d1c2f0e1fe53e391dd2c5d39de4e31
--- /dev/null
+++ b/src/main/java/org/example/service/checkCodeService.java
@@ -0,0 +1,5 @@
+package org.example.service;
+
+public interface checkCodeService {
+    public int checkCode (String code, int restId);
+}
diff --git a/src/main/java/org/example/service/checkCodeServiceImpl.java b/src/main/java/org/example/service/checkCodeServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..4c1101ff25f1f3c980a822ae0c14d5fce4d348db
--- /dev/null
+++ b/src/main/java/org/example/service/checkCodeServiceImpl.java
@@ -0,0 +1,107 @@
+
+package org.example.service;
+
+import javax.annotation.Resource;
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.xml.ws.WebServiceContext;
+import javax.xml.ws.handler.MessageContext;
+import com.sun.net.httpserver.HttpExchange;
+import java.sql.PreparedStatement;
+
+import com.sun.xml.internal.ws.developer.JAXWSProperties;
+import org.example.model.Challenge;
+import org.example.model.ChallengeDAOImpl;
+import org.example.core.Database;
+import org.example.model.Log;
+import org.w3c.dom.Element;
+import java.security.Principal;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+
+@WebService
+public class checkCodeServiceImpl implements checkCodeService {
+
+    @Resource
+    public WebServiceContext wsContext;
+
+   public Boolean checkApiKey() {
+       String[] API_KEYS = { "RestClient" , "PHPClient" };
+       MessageContext msgContext = wsContext.getMessageContext();
+       HttpExchange httpExchange = (HttpExchange) msgContext.get("com.sun.xml.internal.ws.http.exchange");
+       String apiKey = httpExchange.getRequestHeaders().getFirst("X-API-Key");
+       if (apiKey == null) {
+         return false;
+       } else if (apiKey.equals(API_KEYS[0]) || apiKey.equals(API_KEYS[1])) {
+         return true;
+       } else {
+         return false;
+       }
+   }
+
+   public void log(String description) {
+    try {
+        MessageContext msgContext = wsContext.getMessageContext();
+        HttpExchange httpExchange = (HttpExchange) msgContext.get("com.sun.xml.internal.ws.http.exchange");
+        String ip = httpExchange.getRemoteAddress().getAddress().getHostAddress();
+        String endpoint = httpExchange.getRequestURI().toString();
+        System.out.println(ip);
+        System.out.println(endpoint);
+        Log log = new Log();
+        String apiKey = httpExchange.getRequestHeaders().getFirst("X-API-Key");
+        String desc = apiKey + ": " + description;
+       log.InsertLog(desc, ip, endpoint);
+    } catch (Exception e) {
+       System.out.println("Internal Server Error: " + e.getMessage());
+    }
+}
+
+    @WebMethod
+    @Override
+    public int checkCode(String code, int restId) {
+        if (!checkApiKey()) {
+            return 0;
+        }
+        Database db = new Database();
+        Connection connection = db.getConnection();
+        System.out.println(restId);
+        System.out.println(code);
+        try {
+            connection.setAutoCommit(false);
+            
+            String codeCheckQuery = "SELECT * FROM soap_connector WHERE code = ? AND user_id_Rest IS NULL";
+            PreparedStatement codeCheckStatement = connection.prepareStatement(codeCheckQuery);
+            codeCheckStatement.setString(1, code);
+            ResultSet codeCheckResult = codeCheckStatement.executeQuery();
+
+            if (!codeCheckResult.next()) {
+                codeCheckResult.close();
+                codeCheckStatement.close();
+                connection.close();
+                log("Invalid code: " + code);
+                return 0;
+            }
+            String updateRestCodeQuery = "UPDATE soap_connector SET user_id_Rest = ? WHERE code = ? AND user_id_Rest IS NULL";
+            PreparedStatement updateStatement = connection.prepareStatement(updateRestCodeQuery);
+            updateStatement.setInt(1, restId);
+            updateStatement.setString(2, code);
+            int rowsAffected = updateStatement.executeUpdate();
+            updateStatement.close();
+            codeCheckResult.close();
+            codeCheckStatement.close();
+            connection.commit();
+            connection.close();
+            log("check code with code " + code + " success");
+            return 1;
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            log("Error when check code with code " + code);
+            return 0;
+        }
+    }
+
+    
+}
diff --git a/src/main/java/org/example/service/getHistoryService.java b/src/main/java/org/example/service/getHistoryService.java
new file mode 100644
index 0000000000000000000000000000000000000000..09a902448d3a8023b9ace78343fa104d268c283b
--- /dev/null
+++ b/src/main/java/org/example/service/getHistoryService.java
@@ -0,0 +1,5 @@
+package org.example.service;
+
+public interface getHistoryService {
+    public String getHistory(int restId);
+}
diff --git a/src/main/java/org/example/service/getHistoryServiceImpl.java b/src/main/java/org/example/service/getHistoryServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..b9c9d1a07d632c37f4d4a7f9cd685d37c05e1e86
--- /dev/null
+++ b/src/main/java/org/example/service/getHistoryServiceImpl.java
@@ -0,0 +1,89 @@
+
+package org.example.service;
+
+import javax.annotation.Resource;
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.xml.ws.WebServiceContext;
+import javax.xml.ws.handler.MessageContext;
+import com.sun.net.httpserver.HttpExchange;
+import java.sql.PreparedStatement;
+
+import com.sun.xml.internal.ws.developer.JAXWSProperties;
+import org.example.model.Challenge;
+import org.example.model.ChallengeDAOImpl;
+import org.example.core.Database;
+import org.example.model.Log;
+import org.w3c.dom.Element;
+import java.security.Principal;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+
+@WebService
+public class getHistoryServiceImpl implements getHistoryService {
+
+    @Resource
+    public WebServiceContext wsContext;
+
+   public Boolean checkApiKey() {
+       String[] API_KEYS = { "RestClient" , "PHPClient" };
+       MessageContext msgContext = wsContext.getMessageContext();
+       HttpExchange httpExchange = (HttpExchange) msgContext.get("com.sun.xml.internal.ws.http.exchange");
+       String apiKey = httpExchange.getRequestHeaders().getFirst("X-API-Key");
+       if (apiKey == null) {
+         return false;
+       } else if (apiKey.equals(API_KEYS[0]) || apiKey.equals(API_KEYS[1])) {
+         return true;
+       } else {
+         return false;
+       }
+   }
+
+   public void log(String description) {
+    try {
+        MessageContext msgContext = wsContext.getMessageContext();
+        HttpExchange httpExchange = (HttpExchange) msgContext.get("com.sun.xml.internal.ws.http.exchange");
+        String ip = httpExchange.getRemoteAddress().getAddress().getHostAddress();
+        String endpoint = httpExchange.getRequestURI().toString();
+        System.out.println(ip);
+        System.out.println(endpoint);
+        Log log = new Log();
+        String apiKey = httpExchange.getRequestHeaders().getFirst("X-API-Key");
+        String desc = apiKey + ": " + description;
+       log.InsertLog(desc, ip, endpoint);
+    } catch (Exception e) {
+       System.out.println("Internal Server Error: " + e.getMessage());
+    }
+}
+
+    @WebMethod
+    @Override
+    public String getHistory (int restId) {
+        if (!checkApiKey()) {
+            return "Failed";
+        }
+        Database db = new Database();
+        Connection connection = db.getConnection();
+        System.out.println(restId);
+        try {
+            String query = "UPDATE currency SET uang = uang + ? WHERE user_id = ?";
+            PreparedStatement preparedStatement = connection.prepareStatement(query);
+//            preparedStatement.setInt(1, balance);
+            preparedStatement.setInt(2, restId);
+            int rowsAffected = preparedStatement.executeUpdate();
+            preparedStatement.close();
+            connection.close();
+            log("get buying history with user id " + restId);
+            return "";
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            log("Error when get buying history user id " + restId);
+            return "Failed";
+        }
+    }
+
+    
+}
diff --git a/src/main/java/org/example/service/restCodeService.java b/src/main/java/org/example/service/restCodeService.java
index 3efa1b9a33112454bb0f13c5f5489e3c997cd902..4ac28e4334a7f8d4e405f1f2a89e70fba56d173d 100644
--- a/src/main/java/org/example/service/restCodeService.java
+++ b/src/main/java/org/example/service/restCodeService.java
@@ -1,5 +1,5 @@
 package org.example.service;
 
 public interface restCodeService {
-    public int restCode(String username, String code);
+    public int restCode(int userId, String code);
 }
diff --git a/src/main/java/org/example/service/restCodeServiceImpl.java b/src/main/java/org/example/service/restCodeServiceImpl.java
index a83a04aa529e21115b16259824beb48b14e65479..5da3ee6db4c8da912081ee1e9b1cdfa579a920b8 100644
--- a/src/main/java/org/example/service/restCodeServiceImpl.java
+++ b/src/main/java/org/example/service/restCodeServiceImpl.java
@@ -59,28 +59,38 @@ public class restCodeServiceImpl implements restCodeService {
 
     @WebMethod
     @Override
-    public int restCode(String username, String code) {
+    public int restCode(int userId, String code) {
        if (!checkApiKey()) {
            return 0;
        }
         Database db = new Database();
         Connection connection = db.getConnection();
-        System.out.println(username);
+        System.out.println(userId);
         System.out.println(code);
         try {
-            String query = "INSERT INTO rest_code (username_php, code) VALUES (?,?)";
+            // connection.setAutoCommit(false);
+            String query = "INSERT INTO soap_connector (user_id_php, code, point, uang) VALUES (?,?,?,?)";
             PreparedStatement preparedStatement = connection.prepareStatement(query);
-            preparedStatement.setString(1, username); 
+            preparedStatement.setInt(1, userId); 
             preparedStatement.setString(2, code);
+            preparedStatement.setInt(3, 0);
+            preparedStatement.setInt(4, 0);
             int rowsAffected = preparedStatement.executeUpdate();
             preparedStatement.close();
+            // String currencyInsertQuery = "INSERT INTO currency (username_php, point, uang) VALUES (?, ?, ?)";
+            // PreparedStatement currencyInsertStatement = connection.prepareStatement(currencyInsertQuery);
+            // currencyInsertStatement.setString(1, username);
+            // currencyInsertStatement.setInt(2, 0);
+            // currencyInsertStatement.setInt(3, 0);
+            // int currencyRowsAffected = currencyInsertStatement.executeUpdate();
+            // currencyInsertStatement.close();
+            // connection.commit();
             connection.close();
-            log("register code username " + username);
+            log("register code php_user_id " + userId + " success");
             return 1;
-
         } catch (Exception e) {
             e.printStackTrace();
-            log("Error when register code username " + username);
+            log("Error when register code php_user_id " + userId);
             return 0;
         }
     }