diff --git a/.env.example b/.env.example index ac6557a..9cb5ff0 100644 --- a/.env.example +++ b/.env.example @@ -51,10 +51,10 @@ REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 -MAIL_MAILER=log -MAIL_SCHEME=null -MAIL_HOST=127.0.0.1 -MAIL_PORT=2525 +MAIL_MAILER=smtp +MAIL_SCHEME=smtp +MAIL_HOST=smtp.gmail.com +MAIL_PORT=587 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_FROM_ADDRESS="hello@example.com" diff --git a/ShopIt_API_Postman_Collection.json b/ShopIt_API_Postman_Collection.json index fa2b22a..c69f8a3 100644 --- a/ShopIt_API_Postman_Collection.json +++ b/ShopIt_API_Postman_Collection.json @@ -2,7 +2,8 @@ "info": { "_postman_id": "76fd6fd2-53b9-4d92-8e02-1ddcc6207fa2", "name": "ShopIt API", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "description": "Colección de la API vigente de ShopIt. El script previo agrega automáticamente el Bearer token guardado por Login User." }, "item": [ { @@ -260,794 +261,80 @@ "name": "Catalog", "item": [ { - "name": "Brands", - "item": [ - { - "name": "List Brands", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/marcas", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "marcas" - ] - } - }, - "response": [] - }, - { - "name": "Create Brand", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"nombre\": \"Puma\",\n \"descripcion\": \"Marca de prueba\"\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/marcas", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "marcas" - ] - } - }, - "response": [] - }, - { - "name": "Show Brand", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/marcas/{{marca_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "marcas", - "{{marca_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Update Brand", - "request": { - "method": "PATCH", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"nombre\": \"Puma Updated\",\n \"descripcion\": \"Marca actualizada\"\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/marcas/{{marca_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "marcas", - "{{marca_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Delete Brand", - "request": { - "method": "DELETE", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/marcas/{{marca_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "marcas", - "{{marca_id}}" - ] - } - }, - "response": [] - } - ] + "name": "Get Catalog", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/catalog" + }, + "response": [] }, { - "name": "Categories", - "item": [ - { - "name": "List Categories", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/categorias", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "categorias" - ] - } - }, - "response": [] - }, - { - "name": "Create Category", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"categoria_id\": null,\n \"nombre\": \"Accesorios\"\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/categorias", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "categorias" - ] - } - }, - "response": [] - }, - { - "name": "Show Category", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/categorias/{{categoria_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "categorias", - "{{categoria_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Update Category", - "request": { - "method": "PATCH", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"categoria_id\": null,\n \"nombre\": \"Accesorios Updated\"\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/categorias/{{categoria_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "categorias", - "{{categoria_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Delete Category", - "request": { - "method": "DELETE", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/categorias/{{categoria_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "categorias", - "{{categoria_id}}" - ] - } - }, - "response": [] - } - ] + "name": "List Featured Group Items", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/catalog/featured-groups/{{featured_group_id}}/items?page=1", + "description": "Returns one page of items for a featured catalog group." + }, + "response": [] }, { - "name": "Attributes", - "item": [ - { - "name": "List Attributes", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/attributes", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "attributes" - ] - } - }, - "response": [] - }, - { - "name": "Create Attribute", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"codigo\": \"material\",\n \"nombre\": \"Material\",\n \"is_required\": false,\n \"type\": \"select\",\n \"metadata_schema\": {\n \"hex\": {\n \"type\": \"string\"\n }\n },\n \"options\": [\n {\n \"value\": \"algodon\",\n \"label\": \"Algodon\",\n \"sort_order\": 1,\n \"metadata\": null\n },\n {\n \"value\": \"poliester\",\n \"label\": \"Poliester\",\n \"sort_order\": 2,\n \"metadata\": null\n }\n ]\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/attributes", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "attributes" - ] - } - }, - "response": [] - }, - { - "name": "Show Attribute", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/attributes/{{attribute_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "attributes", - "{{attribute_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Update Attribute", - "request": { - "method": "PATCH", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"nombre\": \"Material Updated\",\n \"is_required\": true,\n \"type\": \"select\",\n \"options\": [\n {\n \"value\": \"algodon\",\n \"label\": \"Algodon\",\n \"sort_order\": 1,\n \"metadata\": null\n },\n {\n \"value\": \"modal\",\n \"label\": \"Modal\",\n \"sort_order\": 2,\n \"metadata\": null\n }\n ]\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/attributes/{{attribute_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "attributes", - "{{attribute_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Delete Attribute", - "request": { - "method": "DELETE", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/attributes/{{attribute_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "attributes", - "{{attribute_id}}" - ] - } - }, - "response": [] - } - ] + "name": "Show Catalog Item", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/catalog-items/{{catalog_item_id}}?variant_id={{variant_id}}", + "description": "variant_id is optional; remove the query parameter when the item has no selected variant." + }, + "response": [] }, { - "name": "Products", - "item": [ - { - "name": "List Products", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/productos", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "productos" - ] - } + "name": "Create Standard Catalog Item", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" }, - "response": [] - }, - { - "name": "Create Product", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"categoria_id\": {{categoria_id}},\n \"brand_id\": {{marca_id}},\n \"slug\": \"remera-basica-blanca\",\n \"nombre\": \"Remera Basica Blanca\",\n \"descripcion\": \"Remera de prueba\",\n \"precio\": 24999,\n \"attribute_ids\": [{{color_attribute_id}}, {{talle_attribute_id}}],\n \"images\": []\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/productos", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "productos" - ] + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/catalog-items", + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"standard\",\n \"category_id\": 1,\n \"brand_id\": 1,\n \"slug\": \"entrada-general\",\n \"nombre\": \"Entrada general\",\n \"descripcion\": \"Entrada general de ejemplo\",\n \"precio\": 15000,\n \"inventory_policy\": \"tracked\",\n \"has_tickets\": true,\n \"minimum_use_date\": \"2026-08-01\",\n \"maximum_use_date\": \"2026-08-31\",\n \"real_stock\": 100,\n \"attribute_codes\": [],\n \"images\": [],\n \"variants\": []\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] - }, - { - "name": "Show Product", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/productos/{{producto_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "productos", - "{{producto_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Update Product", - "request": { - "method": "PATCH", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"categoria_id\": {{categoria_id}},\n \"brand_id\": {{marca_id}},\n \"slug\": \"remera-basica-blanca\",\n \"nombre\": \"Remera Basica Blanca Updated\",\n \"descripcion\": \"Remera de prueba actualizada\",\n \"precio\": 26999,\n \"attribute_ids\": [{{color_attribute_id}}, {{talle_attribute_id}}],\n \"images\": []\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/productos/{{producto_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "productos", - "{{producto_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Delete Product", - "request": { - "method": "DELETE", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/productos/{{producto_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "productos", - "{{producto_id}}" - ] - } - }, - "response": [] + } } - ] - }, - { - "name": "Product Variants", - "item": [ - { - "name": "List Product Variants", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/productos/{{producto_id}}/variants", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "productos", - "{{producto_id}}", - "variants" - ] - } - }, - "response": [] - }, - { - "name": "Create Product Variant", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"stock\": 8,\n \"definitions\": [\n {\n \"products_attribute_id\": {{color_product_attribute_id}},\n \"value\": \"Blanco\"\n },\n {\n \"products_attribute_id\": {{talle_product_attribute_id}},\n \"value\": \"M\"\n }\n ],\n \"images\": []\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/productos/{{producto_id}}/variants", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "productos", - "{{producto_id}}", - "variants" - ] - } - }, - "response": [] - }, - { - "name": "Show Product Variant", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/productos/{{producto_id}}/variants/{{product_variant_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "productos", - "{{producto_id}}", - "variants", - "{{product_variant_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Update Product Variant", - "request": { - "method": "PATCH", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"stock\": 12,\n \"definitions\": [\n {\n \"products_attribute_id\": {{color_product_attribute_id}},\n \"value\": \"Blanco\"\n },\n {\n \"products_attribute_id\": {{talle_product_attribute_id}},\n \"value\": \"M\"\n }\n ],\n \"images\": []\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/productos/{{producto_id}}/variants/{{product_variant_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "productos", - "{{producto_id}}", - "variants", - "{{product_variant_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Delete Product Variant", - "request": { - "method": "DELETE", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/productos/{{producto_id}}/variants/{{product_variant_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "productos", - "{{producto_id}}", - "variants", - "{{product_variant_id}}" - ] - } - }, - "response": [] - } - ] + }, + "response": [] } ] }, @@ -1065,18 +352,7 @@ "type": "text" } ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/cart", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "cart" - ] - } + "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/cart" }, "response": [] }, @@ -1096,22 +372,16 @@ "type": "text" } ], + "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/cart/items", + "description": "variant_id is optional and may be removed for catalog items without variants.", "body": { "mode": "raw", - "raw": "{\n \"product_variant_id\": {{product_variant_id}},\n \"cantidad\": 1\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/cart/items", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "cart", - "items" - ] + "raw": "{\n \"catalog_item_id\": {{catalog_item_id}},\n \"variant_id\": {{variant_id}},\n \"cantidad\": 1\n}", + "options": { + "raw": { + "language": "json" + } + } } }, "response": [] @@ -1132,23 +402,15 @@ "type": "text" } ], + "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/cart/items/{{cart_item_id}}", "body": { "mode": "raw", - "raw": "{\n \"cantidad\": 2\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/cart/items/{{product_variant_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "cart", - "items", - "{{product_variant_id}}" - ] + "raw": "{\n \"cantidad\": 2\n}", + "options": { + "raw": { + "language": "json" + } + } } }, "response": [] @@ -1164,20 +426,7 @@ "type": "text" } ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/cart/items/{{product_variant_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "cart", - "items", - "{{product_variant_id}}" - ] - } + "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/cart/items/{{cart_item_id}}" }, "response": [] } @@ -1317,6 +566,35 @@ } }, "response": [] + }, + { + "name": "Update Profile", + "request": { + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": "{{base_url}}/api/me", + "body": { + "mode": "raw", + "raw": "{\n \"nombre_apellido\": \"Ada Lovelace\",\n \"email\": \"ada@example.com\",\n \"dni\": \"12345678\",\n \"telefono\": \"+54 9 341 555-1234\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] } ] }, @@ -1410,14 +688,87 @@ } }, "response": [] + }, + { + "name": "Create QR Payment Intent", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/compras/{{compra_id}}/payment-intent", + "body": { + "mode": "raw", + "raw": "{\n \"method\": \"qr\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Create Transfer Payment Intent", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/compras/{{compra_id}}/payment-intent", + "body": { + "mode": "raw", + "raw": "{\n \"method\": \"transfer\",\n \"transfer_payer_dni\": \"12345678\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Complete Purchase", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/compras/{{compra_id}}/complete" + }, + "response": [] } ] }, { - "name": "Bank Accounts", + "name": "Tickets", "item": [ { - "name": "List Bank Accounts", + "name": "List My Tickets", "request": { "method": "GET", "header": [ @@ -1427,23 +778,33 @@ "type": "text" } ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/bank-accounts", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "bank-accounts" - ] - } + "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/tickets", + "description": "Requires authentication and returns only the current user tickets for this tenant." + }, + "response": [] + } + ] + }, + { + "name": "Menus", + "item": [ + { + "name": "List Menus", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": "{{base_url}}/api/menues" }, "response": [] }, { - "name": "Create Bank Account", + "name": "Create Menu", "request": { "method": "POST", "header": [ @@ -1458,27 +819,21 @@ "type": "text" } ], + "url": "{{base_url}}/api/menues", "body": { "mode": "raw", - "raw": "{\n \"titular\": \"Ada Lovelace\",\n \"entidad\": \"Banco Demo\",\n \"alias\": \"ada.demo.alias\",\n \"cvu\": \"0000003100000000000001\"\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/bank-accounts", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "bank-accounts" - ] + "raw": "{\n \"code\": \"catalog\",\n \"route\": \"/catalog\"\n}", + "options": { + "raw": { + "language": "json" + } + } } }, "response": [] }, { - "name": "Show Selected Bank Account", + "name": "Show Menu", "request": { "method": "GET", "header": [ @@ -1488,53 +843,14 @@ "type": "text" } ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/bank-accounts/selected", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "bank-accounts", - "selected" - ] - } + "url": "{{base_url}}/api/menues/{{menu_id}}" }, "response": [] }, { - "name": "Show Bank Account", + "name": "Update Menu", "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/bank-accounts/{{bank_account_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "bank-accounts", - "{{bank_account_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Update Bank Account", - "request": { - "method": "PATCH", + "method": "PUT", "header": [ { "key": "Accept", @@ -1547,56 +863,21 @@ "type": "text" } ], + "url": "{{base_url}}/api/menues/{{menu_id}}", "body": { "mode": "raw", - "raw": "{\n \"titular\": \"Ada Lovelace Updated\",\n \"entidad\": \"Banco Demo Updated\",\n \"alias\": \"ada.demo.updated\",\n \"cvu\": \"0000003100000000000002\"\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/bank-accounts/{{bank_account_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "bank-accounts", - "{{bank_account_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Select Bank Account", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" + "raw": "{\n \"code\": \"catalog\",\n \"route\": \"/catalogo\"\n}", + "options": { + "raw": { + "language": "json" + } } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/bank-accounts/{{bank_account_id}}/select", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "bank-accounts", - "{{bank_account_id}}", - "select" - ] } }, "response": [] }, { - "name": "Delete Bank Account", + "name": "Delete Menu", "request": { "method": "DELETE", "header": [ @@ -1606,19 +887,7 @@ "type": "text" } ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/bank-accounts/{{bank_account_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "bank-accounts", - "{{bank_account_id}}" - ] - } + "url": "{{base_url}}/api/menues/{{menu_id}}" }, "response": [] } @@ -1861,6 +1130,41 @@ } ] }, + { + "name": "Webhooks", + "item": [ + { + "name": "Telepagos Cash-in Notification", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": "{{base_url}}/api/webhooks/telepagos/{{tenant_codigo}}", + "description": "Receives a Telepagos cash-in identifier and updates the related purchase payment.", + "body": { + "mode": "raw", + "raw": "{\n \"id\": \"{{telepagos_cashin_id}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + } + ] + }, { "name": "Storage Test", "item": [ @@ -1982,6 +1286,41 @@ "response": [] } ] + }, + { + "name": "Mail Test", + "item": [ + { + "name": "Send Test Email", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": "{{base_url}}/api/mail-test/send", + "description": "Sends a real message through the mailer configured in the backend environment.", + "body": { + "mode": "raw", + "raw": "{\n \"to\": \"{{test_email}}\",\n \"subject\": \"Prueba de correo de Shopit\",\n \"message\": \"Este es un correo de prueba enviado desde Postman.\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + } + ] } ], "event": [ @@ -2038,47 +1377,27 @@ "type": "string" }, { - "key": "marca_id", + "key": "catalog_item_id", "value": "1", "type": "string" }, { - "key": "categoria_id", + "key": "featured_group_id", "value": "1", "type": "string" }, { - "key": "attribute_id", + "key": "variant_id", "value": "1", "type": "string" }, { - "key": "color_attribute_id", + "key": "cart_item_id", "value": "1", "type": "string" }, { - "key": "talle_attribute_id", - "value": "2", - "type": "string" - }, - { - "key": "color_product_attribute_id", - "value": "1", - "type": "string" - }, - { - "key": "talle_product_attribute_id", - "value": "2", - "type": "string" - }, - { - "key": "producto_id", - "value": "1", - "type": "string" - }, - { - "key": "product_variant_id", + "key": "cart_id", "value": "1", "type": "string" }, @@ -2098,9 +1417,19 @@ "type": "string" }, { - "key": "bank_account_id", + "key": "menu_id", "value": "1", "type": "string" + }, + { + "key": "telepagos_cashin_id", + "value": "7000", + "type": "string" + }, + { + "key": "test_email", + "value": "destinatario@example.com", + "type": "string" } ] } diff --git a/app/Domains/MailTest/Controllers/MailTestController.php b/app/Domains/MailTest/Controllers/MailTestController.php new file mode 100644 index 0000000..6e5ce5b --- /dev/null +++ b/app/Domains/MailTest/Controllers/MailTestController.php @@ -0,0 +1,26 @@ +json( + $this->mailTestService->send( + $request->validated('to'), + $request->validated('subject'), + $request->validated('message'), + ) + ); + } +} diff --git a/app/Domains/MailTest/Mailables/TestMail.php b/app/Domains/MailTest/Mailables/TestMail.php new file mode 100644 index 0000000..182f00f --- /dev/null +++ b/app/Domains/MailTest/Mailables/TestMail.php @@ -0,0 +1,37 @@ +mailSubject); + } + + public function content(): Content + { + $message = nl2br(e($this->mailMessage)); + + return new Content( + htmlString: <<Prueba de correo de Shopit +

{$message}

+

Si recibiste este mensaje, la configuracion de correo funciona correctamente.

+ HTML, + ); + } +} diff --git a/app/Domains/MailTest/Requests/SendTestMailRequest.php b/app/Domains/MailTest/Requests/SendTestMailRequest.php new file mode 100644 index 0000000..ab98d8b --- /dev/null +++ b/app/Domains/MailTest/Requests/SendTestMailRequest.php @@ -0,0 +1,25 @@ +> + */ + public function rules(): array + { + return [ + 'to' => ['required', 'string', 'email', 'max:255'], + 'subject' => ['nullable', 'string', 'max:255'], + 'message' => ['nullable', 'string', 'max:5000'], + ]; + } +} diff --git a/app/Domains/MailTest/Services/MailTestService.php b/app/Domains/MailTest/Services/MailTestService.php new file mode 100644 index 0000000..e1201f3 --- /dev/null +++ b/app/Domains/MailTest/Services/MailTestService.php @@ -0,0 +1,27 @@ + + */ + public function send(string $recipient, ?string $subject = null, ?string $message = null): array + { + $subject ??= 'Prueba de correo de Shopit'; + $message ??= 'Este es un correo de prueba enviado desde Shopit.'; + + Mail::to($recipient)->send(new TestMail($subject, $message)); + + return [ + 'message' => 'Correo de prueba enviado correctamente.', + 'recipient' => $recipient, + 'mailer' => (string) config('mail.default'), + 'sent_at' => now()->toIso8601String(), + ]; + } +} diff --git a/app/Domains/MailTest/routes/api.php b/app/Domains/MailTest/routes/api.php new file mode 100644 index 0000000..d26b474 --- /dev/null +++ b/app/Domains/MailTest/routes/api.php @@ -0,0 +1,6 @@ + 'email'], + [ + 'name' => 'Email', + 'url' => null, + 'integration_data_schema' => [ + 'MAIL_MAILER' => 'required|string|in:smtp', + 'MAIL_SCHEME' => 'required|string|in:smtp', + 'MAIL_HOST' => 'required|string|in:smtp.gmail.com', + 'MAIL_PORT' => 'required|integer|in:587', + 'MAIL_USERNAME' => 'required|email', + 'MAIL_PASSWORD' => 'required|string', + 'MAIL_FROM_ADDRESS' => 'required|email', + ], + ] + ); + } +} diff --git a/routes/api.php b/routes/api.php index 694d7ce..c75196b 100644 --- a/routes/api.php +++ b/routes/api.php @@ -4,6 +4,7 @@ require __DIR__.'/../app/Domains/Auth/routes/api.php'; require __DIR__.'/../app/Domains/Catalog/routes/api.php'; require __DIR__.'/../app/Domains/Cart/routes/api.php'; require __DIR__.'/../app/Domains/StorageTest/routes/api.php'; +require __DIR__.'/../app/Domains/MailTest/routes/api.php'; require __DIR__.'/../app/Domains/Purchase/routes/api.php'; require __DIR__.'/../app/Domains/Tenant/routes/api.php'; require __DIR__.'/../app/Domains/Integration/routes/api.php'; diff --git a/tests/Feature/MailTest/MailTestControllerTest.php b/tests/Feature/MailTest/MailTestControllerTest.php new file mode 100644 index 0000000..bfc2bcc --- /dev/null +++ b/tests/Feature/MailTest/MailTestControllerTest.php @@ -0,0 +1,59 @@ +postJson('/api/mail-test/send', [ + 'to' => 'recipient@example.com', + 'subject' => 'SMTP test', + 'message' => 'Test message', + ]); + + $response->assertOk() + ->assertJsonPath('message', 'Correo de prueba enviado correctamente.') + ->assertJsonPath('recipient', 'recipient@example.com') + ->assertJsonPath('mailer', 'array') + ->assertJsonStructure(['sent_at']); + + Mail::assertSent(TestMail::class, function (TestMail $mail): bool { + return $mail->hasTo('recipient@example.com') + && $mail->mailSubject === 'SMTP test' + && $mail->mailMessage === 'Test message'; + }); + } + + public function test_it_uses_default_content_when_optional_fields_are_omitted(): void + { + Mail::fake(); + + $this->postJson('/api/mail-test/send', [ + 'to' => 'recipient@example.com', + ])->assertOk(); + + Mail::assertSent(TestMail::class, function (TestMail $mail): bool { + return $mail->mailSubject === 'Prueba de correo de Shopit' + && $mail->mailMessage === 'Este es un correo de prueba enviado desde Shopit.'; + }); + } + + public function test_it_validates_the_recipient(): void + { + Mail::fake(); + + $this->postJson('/api/mail-test/send', [ + 'to' => 'invalid-email', + ])->assertUnprocessable() + ->assertJsonValidationErrors(['to']); + + Mail::assertNothingSent(); + } +}