diff --git a/api/db/order.go b/api/db/order.go
index f402eb5e15beed8b84dec58b03804f1d84f7f334..4f37ef982a713995d82bf4521bf1aa5863de52b1 100644
--- a/api/db/order.go
+++ b/api/db/order.go
@@ -150,7 +150,7 @@ func updateOrderProducts(tx *gorm.DB, order Order, dbOrder Order) (products []Or
 		if dbProduct != nil {
 			dbProduct.Price = product.Price
 			products = append(products, *dbProduct)
-			err = tx.Save(&dbProduct).Error
+			err = tx.Save(dbProduct).Error
 		} else {
 			product.OrderID = uint(dbOrder.ID)
 			err = tx.Create(&product).Error
@@ -300,7 +300,6 @@ func calculateOrderPurchaseTotal(purchase []OrderPurchase, products []OrderProdu
 	for _, p := range purchase {
 		found := false
 		for _, product := range products {
-			log.Printf("%v", p.OrderProduct)
 			if (p.OrderProduct != nil && product.ProductCode == p.OrderProduct.ProductCode) ||
 				product.ID == p.OrderProductID {
 				total += product.Price * p.Amount
diff --git a/api/order_test.go b/api/order_test.go
index b9170d805fe12ad60636f54789ba3a97dd3dcd89..c087aaa72aa9433f12878671022560054117ee86 100644
--- a/api/order_test.go
+++ b/api/order_test.go
@@ -447,6 +447,8 @@ func TestOrderUpdate(t *testing.T) {
 	}
 
 	order := testOrder
+	order.Products = make([]db.OrderProduct, len(testOrder.Products))
+	copy(order.Products, testOrder.Products)
 	order.Products[0].Price = 1000
 	resp = tapi.doOrder("PUT", fmt.Sprintf("/order/%d", orders[0].ID), order, nil)
 	if resp.StatusCode != http.StatusAccepted {
@@ -500,6 +502,8 @@ func TestOrderUpdateProduct(t *testing.T) {
 	}
 
 	order := testOrder
+	order.Products = make([]db.OrderProduct, len(testOrder.Products))
+	copy(order.Products, testOrder.Products)
 	order.Products[0].Price = testProduct2.Price
 	order.Products[0].ProductCode = testProduct2.Code
 	resp = tapi.doOrder("PUT", fmt.Sprintf("/order/%d", orders[0].ID), order, nil)
@@ -538,6 +542,145 @@ func TestOrderUpdateProduct(t *testing.T) {
 	}
 }
 
+func TestOrderUpdateAddProduct(t *testing.T) {
+	tapi := newTestAPI(t)
+	defer tapi.close()
+	tapi.addTestMember()
+	tapi.addTestOrder()
+
+	var orders []db.Order
+	resp := tapi.do("GET", "/order/active", nil, &orders)
+	if resp.StatusCode != http.StatusOK {
+		t.Fatal("Can't get orders:", resp.Status)
+	}
+
+	purchase := []db.OrderPurchase{
+		{
+			OrderProductID: orders[0].Products[0].ID,
+			Amount:         3,
+		},
+	}
+	resp = tapi.do("POST", fmt.Sprintf("/order/%d/purchase", orders[0].ID), purchase, nil)
+	if resp.StatusCode != http.StatusCreated {
+		t.Fatal("Can't create order:", resp.Status)
+	}
+
+	order := testOrder
+	order.Products = make([]db.OrderProduct, len(testOrder.Products))
+	copy(order.Products, testOrder.Products)
+	order.Products = append(order.Products, db.OrderProduct{
+		ProductCode: testProduct2.Code,
+		Price:       testProduct2.Price,
+	})
+	resp = tapi.doOrder("PUT", fmt.Sprintf("/order/%d", orders[0].ID), order, nil)
+	if resp.StatusCode != http.StatusAccepted {
+		tapi.t.Fatal("Can't update order:", resp.Status)
+	}
+
+	var transactions []db.Transaction
+	resp = tapi.do("GET", "/transaction/mine", nil, &transactions)
+	if resp.StatusCode != http.StatusOK {
+		t.Fatal("Can't get transactions:", resp.Status)
+	}
+	if len(transactions) != 1 {
+		t.Fatal("Wrong number of transactions", len(orders), orders)
+	}
+	expectedTotal := -(order.Products[0].Price * 3)
+	if transactions[0].Total != expectedTotal {
+		t.Error("Wrong total", transactions[0].Total, expectedTotal)
+	}
+}
+
+func TestOrderUpdateDelProduct(t *testing.T) {
+	tapi := newTestAPI(t)
+	defer tapi.close()
+	tapi.addTestMember()
+
+	order := testOrder
+	order.Products = make([]db.OrderProduct, len(testOrder.Products))
+	copy(order.Products, testOrder.Products)
+	order.Products = append(order.Products, db.OrderProduct{
+		ProductCode: testProduct2.Code,
+		Price:       testProduct2.Price,
+	})
+	resp := tapi.doOrder("POST", "/order", order, nil)
+	if resp.StatusCode != http.StatusCreated {
+		tapi.t.Fatal("Can't create order:", resp.Status)
+	}
+
+	var orders []db.Order
+	resp = tapi.do("GET", "/order/active", nil, &orders)
+	if resp.StatusCode != http.StatusOK {
+		t.Fatal("Can't get orders:", resp.Status)
+	}
+
+	purchase := []db.OrderPurchase{
+		{
+			OrderProductID: orders[0].Products[0].ID,
+			Amount:         3,
+		},
+		{
+			OrderProductID: orders[0].Products[1].ID,
+			Amount:         2,
+		},
+	}
+	resp = tapi.do("POST", fmt.Sprintf("/order/%d/purchase", orders[0].ID), purchase, nil)
+	if resp.StatusCode != http.StatusCreated {
+		t.Fatal("Can't create order:", resp.Status)
+	}
+
+	var transactions []db.Transaction
+	resp = tapi.do("GET", "/transaction/mine", nil, &transactions)
+	if resp.StatusCode != http.StatusOK {
+		t.Fatal("Can't get transactions:", resp.Status)
+	}
+	if len(transactions) != 1 {
+		t.Fatal("Wrong number of transactions", len(orders), orders)
+	}
+	expectedTotal := -(order.Products[0].Price*3 + order.Products[1].Price*2)
+	if transactions[0].Total != expectedTotal {
+		t.Error("Wrong total", transactions[0].Total, expectedTotal)
+	}
+	if len(transactions[0].OrderPurchase) != 2 {
+		t.Error("Wrong purchases", transactions[0].OrderPurchase)
+	}
+
+	order.Products = []db.OrderProduct{order.Products[0]}
+	resp = tapi.doOrder("PUT", fmt.Sprintf("/order/%d", orders[0].ID), order, nil)
+	if resp.StatusCode != http.StatusAccepted {
+		tapi.t.Fatal("Can't update order:", resp.Status)
+	}
+
+	var orderResponse OrderGetResponse
+	resp = tapi.do("GET", fmt.Sprintf("/order/%d", orders[0].ID), nil, &orderResponse)
+	if resp.StatusCode != http.StatusOK {
+		t.Fatal("Can't get order:", resp.Status)
+	}
+	if len(orderResponse.Order.Products) != 1 {
+		t.Fatal("Wrong len of products:", len(orderResponse.Order.Products), orderResponse.Order.Products)
+	}
+	if orderResponse.Order.Products[0].ProductCode != testProduct.Code {
+		t.Error("Wrong product code:", orderResponse.Order.Products)
+	}
+	if orderResponse.Order.Products[0].Price != testProduct.Price {
+		t.Error("Wrong product price:", orderResponse.Order.Products)
+	}
+
+	resp = tapi.do("GET", "/transaction/mine", nil, &transactions)
+	if resp.StatusCode != http.StatusOK {
+		t.Fatal("Can't get transactions:", resp.Status)
+	}
+	if len(transactions) != 1 {
+		t.Fatal("Wrong number of transactions", len(orders), orders)
+	}
+	if transactions[0].Total != -testProduct.Price*3 {
+		t.Error("Wrong total", transactions[0].Total)
+	}
+	if len(transactions[0].OrderPurchase) != 1 {
+		t.Error("Wrong purchases", transactions[0].OrderPurchase)
+	}
+}
+
 func TestOrderUpdateReactivate(t *testing.T) {
 	tapi := newTestAPI(t)
 	defer tapi.close()