diff --git a/commands/product.py b/commands/product.py
new file mode 100755
index 0000000..16dbb31
--- /dev/null
+++ b/commands/product.py
@@ -0,0 +1,55 @@
+import click
+import requests
+
+from decouple import config
+from .helper import OTPCredentials, load_dump_pretty
+
+
+def product_command(command, otp):
+    data = {**otp.get_json(), "action": command}
+    r = requests.post(f"{config('UCLOUD_PAY_SERVER')}/product/action",
+                      json=data)
+    return r
+
+
+@click.group()
+def product():
+    pass
+
+
+@product.command("list")
+def list():
+    r = requests.get(f"{config('UCLOUD_PAY_SERVER')}/product/list")
+    print(load_dump_pretty(r.content))
+
+
+@product.command("add")
+@click.option("--name", envvar="OTP_NAME", required=True)
+@click.option("--realm", envvar="OTP_REALM", required=True)
+@click.option("--seed", envvar="OTP_SEED", required=True)
+@click.option("--product-name", required=True)
+@click.option("--product-description", required=True)
+@click.option("--product-type", required=True,
+              help="Either one-time or recurring",
+              type=click.Choice(['one-time', 'recurring']))
+@click.option("--product-price", required=True, help="Price in CHF cents",
+              type=int)
+@click.option("--product-recurring-duration", required=False,
+              help="Only used for products with recurring costs",
+              type=int)
+@click.option("--product-recurring-duration-units", required=False, type=int,
+              help="Unit of the recurring costs", default=0)
+def add(name, realm, seed, product_name, product_description, product_type,
+        product_price, product_recurring_duration,
+        product_recurring_duration_units):
+    data = {
+        **OTPCredentials(name, realm, seed).get_json(),
+        "product_name": product_name,
+        "product_description": product_description,
+        "product_type": product_type,
+        "product_price": product_price,
+        "product_recurring_duration": product_recurring_duration,
+        "product_recurring_duration_units": product_recurring_duration_units
+    }
+    r = requests.post(f"{config('UCLOUD_API_SERVER')}/product/add", json=data)
+    print(load_dump_pretty(r.content))
diff --git a/ucloud.py b/ucloud.py
index ceb26fc..7f80b92 100755
--- a/ucloud.py
+++ b/ucloud.py
@@ -4,6 +4,7 @@ from commands.vm import vm
 from commands.user import user
 from commands.host import host
 from commands.image import image
+from commands.product import product
 
 
 @click.group()
@@ -15,6 +16,7 @@ entry_point.add_command(vm)
 entry_point.add_command(user)
 entry_point.add_command(image)
 entry_point.add_command(host)
+entry_point.add_command(product)
 
 if __name__ == "__main__":
     entry_point()