{"info":{"_postman_id":"d337c66a-dced-4070-94a4-6ae9a8f02433","name":"Unbox REST API","description":"<html><head></head><body><h2 id=\"overview\">Overview</h2>\n<p>The Unbox REST API provides an interface for partners who wish to integrate with the Unbox e-commerce platform.</p>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"owner":"33994726","collectionId":"d337c66a-dced-4070-94a4-6ae9a8f02433","publishedId":"2sB2cSiQ4p","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"},"publishDate":"2025-04-03T19:47:02.000Z"},"item":[{"name":"Authentication","item":[{"name":"REST Auth","event":[{"listen":"test","script":{"id":"8a22bdaa-3238-4eac-ad9b-7a26c1d15688","exec":["// Specific Tests for /auth/signin endpoint","let jsonData;","let isJson = false;","try {","    jsonData = pm.response.json();","    isJson = true;","    ","    // Store tokens in collection variables","    if (jsonData.access_token) {","        pm.collectionVariables.set('authorization', jsonData.access_token);","        const expiryTime = new Date();","        expiryTime.setHours(expiryTime.getHours() + 24);","        pm.collectionVariables.set('tokenExpiry', expiryTime.getTime());","        console.log('Auth Token stored.');","    }","} catch (e) {","    console.error('Auth: Failed to parse JSON response.');","}","const statusCode = pm.response.code;","const exampleName = pm.request.headers.get('x-postman-example-name') || 'Root Request';","","// Determine expected outcome based on example name","let expectsSuccess = exampleName.toLowerCase().includes('success') || exampleName == 'Root Request';","let expectsInvalidCredsError = exampleName.toLowerCase().includes('invalid credentials');","let expectsMissingParamError = exampleName.toLowerCase().includes('missing password');","let expectsApiKeyError = exampleName.toLowerCase().includes('invalid api key');","","// --- Shared Checks ---","if (!isJson && !expectsApiKeyError) {","    // Fail if JSON was expected but parsing failed","     pm.test(`[${exampleName}] Response should be valid JSON`, () => pm.expect.fail('Response was not valid JSON.'));","}","","// --- Success Case Tests ---","if (expectsSuccess) {","    pm.test(`[${exampleName}] Status code should be 200 OK`, function () {","        pm.expect(statusCode).to.equal(200);","    });","","    if (isJson && jsonData) {","        pm.test(`[${exampleName}] Response body contains access_token (string)`, function () {","            pm.expect(jsonData).to.be.an('object');","            pm.expect(jsonData.access_token).to.be.a('string').and.to.not.be.empty;","        });","","        pm.test(`[${exampleName}] Response body contains id_token (string)`, function () {","            pm.expect(jsonData.id_token).to.be.a('string').and.to.not.be.empty;","        });","","        pm.test(`[${exampleName}] Body should not contain errors property`, function () {","            pm.expect(jsonData.errors).to.be.undefined;","        });","    } else {","         pm.test(`[${exampleName}] Should have received JSON`, () => pm.expect.fail('Expected JSON body for success case.'));","    }","     // Check if success case incorrectly returned an error status","     pm.test(`[${exampleName}] Status code should not be an error code (4xx/5xx)`, function () {","        pm.expect(statusCode).to.be.below(400);","    });","}","","// --- Error Case Tests ---","","// Test: Invalid Credentials or Missing Parameters (Both examples return 400)","if (expectsInvalidCredsError || expectsMissingParamError) {","    const expectedStatus = 400;","    // Explicitly test that we DO NOT get 200 OK","    pm.test(`[${exampleName}] Should NOT have status 200 OK`, function () {","        pm.expect(statusCode).to.not.equal(200, `Expected non-200 status for ${exampleName}`);","    });","","    // Test for the expected 400 status","    pm.test(`[${exampleName}] Status code should be ${expectedStatus} Bad Request`, function () {","        pm.expect(statusCode).to.equal(expectedStatus);","    });","","    if (isJson && jsonData) {","         pm.test(`[${exampleName}] Body contains errors array`, function () {","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;","        });","","        // Check specific error message (assuming it's consistently INVALID_CREDENTIALS for 400s)","        if (jsonData.errors && jsonData.errors.length > 0) {","            pm.test(`[${exampleName}] Error message indicates invalid credentials/params`, function () {","               // The examples show INVALID_CREDENTIALS_ERROR even for missing password.","               pm.expect(jsonData.errors[0].message).to.equal(\"INVALID_CREDENTIALS_ERROR\");","            });","        }","    } else if (statusCode === expectedStatus) {","         pm.test(`[${exampleName}] Should have received JSON`, () => pm.expect.fail(`Expected JSON body for ${expectedStatus} error case.`));","    }","}","","// Test: Invalid API Key (Example returns 403)","if (expectsApiKeyError) {","    const expectedStatus = 403;","     // Explicitly test that we DO NOT get 200 OK","    pm.test(`[${exampleName}] Should NOT have status 200 OK`, function () {","        pm.expect(statusCode).to.not.equal(200, `Expected non-200 status for ${exampleName}`);","    });","","    // Test for the expected 403 status","    pm.test(`[${exampleName}] Status code should be ${expectedStatus} Forbidden`, function () {","        pm.expect(statusCode).to.equal(expectedStatus);","    });","","    // Check for Forbidden message (works for both JSON and non-JSON 403)","    if (isJson && jsonData) {","        pm.test(`[${exampleName}] Body contains Forbidden message`, function () {","             pm.expect(jsonData.message).to.equal(\"Forbidden\");","        });","    } else if (!isJson && statusCode === expectedStatus) { // Handle if 403 is not JSON","         pm.test(`[${exampleName}] Body text contains Forbidden`, function () {","            pm.expect(pm.response.text()).to.include(\"Forbidden\");","        });","    } else if (statusCode === expectedStatus) {","         // If it was 403 but somehow *was* JSON and *didn't* have the message property","         pm.test(`[${exampleName}] Body should contain Forbidden message`, () => pm.expect.fail('Expected Forbidden message in body.'));","    }","}"],"type":"text/javascript","packages":{},"requests":{}}}],"id":"fdd2f384-a26d-4999-b6a9-149771d90d65","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"}],"body":{"mode":"raw","raw":"{\r\n\t\"username\": \"{{username}}\",\r\n\t\"password\": \"{{password}}\"\r\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/auth/signin","description":"<h2 id=\"request\">Request</h2>\n<p><strong>Purpose:</strong> Authenticates a user account and returns access tokens for subsequent API calls.</p>\n<p><strong>How to use:</strong> Send a POST request with the required API key header and shop credentials in the body to get an access token. The returned <code>access_token</code> should be used in the <code>Authorization</code> header of subsequent requests.</p>\n<p><strong>Headers Required:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>x-api-key</code></td>\n<td><code>YourApiKey...</code></td>\n<td>Your partner-specific API key.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Request Body (</strong><code>application/json</code><strong>):</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>username</code></td>\n<td>string</td>\n<td><code>\"unbox-user\"</code></td>\n<td>Username for shop authentication</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>password</code></td>\n<td>string</td>\n<td><code>\"123456\"</code></td>\n<td>Password for shop authentication</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response\">Response</h2>\n<p><strong>Success (200 OK):</strong></p>\n<p><strong>Response Properties:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>access_token</td>\n<td>string</td>\n<td>JWT access token to be used in the <code>Authorization</code> header for subsequent requests</td>\n</tr>\n<tr>\n<td>id_token</td>\n<td>string</td>\n<td>JWT ID token containing user identification information</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Errors:</strong></p>\n<ul>\n<li><p><strong>400 Bad Request:</strong> Invalid input (e.g., missing username/password).</p>\n</li>\n<li><p><strong>401 Unauthorized:</strong> Incorrect username or password provided. (Note: API Gateway mapping might return 400 for this internally, but conceptually it's 401).</p>\n</li>\n<li><p><strong>403 Forbidden:</strong> Missing or invalid <code>x-api-key</code>.</p>\n</li>\n<li><p><strong>500 Internal Server Error:</strong> An unexpected server error.</p>\n</li>\n</ul>\n","urlObject":{"path":["auth","signin"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"b4a1fe70-9e3e-4f1b-a2b0-594ea3bd6dff","name":"Success - Valid Credentials","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"x-postman-example-name","value":"Success - Valid Credentials","type":"text"}],"body":{"mode":"raw","raw":"{\r\n\t\"username\": \"{{username}}\",\r\n\t\"password\": \"{{password}}\"\r\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/auth/signin"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"3366"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Sun, 30 Mar 2025 20:22:51 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67e9a81a-6997e54d380adade4a5b7656"},{"key":"x-amzn-RequestId","value":"cb9e4adc-215e-48ed-b9e3-e68a794b358c"},{"key":"x-amz-apigw-id","value":"IQc0RHWXoAMErvQ="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 2dcc4ff1eb32256cc8a05a63119f870a.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"QMQDD9DF4pZSNX3Ujzep2BfcLPlmo_K_a10F_KKA_FVzgST7dN-z6A=="}],"cookie":[],"responseTime":null,"body":"{\n    \"access_token\": \"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik54RHljNmp6ODN6TDhwMTlPS2h2QyJ9.eyJpc3MiOiJodHRwczovL3VuYm94aWQuYXV0aDAuY29tLyIsInN1YiI6ImF1dGgwfDY3ZTlhNzYwNGJjYjFiNjc5MWZhYzM2ZSIsImF1ZCI6WyJodHRwczovL3N0YWdlLnVuYm94LmNvbS5ici8iLCJodHRwczovL3VuYm94aWQuYXV0aDAuY29tL3VzZXJpbmZvIl0sImlhdCI6MTc0MzM2NjE3MSwiZXhwIjoxNzQzNDUyNTcxLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwiZ3R5IjoicGFzc3dvcmQiLCJhenAiOiJPcm1iRU9PVHJLTW5MeEZ0V2t3azgyQTZSWDRwb2xWUSIsInBlcm1pc3Npb25zIjpbImNoZWNrb3V0OnNob3BpZnk6bGluayIsImNyZWF0ZTphY2NvdW50IiwiY3JlYXRlOmF1dGg6dXJsIiwiY3JlYXRlOmNhcnQ6dGVtcGxhdGUiLCJjcmVhdGU6Y2F0YWxvZyIsImNyZWF0ZTppbnZvaWNlIiwiY3JlYXRlOnBheW1lbnQ6bGluayIsImNyZWF0ZTpwcm9kdWN0IiwiY3JlYXRlOnByb2R1Y3Q6Z3JvdXAiLCJjcmVhdGU6c2hvcCIsImNyZWF0ZTpzdWJzY3JpcHRpb24iLCJjcmVhdGU6c3Vic2NyaXB0aW9uOnBsYW4iLCJjcmVhdGU6dGFnIiwiZGVsZXRlOmZ1bGZpbGxtZW50Om9wdGlvbiIsImRlbGV0ZTpwcm9kdWN0IiwiZGVsZXRlOnByb2R1Y3Q6Z3JvdXAiLCJkZWxldGU6c3Vic2NyaXB0aW9uIiwiZGVsZXRlOnRhZyIsInJlYWQ6Y2FydDp0ZW1wbGF0ZSIsInJlYWQ6ZnVsZmlsbG1lbnQ6b3B0aW9uIiwicmVhZDpvcmRlciIsInJlYWQ6cGF5bWVudDpsaW5rIiwicmVhZDpwcml2YXRlOmZpbGUiLCJyZWFkOnByb2R1Y3QiLCJyZWFkOnByb2R1Y3Q6Z3JvdXAiLCJyZWFkOnJlY3VycmluZy1vcmRlcnMtcG9saWN5IiwicmVhZDpzaG9wOnJlY3VycmluZzpvcmRlcnMiLCJyZWFkOnN0b3JlOnRlbXBsYXRlIiwicmVhZDpzdWJzY3JpcHRpb24iLCJyZWFkOnN1YnNjcmlwdGlvbjpwbGFuIiwicmVhZDp0YWciLCJyZWFkOnRhc2s6Z3JvdXAiLCJ1cGRhdGU6Y2FydDp0ZW1wbGF0ZSIsInVwZGF0ZTpmaW5hbmNlcyIsInVwZGF0ZTpwYXltZW50OmxpbmsiLCJ3cml0ZTphY2NvdW50Iiwid3JpdGU6ZW1haWw6dGVtcGxhdGUiLCJ3cml0ZTpmdWxmaWxsbWVudDpvcHRpb24iLCJ3cml0ZTpvcmRlciIsIndyaXRlOnByb2R1Y3QiLCJ3cml0ZTpwcm9kdWN0Omdyb3VwIiwid3JpdGU6cmVjdXJyaW5nLW9yZGVycy1wb2xpY3kiLCJ3cml0ZTpzaGlwbWVudCIsIndyaXRlOnNob3AiLCJ3cml0ZTpzaG9wOmZpbGVzIiwid3JpdGU6c2hvcDpyZWN1cnJpbmc6b3JkZXJzIiwid3JpdGU6c2hvcDpzZXR0aW5ncyIsIndyaXRlOnN0b3JlZnJvbnQ6dGVtcGxhdGUiLCJ3cml0ZTpzdG9yZTp0ZW1wbGF0ZSIsIndyaXRlOnRhZyIsIndyaXRlOnRhc2s6Z3JvdXAiLCJ3cml0ZTp3ZWJob29rOnN1YnNjcmliZXIiXX0.kIvgI4APnHOz6T6gb-ZD4Vk03etU8jUFb3s5uO-WLxjMphSpGvnaeRIHUT3nesWFBDvPg8IkqAAjiIYzxLJw91vV2BamkqLksIOdpCW-197z7TKMSuj0j_nYepOSIWzlUN4zv-paki_dLLWNa21CrjeC978ChWg6Mq4MRyMqsGreOfJtX8e77v5d8m524as_ffQ3Qe2_qnx7vXAzZDPHakJya84JqR-kXY-BiE_mp-v0W0jO0oV_AcPcdPbWsiLvPwJqqGhll3lKzQHYJZ0NbBEa9_M1T1R4IBv-TmZkiZkSm2kqh550RGhoW8WehzzGR8QRpi8HzCZNxQ3lp3jlmA\",\n    \"id_token\": \"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik54RHljNmp6ODN6TDhwMTlPS2h2QyJ9.eyJuaWNrbmFtZSI6ImxvamEuZXhlbXBsby5zdGFnZS5yZXN0LmFwaS5saW1pdGVkdXNlciIsIm5hbWUiOiJSZXN0IEFQSSAtIFVzdcOhcmlvIEV4ZW1wbG8gU3RhZ2UiLCJwaWN0dXJlIjoiaHR0cHM6Ly9zLmdyYXZhdGFyLmNvbS9hdmF0YXIvM2RhNTJjZWI3NmVmNjBkNDFhZWQ5N2FiNDEzZDA1N2I_cz00ODAmcj1wZyZkPWh0dHBzJTNBJTJGJTJGY2RuLmF1dGgwLmNvbSUyRmF2YXRhcnMlMkZyYS5wbmciLCJ1cGRhdGVkX2F0IjoiMjAyNS0wMy0zMFQyMDoyMjo1MS40NDNaIiwiZW1haWwiOiJsb2phLmV4ZW1wbG8uc3RhZ2UucmVzdC5hcGkubGltaXRlZHVzZXJAdW5ib3guY29tLmJyIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8vdW5ib3hpZC5hdXRoMC5jb20vIiwiYXVkIjoiT3JtYkVPT1RyS01uTHhGdFdrd2s4MkE2Ulg0cG9sVlEiLCJzdWIiOiJhdXRoMHw2N2U5YTc2MDRiY2IxYjY3OTFmYWMzNmUiLCJpYXQiOjE3NDMzNjYxNzEsImV4cCI6MTc0MzQwMjE3MX0.m2d3k58o836Cf7dFQjNHEUXvMNR94MUF1jq5HCN1ph17htVWpMpqs-wAFMPn25OTnjwmMIu1XoxJ6jseMJXV1BAvTM2ZAPGP37Bh3yHIM6WewahXM4aVZ9vg3kyWMWSJaTtevhsi4w_usuNmLcZF2mCRlDYZVHaf2ZP9fWebD0lKGl1u6HZFYKTi85LMXcQrqGgf2dh7FPo07GnY1XzkLArs3SFJpb75rpGD-hCNXyq3zeYXsTf91IH7jg-oS8SQJJ8rKlbJo2gpiuuO-QVrPyj9ttQ7qhvXv05M3KoaY_J1TIL9GKepPtQXEI6w9fhF1CztX8RwSeS_k4uPf-LUHg\"\n}"},{"id":"4ed3dc9e-949a-4224-a830-0f25339d26cc","name":"Error - Invalid Credentials","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"x-postman-example-name","value":"Error - Invalid Credentials","type":"text"}],"body":{"mode":"raw","raw":"{\r\n\t\"username\": \"{{username}}\",\r\n\t\"password\": \"wrong password\"\r\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/auth/signin"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"692"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Sun, 30 Mar 2025 20:23:03 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67e9a827-4e66f86e797bb47d7bb403c2"},{"key":"x-amzn-RequestId","value":"021456d1-824a-4b21-9ee8-9320ebbf5b6f"},{"key":"x-amz-apigw-id","value":"IQc2KHlzoAMEViQ="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 2dcc4ff1eb32256cc8a05a63119f870a.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"_YmbknKrnTPwuyQxxQHCSGqIFFcXatQR3_c3ZFSC0ygR8n-_8WxccQ=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"INVALID_CREDENTIALS_ERROR\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 59\n                }\n            ],\n            \"path\": [\n                \"signIn\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"stacktrace\": [\n                        \"Error: INVALID_CREDENTIALS_ERROR\",\n                        \"    at file:///usr/local/yggdrasil/packages/plugins/accounts/dist/src/mutations/signIn.js:22:15\",\n                        \"    at runMicrotasks (<anonymous>)\",\n                        \"    at processTicksAndRejections (node:internal/process/task_queues:96:5)\",\n                        \"    at async signIn (file:///usr/local/yggdrasil/packages/plugins/accounts/dist/src/mutations/signIn.js:13:27)\",\n                        \"    at async signIn (file:///usr/local/yggdrasil/packages/plugins/accounts/dist/src/resolvers/Mutation/signIn.js:9:26)\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"signIn\": null\n    }\n}"},{"id":"cca25788-1603-411d-bb9e-844d9d965b37","name":"Error - Missing Password","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"x-postman-example-name","value":"Error - Missing Password","type":"text"}],"body":{"mode":"raw","raw":"{\r\n\t\"username\": \"{{username}}\"\r\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/auth/signin"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"692"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Sun, 30 Mar 2025 20:23:24 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67e9a83b-72b5bf69244b17c969e6a84f"},{"key":"x-amzn-RequestId","value":"98e7d4b8-ffd7-436f-907d-a52ab20c7429"},{"key":"x-amz-apigw-id","value":"IQc5bHwlIAMEV2g="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 2dcc4ff1eb32256cc8a05a63119f870a.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"1MPkncZ1_IuDV8qfzhRrIEjnQpwb2vHR70ZZm06zTExphB_UBmANKg=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"INVALID_CREDENTIALS_ERROR\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 59\n                }\n            ],\n            \"path\": [\n                \"signIn\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"stacktrace\": [\n                        \"Error: INVALID_CREDENTIALS_ERROR\",\n                        \"    at file:///usr/local/yggdrasil/packages/plugins/accounts/dist/src/mutations/signIn.js:22:15\",\n                        \"    at runMicrotasks (<anonymous>)\",\n                        \"    at processTicksAndRejections (node:internal/process/task_queues:96:5)\",\n                        \"    at async signIn (file:///usr/local/yggdrasil/packages/plugins/accounts/dist/src/mutations/signIn.js:13:27)\",\n                        \"    at async signIn (file:///usr/local/yggdrasil/packages/plugins/accounts/dist/src/resolvers/Mutation/signIn.js:9:26)\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"signIn\": null\n    }\n}"},{"id":"712af4a1-0b04-41b6-aecd-afede116b615","name":"Error - Invalid API Key","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"invalid-api-key","type":"text"},{"key":"x-postman-example-name","value":"Error - Invalid API Key","type":"text"}],"body":{"mode":"raw","raw":"{\r\n\t\"username\": \"{{username}}\",\r\n\t\"password\": \"{{password}}\"\r\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/auth/signin"},"status":"Forbidden","code":403,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"23"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Sun, 30 Mar 2025 20:23:33 GMT"},{"key":"x-amz-apigw-id","value":"IQc63H75oAMEi0Q="},{"key":"x-amzn-RequestId","value":"b26d209f-d7bf-4105-864b-5e1763e59a98"},{"key":"x-amzn-ErrorType","value":"ForbiddenException"},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 2dcc4ff1eb32256cc8a05a63119f870a.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"3jZ3dajnX5VH52SY-_ryJmbq00OYjWI-8XZE2gOkTkIFD8IUDfa6Cw=="}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Forbidden\"\n}"}],"_postman_id":"fdd2f384-a26d-4999-b6a9-149771d90d65"}],"id":"2f1552ab-c4b6-4d8a-bbcc-2f1ad5d46d3b","description":"<p>The API uses a two-step authentication process:</p>\n<ol>\n<li><p>API Key Authentication: All requests require an API key in the x-api-key header. This key is partner-specific, environment-agnostic, and controls rate limits.</p>\n</li>\n<li><p>Shop Authentication: After obtaining an API key, you need to authenticate with shop credentials using the /auth/signin endpoint. This provides an access token tied to a specific shop in a specific environment.</p>\n</li>\n<li><p>Using the Access Token: Include the received token in the Authorization header for all subsequent requests (do <strong>not</strong> preappend the 'Bearer' word)</p>\n</li>\n</ol>\n<h3 id=\"token-expiration\">Token Expiration</h3>\n<p>Access tokens have a limited validity period. When a token expires, API requests will return a 400 error. In this case, you need to request a new token using the signin endpoint.</p>\n","_postman_id":"2f1552ab-c4b6-4d8a-bbcc-2f1ad5d46d3b"},{"name":"Discount Codes","item":[{"name":"List Discount Codes","event":[{"listen":"test","script":{"id":"0c524c2e-f4f4-4974-840c-1e6794d5a6c8","exec":["// Specific Tests for GET /discount-codes endpoint\r","let jsonData;\r","let isJson = false;\r","try {\r","    jsonData = pm.response.json();\r","    isJson = true;\r","} catch (e) {\r","    console.error('GET /discount-codes: Failed to parse JSON response.');\r","}\r","\r","const statusCode = pm.response.code;\r","const requestName = pm.request.headers.get('x-postman-example-name') || 'Root Request';\r","\r","// Determine expected outcome based on request name (from examples)\r","let expectsSuccess = requestName.toLowerCase().includes('success') || requestName == 'Root Request';\r","let expectsMissingAuthError = requestName.toLowerCase().includes('missing auth');\r","let expectsMissingApiKeyError = requestName.toLowerCase().includes('missing api key');\r","let expectsMissingShopIdError = requestName.toLowerCase().includes('missing shop id');\r","\r","// --- Shared Checks ---\r","if (!isJson && !expectsMissingApiKeyError) { // 403 Missing API Key might be non-JSON\r","    // Fail if JSON was expected but parsing failed\r","     pm.test(`[${requestName}] Response should be valid JSON`, () => pm.expect.fail('Response was not valid JSON.'));\r","}\r","\r","// --- Success Case Tests ---\r","if (expectsSuccess) {\r","    pm.test(`[${requestName}] Status code should be 200 OK`, function () {\r","        pm.expect(statusCode).to.equal(200);\r","    });\r","\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body should not contain errors property`, function () {\r","            // Checks if the top-level 'errors' key exists\r","            pm.expect(jsonData.errors).to.be.undefined;\r","        });\r","\r","        pm.test(`[${requestName}] Response body has core structure`, function () {\r","            pm.expect(jsonData).to.be.an('object');\r","            pm.expect(jsonData).to.have.all.keys('totalCount', 'pageInfo', 'discounts');\r","            pm.expect(jsonData.totalCount).to.be.a('number');\r","            pm.expect(jsonData.pageInfo).to.be.an('object');\r","            pm.expect(jsonData.discounts).to.be.an('array');\r","        });\r","\r","        pm.test(`[${requestName}] pageInfo structure is correct`, function () {\r","            pm.expect(jsonData.pageInfo).to.have.all.keys('hasNextPage', 'hasPreviousPage', 'startCursor', 'endCursor');\r","            pm.expect(jsonData.pageInfo.hasNextPage).to.be.a('boolean');\r","            pm.expect(jsonData.pageInfo.hasPreviousPage).to.be.a('boolean');\r","\r","            // Cursors can be null or string\r","            if (jsonData.pageInfo.startCursor !== null) pm.expect(jsonData.pageInfo.startCursor).to.be.a('string');\r","            if (jsonData.pageInfo.endCursor !== null) pm.expect(jsonData.pageInfo.endCursor).to.be.a('string');\r","        });\r","\r","        pm.test(`[${requestName}] Discount items have expected properties (if any)`, function () {\r","            if (jsonData.discounts.length > 0) {\r","                const firstDiscount = jsonData.discounts[0];\r","                pm.expect(firstDiscount).to.be.an('object');\r","                pm.expect(firstDiscount).to.have.property('_id').that.is.a('string');\r","                pm.expect(firstDiscount).to.have.property('code').that.is.a('string');\r","                pm.expect(firstDiscount).to.have.property('enabled').that.is.a('boolean');\r","                pm.expect(firstDiscount).to.have.property('conditions').that.is.an('object');\r","            } else {\r","                 pm.expect(jsonData.discounts).to.be.an('array').that.is.empty;\r","            }\r","        });\r","    } else if (!isJson) {\r","         pm.test(`[${requestName}] Should have received JSON`, () => pm.expect.fail('Expected JSON body for success case.'));\r","    }\r","}\r","// --- Error Case Tests ---\r","\r","// Test: Missing Auth Token\r","if (expectsMissingAuthError) {\r","    // Explicitly test that we DO NOT get 200 OK\r","    pm.test(`[${requestName}] Should NOT have status 200 OK`, function () {\r","        pm.expect(statusCode).to.not.equal(200, \"Expected non-200 status for missing auth token (EXPECTED TO FAIL CURRENTLY)\");\r","    });\r","\r","    // Test for the *expected* 401 status. This WILL FAIL with the current example body/status.\r","    pm.test(`[${requestName}] Status code SHOULD BE 401 Unauthorized (EXPECTED TO FAIL CURRENTLY)`, function () {\r","        pm.expect(statusCode).to.equal(401);\r","    });\r","\r","    pm.test(`[${requestName}] Body should contain unauthorized error (EXPECTED TO FAIL CURRENTLY)`, function () {\r","        pm.expect(jsonData.errors[0].extensions.code).to.equal('UNAUTHENTICATED');\r","        pm.expect(jsonData.errors[0].message).to.include('Unauthorized');\r","    });\r","}\r","\r","// Test: Missing API Key\r","if (expectsMissingApiKeyError) {\r","     // Explicitly test that we DO NOT get 200 OK\r","    pm.test(`[${requestName}] Should NOT have status 200 OK`, function () {\r","        pm.expect(statusCode).to.not.equal(200, \"Expected non-200 status for missing API key\");\r","    });\r","\r","    // Test for the expected 403 status\r","    pm.test(`[${requestName}] Status code should be 403 Forbidden`, function () {\r","        pm.expect(statusCode).to.equal(403);\r","    });\r","\r","    // Check for Forbidden message (works for both JSON and non-JSON 403)\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body contains Forbidden message`, function () {\r","             pm.expect(jsonData.message).to.equal(\"Forbidden\");\r","        });\r","    } else if (!isJson) { // Handle if 403 is not JSON\r","         pm.test(`[${requestName}] Body text contains Forbidden`, function () {\r","            pm.expect(pm.response.text()).to.include(\"Forbidden\");\r","        });\r","    }\r","}\r","\r","// Test: Missing Shop ID\r","if (expectsMissingShopIdError) {\r","    // Explicitly test that we DO NOT get 200 OK\r","    pm.test(`[${requestName}] Should NOT have status 200 OK`, function () {\r","        pm.expect(statusCode).to.not.equal(200, \"Expected non-200 status for missing Shop ID (EXPECTED TO FAIL CURRENTLY)\");\r","    });\r","\r","    // Test for the expected 400 status.\r","    pm.test(`[${requestName}] Status code SHOULD BE 400 Bad Request (EXPECTED TO FAIL CURRENTLY)`, function () {\r","        pm.expect(statusCode).to.equal(400);\r","    });\r","}"],"type":"text/javascript","packages":{},"requests":{}}}],"id":"0436b95a-6720-4694-8864-fdc15d4bfa45","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"GET","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"}],"url":"{{base_url}}/discount-codes?shopId={{shopId}}&version=v2","description":"<h2 id=\"request\">Request</h2>\n<p><strong>Purpose:</strong> Retrieves a paginated list of discount codes for a specific shop.</p>\n<p><strong>How to use:</strong> Send a GET request with the required API key and Authorization headers, and the mandatory <code>shopId</code> query parameter. Use optional pagination parameters (<code>first</code>/<code>after</code> or <code>last</code>/<code>before</code>) to navigate through results.</p>\n<p><strong>Headers Required:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>x-api-key</code></td>\n<td><code>YourApiKey...</code></td>\n<td>Your partner-specific API key.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>Authorization</code></td>\n<td><code>YourToken...</code></td>\n<td>The access token obtained via <code>/auth/signin</code>.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Query Parameters:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>shopId</code></td>\n<td>string</td>\n<td><code>\"MRxLZSpu6Aaw...\"</code></td>\n<td>Opaque ID of the shop to retrieve discount codes for.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>first</code></td>\n<td>integer</td>\n<td><code>20</code></td>\n<td>Number of discount codes to return (forward pagination). Use with <code>after</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>after</code></td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items after this point. Use with <code>first</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>last</code></td>\n<td>integer</td>\n<td><code>10</code></td>\n<td>Number of discount codes to return (backward pagination). Use with <code>before</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>before</code></td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Query Parameters (for version = 'v2':</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>shopId</code></td>\n<td>string</td>\n<td><code>\"MRxLZSpu6Aaw...\"</code></td>\n<td>Opaque ID of the shop to retrieve discount codes for.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>version</code></td>\n<td>string</td>\n<td><code>v2</code></td>\n<td>Version must be 'v2' to enable new filters</td>\n<td></td>\n</tr>\n<tr>\n<td>sortOrder</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items after this point. Use with <code>first</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>sortBy</td>\n<td>integer</td>\n<td><code>10</code></td>\n<td>Number of discount codes to return (backward pagination). Use with <code>before</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>offset</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>enabled</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>code</td>\n<td></td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>productType</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>calculationMethod</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>redemptionLimitReached</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>endDate[gte]</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>endDate[lte]</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>startDate[gte]</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>startDate[lte]</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>createdAt[gte]</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>createdAt[lte]</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>updatedAt[gte]</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td>updatedAt[lte]</td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response\">Response</h2>\n<p><strong>Success (200 OK):</strong></p>\n<p>Returns a paginated list of discount codes.</p>\n<p><strong>Response Properties:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>totalCount</code></td>\n<td>integer</td>\n<td>Total number of discount codes matching the query</td>\n</tr>\n<tr>\n<td><code>pageInfo</code></td>\n<td>object</td>\n<td>Pagination information</td>\n</tr>\n<tr>\n<td><code>pageInfo.hasNextPage</code></td>\n<td>boolean</td>\n<td>Indicates if there are more items after the current page</td>\n</tr>\n<tr>\n<td><code>pageInfo.hasPreviousPage</code></td>\n<td>boolean</td>\n<td>Indicates if there are items before the current page</td>\n</tr>\n<tr>\n<td><code>pageInfo.startCursor</code></td>\n<td>string</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>pageInfo.endCursor</code></td>\n<td>string</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts</code></td>\n<td>array[object]</td>\n<td>List of discount code objects</td>\n</tr>\n<tr>\n<td><code>discounts[]._id</code></td>\n<td>string</td>\n<td>Unique identifier for the discount code</td>\n</tr>\n<tr>\n<td><code>discounts[].code</code></td>\n<td>string</td>\n<td>The discount code string</td>\n</tr>\n<tr>\n<td><code>discounts[].label</code></td>\n<td>string</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].description</code></td>\n<td>string</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].enabled</code></td>\n<td>boolean</td>\n<td>Whether the discount code is active</td>\n</tr>\n<tr>\n<td><code>discounts[].discountMethod</code></td>\n<td>string</td>\n<td>The method by which this discount is applied (e.g., \"CODE\")</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions</code></td>\n<td>object</td>\n<td>Conditions that must be met for the discount to apply</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.accountLimit</code></td>\n<td>integer</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.redemptionLimit</code></td>\n<td>integer</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.startDate</code></td>\n<td>string (ISO 8601)</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.endDate</code></td>\n<td>string (ISO 8601)</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.min</code></td>\n<td>number</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.max</code></td>\n<td>number</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.productType</code></td>\n<td>string</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].calculation</code></td>\n<td>object</td>\n<td>Calculation method and parameters for the discount</td>\n</tr>\n<tr>\n<td><code>discounts[].transactions</code></td>\n<td>array[object]</td>\n<td>null</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Errors:</strong></p>\n<ul>\n<li><p><strong>400 Bad Request:</strong> Invalid parameter format (e.g., non-integer <code>first</code>/<code>last</code>) or missing required <code>shopId</code>.</p>\n</li>\n<li><p><strong>401 Unauthorized:</strong> Missing or invalid <code>Authorization</code> token.</p>\n</li>\n<li><p><strong>403 Forbidden:</strong> Missing or invalid <code>x-api-key</code>, or insufficient permissions to access the specified shop's discounts.</p>\n</li>\n<li><p><strong>500 Internal Server Error:</strong> An unexpected server error.</p>\n</li>\n</ul>\n","urlObject":{"path":["discount-codes"],"host":["{{base_url}}"],"query":[{"key":"shopId","value":"{{shopId}}"},{"disabled":true,"description":{"content":"<p>desc (default), asc</p>\n","type":"text/plain"},"key":"sortOrder","value":"asc"},{"disabled":true,"description":{"content":"<p>createdAt (default), updatedAt, startDate, endDate, code, calculationMethod, amountOfRedemptions</p>\n","type":"text/plain"},"key":"sortBy","value":"createdAt"},{"disabled":true,"key":"offset","value":"0"},{"disabled":true,"description":{"content":"<p>true (default), false</p>\n","type":"text/plain"},"key":"enabled","value":"false"},{"disabled":true,"key":"code","value":"FRETE"},{"disabled":true,"description":{"content":"<p>NON_RECURRING, RECURRING, ALL</p>\n","type":"text/plain"},"key":"productType","value":"NON_RECURRING"},{"disabled":true,"description":{"content":"<p>DISCOUNT, CREDIT_OFF_FLAT, CREDIT_OFF_BY_PRODUCT_TYPE, SHIPPING</p>\n","type":"text/plain"},"key":"calculationMethod","value":"NON_RECURRING"},{"disabled":true,"description":{"content":"<p>true, false</p>\n","type":"text/plain"},"key":"redemptionLimitReached","value":"false"},{"disabled":true,"description":{"content":"<p>Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT</p>\n","type":"text/plain"},"key":"endDate[gte]","value":"2050-01-01T03:00:00.000Z"},{"disabled":true,"description":{"content":"<p>Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT</p>\n","type":"text/plain"},"key":"endDate[lte]","value":"2050-03-01T03:00:00.000Z"},{"disabled":true,"description":{"content":"<p>Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT</p>\n","type":"text/plain"},"key":"startDate[gte]","value":"2040-01-01T03:00:00.000Z"},{"disabled":true,"description":{"content":"<p>Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT</p>\n","type":"text/plain"},"key":"startDate[lte]","value":"2040-03-01T03:00:00.000Z"},{"disabled":true,"description":{"content":"<p>Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT</p>\n","type":"text/plain"},"key":"createdAt[gte]","value":"2025-06-01T03:00:00.000Z"},{"disabled":true,"description":{"content":"<p>Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT</p>\n","type":"text/plain"},"key":"createdAt[lte]","value":"2025-06-01T03:00:00.000Z"},{"disabled":true,"description":{"content":"<p>Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT</p>\n","type":"text/plain"},"key":"updatedAt[gte]","value":"2025-01-01T03:00:00.000Z"},{"disabled":true,"description":{"content":"<p>Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT</p>\n","type":"text/plain"},"key":"updatedAt[lte]","value":"2025-05-01T03:00:00.000Z"},{"key":"version","value":"v2"}],"variable":[]}},"response":[{"id":"cb749986-0bab-4393-a761-63e34ad7f354","name":"Success - No discount code found","originalRequest":{"method":"GET","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"}],"url":{"raw":"{{base_url}}/discount-codes?shopId={{shopId}}&createdAt[lte]=2000-01-01T03:00:00.000Z","host":["{{base_url}}"],"path":["discount-codes"],"query":[{"key":"shopId","value":"{{shopId}}"},{"key":"sortOrder","value":"asc","description":"desc (default), asc","disabled":true},{"key":"sortBy","value":"createdAt","description":"createdAt (default), updatedAt, startDate, endDate, code, calculationMethod, amountOfRedemptions","disabled":true},{"key":"offset","value":"0","type":"text","disabled":true},{"key":"enabled","value":"false","description":"true (default), false","disabled":true},{"key":"code","value":"FRETE","disabled":true},{"key":"productType","value":"NON_RECURRING","description":"NON_RECURRING, RECURRING, ALL","disabled":true},{"key":"calculationMethod","value":"SHIPPING","description":"DISCOUNT, CREDIT_OFF_FLAT, CREDIT_OFF_BY_PRODUCT_TYPE, SHIPPING","disabled":true},{"key":"redemptionLimitReached","value":"false","description":"true, false","disabled":true},{"key":"endDate[gte]","value":"2050-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"endDate[lte]","value":"2050-03-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"startDate[gte]","value":"2040-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"startDate[lte]","value":"2040-03-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"createdAt[gte]","value":"2025-06-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"createdAt[lte]","value":"2000-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT"},{"key":"updatedAt[gte]","value":"2025-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"updatedAt[lte]","value":"2025-05-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"52"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Wed, 02 Jul 2025 00:56:34 GMT"},{"key":"x-amzn-RequestId","value":"1b16ca21-d81d-4598-8291-d5da2e391cbc"},{"key":"x-amz-apigw-id","value":"NDmGdHKaoAMEDSA="},{"key":"X-Amzn-Trace-Id","value":"Root=1-686483c2-7d223b1a76d5328139837f38"},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 55b6418a8a2f714a67d8e4d292154ef2.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"IAD89-C1"},{"key":"X-Amz-Cf-Id","value":"tx75o5gtFnscsc7u5m6cVqDGtxql-m1cj83W1m6MrPq-d5d3CuPX5Q=="}],"cookie":[],"responseTime":null,"body":"{\n    \"totalCount\": 0,\n    \"discounts\": []\n}"},{"id":"20da6a7b-52a0-49b9-a882-c12835eb0689","name":"Error - Invalid Date","originalRequest":{"method":"GET","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"}],"url":{"raw":"{{base_url}}/discount-codes?shopId={{shopId}}&createdAt[lte]=2000-00-00T03:00:00.000Z","host":["{{base_url}}"],"path":["discount-codes"],"query":[{"key":"shopId","value":"{{shopId}}"},{"key":"sortOrder","value":"asc","description":"desc (default), asc","disabled":true},{"key":"sortBy","value":"createdAt","description":"createdAt (default), updatedAt, startDate, endDate, code, calculationMethod, amountOfRedemptions","disabled":true},{"key":"offset","value":"0","type":"text","disabled":true},{"key":"enabled","value":"false","description":"true (default), false","disabled":true},{"key":"code","value":"FRETE","disabled":true},{"key":"productType","value":"NON_RECURRING","description":"NON_RECURRING, RECURRING, ALL","disabled":true},{"key":"calculationMethod","value":"SHIPPING","description":"DISCOUNT, CREDIT_OFF_FLAT, CREDIT_OFF_BY_PRODUCT_TYPE, SHIPPING","disabled":true},{"key":"redemptionLimitReached","value":"false","description":"true, false","disabled":true},{"key":"endDate[gte]","value":"2050-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"endDate[lte]","value":"2050-03-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"startDate[gte]","value":"2040-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"startDate[lte]","value":"2040-03-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"createdAt[gte]","value":"2025-06-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"createdAt[lte]","value":"2000-00-00T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT"},{"key":"updatedAt[gte]","value":"2025-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"updatedAt[lte]","value":"2025-05-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true}]}},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"1838"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Wed, 02 Jul 2025 00:57:19 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-686483ef-127d10430151060c51abb0bf"},{"key":"x-amzn-RequestId","value":"efeb521b-6ca9-4211-9d8e-22adf2493e61"},{"key":"x-amz-apigw-id","value":"NDmNdG5hoAMEJAA="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 8fc9659fc06389e49927f68638e9bc94.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"IAD89-C1"},{"key":"X-Amz-Cf-Id","value":"t-Ykd4fbPVOIEZtH1HA08B_3gdqK5T0hHFVpDtg_KSGvQTeWFeERVQ=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"Variable \\\"$filters\\\" got invalid value \\\"2000-00-00T03:00:00.000Z\\\" at \\\"filters.createdAt.lte\\\"; Expected type \\\"DateTime\\\". DateTime cannot represent an invalid date-time-string 2000-00-00T03:00:00.000Z.\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 39\n                }\n            ],\n            \"extensions\": {\n                \"code\": \"BAD_USER_INPUT\",\n                \"exception\": {\n                    \"stacktrace\": [\n                        \"TypeError: DateTime cannot represent an invalid date-time-string 2000-00-00T03:00:00.000Z.\",\n                        \"    at GraphQLScalarType.parseValue (/usr/local/yggdrasil/node_modules/.pnpm/graphql-iso-date@3.6.1_graphql@15.8.0/node_modules/graphql-iso-date/dist/dateTime/index.js:64:11)\",\n                        \"    at coerceInputValueImpl (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/utilities/coerceInputValue.js:128:26)\",\n                        \"    at coerceInputValueImpl (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/utilities/coerceInputValue.js:105:34)\",\n                        \"    at coerceInputValueImpl (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/utilities/coerceInputValue.js:105:34)\",\n                        \"    at coerceInputValue (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/utilities/coerceInputValue.js:37:10)\",\n                        \"    at _loop (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/values.js:109:69)\",\n                        \"    at coerceVariableValues (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/values.js:121:16)\",\n                        \"    at getVariableValues (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/values.js:50:19)\",\n                        \"    at buildExecutionContext (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/execute.js:203:61)\",\n                        \"    at executeImpl (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/execute.js:101:20)\"\n                    ]\n                }\n            }\n        }\n    ]\n}"},{"id":"83491ed8-13f8-48dc-b949-1b4ea0f949f5","name":"Error - Missing shopId query param","originalRequest":{"method":"GET","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"}],"url":{"raw":"{{base_url}}/discount-codes","host":["{{base_url}}"],"path":["discount-codes"],"query":[{"key":"shopId","value":"{{shopId}}","disabled":true},{"key":"sortOrder","value":"asc","description":"desc (default), asc","disabled":true},{"key":"sortBy","value":"createdAt","description":"createdAt (default), updatedAt, startDate, endDate, code, calculationMethod, amountOfRedemptions","disabled":true},{"key":"offset","value":"0","type":"text","disabled":true},{"key":"enabled","value":"false","description":"true (default), false","disabled":true},{"key":"code","value":"FRETE","disabled":true},{"key":"productType","value":"NON_RECURRING","description":"NON_RECURRING, RECURRING, ALL","disabled":true},{"key":"calculationMethod","value":"SHIPPING","description":"DISCOUNT, CREDIT_OFF_FLAT, CREDIT_OFF_BY_PRODUCT_TYPE, SHIPPING","disabled":true},{"key":"redemptionLimitReached","value":"false","description":"true, false","disabled":true},{"key":"endDate[gte]","value":"2050-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"endDate[lte]","value":"2050-03-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"startDate[gte]","value":"2040-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"startDate[lte]","value":"2040-03-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"createdAt[gte]","value":"2025-06-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"createdAt[lte]","value":"2025-06-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"updatedAt[gte]","value":"2025-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"updatedAt[lte]","value":"2025-05-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true}]}},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"639"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Wed, 02 Jul 2025 00:58:03 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-6864841b-4f1325103ea4160508b80be4"},{"key":"x-amzn-RequestId","value":"a854efef-2f70-4c35-9935-a63395f7533c"},{"key":"x-amz-apigw-id","value":"NDmUSEtpIAMERpA="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 263d97c176fc51d1d08116820c013de4.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"IAD89-C1"},{"key":"X-Amz-Cf-Id","value":"OGY574lIksTQ3VvDUQPNZy-V0PXlhzPbKCVmaXGsP3ntx3YDwYMg7A=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"\\\"shopId\\\" is not allowed to be empty\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 148\n                }\n            ],\n            \"path\": [\n                \"discountCodes\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"stacktrace\": [\n                        \"Error: \\\"shopId\\\" is not allowed to be empty\",\n                        \"    at discountCodes (file:///usr/local/yggdrasil/packages/plugins/discounts-codes/dist/src/resolvers/Query/discountCodes.js:28:15)\",\n                        \"    at file:///usr/local/yggdrasil/packages/authorization-tools/dist/src/tools/authorizeResolver.js:24:12\",\n                        \"    at runMicrotasks (<anonymous>)\",\n                        \"    at processTicksAndRejections (node:internal/process/task_queues:96:5)\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"discountCodes\": null\n    }\n}"},{"id":"0f8ee3cd-2512-4281-a054-1aa5afa952b9","name":"Error - Missing API Key","originalRequest":{"method":"GET","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text","disabled":true},{"key":"Authorization","value":"","type":"text"}],"url":{"raw":"{{base_url}}/discount-codes?shopId={{shopId}}","host":["{{base_url}}"],"path":["discount-codes"],"query":[{"key":"shopId","value":"{{shopId}}"},{"key":"sortOrder","value":"asc","description":"desc (default), asc","disabled":true},{"key":"sortBy","value":"createdAt","description":"createdAt (default), updatedAt, startDate, endDate, code, calculationMethod, amountOfRedemptions","disabled":true},{"key":"offset","value":"0","type":"text","disabled":true},{"key":"enabled","value":"false","description":"true (default), false","disabled":true},{"key":"code","value":"FRETE","disabled":true},{"key":"productType","value":"NON_RECURRING","description":"NON_RECURRING, RECURRING, ALL","disabled":true},{"key":"calculationMethod","value":"SHIPPING","description":"DISCOUNT, CREDIT_OFF_FLAT, CREDIT_OFF_BY_PRODUCT_TYPE, SHIPPING","disabled":true},{"key":"redemptionLimitReached","value":"false","description":"true, false","disabled":true},{"key":"endDate[gte]","value":"2050-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"endDate[lte]","value":"2050-03-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"startDate[gte]","value":"2040-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"startDate[lte]","value":"2040-03-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"createdAt[gte]","value":"2025-06-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"createdAt[lte]","value":"2025-06-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"updatedAt[gte]","value":"2025-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"updatedAt[lte]","value":"2025-05-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true}]}},"status":"Forbidden","code":403,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"23"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Wed, 02 Jul 2025 00:59:52 GMT"},{"key":"x-amz-apigw-id","value":"NDmlbGIToAMELDA="},{"key":"x-amzn-RequestId","value":"f9ea88e3-212c-44eb-bd90-15c7564fcd11"},{"key":"x-amzn-ErrorType","value":"ForbiddenException"},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 5eb5e19c1a78889d10ff38f1551ed2aa.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"IAD89-C1"},{"key":"X-Amz-Cf-Id","value":"nLCEwx0RKCw81-fJOYtlQGfkBSPxy7EPfXI0H-1vLvVe87s400krLQ=="}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Forbidden\"\n}"},{"id":"c645dd92-3ef9-4c83-8aa0-09da95123ff6","name":"Error - Missing Auth Token","originalRequest":{"method":"GET","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text","disabled":true}],"url":{"raw":"{{base_url}}/discount-codes?shopId={{shopId}}","host":["{{base_url}}"],"path":["discount-codes"],"query":[{"key":"shopId","value":"{{shopId}}"},{"key":"sortOrder","value":"asc","description":"desc (default), asc","disabled":true},{"key":"sortBy","value":"createdAt","description":"createdAt (default), updatedAt, startDate, endDate, code, calculationMethod, amountOfRedemptions","disabled":true},{"key":"offset","value":"0","type":"text","disabled":true},{"key":"enabled","value":"false","description":"true (default), false","disabled":true},{"key":"code","value":"FRETE","disabled":true},{"key":"productType","value":"NON_RECURRING","description":"NON_RECURRING, RECURRING, ALL","disabled":true},{"key":"calculationMethod","value":"SHIPPING","description":"DISCOUNT, CREDIT_OFF_FLAT, CREDIT_OFF_BY_PRODUCT_TYPE, SHIPPING","disabled":true},{"key":"redemptionLimitReached","value":"false","description":"true, false","disabled":true},{"key":"endDate[gte]","value":"2050-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"endDate[lte]","value":"2050-03-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"startDate[gte]","value":"2040-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"startDate[lte]","value":"2040-03-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"createdAt[gte]","value":"2025-06-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"createdAt[lte]","value":"2025-06-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"updatedAt[gte]","value":"2025-01-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true},{"key":"updatedAt[lte]","value":"2025-05-01T03:00:00.000Z","description":"Format: YYYY-MM-DDTHH:MM:SS.000Z - Important: Timezone is always set to GMT","disabled":true}]}},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"1708"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Wed, 02 Jul 2025 01:00:28 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-686484ac-3315f95130dd520814a48935"},{"key":"x-amzn-RequestId","value":"f87637ea-49ca-464b-b826-484525c34892"},{"key":"x-amz-apigw-id","value":"NDmrFGoUoAMEtpw="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 8fc9659fc06389e49927f68638e9bc94.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"IAD89-C1"},{"key":"X-Amz-Cf-Id","value":"H9OQvL_XS51bWRKr31ZGvrE8TDkoaojvVDc4bCG4t4G4vvWQ_cLVuA=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"Unauthorized - No authenticated user\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 148\n                }\n            ],\n            \"path\": [\n                \"discountCodes\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"stacktrace\": [\n                        \"Error: Unauthorized - No authenticated user\",\n                        \"    at file:///usr/local/yggdrasil/packages/authorization-tools/dist/src/tools/authorizeResolver.js:16:15\",\n                        \"    at file:///usr/local/yggdrasil/node_modules/.pnpm/graphql-middleware@6.1.35_graphql@15.8.0/node_modules/graphql-middleware/dist/applicator.mjs:5:112\",\n                        \"    at addResolverDataToLoggerMiddleware (file:///usr/local/yggdrasil/packages/plugins/logger-data/dist/src/middlewares/addResolverDataToLoggerMiddleware.js:23:12)\",\n                        \"    at file:///usr/local/yggdrasil/node_modules/.pnpm/graphql-middleware@6.1.35_graphql@15.8.0/node_modules/graphql-middleware/dist/applicator.mjs:5:39\",\n                        \"    at /usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.55.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:237:25\",\n                        \"    at exports.AsyncResource.runInAsyncScope (node:async_hooks:201:9)\",\n                        \"    at callInAsyncScope (/usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.55.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:230:13)\",\n                        \"    at resolveAsync (/usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.55.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:217:12)\",\n                        \"    at field.resolve (/usr/local/yggdrasil/node_modules/.pnpm/apollo-server-core@2.26.2_graphql@15.8.0/node_modules/apollo-server-core/dist/utils/schemaInstrumentation.js:52:26)\",\n                        \"    at resolveField (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/execute.js:464:18)\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"discountCodes\": null\n    }\n}"}],"_postman_id":"0436b95a-6720-4694-8864-fdc15d4bfa45"},{"name":"Get Discount Code","event":[{"listen":"test","script":{"id":"0c524c2e-f4f4-4974-840c-1e6794d5a6c8","exec":["// Specific Tests for GET /discount-codes endpoint\r","let jsonData;\r","let isJson = false;\r","try {\r","    jsonData = pm.response.json();\r","    isJson = true;\r","} catch (e) {\r","    console.error('GET /discount-codes: Failed to parse JSON response.');\r","}\r","\r","const statusCode = pm.response.code;\r","const requestName = pm.request.headers.get('x-postman-example-name') || 'Root Request';\r","\r","// Determine expected outcome based on request name (from examples)\r","let expectsSuccess = requestName.toLowerCase().includes('success') || requestName == 'Root Request';\r","let expectsMissingAuthError = requestName.toLowerCase().includes('missing auth');\r","let expectsMissingApiKeyError = requestName.toLowerCase().includes('missing api key');\r","let expectsMissingShopIdError = requestName.toLowerCase().includes('missing shop id');\r","\r","// --- Shared Checks ---\r","if (!isJson && !expectsMissingApiKeyError) { // 403 Missing API Key might be non-JSON\r","    // Fail if JSON was expected but parsing failed\r","     pm.test(`[${requestName}] Response should be valid JSON`, () => pm.expect.fail('Response was not valid JSON.'));\r","}\r","\r","// --- Success Case Tests ---\r","if (expectsSuccess) {\r","    pm.test(`[${requestName}] Status code should be 200 OK`, function () {\r","        pm.expect(statusCode).to.equal(200);\r","    });\r","\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body should not contain errors property`, function () {\r","            // Checks if the top-level 'errors' key exists\r","            pm.expect(jsonData.errors).to.be.undefined;\r","        });\r","\r","        pm.test(`[${requestName}] Response body has core structure`, function () {\r","            pm.expect(jsonData).to.be.an('object');\r","            pm.expect(jsonData).to.have.all.keys('totalCount', 'pageInfo', 'discounts');\r","            pm.expect(jsonData.totalCount).to.be.a('number');\r","            pm.expect(jsonData.pageInfo).to.be.an('object');\r","            pm.expect(jsonData.discounts).to.be.an('array');\r","        });\r","\r","        pm.test(`[${requestName}] pageInfo structure is correct`, function () {\r","            pm.expect(jsonData.pageInfo).to.have.all.keys('hasNextPage', 'hasPreviousPage', 'startCursor', 'endCursor');\r","            pm.expect(jsonData.pageInfo.hasNextPage).to.be.a('boolean');\r","            pm.expect(jsonData.pageInfo.hasPreviousPage).to.be.a('boolean');\r","\r","            // Cursors can be null or string\r","            if (jsonData.pageInfo.startCursor !== null) pm.expect(jsonData.pageInfo.startCursor).to.be.a('string');\r","            if (jsonData.pageInfo.endCursor !== null) pm.expect(jsonData.pageInfo.endCursor).to.be.a('string');\r","        });\r","\r","        pm.test(`[${requestName}] Discount items have expected properties (if any)`, function () {\r","            if (jsonData.discounts.length > 0) {\r","                const firstDiscount = jsonData.discounts[0];\r","                pm.expect(firstDiscount).to.be.an('object');\r","                pm.expect(firstDiscount).to.have.property('_id').that.is.a('string');\r","                pm.expect(firstDiscount).to.have.property('code').that.is.a('string');\r","                pm.expect(firstDiscount).to.have.property('enabled').that.is.a('boolean');\r","                pm.expect(firstDiscount).to.have.property('conditions').that.is.an('object');\r","            } else {\r","                 pm.expect(jsonData.discounts).to.be.an('array').that.is.empty;\r","            }\r","        });\r","    } else if (!isJson) {\r","         pm.test(`[${requestName}] Should have received JSON`, () => pm.expect.fail('Expected JSON body for success case.'));\r","    }\r","}\r","// --- Error Case Tests ---\r","\r","// Test: Missing Auth Token\r","if (expectsMissingAuthError) {\r","    // Explicitly test that we DO NOT get 200 OK\r","    pm.test(`[${requestName}] Should NOT have status 200 OK`, function () {\r","        pm.expect(statusCode).to.not.equal(200, \"Expected non-200 status for missing auth token (EXPECTED TO FAIL CURRENTLY)\");\r","    });\r","\r","    // Test for the *expected* 401 status. This WILL FAIL with the current example body/status.\r","    pm.test(`[${requestName}] Status code SHOULD BE 401 Unauthorized (EXPECTED TO FAIL CURRENTLY)`, function () {\r","        pm.expect(statusCode).to.equal(401);\r","    });\r","\r","    pm.test(`[${requestName}] Body should contain unauthorized error (EXPECTED TO FAIL CURRENTLY)`, function () {\r","        pm.expect(jsonData.errors[0].extensions.code).to.equal('UNAUTHENTICATED');\r","        pm.expect(jsonData.errors[0].message).to.include('Unauthorized');\r","    });\r","}\r","\r","// Test: Missing API Key\r","if (expectsMissingApiKeyError) {\r","     // Explicitly test that we DO NOT get 200 OK\r","    pm.test(`[${requestName}] Should NOT have status 200 OK`, function () {\r","        pm.expect(statusCode).to.not.equal(200, \"Expected non-200 status for missing API key\");\r","    });\r","\r","    // Test for the expected 403 status\r","    pm.test(`[${requestName}] Status code should be 403 Forbidden`, function () {\r","        pm.expect(statusCode).to.equal(403);\r","    });\r","\r","    // Check for Forbidden message (works for both JSON and non-JSON 403)\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body contains Forbidden message`, function () {\r","             pm.expect(jsonData.message).to.equal(\"Forbidden\");\r","        });\r","    } else if (!isJson) { // Handle if 403 is not JSON\r","         pm.test(`[${requestName}] Body text contains Forbidden`, function () {\r","            pm.expect(pm.response.text()).to.include(\"Forbidden\");\r","        });\r","    }\r","}\r","\r","// Test: Missing Shop ID\r","if (expectsMissingShopIdError) {\r","    // Explicitly test that we DO NOT get 200 OK\r","    pm.test(`[${requestName}] Should NOT have status 200 OK`, function () {\r","        pm.expect(statusCode).to.not.equal(200, \"Expected non-200 status for missing Shop ID (EXPECTED TO FAIL CURRENTLY)\");\r","    });\r","\r","    // Test for the expected 400 status.\r","    pm.test(`[${requestName}] Status code SHOULD BE 400 Bad Request (EXPECTED TO FAIL CURRENTLY)`, function () {\r","        pm.expect(statusCode).to.equal(400);\r","    });\r","}"],"type":"text/javascript","packages":{}}}],"id":"14b512aa-d047-4e55-8565-7d824e6e9910","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"GET","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"}],"url":"{{base_url}}/discount-codes/:discountCodeId?shopId={{shopId}}","description":"<h2 id=\"request\">Request</h2>\n<p><strong>Purpose:</strong> Retrieves a paginated list of discount codes for a specific shop.</p>\n<p><strong>How to use:</strong> Send a GET request with the required API key and Authorization headers, and the mandatory <code>shopId</code> query parameter. Use optional pagination parameters (<code>first</code>/<code>after</code> or <code>last</code>/<code>before</code>) to navigate through results.</p>\n<p><strong>Headers Required:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>x-api-key</code></td>\n<td><code>YourApiKey...</code></td>\n<td>Your partner-specific API key.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>Authorization</code></td>\n<td><code>YourToken...</code></td>\n<td>The access token obtained via <code>/auth/signin</code>.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Query Parameters:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>shopId</code></td>\n<td>string</td>\n<td><code>\"MRxLZSpu6Aaw...\"</code></td>\n<td>Opaque ID of the shop to retrieve discount codes for.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>first</code></td>\n<td>integer</td>\n<td><code>20</code></td>\n<td>Number of discount codes to return (forward pagination). Use with <code>after</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>after</code></td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items after this point. Use with <code>first</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>last</code></td>\n<td>integer</td>\n<td><code>10</code></td>\n<td>Number of discount codes to return (backward pagination). Use with <code>before</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>before</code></td>\n<td>string</td>\n<td><code>\"cursor_string\"</code></td>\n<td>Cursor for pagination, retrieve items before this point. Use with <code>last</code>.</td>\n<td>No</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response\">Response</h2>\n<p><strong>Success (200 OK):</strong></p>\n<p>Returns a paginated list of discount codes.</p>\n<p><strong>Response Properties:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>totalCount</code></td>\n<td>integer</td>\n<td>Total number of discount codes matching the query</td>\n</tr>\n<tr>\n<td><code>pageInfo</code></td>\n<td>object</td>\n<td>Pagination information</td>\n</tr>\n<tr>\n<td><code>pageInfo.hasNextPage</code></td>\n<td>boolean</td>\n<td>Indicates if there are more items after the current page</td>\n</tr>\n<tr>\n<td><code>pageInfo.hasPreviousPage</code></td>\n<td>boolean</td>\n<td>Indicates if there are items before the current page</td>\n</tr>\n<tr>\n<td><code>pageInfo.startCursor</code></td>\n<td>string</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>pageInfo.endCursor</code></td>\n<td>string</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts</code></td>\n<td>array[object]</td>\n<td>List of discount code objects</td>\n</tr>\n<tr>\n<td><code>discounts[]._id</code></td>\n<td>string</td>\n<td>Unique identifier for the discount code</td>\n</tr>\n<tr>\n<td><code>discounts[].code</code></td>\n<td>string</td>\n<td>The discount code string</td>\n</tr>\n<tr>\n<td><code>discounts[].label</code></td>\n<td>string</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].description</code></td>\n<td>string</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].enabled</code></td>\n<td>boolean</td>\n<td>Whether the discount code is active</td>\n</tr>\n<tr>\n<td><code>discounts[].discountMethod</code></td>\n<td>string</td>\n<td>The method by which this discount is applied (e.g., \"CODE\")</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions</code></td>\n<td>object</td>\n<td>Conditions that must be met for the discount to apply</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.accountLimit</code></td>\n<td>integer</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.redemptionLimit</code></td>\n<td>integer</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.startDate</code></td>\n<td>string (ISO 8601)</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.endDate</code></td>\n<td>string (ISO 8601)</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.min</code></td>\n<td>number</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.max</code></td>\n<td>number</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].conditions.productType</code></td>\n<td>string</td>\n<td>null</td>\n</tr>\n<tr>\n<td><code>discounts[].calculation</code></td>\n<td>object</td>\n<td>Calculation method and parameters for the discount</td>\n</tr>\n<tr>\n<td><code>discounts[].transactions</code></td>\n<td>array[object]</td>\n<td>null</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Errors:</strong></p>\n<ul>\n<li><p><strong>400 Bad Request:</strong> Invalid parameter format (e.g., non-integer <code>first</code>/<code>last</code>) or missing required <code>shopId</code>.</p>\n</li>\n<li><p><strong>401 Unauthorized:</strong> Missing or invalid <code>Authorization</code> token.</p>\n</li>\n<li><p><strong>403 Forbidden:</strong> Missing or invalid <code>x-api-key</code>, or insufficient permissions to access the specified shop's discounts.</p>\n</li>\n<li><p><strong>500 Internal Server Error:</strong> An unexpected server error.</p>\n</li>\n</ul>\n","urlObject":{"path":["discount-codes",":discountCodeId"],"host":["{{base_url}}"],"query":[{"key":"shopId","value":"{{shopId}}"}],"variable":[{"type":"any","value":"03ac4c5e-30c8-42b4-8250-1c06d7c4fd00","key":"discountCodeId"}]}},"response":[{"id":"f76d5c25-822a-4a5a-ba5d-9b14817ccf60","name":"Success - No pagination (defaults to 20 returned results)","originalRequest":{"method":"GET","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"},{"key":"x-postman-example-name","value":"Success - Default (up to 20 results returned)","description":"Header used by Postman's internal tests. Remove it during actual usage.","type":"text"}],"url":{"raw":"{{base_url}}/discount-codes?shopId={{shopId}}","host":["{{base_url}}"],"path":["discount-codes"],"query":[{"key":"shopId","value":"{{shopId}}"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"10384"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 16:36:24 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eac487-369689666844238b4440d608"},{"key":"x-amzn-RequestId","value":"9913f09d-18ae-4735-aaa0-5e99cd920eb1"},{"key":"x-amz-apigw-id","value":"ITOlQGUHIAMEkjA="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 3e1d16a0d00396c931fa139a61520d38.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"dFJpXdpZgl_0ain7_TEl_pJghWSDiPsLRjCmo9XnmAitDOcSugYERw=="}],"cookie":[],"responseTime":null,"body":"{\n    \"totalCount\": 59,\n    \"pageInfo\": {\n        \"hasNextPage\": true,\n        \"hasPreviousPage\": false,\n        \"startCursor\": \"MDJiMTVkYTYtNDFiOS00YmRlLTg4YzEtN2NmYWFiNTUzOWQ5\",\n        \"endCursor\": \"NGEyNWIwMzAtYWE4ZS00NjhkLWEzY2EtODVjNzg4OGIzNWM4\"\n    },\n    \"discounts\": [\n        {\n            \"_id\": \"02b15da6-41b9-4bde-88c1-7cfaab5539d9\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-00\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"ALL\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"176e6182-42b1-42ac-83bc-0d2c7e11eb79\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-12\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"ALL\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"17b42afd-233f-4e4c-82d9-08efff10dd99\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-18\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"19efa994-b2e9-447a-9fb6-744eecd26842\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-11\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"ALL\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"1b4886cb-d50b-4f02-bf93-f38117a5f9dc\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-3\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"25bd27ec-6035-40a2-a64f-4aafa112ba4f\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2715219a-82be-4348-98e5-efa334ae3a31\",\n            \"code\": \"10DESC\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 10\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2aaab311-2f9b-47b3-a735-12ef84a5166b\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-19\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2daff61b-f353-4631-8537-a0e7d511502c\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-2\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2e74f17c-3769-4827-b428-89bd407d8608\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-14\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2e7d90bd-2ff5-407c-aece-c03f7497bf88\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-8\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2e8c0e3f-2111-430c-bcfb-677b83fad400\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-17\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"30af2b74-7eac-4832-bc23-844d99533eb6\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-10\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"ALL\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"3897bc21-f670-418c-9813-3fcb2ce9c96c\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-16\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"39289a98-2075-45aa-94c1-174f0df78e17\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-13\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"ALL\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"3bd7f125-ccfc-4afc-b98b-b73d7a507e13\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-15\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"44d74b2b-ba57-4713-898f-2ee9f105bb9b\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-24\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"47dfc4f0-382a-45ab-9927-b80abcb1e95d\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-22\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"486f6dc9-804c-40e2-a01e-e1382af087a6\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-2\",\n            \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n            \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 30,\n                    \"RECURRING\": 45\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"4a25b030-aa8e-468d-a3ca-85c7888b35c8\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-9\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        }\n    ]\n}"},{"id":"29576d11-e841-4dd9-a085-20b107174f5c","name":"Success - Forward Pagination (first/after)","originalRequest":{"method":"GET","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"},{"key":"x-postman-example-name","value":"Success - Forward Pagination (first/after)","description":"Header used by Postman's internal tests. Remove it during actual usage.","type":"text"}],"url":{"raw":"{{base_url}}/discount-codes?shopId={{shopId}}&first=20&after=YTlkZmFmZTQtNTBhMy00ZmM0LTljMmQtYWQ3ZDJjZTg4NTc3","host":["{{base_url}}"],"path":["discount-codes"],"query":[{"key":"shopId","value":"{{shopId}}"},{"key":"first","value":"20"},{"key":"after","value":"YTlkZmFmZTQtNTBhMy00ZmM0LTljMmQtYWQ3ZDJjZTg4NTc3"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"9973"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 16:36:38 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eac496-47e0b45e1cab1c9b73bf3414"},{"key":"x-amzn-RequestId","value":"b55035ff-c09b-4c50-80bb-4526fe172f19"},{"key":"x-amz-apigw-id","value":"ITOnmH3yoAMEsRQ="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 3e1d16a0d00396c931fa139a61520d38.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"JvmKEBgGEkUHgEW5nDiLIJiRnLPbgGt9xLXu_P_UI69vJP3K2gqKvg=="}],"cookie":[],"responseTime":null,"body":"{\n    \"totalCount\": 59,\n    \"pageInfo\": {\n        \"hasNextPage\": false,\n        \"hasPreviousPage\": true,\n        \"startCursor\": \"YWQyOTU2MDYtOWE0ZS00MWViLWEyMmQtYzUzNTUzOTkzNmQ1\",\n        \"endCursor\": \"ZmJiNDRiZWQtNWMwMy00MGFlLWEyNzEtNjg2NDRjYTViMjYz\"\n    },\n    \"discounts\": [\n        {\n            \"_id\": \"ad295606-9a4e-41eb-a22d-c535539936d5\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-5\",\n            \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n            \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 30,\n                    \"RECURRING\": 45\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"b0195cf6-93ee-4a11-b945-59beb783e764\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-6\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"b1f7ccea-7f29-4086-baf1-997d4961e0db\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-4\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"b3024642-dd7f-44b5-9a79-56033e757fef\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-6\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"b6f627a6-e5bb-4ea3-9815-98d20466a66a\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-7\",\n            \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n            \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"ALL\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 30,\n                    \"RECURRING\": 45\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"bcb97f41-d396-4012-8e07-7ee5b79f8460\",\n            \"code\": \"TESTE-TAIS-10\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"bdc34078-aaf7-4386-bdd8-06c57363b956\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-TAIS\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"c2512302-2e6d-4050-9649-4a7ca7fbaa33\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-23\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"ca597745-4986-4aba-bbf5-0ed21e06070d\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-8\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"cfd55890-6cfa-409e-b3ad-a24f1706ebae\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-20\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"d4de9fde-3a41-4281-8bd6-ba98e07c499e\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-6\",\n            \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n            \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 30,\n                    \"RECURRING\": 45\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"d63ca8fc-9fce-4d26-8298-200ded05b665\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-3\",\n            \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n            \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 30,\n                    \"RECURRING\": 45\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"d6547aff-87cc-4fd5-a243-c9ee07333c04\",\n            \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS-2\",\n            \"label\": \"Frete grátis\",\n            \"description\": \"Frete grátis\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"SHIPPING\",\n                \"fulfillmentOptionNames\": [\n                    \"Correios Sedex\",\n                    \"PAC Sedex\"\n                ]\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"e1915726-90ec-4be7-ab40-df7814ee16f5\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-5\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"e2d311d0-1f2e-4d87-a392-812190b495fc\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-30\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"ALL\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"e8b60fef-b6b9-4be2-8188-f9af25d60abb\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-18\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"f19f5806-f5bd-4794-ab7b-3e8cea02f95c\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-9\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"fbb44bed-5c03-40ae-a271-68644ca5b263\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-15\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        }\n    ]\n}"},{"id":"e24b1e94-807f-4099-a155-f15cd6905d11","name":"Success - Backward Pagination (last/before)","originalRequest":{"method":"GET","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"},{"key":"x-postman-example-name","value":"Success - Backward Pagination (last/before)","description":"Header used by Postman's internal tests. Remove it during actual usage.","type":"text"}],"url":{"raw":"{{base_url}}/discount-codes?shopId={{shopId}}&last=20&before=ZTE5MTU3MjYtOTBlYy00YmU3LWFiNDAtZGY3ODE0ZWUxNmY1","host":["{{base_url}}"],"path":["discount-codes"],"query":[{"key":"shopId","value":"{{shopId}}"},{"key":"last","value":"20"},{"key":"before","value":"ZTE5MTU3MjYtOTBlYy00YmU3LWFiNDAtZGY3ODE0ZWUxNmY1"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"10383"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 16:36:54 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eac4a6-667e5c736f67c5b65d4c0067"},{"key":"x-amzn-RequestId","value":"7b0a178f-88e4-48b1-ae6b-30cd9fbf793a"},{"key":"x-amz-apigw-id","value":"ITOqCF-7oAMEXtQ="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 3e1d16a0d00396c931fa139a61520d38.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"_J12am56yp33ZeRAWIure2atXSn5wDhPbwoJc4UwBZRXHYJJgTd2UQ=="}],"cookie":[],"responseTime":null,"body":"{\n    \"totalCount\": 59,\n    \"pageInfo\": {\n        \"hasNextPage\": true,\n        \"hasPreviousPage\": true,\n        \"startCursor\": \"MDJiMTVkYTYtNDFiOS00YmRlLTg4YzEtN2NmYWFiNTUzOWQ5\",\n        \"endCursor\": \"NGEyNWIwMzAtYWE4ZS00NjhkLWEzY2EtODVjNzg4OGIzNWM4\"\n    },\n    \"discounts\": [\n        {\n            \"_id\": \"02b15da6-41b9-4bde-88c1-7cfaab5539d9\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-00\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"ALL\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"176e6182-42b1-42ac-83bc-0d2c7e11eb79\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-12\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"ALL\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"17b42afd-233f-4e4c-82d9-08efff10dd99\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-18\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"19efa994-b2e9-447a-9fb6-744eecd26842\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-11\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"ALL\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"1b4886cb-d50b-4f02-bf93-f38117a5f9dc\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-3\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"25bd27ec-6035-40a2-a64f-4aafa112ba4f\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2715219a-82be-4348-98e5-efa334ae3a31\",\n            \"code\": \"10DESC\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 10\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2aaab311-2f9b-47b3-a735-12ef84a5166b\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-19\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2daff61b-f353-4631-8537-a0e7d511502c\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-2\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2e74f17c-3769-4827-b428-89bd407d8608\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-14\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2e7d90bd-2ff5-407c-aece-c03f7497bf88\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-8\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2e8c0e3f-2111-430c-bcfb-677b83fad400\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-17\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"30af2b74-7eac-4832-bc23-844d99533eb6\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-10\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"ALL\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"3897bc21-f670-418c-9813-3fcb2ce9c96c\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-16\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"39289a98-2075-45aa-94c1-174f0df78e17\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-13\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"ALL\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_FLAT\",\n                \"amount\": 30\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"3bd7f125-ccfc-4afc-b98b-b73d7a507e13\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-15\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"44d74b2b-ba57-4713-898f-2ee9f105bb9b\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-24\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"47dfc4f0-382a-45ab-9927-b80abcb1e95d\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-22\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"486f6dc9-804c-40e2-a01e-e1382af087a6\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-2\",\n            \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n            \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 30,\n                    \"RECURRING\": 45\n                }\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"4a25b030-aa8e-468d-a3ca-85c7888b35c8\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-9\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"calculation\": {\n                \"method\": \"DISCOUNT\",\n                \"amountByProductType\": {\n                    \"NON_RECURRING\": 10,\n                    \"RECURRING\": 0\n                }\n            },\n            \"transactions\": null\n        }\n    ]\n}"},{"id":"74fb678d-7e64-4faf-9139-86d2bf2d8151","name":"[TODO FIX] Error - Missing Auth Token","originalRequest":{"method":"GET","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"x-postman-example-name","value":"[TODO FIX] Error - Missing Auth Token","description":"Header used by Postman's internal tests. Remove it during actual usage.","type":"text"}],"url":{"raw":"{{base_url}}/discount-codes?shopId={{shopId}}","host":["{{base_url}}"],"path":["discount-codes"],"query":[{"key":"shopId","value":"{{shopId}}"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"8578"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Sun, 30 Mar 2025 20:35:42 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67e9ab1e-4ad831f7530783b80939a1dc"},{"key":"x-amzn-RequestId","value":"12ed1aca-9fa7-4731-904b-3c2cf7efb05f"},{"key":"x-amz-apigw-id","value":"IQesyHDXIAMEP3g="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 ba4ab412b1deeae23ff138b73bbe555a.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GIG51-P3"},{"key":"X-Amz-Cf-Id","value":"a1fL95CnhRShxE2u86DCJtqEJUQyFwDRo8Tr3huDpplT4e-eefg7kg=="}],"cookie":[],"responseTime":null,"body":"{\n    \"totalCount\": 22,\n    \"pageInfo\": {\n        \"hasNextPage\": true,\n        \"hasPreviousPage\": false,\n        \"startCursor\": \"MTdiNDJhZmQtMjMzZi00ZTRjLTgyZDktMDhlZmZmMTBkZDk5\",\n        \"endCursor\": \"YTlkZmFmZTQtNTBhMy00ZmM0LTljMmQtYWQ3ZDJjZTg4NTc3\"\n    },\n    \"discounts\": [\n        {\n            \"_id\": \"17b42afd-233f-4e4c-82d9-08efff10dd99\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-18\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"1b4886cb-d50b-4f02-bf93-f38117a5f9dc\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-3\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"25bd27ec-6035-40a2-a64f-4aafa112ba4f\",\n            \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO\",\n            \"label\": \"30 reais de desconto\",\n            \"description\": \"30 reais de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 100,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2aaab311-2f9b-47b3-a735-12ef84a5166b\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-19\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2daff61b-f353-4631-8537-a0e7d511502c\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-2\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2e74f17c-3769-4827-b428-89bd407d8608\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-14\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2e7d90bd-2ff5-407c-aece-c03f7497bf88\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-8\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"2e8c0e3f-2111-430c-bcfb-677b83fad400\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-17\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"3bd7f125-ccfc-4afc-b98b-b73d7a507e13\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-15\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"4a25b030-aa8e-468d-a3ca-85c7888b35c8\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-9\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"4e7c43b4-cab8-49b3-bbf3-19d19e800c7b\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-20\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"5263b9db-9cd9-48f6-af15-bcf7c92d1d41\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-16\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"54794e58-e921-42aa-8385-db6a01c38fc8\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-7\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"563c0c6f-bb9b-4e2d-9127-84f287639046\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-13\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"5c774769-cab8-4bc5-84da-afa3d8247cd9\",\n            \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS\",\n            \"label\": \"Frete grátis\",\n            \"description\": \"Frete grátis\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"5cf67117-cf8f-4c1d-b43d-1d52b91a880b\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-11\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"5f343197-da19-4438-a034-b7520b8e530b\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-10\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"9d0e3bd7-658a-4d1f-8b76-e43bc390155f\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-12\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"a743ec15-703b-42a5-81d5-6bd8bb152f7f\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO-4\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": false,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        },\n        {\n            \"_id\": \"a9dfafe4-50a3-4fc4-9c2d-ad7d2ce88577\",\n            \"code\": \"CUPOM-EXEMPLO-DESCONTO\",\n            \"label\": \"10% de desconto\",\n            \"description\": \"10% de desconto\",\n            \"enabled\": true,\n            \"discountMethod\": \"CODE\",\n            \"conditions\": {\n                \"accountLimit\": 999999,\n                \"redemptionLimit\": 999999,\n                \"recurrenceCycleLimit\": null,\n                \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                \"min\": 0,\n                \"max\": 999999,\n                \"productType\": \"NON_RECURRING\"\n            },\n            \"transactions\": null\n        }\n    ]\n}"},{"id":"560c1f24-9036-4d4d-83ee-3744a301199a","name":"Error - Missing API Key","originalRequest":{"method":"GET","header":[{"key":"Authorization","value":"","type":"text"},{"key":"x-postman-example-name","value":"Error - Missing API Key","description":"Header used by Postman's internal tests. Remove it during actual usage.","type":"text"}],"url":{"raw":"{{base_url}}/discount-codes?shopId={{shopId}}","host":["{{base_url}}"],"path":["discount-codes"],"query":[{"key":"shopId","value":"{{shopId}}"}]}},"status":"Forbidden","code":403,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"23"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Sun, 30 Mar 2025 20:35:48 GMT"},{"key":"x-amz-apigw-id","value":"IQetxH0OIAMErDg="},{"key":"x-amzn-RequestId","value":"2b565311-2683-47fb-b648-6fd414dc1992"},{"key":"x-amzn-ErrorType","value":"ForbiddenException"},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 ba4ab412b1deeae23ff138b73bbe555a.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GIG51-P3"},{"key":"X-Amz-Cf-Id","value":"ARbgheRkpQeBz_OD7GScH7FOZl1rw0PAwd9zz_f4gpnHuQcQcvFoCw=="}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Forbidden\"\n}"},{"id":"e0863d8e-8cea-4282-92fe-9d07bb8d8726","name":"[TODO FIX] Error - Missing Shop ID","originalRequest":{"method":"GET","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"},{"key":"x-postman-example-name","value":"[TODO FIX] Error - Missing Shop ID","description":"Header used by Postman's internal tests. Remove it during actual usage.","type":"text"}],"url":"{{base_url}}/discount-codes"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"151"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Sun, 30 Mar 2025 20:36:05 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67e9ab35-72ab5458600ac16b4961ab2a"},{"key":"x-amzn-RequestId","value":"372765d6-2adf-4233-8b3f-efc61f686bc8"},{"key":"x-amz-apigw-id","value":"IQewYEjcIAMEN4w="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 ba4ab412b1deeae23ff138b73bbe555a.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GIG51-P3"},{"key":"X-Amz-Cf-Id","value":"rmypX50f9yYSXFEF5rYd7dozc8c4pUpVY4LMMMhlKGtDgwtR8IFyFg=="}],"cookie":[],"responseTime":null,"body":"{\n    \"totalCount\": 0,\n    \"pageInfo\": {\n        \"hasNextPage\": false,\n        \"hasPreviousPage\": false,\n        \"startCursor\": null,\n        \"endCursor\": null\n    },\n    \"discounts\": []\n}"}],"_postman_id":"14b512aa-d047-4e55-8565-7d824e6e9910"},{"name":"Delete Discount Code","event":[{"listen":"test","script":{"id":"a6cdb37d-c7af-49ff-8057-37d3ec6e056e","exec":["// --- Test Script for DELETE /discount-codes ---\r","\r","// Attempt to parse JSON response\r","let jsonData;\r","let isJson = false;\r","try {\r","    jsonData = pm.response.json();\r","    isJson = true;\r","} catch (e) {\r","    console.error('DELETE /discount-codes: Failed to parse JSON response.');\r","}\r","\r","// Get Status Code and Example Name\r","const statusCode = pm.response.code;\r","const requestName = pm.request.headers.get('x-postman-example-name') || 'Root Request';\r","\r","// Determine expected outcome from Example Name\r","const expectsSuccess = requestName.toLowerCase().includes('success') || requestName == 'Root Request';\r","const expects400 = requestName.toLowerCase().includes('400');\r","const expects403 = requestName.toLowerCase().includes('403') || requestName.toLowerCase().includes('missing api key');\r","const expects404 = requestName.toLowerCase().includes('404') || requestName.toLowerCase().includes('not found');\r","const expects500 = requestName.toLowerCase().includes('500') || requestName.toLowerCase().includes('server error');\r","\r","// Specific Bad Request checks for this endpoint\r","const expectMissingAuth = requestName.toLowerCase().includes('missing auth');\r","const expectDuplicateCode = requestName.toLowerCase().includes('duplicate');\r","const expectsInvalidPercent = requestName.toLowerCase().includes('invalid percentage');\r","const expectsMissingField = requestName.toLowerCase().includes('missing required field');\r","\r","// --- Shared Checks ---\r","// Ensure response is JSON unless it's an expected non-JSON 403\r","if (!isJson && !expects403) {\r","     pm.test(`[${requestName}] Response should be valid JSON`, () => {\r","         if (statusCode !== 403) { // Only fail if not an expected non-JSON 403\r","            pm.expect.fail('Response was not valid JSON.');\r","         } else {\r","             console.log(\"Skipping JSON check for expected 403 Forbidden response.\");\r","         }\r","     });\r","}\r","\r","// --- Success Case (200 OK) ---\r","if (expectsSuccess) {\r","    pm.test(`[${requestName}] Status code should be 200 OK`, () => {\r","        pm.expect(statusCode).to.equal(200);\r","    });\r","\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body should not contain 'errors' property`, () => {\r","            pm.expect(jsonData.errors).to.be.undefined;\r","        });\r","\r","        pm.test(`[${requestName}] Response body has core discount structure (_id, code, calculation)`, () => {\r","            pm.expect(jsonData).to.be.an('object');\r","            pm.expect(jsonData).to.have.property('_id').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('code').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('label');\r","            pm.expect(jsonData).to.have.property('enabled').that.is.a('boolean');\r","            pm.expect(jsonData).to.have.property('calculation').that.is.an('object');\r","            pm.expect(jsonData).to.have.property('conditions').that.is.an('object');\r","        });\r","\r","    } else if (!isJson && statusCode === 200) {\r","         pm.test(`[${requestName}] Should have received JSON for success`, () => pm.expect.fail('Expected JSON body for 200 OK.'));\r","    }\r","}\r","\r","// --- Error Cases ---\r","\r","// Error 400 Bad Request (covers general 400, invalid percent, missing field)\r","if (expects400 || expectMissingAuth || expectDuplicateCode || expectsInvalidPercent || expectsMissingField) {\r","    const expectedStatus = 400;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Bad Request`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body should contain 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","        });\r","        \r","        if (jsonData.errors && jsonData.errors.length > 0) {\r","             pm.test(`[${requestName}] First error has 'message'`, () => {\r","                 const firstError = jsonData.errors[0];\r","                 pm.expect(firstError).to.have.property('message').that.is.a('string');\r","             });\r","\r","             if (expectMissingAuth) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"Unauthorized - No authenticated user\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.equal(expectedMessage);\r","                });\r","             }\r","\r","             if (expectDuplicateCode) {\r","                pm.test(`[${requestName}] First error has correct value for 'code'`, () => {\r","                    expectedCode = \"DUPLICATE_DISCOUNT_CODE\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('code').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('code').to.equal(expectedCode);\r","                });\r","            }\r","\r","             if (expectsInvalidPercent) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"must be a positive number\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","\r","             if (expectsMissingField) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"is required\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","        }\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should have received JSON for ${expectedStatus}`, () => pm.expect.fail(`Expected JSON body for ${expectedStatus} error.`));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 403 Forbidden\r","if (expects403) {\r","    const expectedStatus = 403;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Forbidden`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    // Check for standard \"Forbidden\" message (can be JSON or plain text)\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body contains 'message: Forbidden'`, () => {\r","             pm.expect(jsonData.message).to.equal(\"Forbidden\");\r","        });\r","    } else if (!isJson && statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Body text contains 'Forbidden'`, () => {\r","            pm.expect(pm.response.text()).to.include(\"Forbidden\");\r","        });\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should contain 'Forbidden' message`, () => pm.expect.fail('Expected \"Forbidden\" message in body for 403.'));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 404 Forbidden\r","if (expects404) {\r","    const expectedStatus = 404;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Not Found`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    // Check for standard \"Discount code not found.\" message and \"NOT_FOUND\" code (can be JSON or plain text) \r","    const expectMessage = \"Discount code not found.\"\r","    const expectCode = \"NOT_FOUND\"\r","    if (isJson && jsonData && jsonData.errors && jsonData.errors.length > 0) {\r","        const firstError = jsonData.errors[0];\r","\r","        pm.test(`[${requestName}] First error has 'message' and 'code'`, () => {            \r","            pm.expect(firstError).to.have.property('message').that.is.a('string');\r","            pm.expect(firstError).to.have.property('code').that.is.a('string');\r","        });\r","\r","        pm.test(`[${requestName}] Body contains 'message: Discount code not found.'`, () => {\r","            pm.expect(firstError.message).to.equal(expectMessage);\r","        });\r","        pm.test(`[${requestName}] Body contains 'code: NOT_FOUND'`, () => {\r","            pm.expect(firstError.code).to.equal(expectCode);\r","        });\r","    } else if (!isJson && statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Body text contains 'Forbidden'`, () => {\r","            pm.expect(pm.response.text()).to.include(expectMessage);\r","        });\r","        pm.test(`[${requestName}] Body text contains 'NOT_FOUND'`, () => {\r","            pm.expect(pm.response.text()).to.include(expectCode);\r","        });\r","    }\r","    \r","    pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 500 Internal Server Error\r","if (expects500) {\r","    const expectedStatus = 500;\r","     pm.test(`[${requestName}] Status code should be ${expectedStatus} Internal Server Error`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","     if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body contains 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","             // Check if message indicates server error, but allow for variations\r","             const firstError = jsonData.errors[0];\r","             pm.expect(firstError.message.toLowerCase()).to.include('internal server error');\r","        });\r","    } // Don't strictly require JSON for 500\r","\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// --- General Check ---\r","// Flag if status code doesn't match any expected pattern for this endpoint\r","if (!expectsSuccess && !expects400 && !expects403 && !expects404 && !expects500 &&\r","    !expectMissingAuth && !expectDuplicateCode && !expectsInvalidPercent && !expectsMissingField) {\r","    pm.test(`[${requestName}] Received UNEXPECTED status code: ${statusCode}`, () => {\r","        // This test will fail if the status code wasn't one of the expected ones\r","        pm.expect.fail(`Received unexpected status code ${statusCode}. Check Example Name or API response.`);\r","    });\r","}"],"type":"text/javascript","packages":{}}},{"listen":"prerequest","script":{"id":"02305a6e-1144-44b3-a1ae-dcfd69da1fd8","exec":[""],"type":"text/javascript","packages":{}}}],"id":"dc6cc4f1-dbe6-4fb4-a32a-e33102cd7fdf","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"DELETE","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"}],"url":"{{base_url}}/discount-codes/:discountCodeId","description":"<h2 id=\"request\">Request</h2>\n<p><strong>Purpose:</strong> Deletes a specific discount code identified by its ID.</p>\n<p><strong>How to use:</strong> Send a DELETE request to the endpoint including the ID of the discount code to be deleted in the URL path.</p>\n<p><strong>Headers Required:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>x-api-key</code></td>\n<td><code>YourApiKey...</code></td>\n<td>Your partner-specific API key.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>Authorization</code></td>\n<td><code>YourToken...</code></td>\n<td>The access token obtained via <code>/auth/signin</code>.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Path Parameters:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Location</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>discountCodeId</code></td>\n<td>path</td>\n<td><code>\"02b15da6-41b9-4bde-88c1-7cfaab5539d9\"</code></td>\n<td>The unique ID of the discount code.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response\">Response</h2>\n<p><strong>Success (200 OK):</strong><br />Returns the full object of the discount code that was just deleted.</p>\n<p><strong>Response Properties (on Success):</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>_id</code></td>\n<td>string</td>\n<td>Unique identifier for the discount code</td>\n</tr>\n<tr>\n<td><code>code</code></td>\n<td>string</td>\n<td>The discount code string</td>\n</tr>\n<tr>\n<td><code>label</code></td>\n<td>string</td>\n<td>Short user-facing label for the discount</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>Detailed description of the discount</td>\n</tr>\n<tr>\n<td><code>enabled</code></td>\n<td>boolean</td>\n<td>Whether the discount code was active before deletion</td>\n</tr>\n<tr>\n<td><code>discountMethod</code></td>\n<td>string (enum)</td>\n<td>The method by which this discount was applied (e.g., \"CODE\")</td>\n</tr>\n<tr>\n<td><code>conditions</code></td>\n<td>object</td>\n<td>Conditions that applied to the discount code</td>\n</tr>\n<tr>\n<td><code>calculation</code></td>\n<td>object</td>\n<td>Calculation method and parameters used for the discount</td>\n</tr>\n<tr>\n<td><code>transactions</code></td>\n<td>array / null</td>\n<td>History of transactions where this discount was applied (may be null)</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Error Responses:</strong></p>\n<ul>\n<li><p><strong>404 Not Found:</strong> Returned if the <code>discountCodeId</code> does not exist or does not belong to the authenticated shop.</p>\n</li>\n<li><p><strong>400 Bad Request:</strong> Invalid or missing <code>Authorization</code> token.</p>\n</li>\n<li><p><strong>403 Forbidden:</strong> Invalid <code>x-api-key</code> or insufficient permissions.</p>\n</li>\n<li><p><strong>400 Bad Request:</strong> Malformed request (e.g., invalid ID format).</p>\n</li>\n<li><p><strong>500 Internal Server Error:</strong> Unexpected server error.</p>\n</li>\n</ul>\n","urlObject":{"path":["discount-codes",":discountCodeId"],"host":["{{base_url}}"],"query":[],"variable":[{"type":"any","value":"7719a793-8516-40d3-9ded-2f5e09d96d63","key":"discountCodeId"}]}},"response":[{"id":"65295749-7f64-473c-a2ee-cbcbd3941a18","name":"Success - Delete Discount Code","originalRequest":{"method":"DELETE","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"},{"key":"x-postman-example-name","value":"Success - Delete Discount Code","type":"text"}],"url":{"raw":"{{base_url}}/discount-codes/:discountCodeId","host":["{{base_url}}"],"path":["discount-codes",":discountCodeId"],"variable":[{"key":"discountCodeId","value":"dc94ff91-e71b-485c-bc03-d24037658151","description":"The opaque ID of the discount code to delete"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"528"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Tue, 01 Apr 2025 19:36:22 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67ec4036-33a47ea7151c58a7301fa9e8"},{"key":"x-amzn-RequestId","value":"08acf354-0579-4939-b5c9-e51702934806"},{"key":"x-amz-apigw-id","value":"IW74gFPpoAMEsRQ="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 f56f9dbd022b7276544822a40d05129a.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"j4jm6drJylASjHKCOsLkZoeFZPuXvLoa-ClfQuwzDrgK1J8jyG7CrA=="}],"cookie":[],"responseTime":null,"body":"{\n    \"_id\": \"dc94ff91-e71b-485c-bc03-d24037658151\",\n    \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS-000\",\n    \"label\": \"Frete grátis\",\n    \"description\": \"Frete grátis\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"recurrenceCycleLimit\": null,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"productType\": \"NON_RECURRING\"\n    },\n    \"calculation\": {\n        \"method\": \"SHIPPING\",\n        \"fulfillmentOptionNames\": [\n            \"Correios Sedex\",\n            \"PAC Sedex\"\n        ]\n    },\n    \"transactions\": null\n}"},{"id":"61f54da9-94d6-49c4-bd1a-e9c1851852e0","name":"Error 404 - Not Found","originalRequest":{"method":"DELETE","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"},{"key":"x-postman-example-name","value":"Error - Not Found","type":"text"}],"url":{"raw":"{{base_url}}/discount-codes/:discountCodeId","host":["{{base_url}}"],"path":["discount-codes",":discountCodeId"],"variable":[{"key":"discountCodeId","value":"INVALID_CODE","description":"The opaque ID of the discount code to delete"}]}},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"86"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Wed, 02 Apr 2025 00:55:07 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67ec8aeb-569529ca5dfc6104303c18d5"},{"key":"x-amzn-RequestId","value":"15d03e16-e987-40a0-8ada-825bc466d320"},{"key":"x-amz-apigw-id","value":"IXqkzE9TIAMEbTA="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 c1491e40e5ab94bf1b27d5c0452ced7a.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"dWYuhBWJDNinbIIQaIX8bQ7juOOFiKAt3WhRcQRUj2UmoiiKVcOknw=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"Discount code not found.\",\n            \"code\": \"NOT_FOUND\"\n        }\n    ]\n}"},{"id":"ac7f50a5-bb5f-4d6d-a372-502d6a5a04f5","name":"Error 403 - Missing API Key","originalRequest":{"method":"DELETE","header":[{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 403 - Missing API Key","type":"text"}],"url":{"raw":"{{base_url}}/discount-codes/:discountCodeId","host":["{{base_url}}"],"path":["discount-codes",":discountCodeId"],"variable":[{"key":"discountCodeId","value":"dc94ff91-e71b-485c-bc03-d24037658151"}]}},"status":"Forbidden","code":403,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"23"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Wed, 02 Apr 2025 00:55:26 GMT"},{"key":"x-amz-apigw-id","value":"IXqnxGvnoAMEc_Q="},{"key":"x-amzn-RequestId","value":"26f74209-5e8f-40ee-808b-457bf53925b5"},{"key":"x-amzn-ErrorType","value":"ForbiddenException"},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 c1491e40e5ab94bf1b27d5c0452ced7a.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"Bf2gWz0zVf5clKvgEceyS5YMhIfsQdg-3P_UNlLtfA0MijKnJ8Egqg=="}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Forbidden\"\n}"},{"id":"23d66436-0071-4bf3-b36b-cfa49a4618c3","name":"Error 400 - Missing Auth Token","originalRequest":{"method":"DELETE","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"x-postman-example-name","value":"Error 400 - Missing Auth Token","type":"text"}],"url":{"raw":"{{base_url}}/discount-codes/:discountCodeId","host":["{{base_url}}"],"path":["discount-codes",":discountCodeId"],"variable":[{"key":"discountCodeId","value":"dc94ff91-e71b-485c-bc03-d24037658151"}]}},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"1714"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Wed, 02 Apr 2025 00:55:34 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67ec8b06-701c6eda213eb71342a47e94"},{"key":"x-amzn-RequestId","value":"9df824cd-9cc9-4be6-b5cd-677922986567"},{"key":"x-amz-apigw-id","value":"IXqpDFn8oAMEhaQ="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 c1491e40e5ab94bf1b27d5c0452ced7a.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"tvAV6bxkXwenOR6GKFPMH34Qe8jEKugIYwH8DyIQX60Zg5A4f2W7nQ=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"Unauthorized - No authenticated user\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 65\n                }\n            ],\n            \"path\": [\n                \"deleteDiscountCode\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"stacktrace\": [\n                        \"Error: Unauthorized - No authenticated user\",\n                        \"    at file:///usr/local/yggdrasil/packages/authorization-tools/dist/src/tools/authorizeResolver.js:16:15\",\n                        \"    at file:///usr/local/yggdrasil/node_modules/.pnpm/graphql-middleware@6.1.35_graphql@15.8.0/node_modules/graphql-middleware/dist/applicator.mjs:5:112\",\n                        \"    at addResolverDataToLoggerMiddleware (file:///usr/local/yggdrasil/packages/plugins/logger-data/dist/src/middlewares/addResolverDataToLoggerMiddleware.js:23:12)\",\n                        \"    at file:///usr/local/yggdrasil/node_modules/.pnpm/graphql-middleware@6.1.35_graphql@15.8.0/node_modules/graphql-middleware/dist/applicator.mjs:5:39\",\n                        \"    at /usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:225:25\",\n                        \"    at exports.AsyncResource.runInAsyncScope (node:async_hooks:201:9)\",\n                        \"    at callInAsyncScope (/usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:223:13)\",\n                        \"    at resolveAsync (/usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:210:12)\",\n                        \"    at field.resolve (/usr/local/yggdrasil/node_modules/.pnpm/apollo-server-core@2.26.2_graphql@15.8.0/node_modules/apollo-server-core/dist/utils/schemaInstrumentation.js:52:26)\",\n                        \"    at resolveField (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/execute.js:464:18)\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"deleteDiscountCode\": null\n    }\n}"}],"_postman_id":"dc6cc4f1-dbe6-4fb4-a32a-e33102cd7fdf"},{"name":"Create Percentage Discount","event":[{"listen":"test","script":{"exec":["// --- Test Script for POST /discount-codes/percentage ---\r","\r","// Attempt to parse JSON response\r","let jsonData;\r","let isJson = false;\r","try {\r","    jsonData = pm.response.json();\r","    isJson = true;\r","} catch (e) {\r","    console.error('POST /discount-codes/percentage: Failed to parse JSON response.');\r","}\r","\r","// Get Status Code and Example Name\r","const statusCode = pm.response.code;\r","const requestName = pm.request.headers.get('x-postman-example-name') || 'Root Request';\r","\r","// Determine expected outcome from Example Name\r","const expectsSuccess = requestName.toLowerCase().includes('success') || requestName == 'Root Request';\r","const expects400 = requestName.toLowerCase().includes('400');\r","const expects403 = requestName.toLowerCase().includes('403') || requestName.toLowerCase().includes('missing api key');\r","const expects500 = requestName.toLowerCase().includes('500') || requestName.toLowerCase().includes('server error');\r","\r","// Specific Bad Request checks for this endpoint\r","const expectMissingAuth = requestName.toLowerCase().includes('missing auth');\r","const expectDuplicateCode = requestName.toLowerCase().includes('duplicate');\r","const expectsInvalidPercent = requestName.toLowerCase().includes('invalid percentage');\r","const expectsMissingField = requestName.toLowerCase().includes('missing required field');\r","\r","// --- Shared Checks ---\r","// Ensure response is JSON unless it's an expected non-JSON 403\r","if (!isJson && !expects403) {\r","     pm.test(`[${requestName}] Response should be valid JSON`, () => {\r","         if (statusCode !== 403) { // Only fail if not an expected non-JSON 403\r","            pm.expect.fail('Response was not valid JSON.');\r","         } else {\r","             console.log(\"Skipping JSON check for expected 403 Forbidden response.\");\r","         }\r","     });\r","}\r","\r","// --- Success Case (200 OK) ---\r","if (expectsSuccess) {\r","    pm.test(`[${requestName}] Status code should be 200 OK`, () => {\r","        pm.expect(statusCode).to.equal(200);\r","    });\r","\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body should not contain 'errors' property`, () => {\r","            pm.expect(jsonData.errors).to.be.undefined;\r","        });\r","\r","        pm.test(`[${requestName}] Response body has core discount structure (_id, code, calculation)`, () => {\r","            pm.expect(jsonData).to.be.an('object');\r","            pm.expect(jsonData).to.have.property('_id').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('code').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('label');\r","            pm.expect(jsonData).to.have.property('enabled').that.is.a('boolean');\r","            pm.expect(jsonData).to.have.property('calculation').that.is.an('object');\r","            pm.expect(jsonData).to.have.property('conditions').that.is.an('object');\r","        });\r","\r","        pm.test(`[${requestName}] Calculation object has correct structure for Percentage`, () => {\r","            pm.expect(jsonData.calculation).to.have.property('method').that.equals('DISCOUNT');\r","            pm.expect(jsonData.calculation).to.have.property('amountByProductType').that.is.an('object');\r","            pm.expect(jsonData.calculation.amountByProductType).to.have.property('NON_RECURRING').that.is.a('number');\r","             pm.expect(jsonData.calculation.amountByProductType).to.have.property('RECURRING').that.is.a('number');\r","        });\r","\r","    } else if (!isJson && statusCode === 200) {\r","         pm.test(`[${requestName}] Should have received JSON for success`, () => pm.expect.fail('Expected JSON body for 200 OK.'));\r","    }\r","}\r","\r","// --- Error Cases ---\r","\r","// Error 400 Bad Request (covers general 400, invalid percent, missing field)\r","if (expects400 || expectMissingAuth || expectDuplicateCode || expectsInvalidPercent || expectsMissingField) {\r","    const expectedStatus = 400;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Bad Request`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body should contain 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","        });\r","        \r","        if (jsonData.errors && jsonData.errors.length > 0) {\r","             pm.test(`[${requestName}] First error has 'message'`, () => {\r","                 const firstError = jsonData.errors[0];\r","                 pm.expect(firstError).to.have.property('message').that.is.a('string');\r","             });\r","\r","             if (expectMissingAuth) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"Unauthorized - No authenticated user\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.equal(expectedMessage);\r","                });\r","             }\r","\r","             if (expectDuplicateCode) {\r","                pm.test(`[${requestName}] First error has correct value for 'code'`, () => {\r","                    expectedCode = \"DUPLICATE_DISCOUNT_CODE\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('code').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('code').to.equal(expectedCode);\r","                });\r","            }\r","\r","             if (expectsInvalidPercent) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"must be a positive number\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","\r","             if (expectsMissingField) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"is required\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","        }\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should have received JSON for ${expectedStatus}`, () => pm.expect.fail(`Expected JSON body for ${expectedStatus} error.`));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 403 Forbidden\r","if (expects403) {\r","    const expectedStatus = 403;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Forbidden`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    // Check for standard \"Forbidden\" message (can be JSON or plain text)\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body contains 'message: Forbidden'`, () => {\r","             pm.expect(jsonData.message).to.equal(\"Forbidden\");\r","        });\r","    } else if (!isJson && statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Body text contains 'Forbidden'`, () => {\r","            pm.expect(pm.response.text()).to.include(\"Forbidden\");\r","        });\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should contain 'Forbidden' message`, () => pm.expect.fail('Expected \"Forbidden\" message in body for 403.'));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 500 Internal Server Error\r","if (expects500) {\r","    const expectedStatus = 500;\r","     pm.test(`[${requestName}] Status code should be ${expectedStatus} Internal Server Error`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","     if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body contains 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","             // Check if message indicates server error, but allow for variations\r","             const firstError = jsonData.errors[0];\r","             pm.expect(firstError.message.toLowerCase()).to.include('internal server error');\r","        });\r","    } // Don't strictly require JSON for 500\r","\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// --- General Check ---\r","// Flag if status code doesn't match any expected pattern for this endpoint\r","if (!expectsSuccess && !expects400 && !expects403 && !expects500 &&\r","    !expectMissingAuth && !expectDuplicateCode && !expectsInvalidPercent && !expectsMissingField) {\r","    pm.test(`[${requestName}] Received UNEXPECTED status code: ${statusCode}`, () => {\r","        // This test will fail if the status code wasn't one of the expected ones\r","        pm.expect.fail(`Received unexpected status code ${statusCode}. Check Example Name or API response.`);\r","    });\r","}"],"type":"text/javascript","packages":{},"id":"9d4d6a8f-b0ac-4167-b71a-29eb36db414b"}}],"id":"b929fa11-cdfa-4338-af24-bec3886930b0","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""}],"body":{"mode":"raw","raw":"{\n  \"code\": \"CUPOM-EXEMPLO-DESCONTO\",\n  \"label\": \"10% de desconto\",\n  \"description\": \"10% de desconto\",\n  \"discountMethod\": \"CODE\",\n  \"calculation\": {\n    \"method\": \"DISCOUNT\",\n    \"amountByProductType\": {\n      \"NON_RECURRING\": 10,\n      \"RECURRING\": 0\n    }\n  },\n  \"conditions\": {\n    \"min\": 0,\n    \"max\": 999999,\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\n    \"redemptionLimit\": 999999,\n    \"accountLimit\": 999999\n  },\n  \"enabled\": true\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/percentage","description":"<h2 id=\"request\">Request</h2>\n<p><strong>Purpose:</strong> Creates a new discount code that applies a percentage-based discount.</p>\n<p><strong>How to use:</strong> Send a POST request with the required API key and Authorization headers, and the full discount code configuration in the request body.</p>\n<p><strong>Headers Required:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>x-api-key</code></td>\n<td><code>YourApiKey...</code></td>\n<td>Your partner-specific API key.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>Authorization</code></td>\n<td><code>YourToken...</code></td>\n<td>The access token obtained via <code>/auth/signin</code>.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Request Body (</strong><code>application/json</code><strong>):</strong></p>\n<p>The body should contain the full definition for the new percentage discount code.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n<th>Required</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>string</td>\n<td>The discount code string. Will be trimmed and must be unique.</td>\n<td>Yes</td>\n<td><code>\"SUMMERFUN10\"</code></td>\n</tr>\n<tr>\n<td><code>label</code></td>\n<td>string</td>\n<td>A short, user-facing label for the discount.</td>\n<td>No</td>\n<td><code>\"10% Off Summer Sale\"</code></td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>A more detailed description for internal use.</td>\n<td>No</td>\n<td><code>\"10% off non-recurring items for summer sale\"</code></td>\n</tr>\n<tr>\n<td><code>enabled</code></td>\n<td>boolean</td>\n<td>Whether the discount code should be active immediately upon creation.</td>\n<td>Yes</td>\n<td><code>true</code></td>\n</tr>\n<tr>\n<td><code>calculation</code></td>\n<td>object</td>\n<td>Defines how the discount value is calculated.</td>\n<td>Yes</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>calculation.method</code></td>\n<td>string</td>\n<td><strong>Must be</strong> <strong><code>\"DISCOUNT\"</code></strong> <strong>for this endpoint.</strong></td>\n<td>Yes</td>\n<td><code>\"DISCOUNT\"</code></td>\n</tr>\n<tr>\n<td><code>calculation.amountByProductType</code></td>\n<td>object</td>\n<td>Specifies the percentage discount for different product types.</td>\n<td>Yes</td>\n<td><code>{\"NON_RECURRING\": 10.0, \"RECURRING\": 0.0}</code></td>\n</tr>\n<tr>\n<td><code>calculation.amountByProductType.NON_RECURRING</code></td>\n<td>number</td>\n<td>Percentage discount for non-recurring products (0-100).</td>\n<td>Yes</td>\n<td><code>10.0</code></td>\n</tr>\n<tr>\n<td><code>calculation.amountByProductType.RECURRING</code></td>\n<td>number</td>\n<td>Percentage discount for recurring products (0-100).</td>\n<td>Yes</td>\n<td><code>0.0</code></td>\n</tr>\n<tr>\n<td><code>conditions</code></td>\n<td>object</td>\n<td>Sets the conditions under which the discount applies. All are optional and have defaults.</td>\n<td>No</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>conditions.productType</code></td>\n<td>string</td>\n<td>Which product types this applies to (<code>ALL</code>, <code>RECURRING</code>, <code>NON_RECURRING</code>). Defaults to <code>ALL</code>.</td>\n<td>No</td>\n<td><code>\"NON_RECURRING\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.min</code></td>\n<td>number</td>\n<td>Minimum order subtotal required for the discount. Defaults to 0.</td>\n<td>No</td>\n<td><code>50.0</code></td>\n</tr>\n<tr>\n<td><code>conditions.max</code></td>\n<td>number</td>\n<td>Maximum order subtotal allowed for the discount. Defaults to unlimited.</td>\n<td>No</td>\n<td><code>500.0</code></td>\n</tr>\n<tr>\n<td><code>conditions.startDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount becomes active. Defaults to now.</td>\n<td>No</td>\n<td><code>\"2025-06-01T00:00:00Z\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.endDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount expires. Defaults to never.</td>\n<td>No</td>\n<td><code>\"2025-09-01T00:00:00Z\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.redemptionLimit</code></td>\n<td>integer</td>\n<td>Max number of times the code can be used in total. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>1000</code></td>\n</tr>\n<tr>\n<td><code>conditions.accountLimit</code></td>\n<td>integer</td>\n<td>Max number of times a single logged-in user can use the code. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>1</code></td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response\">Response</h2>\n<p><strong>Success (200 OK):</strong><br />Returns the complete <code>Discount</code> object for the newly created discount code. The structure matches the <code>Discount</code> schema defined in the OpenAPI specification, including the generated <code>_id</code>.</p>\n<p><strong>Errors:</strong></p>\n<ul>\n<li><p><strong>400 Bad Request:</strong> Invalid input format, missing required fields, or invalid values (e.g., percentage &gt; 100).</p>\n</li>\n<li><p><strong>401 Unauthorized:</strong> Missing or invalid <code>Authorization</code> token.</p>\n</li>\n<li><p><strong>403 Forbidden:</strong> Missing or invalid <code>x-api-key</code>, or insufficient permissions.</p>\n</li>\n<li><p><strong>409 Conflict:</strong> A discount code with the provided <code>code</code> already exists.</p>\n</li>\n<li><p><strong>500 Internal Server Error:</strong> An unexpected server error.</p>\n</li>\n</ul>\n","urlObject":{"path":["discount-codes","percentage"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"db8f68d5-2cf0-4f64-b93d-8b7cc1a7342b","name":"Success - Create Percentage Discount","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Success - Create Percentage Discount","type":"text"}],"body":{"mode":"raw","raw":"{\r\n  \"code\": \"CUPOM-EXEMPLO-DESCONTO-29\",\r\n  \"label\": \"10% de desconto\",\r\n  \"description\": \"10% de desconto\",\r\n  \"discountMethod\": \"CODE\",\r\n  \"calculation\": {\r\n    \"method\": \"DISCOUNT\",\r\n    \"amountByProductType\": {\r\n      \"NON_RECURRING\": 10,\r\n      \"RECURRING\": 0\r\n    }\r\n  },\r\n  \"conditions\": {\r\n    \"min\": 0,\r\n    \"max\": 999999,\r\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\r\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\r\n    \"redemptionLimit\": 999999,\r\n    \"accountLimit\": 999999\r\n  },\r\n  \"enabled\": true\r\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/percentage"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"514"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 16:39:04 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eac528-5af513a571a6afc67a252505"},{"key":"x-amzn-RequestId","value":"a657b32d-48d0-4a7d-869c-36b7a8b0b4a2"},{"key":"x-amz-apigw-id","value":"ITO-WHyWIAMEDSQ="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 4eb0bd900469dfae367adc2fabf442ba.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"AMLft9ya3kI0Ck1E5wN6mbMilqCML0CBRjoZPxAbg0l1w2XPyAXI6Q=="}],"cookie":[],"responseTime":null,"body":"{\n    \"_id\": \"c7274bfc-2f5b-4453-8bbe-125fdad60d6e\",\n    \"code\": \"CUPOM-EXEMPLO-DESCONTO-26\",\n    \"label\": \"10% de desconto\",\n    \"description\": \"10% de desconto\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"recurrenceCycleLimit\": null,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"productType\": \"NON_RECURRING\"\n    },\n    \"calculation\": {\n        \"method\": \"DISCOUNT\",\n        \"amountByProductType\": {\n            \"RECURRING\": 0,\n            \"NON_RECURRING\": 10\n        }\n    },\n    \"transactions\": null\n}"},{"id":"7158813f-96b2-4ebd-b93d-41d4cd71b41c","name":"Error 400 - Invalid Percentage","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 400 - Invalid Percentage","type":"text"}],"body":{"mode":"raw","raw":"{\r\n  \"code\": \"CUPOM-EXEMPLO-DESCONTO-999\",\r\n  \"label\": \"10% de desconto\",\r\n  \"description\": \"10% de desconto\",\r\n  \"discountMethod\": \"CODE\",\r\n  \"calculation\": {\r\n    \"method\": \"DISCOUNT\",\r\n    \"amountByProductType\": {\r\n      \"NON_RECURRING\": -10,\r\n      \"RECURRING\": 0\r\n    }\r\n  },\r\n  \"conditions\": {\r\n    \"min\": 0,\r\n    \"max\": 999999,\r\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\r\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\r\n    \"redemptionLimit\": 999999,\r\n    \"accountLimit\": 999999\r\n  },\r\n  \"enabled\": true\r\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/percentage"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"1254"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:34:00 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67ead208-76704686140bad185ca978a5"},{"key":"x-amzn-RequestId","value":"0ad3a767-b5f4-4b62-9aab-2bd5397749df"},{"key":"x-amz-apigw-id","value":"ITXBVEnEIAMERyA="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 9b2f6b3eebab475cbedb990936249ab2.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GIG51-P3"},{"key":"X-Amz-Cf-Id","value":"ZlVzo9h-xAPPUkbCP0sn8Eqjqzkt-eo2eQdKoLRTMlxuX-rU0ULycA=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"\\\"calculation.amountByProductType.NON_RECURRING\\\" must be a positive number\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 65\n                }\n            ],\n            \"path\": [\n                \"createDiscountCode\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"_original\": {\n                        \"_id\": \"3ef1b2f0-741c-4cd1-8ea8-31eddad72d5c\",\n                        \"shopId\": \"MRxLZSpu6AawLoRA9\",\n                        \"code\": \"CUPOM-EXEMPLO-DESCONTO-999\",\n                        \"createdAt\": \"2025-03-31T17:34:00.154Z\",\n                        \"updatedAt\": \"2025-03-31T17:34:00.154Z\",\n                        \"calculation\": {\n                            \"method\": \"DISCOUNT\",\n                            \"amountByProductType\": {\n                                \"NON_RECURRING\": -10,\n                                \"RECURRING\": 0\n                            }\n                        },\n                        \"conditions\": {\n                            \"accountLimit\": 999999,\n                            \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                            \"max\": 999999,\n                            \"min\": 0,\n                            \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                            \"redemptionLimit\": 999999,\n                            \"productType\": \"NON_RECURRING\"\n                        },\n                        \"description\": \"10% de desconto\",\n                        \"discountMethod\": \"CODE\",\n                        \"label\": \"10% de desconto\",\n                        \"enabled\": true\n                    },\n                    \"details\": [\n                        {\n                            \"message\": \"\\\"calculation.amountByProductType.NON_RECURRING\\\" must be a positive number\",\n                            \"path\": [\n                                \"calculation\",\n                                \"amountByProductType\",\n                                \"NON_RECURRING\"\n                            ],\n                            \"type\": \"number.positive\",\n                            \"context\": {\n                                \"label\": \"calculation.amountByProductType.NON_RECURRING\",\n                                \"value\": -10,\n                                \"key\": \"NON_RECURRING\"\n                            }\n                        }\n                    ],\n                    \"stacktrace\": [\n                        \"ValidationError: \\\"calculation.amountByProductType.NON_RECURRING\\\" must be a positive number\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"createDiscountCode\": null\n    }\n}"},{"id":"f12179e2-b60b-462b-9b24-466a77d3aefe","name":"Error 400 - Missing Required Field","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 400 - Missing Required Field","type":"text"}],"body":{"mode":"raw","raw":"{\r\n  \"code\": \"CUPOM-EXEMPLO-DESCONTO-999\",\r\n  \"label\": \"10% de desconto\",\r\n  \"enabled\": true\r\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/percentage"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"745"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 16:41:43 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eac5c7-2e58825731469472240a35fe"},{"key":"x-amzn-RequestId","value":"16755213-9e24-417b-b2e3-dbfe2c2022f6"},{"key":"x-amz-apigw-id","value":"ITPXPF1woAMEhSg="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 94de18248592dccef7cf16902e5678f6.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"N-B8MXFUaRHwkmKKxV7uDU52E-hRDUAlYNtjT-P_4cCT86bcT2BAYQ=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"\\\"discountMethod\\\" is required\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 65\n                }\n            ],\n            \"path\": [\n                \"createDiscountCode\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"_original\": {\n                        \"_id\": \"77b408d8-de49-494d-bdf6-cd4dc8283fb3\",\n                        \"shopId\": \"MRxLZSpu6AawLoRA9\",\n                        \"code\": \"CUPOM-EXEMPLO-DESCONTO-999\",\n                        \"createdAt\": \"2025-03-31T16:41:43.582Z\",\n                        \"updatedAt\": \"2025-03-31T16:41:43.582Z\",\n                        \"label\": \"10% de desconto\",\n                        \"enabled\": true,\n                        \"conditions\": {\n                            \"productType\": \"NON_RECURRING\"\n                        }\n                    },\n                    \"details\": [\n                        {\n                            \"message\": \"\\\"discountMethod\\\" is required\",\n                            \"path\": [\n                                \"discountMethod\"\n                            ],\n                            \"type\": \"any.required\",\n                            \"context\": {\n                                \"label\": \"discountMethod\",\n                                \"key\": \"discountMethod\"\n                            }\n                        }\n                    ],\n                    \"stacktrace\": [\n                        \"ValidationError: \\\"discountMethod\\\" is required\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"createDiscountCode\": null\n    }\n}"},{"id":"659d6d78-c40c-497c-a0be-2ea40691954b","name":"Error 400 - Duplicate Code","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 400 - Duplicate Code","type":"text"}],"body":{"mode":"raw","raw":"{\r\n  \"code\": \"CUPOM-EXEMPLO-DESCONTO\",\r\n  \"label\": \"10% de desconto\",\r\n  \"description\": \"10% de desconto\",\r\n  \"discountMethod\": \"CODE\",\r\n  \"calculation\": {\r\n    \"method\": \"DISCOUNT\",\r\n    \"amountByProductType\": {\r\n      \"NON_RECURRING\": 10,\r\n      \"RECURRING\": 0\r\n    }\r\n  },\r\n  \"conditions\": {\r\n    \"min\": 0,\r\n    \"max\": 999999,\r\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\r\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\r\n    \"redemptionLimit\": 999999,\r\n    \"accountLimit\": 999999\r\n  },\r\n  \"enabled\": true\r\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/percentage"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"120"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 16:43:11 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eac61f-68d7fd0e43c0017a6380708f"},{"key":"x-amzn-RequestId","value":"52fe7e6e-db06-4d76-8159-59e652509ed0"},{"key":"x-amz-apigw-id","value":"ITPlAFVFIAMEBwQ="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 94de18248592dccef7cf16902e5678f6.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"SS3XcWKEMUURwholwrnN-ZAq6G6Pmf0uf4X1yRPsPvt329ARU34XIA=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"A discount code with this code already exists.\",\n            \"code\": \"DUPLICATE_DISCOUNT_CODE\"\n        }\n    ]\n}"},{"id":"75f4cedb-c941-48ae-aec8-0793b8d7e9a3","name":"Error 400 - Missing Auth Token","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"x-postman-example-name","value":"Error 400 - Missing Auth Token","type":"text"}],"body":{"mode":"raw","raw":"{\r\n  \"code\": \"CUPOM-EXEMPLO-DESCONTO-888\",\r\n  \"label\": \"10% de desconto\",\r\n  \"description\": \"10% de desconto\",\r\n  \"discountMethod\": \"CODE\",\r\n  \"calculation\": {\r\n    \"method\": \"DISCOUNT\",\r\n    \"amountByProductType\": {\r\n      \"NON_RECURRING\": 10,\r\n      \"RECURRING\": 0\r\n    }\r\n  },\r\n  \"conditions\": {\r\n    \"min\": 0,\r\n    \"max\": 999999,\r\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\r\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\r\n    \"redemptionLimit\": 999999,\r\n    \"accountLimit\": 999999\r\n  },\r\n  \"enabled\": true\r\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/percentage"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"1717"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 16:42:30 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eac5f5-69114e1e5f666a0957bd4517"},{"key":"x-amzn-RequestId","value":"d7da6a55-ee6e-4e5a-97d8-88be556373d1"},{"key":"x-amz-apigw-id","value":"ITPefGKLIAMEl_Q="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 94de18248592dccef7cf16902e5678f6.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"uIk05ncaeUN3KfyOxmMl8CbwWxJtpA5_TEDqu4UHJY8QztRfEXU7TQ=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"Unauthorized - No authenticated user\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 65\n                }\n            ],\n            \"path\": [\n                \"createDiscountCode\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"stacktrace\": [\n                        \"Error: Unauthorized - No authenticated user\",\n                        \"    at file:///usr/local/yggdrasil/packages/authorization-tools/dist/src/tools/authorizeResolver.js:16:15\",\n                        \"    at file:///usr/local/yggdrasil/node_modules/.pnpm/graphql-middleware@6.1.35_graphql@15.8.0/node_modules/graphql-middleware/dist/applicator.mjs:5:112\",\n                        \"    at addResolverDataToLoggerMiddleware (file:///usr/local/yggdrasil/packages/plugins/logger-data/dist/src/middlewares/addResolverDataToLoggerMiddleware.js:23:12)\",\n                        \"    at file:///usr/local/yggdrasil/node_modules/.pnpm/graphql-middleware@6.1.35_graphql@15.8.0/node_modules/graphql-middleware/dist/applicator.mjs:5:39\",\n                        \"    at /usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:225:25\",\n                        \"    at exports.AsyncResource.runInAsyncScope (node:async_hooks:201:9)\",\n                        \"    at callInAsyncScope (/usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:223:13)\",\n                        \"    at resolveAsync (/usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:210:12)\",\n                        \"    at field.resolve (/usr/local/yggdrasil/node_modules/.pnpm/apollo-server-core@2.26.2_graphql@15.8.0/node_modules/apollo-server-core/dist/utils/schemaInstrumentation.js:52:26)\",\n                        \"    at resolveField (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/execute.js:464:18)\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"createDiscountCode\": null\n    }\n}"},{"id":"b633bd2b-4dd3-4c74-bf67-25241c4eeb44","name":"Error 403 - Missing API Key","originalRequest":{"method":"POST","header":[{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 403 - Missing API Key","type":"text"}],"body":{"mode":"raw","raw":"{\r\n  \"code\": \"CUPOM-EXEMPLO-DESCONTO-888\",\r\n  \"label\": \"10% de desconto\",\r\n  \"description\": \"10% de desconto\",\r\n  \"discountMethod\": \"CODE\",\r\n  \"calculation\": {\r\n    \"method\": \"DISCOUNT\",\r\n    \"amountByProductType\": {\r\n      \"NON_RECURRING\": 10,\r\n      \"RECURRING\": 0\r\n    }\r\n  },\r\n  \"conditions\": {\r\n    \"min\": 0,\r\n    \"max\": 999999,\r\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\r\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\r\n    \"redemptionLimit\": 999999,\r\n    \"accountLimit\": 999999\r\n  },\r\n  \"enabled\": true\r\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/percentage"},"status":"Forbidden","code":403,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"23"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 16:42:57 GMT"},{"key":"x-amz-apigw-id","value":"ITPiyEpyIAMEnCA="},{"key":"x-amzn-RequestId","value":"21ddba0c-6c5a-482c-9225-956be9ec302a"},{"key":"x-amzn-ErrorType","value":"ForbiddenException"},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 94de18248592dccef7cf16902e5678f6.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"_XhZd8Ky6HXiVRZGYGg2kykOdhqULot5M8jKl4MWvqgxWb7M2ASW9w=="}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Forbidden\"\n}"}],"_postman_id":"b929fa11-cdfa-4338-af24-bec3886930b0"},{"name":"Create Flat Discount","event":[{"listen":"test","script":{"exec":["// --- Test Script for POST /discount-codes/flat ---\r","\r","// Attempt to parse JSON response\r","let jsonData;\r","let isJson = false;\r","try {\r","    jsonData = pm.response.json();\r","    isJson = true;\r","} catch (e) {\r","    console.error('POST /discount-codes/flat: Failed to parse JSON response.');\r","}\r","\r","// Get Status Code and Example Name\r","const statusCode = pm.response.code;\r","const requestName = pm.request.headers.get('x-postman-example-name') || 'Root Request';\r","\r","// Determine expected outcome from Example Name\r","const expectsSuccess = requestName.toLowerCase().includes('success') || requestName == 'Root Request';\r","const expects400 = requestName.toLowerCase().includes('400');\r","const expects403 = requestName.toLowerCase().includes('403') || requestName.toLowerCase().includes('missing api key');\r","const expects500 = requestName.toLowerCase().includes('500') || requestName.toLowerCase().includes('server error');\r","\r","// Specific Bad Request checks for this \r","const expectMissingAuth = requestName.toLowerCase().includes('missing auth');\r","const expectDuplicateCode = requestName.toLowerCase().includes('duplicate');\r","const expectsInvalidAmount = requestName.toLowerCase().includes('invalid amount');\r","const expectsMissingField = requestName.toLowerCase().includes('missing required field');\r","\r","// --- Shared Checks ---\r","// Ensure response is JSON unless it's an expected non-JSON 403\r","if (!isJson && !expects403) {\r","     pm.test(`[${requestName}] Response should be valid JSON`, () => {\r","         if (statusCode !== 403) { // Only fail if not an expected non-JSON 403\r","            pm.expect.fail('Response was not valid JSON.');\r","         } else {\r","             console.log(\"Skipping JSON check for expected 403 Forbidden response.\");\r","         }\r","     });\r","}\r","\r","// --- Success Case (200 OK) ---\r","if (expectsSuccess) {\r","    pm.test(`[${requestName}] Status code should be 200 OK`, () => {\r","        pm.expect(statusCode).to.equal(200);\r","    });\r","\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body should not contain 'errors' property`, () => {\r","            pm.expect(jsonData.errors).to.be.undefined;\r","        });\r","\r","        pm.test(`[${requestName}] Response body has core discount structure (_id, code, calculation)`, () => {\r","            pm.expect(jsonData).to.be.an('object');\r","            pm.expect(jsonData).to.have.property('_id').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('code').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('label');\r","            pm.expect(jsonData).to.have.property('enabled').that.is.a('boolean');\r","            pm.expect(jsonData).to.have.property('calculation').that.is.an('object');\r","            pm.expect(jsonData).to.have.property('conditions').that.is.an('object');\r","        });\r","\r","        pm.test(`[${requestName}] Calculation object has correct structure for Flat Discount`, () => {\r","            pm.expect(jsonData.calculation).to.have.property('method').that.equals('CREDIT_OFF_FLAT');\r","            pm.expect(jsonData.calculation).to.have.property('amount').that.is.a('number');\r","        });\r","\r","    } else if (!isJson && statusCode === 200) {\r","         pm.test(`[${requestName}] Should have received JSON for success`, () => pm.expect.fail('Expected JSON body for 200 OK.'));\r","    }\r","}\r","\r","// --- Error Cases ---\r","\r","// Error 400 Bad Request (covers general 400, invalid amount, missing field)\r","if (expects400 || expectMissingAuth || expectDuplicateCode || expectsInvalidAmount || expectsMissingField) {\r","    const expectedStatus = 400;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Bad Request`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body should contain 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","        });\r","        \r","        if (jsonData.errors && jsonData.errors.length > 0) {\r","             pm.test(`[${requestName}] First error has 'message'`, () => {\r","                 const firstError = jsonData.errors[0];\r","                 pm.expect(firstError).to.have.property('message').that.is.a('string');\r","             });\r","\r","             if (expectMissingAuth) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"Unauthorized - No authenticated user\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.equal(expectedMessage);\r","                });\r","             }\r","\r","             if (expectDuplicateCode) {\r","                pm.test(`[${requestName}] First error has correct value for 'code'`, () => {\r","                    expectedCode = \"DUPLICATE_DISCOUNT_CODE\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('code').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('code').to.equal(expectedCode);\r","                });\r","            }\r","\r","             if (expectsInvalidAmount) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"must be a positive number\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","\r","             if (expectsMissingField) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"is required\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","        }\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should have received JSON for ${expectedStatus}`, () => pm.expect.fail(`Expected JSON body for ${expectedStatus} error.`));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 403 Forbidden\r","if (expects403) {\r","    const expectedStatus = 403;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Forbidden`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    // Check for standard \"Forbidden\" message (can be JSON or plain text)\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body contains 'message: Forbidden'`, () => {\r","             pm.expect(jsonData.message).to.equal(\"Forbidden\");\r","        });\r","    } else if (!isJson && statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Body text contains 'Forbidden'`, () => {\r","            pm.expect(pm.response.text()).to.include(\"Forbidden\");\r","        });\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should contain 'Forbidden' message`, () => pm.expect.fail('Expected \"Forbidden\" message in body for 403.'));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 500 Internal Server Error\r","if (expects500) {\r","    const expectedStatus = 500;\r","     pm.test(`[${requestName}] Status code should be ${expectedStatus} Internal Server Error`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","     if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body contains 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","             // Check if message indicates server error, but allow for variations\r","             const firstError = jsonData.errors[0];\r","             pm.expect(firstError.message.toLowerCase()).to.include('internal server error');\r","        });\r","    } // Don't strictly require JSON for 500\r","\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// --- General Check ---\r","// Flag if status code doesn't match any expected pattern for this endpoint\r","if (!expectsSuccess && !expects400 && !expects403 && !expects500 &&\r","    !expectMissingAuth && !expectDuplicateCode && !expectsInvalidAmount && !expectsMissingField) {\r","    pm.test(`[${requestName}] Received UNEXPECTED status code: ${statusCode}`, () => {\r","        // This test will fail if the status code wasn't one of the expected ones\r","        pm.expect.fail(`Received unexpected status code ${statusCode}. Check Example Name or API response.`);\r","    });\r","}"],"type":"text/javascript","packages":{},"id":"f30305aa-f9b6-442b-a431-067dc62e2fb7"}}],"id":"96ef745c-1f3a-4ed1-9de6-fd98b39bcf99","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""}],"body":{"mode":"raw","raw":"{\n  \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-3\",\n  \"label\": \"30 reais de desconto\",\n  \"description\": \"30 reais de desconto\",\n  \"discountMethod\": \"CODE\",\n  \"calculation\": {\n    \"method\": \"CREDIT_OFF_FLAT\",\n    \"amount\": 30\n  },\n  \"conditions\": {\n    \"productType\": \"ALL\",\n    \"min\": 100,\n    \"max\": 999999,\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\n    \"redemptionLimit\": 999999,\n    \"accountLimit\": 999999\n  },\n  \"enabled\": true\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat","description":"<h2 id=\"request\">Request</h2>\n<p><strong>Purpose:</strong> Creates a new discount code that applies a fixed flat amount discount.</p>\n<p><strong>How to use:</strong> Send a POST request with the required API key and Authorization headers, and the full discount code configuration in the request body.</p>\n<p><strong>Headers Required:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>x-api-key</code></td>\n<td><code>YourApiKey...</code></td>\n<td>Your partner-specific API key.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>Authorization</code></td>\n<td><code>YourToken...</code></td>\n<td>The access token obtained via <code>/auth/signin</code>.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Request Body (</strong><code>application/json</code><strong>):</strong></p>\n<p>The body should contain the full definition for the new flat amount discount code.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n<th>Required</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>string</td>\n<td>The discount code string. Will be trimmed and must be unique.</td>\n<td>Yes</td>\n<td><code>\"WELCOME20\"</code></td>\n</tr>\n<tr>\n<td><code>label</code></td>\n<td>string</td>\n<td>A short, user-facing label for the discount.</td>\n<td>No</td>\n<td><code>\"R$20 Welcome Bonus\"</code></td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>A more detailed description for internal use.</td>\n<td>No</td>\n<td><code>\"R$20 off first order\"</code></td>\n</tr>\n<tr>\n<td><code>enabled</code></td>\n<td>boolean</td>\n<td>Whether the discount code should be active immediately upon creation.</td>\n<td>Yes</td>\n<td><code>true</code></td>\n</tr>\n<tr>\n<td><code>calculation</code></td>\n<td>object</td>\n<td>Defines how the discount value is calculated.</td>\n<td>Yes</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>calculation.method</code></td>\n<td>string</td>\n<td><strong>Must be</strong> <strong><code>\"CREDIT_OFF_FLAT\"</code></strong> <strong>for this endpoint.</strong></td>\n<td>Yes</td>\n<td><code>\"CREDIT_OFF_FLAT\"</code></td>\n</tr>\n<tr>\n<td><code>calculation.amount</code></td>\n<td>integer</td>\n<td>The fixed discount amount in <strong>Reais (R$)</strong>. Must be a whole number (integer).</td>\n<td>Yes</td>\n<td><code>20</code></td>\n</tr>\n<tr>\n<td><code>conditions</code></td>\n<td>object</td>\n<td>Sets the conditions under which the discount applies. All are optional and have defaults.</td>\n<td>No</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>conditions.productType</code></td>\n<td>string</td>\n<td>Which product types this applies to (<code>ALL</code>, <code>RECURRING</code>, <code>NON_RECURRING</code>). Defaults to <code>ALL</code>.</td>\n<td>No</td>\n<td><code>\"ALL\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.min</code></td>\n<td>number</td>\n<td>Minimum order subtotal required for the discount. Defaults to 0.</td>\n<td>No</td>\n<td><code>100.0</code></td>\n</tr>\n<tr>\n<td><code>conditions.max</code></td>\n<td>number</td>\n<td>Maximum order subtotal allowed for the discount. Defaults to unlimited.</td>\n<td>No</td>\n<td><code>999999</code></td>\n</tr>\n<tr>\n<td><code>conditions.startDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount becomes active. Defaults to now.</td>\n<td>No</td>\n<td><code>null</code></td>\n</tr>\n<tr>\n<td><code>conditions.endDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount expires. Defaults to never.</td>\n<td>No</td>\n<td><code>null</code></td>\n</tr>\n<tr>\n<td><code>conditions.redemptionLimit</code></td>\n<td>integer</td>\n<td>Max number of times the code can be used in total. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>999999</code></td>\n</tr>\n<tr>\n<td><code>conditions.accountLimit</code></td>\n<td>integer</td>\n<td>Max number of times a single logged-in user can use the code. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>1</code></td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response\">Response</h2>\n<p><strong>Success (200 OK):</strong><br />Returns the complete <code>Discount</code> object for the newly created discount code. The structure matches the <code>Discount</code> schema defined in the OpenAPI specification, including the generated <code>_id</code>.</p>\n<p><strong>Errors:</strong></p>\n<ul>\n<li><p><strong>400 Bad Request:</strong> Invalid input format, missing required fields, or invalid values (e.g., non-integer <code>amount</code>).</p>\n</li>\n<li><p><strong>401 Unauthorized:</strong> Missing or invalid <code>Authorization</code> token.</p>\n</li>\n<li><p><strong>403 Forbidden:</strong> Missing or invalid <code>x-api-key</code>, or insufficient permissions.</p>\n</li>\n<li><p><strong>409 Conflict:</strong> A discount code with the provided <code>code</code> already exists.</p>\n</li>\n<li><p><strong>500 Internal Server Error:</strong> An unexpected server error.</p>\n</li>\n</ul>\n","urlObject":{"path":["discount-codes","flat"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"8da02878-28f1-476f-a497-a7292aeb5c30","name":"Success - Create Flat Discount","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Success - Create Flat Discount","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-33\",\n  \"label\": \"30 reais de desconto\",\n  \"description\": \"30 reais de desconto\",\n  \"discountMethod\": \"CODE\",\n  \"calculation\": {\n    \"method\": \"CREDIT_OFF_FLAT\",\n    \"amount\": 30\n  },\n  \"conditions\": {\n    \"productType\": \"ALL\",\n    \"min\": 100,\n    \"max\": 999999,\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\n    \"redemptionLimit\": 999999,\n    \"accountLimit\": 999999\n  },\n  \"enabled\": true\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"478"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:56:43 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67ead75b-307f746d13f883a54ef2ffef"},{"key":"x-amzn-RequestId","value":"642be416-1197-4367-9036-42fedf16dede"},{"key":"x-amz-apigw-id","value":"ITaWVGokIAMEB7g="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 d404c3bebc750eb51899db319be58a7e.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GIG51-P3"},{"key":"X-Amz-Cf-Id","value":"phMiHI1rGSjkNnP6_2raKMaeP5OwIbPKL5YjbVhFwwDcL6aYo36l8g=="}],"cookie":[],"responseTime":null,"body":"{\n    \"_id\": \"9e68958f-6ccb-4b83-b890-7fbd36323cd3\",\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-33\",\n    \"label\": \"30 reais de desconto\",\n    \"description\": \"30 reais de desconto\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"recurrenceCycleLimit\": null,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"productType\": \"ALL\"\n    },\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_FLAT\",\n        \"amount\": 30\n    },\n    \"transactions\": null\n}"},{"id":"dc0567b8-4ad9-4274-bac3-8ec7cc6fe27a","name":"Success - Create Flat Discount For Recurring Products Only","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Success - Create Flat Discount For Recurring Products Only","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-34\",\n  \"label\": \"30 reais de desconto\",\n  \"description\": \"30 reais de desconto\",\n  \"discountMethod\": \"CODE\",\n  \"calculation\": {\n    \"method\": \"CREDIT_OFF_FLAT\",\n    \"amount\": 30\n  },\n  \"conditions\": {\n    \"productType\": \"RECURRING\",\n    \"min\": 100,\n    \"max\": 999999,\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\n    \"redemptionLimit\": 999999,\n    \"accountLimit\": 999999\n  },\n  \"enabled\": true\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"484"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:56:54 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67ead765-2a6708ce4aef7c1c2fd2d9bf"},{"key":"x-amzn-RequestId","value":"62e0954b-7b50-4666-812d-211639ae792a"},{"key":"x-amz-apigw-id","value":"ITaX-GmVoAMEH_g="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 d404c3bebc750eb51899db319be58a7e.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GIG51-P3"},{"key":"X-Amz-Cf-Id","value":"YdI_q55p5FlhrRGDZpR6v0K_E9_SIIGiRxRqiq6faHGf-Ikbq81ETw=="}],"cookie":[],"responseTime":null,"body":"{\n    \"_id\": \"550fb05c-279b-4782-98e7-5ea3cb701532\",\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-34\",\n    \"label\": \"30 reais de desconto\",\n    \"description\": \"30 reais de desconto\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"recurrenceCycleLimit\": null,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"productType\": \"RECURRING\"\n    },\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_FLAT\",\n        \"amount\": 30\n    },\n    \"transactions\": null\n}"},{"id":"45e5632e-3ed7-4071-a607-87a1f2bd1ee3","name":"Success - Create Flat Discount For Non-Recurring Products Only","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Success - Create Flat Discount For Non-Recurring Products Only","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-36\",\n  \"label\": \"30 reais de desconto\",\n  \"description\": \"30 reais de desconto\",\n  \"discountMethod\": \"CODE\",\n  \"calculation\": {\n    \"method\": \"CREDIT_OFF_FLAT\",\n    \"amount\": 30\n  },\n  \"conditions\": {\n    \"productType\": \"NON_RECURRING\",\n    \"min\": 100,\n    \"max\": 999999,\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\n    \"redemptionLimit\": 999999,\n    \"accountLimit\": 999999\n  },\n  \"enabled\": true\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"488"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:57:03 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67ead76f-625e1d85068c1cbe2088bcbc"},{"key":"x-amzn-RequestId","value":"5a3b6578-7ea0-4252-b44d-6b6ed5511db4"},{"key":"x-amz-apigw-id","value":"ITaZhEOrIAMELVw="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 d404c3bebc750eb51899db319be58a7e.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GIG51-P3"},{"key":"X-Amz-Cf-Id","value":"A2CVHsFksGm0BFcGDYPJHkp6E2t2dzgg7-nNsQJCIxulT-FLEikjzg=="}],"cookie":[],"responseTime":null,"body":"{\n    \"_id\": \"4b4982c2-00f7-46ba-b689-e3e11091398c\",\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-36\",\n    \"label\": \"30 reais de desconto\",\n    \"description\": \"30 reais de desconto\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"recurrenceCycleLimit\": null,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"productType\": \"NON_RECURRING\"\n    },\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_FLAT\",\n        \"amount\": 30\n    },\n    \"transactions\": null\n}"},{"id":"bb376839-32bc-4460-adb8-511f40a33be0","name":"Error 400 - Invalid Amount","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 400 - Invalid Amount","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-99\",\n  \"label\": \"-30 reais de desconto\",\n  \"description\": \"-30 reais de desconto\",\n  \"discountMethod\": \"CODE\",\n  \"calculation\": {\n    \"method\": \"CREDIT_OFF_FLAT\",\n    \"amount\": -30\n  },\n  \"conditions\": {\n    \"productType\": \"ALL\",\n    \"min\": 100,\n    \"max\": 999999,\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\n    \"redemptionLimit\": 999999,\n    \"accountLimit\": 999999\n  },\n  \"enabled\": true\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"1078"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 16:45:29 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eac6a9-58fa8cd47a4b7b394d16810c"},{"key":"x-amzn-RequestId","value":"b80e688a-912d-4e93-a779-c5f45da41db2"},{"key":"x-amz-apigw-id","value":"ITP6iE0jIAMEFOg="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 8822b02845e730d6fbf493930f40c946.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"26DGIMCkhRxjFyl3xYxm6o9hNIEKdP8D_YclnDKVdei2HZN92Jwnuw=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"\\\"calculation.amount\\\" must be a positive number\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 65\n                }\n            ],\n            \"path\": [\n                \"createDiscountCode\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"_original\": {\n                        \"_id\": \"be1bef0a-bc78-4d5d-899d-0d307f380e5c\",\n                        \"shopId\": \"MRxLZSpu6AawLoRA9\",\n                        \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-99\",\n                        \"createdAt\": \"2025-03-31T16:45:29.572Z\",\n                        \"updatedAt\": \"2025-03-31T16:45:29.572Z\",\n                        \"calculation\": {\n                            \"method\": \"CREDIT_OFF_FLAT\",\n                            \"amount\": -30\n                        },\n                        \"conditions\": {\n                            \"accountLimit\": 999999,\n                            \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                            \"max\": 999999,\n                            \"min\": 100,\n                            \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                            \"redemptionLimit\": 999999,\n                            \"productType\": \"ALL\"\n                        },\n                        \"description\": \"-30 reais de desconto\",\n                        \"discountMethod\": \"CODE\",\n                        \"label\": \"-30 reais de desconto\",\n                        \"enabled\": true\n                    },\n                    \"details\": [\n                        {\n                            \"message\": \"\\\"calculation.amount\\\" must be a positive number\",\n                            \"path\": [\n                                \"calculation\",\n                                \"amount\"\n                            ],\n                            \"type\": \"number.positive\",\n                            \"context\": {\n                                \"label\": \"calculation.amount\",\n                                \"value\": -30,\n                                \"key\": \"amount\"\n                            }\n                        }\n                    ],\n                    \"stacktrace\": [\n                        \"ValidationError: \\\"calculation.amount\\\" must be a positive number\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"createDiscountCode\": null\n    }\n}"},{"id":"86b63db4-bfe0-4b1b-90cf-8b90b8a9e65e","name":"Error 400 - Missing Required Field","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 400 - Missing Required Field","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"code\": \"FLAT_REST_MISSING_CALC\",\n  \"label\": \"R$25 Off Missing Calc\",\n  \"enabled\": true\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"749"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 16:46:10 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eac6d2-4e30d7fe42b9e6550b00007b"},{"key":"x-amzn-RequestId","value":"2f04a720-b899-48ea-9d55-ab0c73ac7a87"},{"key":"x-amz-apigw-id","value":"ITQA5FO-IAMEY_g="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 8822b02845e730d6fbf493930f40c946.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"44YB8XzrYml71R0TMYYvUVBC9-KGR_k6rykfzIMewhzTrTq2oZTJOQ=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"\\\"discountMethod\\\" is required\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 65\n                }\n            ],\n            \"path\": [\n                \"createDiscountCode\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"_original\": {\n                        \"_id\": \"97a2fff8-e411-4224-82a7-c9d84eff7554\",\n                        \"shopId\": \"MRxLZSpu6AawLoRA9\",\n                        \"code\": \"FLAT_REST_MISSING_CALC\",\n                        \"createdAt\": \"2025-03-31T16:46:10.269Z\",\n                        \"updatedAt\": \"2025-03-31T16:46:10.269Z\",\n                        \"label\": \"R$25 Off Missing Calc\",\n                        \"enabled\": true,\n                        \"conditions\": {\n                            \"productType\": \"NON_RECURRING\"\n                        }\n                    },\n                    \"details\": [\n                        {\n                            \"message\": \"\\\"discountMethod\\\" is required\",\n                            \"path\": [\n                                \"discountMethod\"\n                            ],\n                            \"type\": \"any.required\",\n                            \"context\": {\n                                \"label\": \"discountMethod\",\n                                \"key\": \"discountMethod\"\n                            }\n                        }\n                    ],\n                    \"stacktrace\": [\n                        \"ValidationError: \\\"discountMethod\\\" is required\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"createDiscountCode\": null\n    }\n}"},{"id":"1397ef50-8954-42bd-a4b0-cdb09bea487d","name":"Error 400 - Duplicate Code","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 400 - Duplicate Code","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO\",\n  \"label\": \"30 reais de desconto\",\n  \"description\": \"30 reais de desconto\",\n  \"discountMethod\": \"CODE\",\n  \"conditions\": {\n    \"productType\": \"ALL\",\n    \"min\": 100,\n    \"max\": 999999,\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\n    \"redemptionLimit\": 999999,\n    \"accountLimit\": 999999\n  },\n  \"enabled\": true\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"120"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 16:47:04 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eac707-7c69c281241ab0c959dfca43"},{"key":"x-amzn-RequestId","value":"9a7967e9-5a0d-49b2-b37d-42db90b5bfef"},{"key":"x-amz-apigw-id","value":"ITQJSFW2oAMEW3g="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 8822b02845e730d6fbf493930f40c946.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"hQI_RL7uMQj6isS5yrk3b-3ntuKCYsfp8YpKEIjQ31w42z9X3kjISg=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"A discount code with this code already exists.\",\n            \"code\": \"DUPLICATE_DISCOUNT_CODE\"\n        }\n    ]\n}"},{"id":"a88e30e9-5dd6-48be-b516-c4e14e5bc956","name":"Error 400 - Missing Auth Token","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"x-postman-example-name","value":"Error 400 - Missing Auth Token","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-888\",\n  \"label\": \"30 reais de desconto\",\n  \"description\": \"30 reais de desconto\",\n  \"discountMethod\": \"CODE\",\n  \"conditions\": {\n    \"productType\": \"ALL\",\n    \"min\": 100,\n    \"max\": 999999,\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\n    \"redemptionLimit\": 999999,\n    \"accountLimit\": 999999\n  },\n  \"enabled\": true\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"1719"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 16:46:35 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eac6eb-54548989306f8cf6449b369b"},{"key":"x-amzn-RequestId","value":"a6d7ef76-95c9-4441-90f2-5acc7f964b8d"},{"key":"x-amz-apigw-id","value":"ITQE5FZ2oAMERyA="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 8822b02845e730d6fbf493930f40c946.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"W0lKkstJqLL-il9qepHf1TnSYUGYHnbT-drxng_5OaBzxydan3BLwA=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"Unauthorized - No authenticated user\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 65\n                }\n            ],\n            \"path\": [\n                \"createDiscountCode\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"stacktrace\": [\n                        \"Error: Unauthorized - No authenticated user\",\n                        \"    at file:///usr/local/yggdrasil/packages/authorization-tools/dist/src/tools/authorizeResolver.js:16:15\",\n                        \"    at file:///usr/local/yggdrasil/node_modules/.pnpm/graphql-middleware@6.1.35_graphql@15.8.0/node_modules/graphql-middleware/dist/applicator.mjs:5:112\",\n                        \"    at addResolverDataToLoggerMiddleware (file:///usr/local/yggdrasil/packages/plugins/logger-data/dist/src/middlewares/addResolverDataToLoggerMiddleware.js:23:12)\",\n                        \"    at file:///usr/local/yggdrasil/node_modules/.pnpm/graphql-middleware@6.1.35_graphql@15.8.0/node_modules/graphql-middleware/dist/applicator.mjs:5:39\",\n                        \"    at /usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:225:25\",\n                        \"    at exports.AsyncResource.runInAsyncScope (node:async_hooks:201:9)\",\n                        \"    at callInAsyncScope (/usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:223:13)\",\n                        \"    at resolveAsync (/usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:210:12)\",\n                        \"    at field.resolve (/usr/local/yggdrasil/node_modules/.pnpm/apollo-server-core@2.26.2_graphql@15.8.0/node_modules/apollo-server-core/dist/utils/schemaInstrumentation.js:52:26)\",\n                        \"    at resolveField (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/execute.js:464:18)\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"createDiscountCode\": null\n    }\n}"},{"id":"90fb7135-74cd-4494-b3c4-cd3ab715e803","name":"Error 403 - Missing API Key","originalRequest":{"method":"POST","header":[{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 403 - Missing API Key","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-888\",\n  \"label\": \"30 reais de desconto\",\n  \"description\": \"30 reais de desconto\",\n  \"discountMethod\": \"CODE\",\n  \"conditions\": {\n    \"productType\": \"ALL\",\n    \"min\": 100,\n    \"max\": 999999,\n    \"startDate\": \"2025-01-01T03:00:00.000Z\",\n    \"endDate\": \"2035-01-01T03:00:00.000Z\",\n    \"redemptionLimit\": 999999,\n    \"accountLimit\": 999999\n  },\n  \"enabled\": true\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat"},"status":"Forbidden","code":403,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"23"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 16:46:47 GMT"},{"key":"x-amz-apigw-id","value":"ITQGsFYkoAMEdFg="},{"key":"x-amzn-RequestId","value":"cc8821e9-e617-45bd-b730-4c54184638dd"},{"key":"x-amzn-ErrorType","value":"ForbiddenException"},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 8822b02845e730d6fbf493930f40c946.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"RkwwnouMiCizDIETThNf2H1FvmJwHlMbrgTQuaDmz3RnNJhHc1RR3A=="}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Forbidden\"\n}"}],"_postman_id":"96ef745c-1f3a-4ed1-9de6-fd98b39bcf99"},{"name":"Create Flat by Product Type Discount","event":[{"listen":"test","script":{"id":"5a8d88f9-9b6f-40a6-9345-4aa049fa3d41","exec":["// --- Test Script for POST /discount-codes/flat-by-product-type ---\r","\r","// Attempt to parse JSON response\r","let jsonData;\r","let isJson = false;\r","try {\r","    jsonData = pm.response.json();\r","    isJson = true;\r","} catch (e) {\r","    console.error('POST /discount-codes/flat-by-product-type: Failed to parse JSON response.');\r","}\r","\r","// Get Status Code and Example Name\r","const statusCode = pm.response.code;\r","const requestName = pm.request.headers.get('x-postman-example-name') || 'Root Request';\r","\r","// Determine expected outcome from Example Name\r","const expectsSuccess = requestName.toLowerCase().includes('success') || requestName == 'Root Request';\r","const expects400 = requestName.toLowerCase().includes('400');\r","const expects403 = requestName.toLowerCase().includes('403') || requestName.toLowerCase().includes('missing api key');\r","const expects500 = requestName.toLowerCase().includes('500') || requestName.toLowerCase().includes('server error');\r","\r","// Specific Bad Request checks for this \r","const expectMissingAuth = requestName.toLowerCase().includes('missing auth');\r","const expectDuplicateCode = requestName.toLowerCase().includes('duplicate');\r","const expectsInvalidAmount = requestName.toLowerCase().includes('invalid amount');\r","const expectsMissingField = requestName.toLowerCase().includes('missing required field');\r","\r","// --- Shared Checks ---\r","// Ensure response is JSON unless it's an expected non-JSON 403\r","if (!isJson && !expects403) {\r","     pm.test(`[${requestName}] Response should be valid JSON`, () => {\r","         if (statusCode !== 403) { // Only fail if not an expected non-JSON 403\r","            pm.expect.fail('Response was not valid JSON.');\r","         } else {\r","             console.log(\"Skipping JSON check for expected 403 Forbidden response.\");\r","         }\r","     });\r","}\r","\r","// --- Success Case (200 OK) ---\r","if (expectsSuccess) {\r","    pm.test(`[${requestName}] Status code should be 200 OK`, () => {\r","        pm.expect(statusCode).to.equal(200);\r","    });\r","\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body should not contain 'errors' property`, () => {\r","            pm.expect(jsonData.errors).to.be.undefined;\r","        });\r","\r","        pm.test(`[${requestName}] Response body has core discount structure (_id, code, calculation)`, () => {\r","            pm.expect(jsonData).to.be.an('object');\r","            pm.expect(jsonData).to.have.property('_id').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('code').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('label');\r","            pm.expect(jsonData).to.have.property('enabled').that.is.a('boolean');\r","            pm.expect(jsonData).to.have.property('calculation').that.is.an('object');\r","            pm.expect(jsonData).to.have.property('conditions').that.is.an('object');\r","        });\r","\r","        pm.test(`[${requestName}] Calculation object has correct structure for Flat by Product Type Discount`, () => {\r","            pm.expect(jsonData.calculation).to.have.property('method').that.equals('CREDIT_OFF_BY_PRODUCT_TYPE');\r","            pm.expect(jsonData.calculation).to.have.property('amountByProductType').that.is.an('object');\r","            pm.expect(jsonData.calculation.amountByProductType).to.have.property('NON_RECURRING').that.is.a('number');\r","             pm.expect(jsonData.calculation.amountByProductType).to.have.property('RECURRING').that.is.a('number');\r","        });\r","\r","        pm.test(`[${requestName}] Conditions object has correct structure for ALL Product Types`, () => {\r","            pm.expect(jsonData.conditions).to.have.property('productType').that.equals('ALL');\r","        });\r","\r","    } else if (!isJson && statusCode === 200) {\r","         pm.test(`[${requestName}] Should have received JSON for success`, () => pm.expect.fail('Expected JSON body for 200 OK.'));\r","    }\r","}\r","\r","// --- Error Cases ---\r","\r","// Error 400 Bad Request (covers general 400, invalid amount, missing field)\r","if (expects400 || expectMissingAuth || expectDuplicateCode || expectsInvalidAmount || expectsMissingField) {\r","    const expectedStatus = 400;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Bad Request`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body should contain 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","        });\r","        \r","        if (jsonData.errors && jsonData.errors.length > 0) {\r","             pm.test(`[${requestName}] First error has 'message'`, () => {\r","                 const firstError = jsonData.errors[0];\r","                 pm.expect(firstError).to.have.property('message').that.is.a('string');\r","             });\r","\r","             if (expectMissingAuth) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"Unauthorized - No authenticated user\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.equal(expectedMessage);\r","                });\r","             }\r","\r","             if (expectDuplicateCode) {\r","                pm.test(`[${requestName}] First error has correct value for 'code'`, () => {\r","                    expectedCode = \"DUPLICATE_DISCOUNT_CODE\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('code').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('code').to.equal(expectedCode);\r","                });\r","            }\r","\r","             if (expectsInvalidAmount) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"must be a positive number\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","\r","             if (expectsMissingField) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"is required\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","        }\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should have received JSON for ${expectedStatus}`, () => pm.expect.fail(`Expected JSON body for ${expectedStatus} error.`));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 403 Forbidden\r","if (expects403) {\r","    const expectedStatus = 403;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Forbidden`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    // Check for standard \"Forbidden\" message (can be JSON or plain text)\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body contains 'message: Forbidden'`, () => {\r","             pm.expect(jsonData.message).to.equal(\"Forbidden\");\r","        });\r","    } else if (!isJson && statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Body text contains 'Forbidden'`, () => {\r","            pm.expect(pm.response.text()).to.include(\"Forbidden\");\r","        });\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should contain 'Forbidden' message`, () => pm.expect.fail('Expected \"Forbidden\" message in body for 403.'));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 500 Internal Server Error\r","if (expects500) {\r","    const expectedStatus = 500;\r","     pm.test(`[${requestName}] Status code should be ${expectedStatus} Internal Server Error`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","     if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body contains 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","             // Check if message indicates server error, but allow for variations\r","             const firstError = jsonData.errors[0];\r","             pm.expect(firstError.message.toLowerCase()).to.include('internal server error');\r","        });\r","    } // Don't strictly require JSON for 500\r","\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// --- General Check ---\r","// Flag if status code doesn't match any expected pattern for this endpoint\r","if (!expectsSuccess && !expects400 && !expects403 && !expects500 &&\r","    !expectMissingAuth && !expectDuplicateCode && !expectsInvalidAmount && !expectsMissingField) {\r","    pm.test(`[${requestName}] Received UNEXPECTED status code: ${statusCode}`, () => {\r","        // This test will fail if the status code wasn't one of the expected ones\r","        pm.expect.fail(`Received unexpected status code ${statusCode}. Check Example Name or API response.`);\r","    });\r","}"],"type":"text/javascript","packages":{}}},{"listen":"prerequest","script":{"id":"c5eadad9-3ffe-45c9-b1a9-8aeb656404cf","exec":[""],"type":"text/javascript","packages":{}}}],"id":"cca22d07-2766-4fe6-bb68-6829b9790301","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""}],"body":{"mode":"raw","raw":"{\n    \"code\": \"TESTE-REST-3a\",\n    \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"discountMethod\": \"CODE\",\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n        \"amountByProductType\": {\n            \"RECURRING\": 45,\n            \"NON_RECURRING\": 30\n        }\n    },\n    \"enabled\": true,\n    \"conditions\": {\n        \"productType\": \"ALL\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"redemptionLimit\": 999999,\n        \"accountLimit\": 999999\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat-by-product-type","description":"<h2 id=\"request\">Request</h2>\n<p><strong>Purpose:</strong> Creates a new discount code that applies different fixed flat amounts based on product type (recurring vs. non-recurring).</p>\n<p><strong>How to use:</strong> Send a POST request with the required API key and Authorization headers, and the full discount code configuration in the request body.</p>\n<p><strong>Headers Required:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>x-api-key</code></td>\n<td><code>YourApiKey...</code></td>\n<td>Your partner-specific API key.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>Authorization</code></td>\n<td><code>YourToken...</code></td>\n<td>The access token obtained via <code>/auth/signin</code>.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Request Body (</strong><code>application/json</code><strong>):</strong></p>\n<p>The body should contain the full definition for the new flat-by-product-type discount code.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n<th>Required</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>string</td>\n<td>The discount code string. Will be trimmed and must be unique.</td>\n<td>Yes</td>\n<td><code>\"SUBSSAVER\"</code></td>\n</tr>\n<tr>\n<td><code>label</code></td>\n<td>string</td>\n<td>A short, user-facing label for the discount.</td>\n<td>No</td>\n<td><code>\"Subscription Discount\"</code></td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>A more detailed description for internal use.</td>\n<td>No</td>\n<td><code>\"R$5 off non-recurring, R$15 off recurring\"</code></td>\n</tr>\n<tr>\n<td><code>enabled</code></td>\n<td>boolean</td>\n<td>Whether the discount code should be active immediately upon creation.</td>\n<td>Yes</td>\n<td><code>true</code></td>\n</tr>\n<tr>\n<td><code>calculation</code></td>\n<td>object</td>\n<td>Defines how the discount value is calculated.</td>\n<td>Yes</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>calculation.method</code></td>\n<td>string</td>\n<td><strong>Must be</strong> <strong><code>\"CREDIT_OFF_BY_PRODUCT_TYPE\"</code></strong> <strong>for this endpoint.</strong></td>\n<td>Yes</td>\n<td><code>\"CREDIT_OFF_BY_PRODUCT_TYPE\"</code></td>\n</tr>\n<tr>\n<td><code>calculation.amountByProductType</code></td>\n<td>object</td>\n<td>Specifies the flat discount amount in <strong>Reais (R$)</strong> for different product types.</td>\n<td>Yes</td>\n<td><code>{\"NON_RECURRING\": 5, \"RECURRING\": 15}</code></td>\n</tr>\n<tr>\n<td><code>calculation.amountByProductType.NON_RECURRING</code></td>\n<td>integer</td>\n<td>Fixed discount (R$) for non-recurring products. Must be a whole number.</td>\n<td>Yes</td>\n<td><code>5</code></td>\n</tr>\n<tr>\n<td><code>calculation.amountByProductType.RECURRING</code></td>\n<td>integer</td>\n<td>Fixed discount (R$) for recurring products. Must be a whole number.</td>\n<td>Yes</td>\n<td><code>15</code></td>\n</tr>\n<tr>\n<td><code>conditions</code></td>\n<td>object</td>\n<td>Sets the conditions under which the discount applies. All are optional and have defaults.</td>\n<td>No</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>conditions.productType</code></td>\n<td>string</td>\n<td>Which product types this applies to (<code>ALL</code>, <code>RECURRING</code>, <code>NON_RECURRING</code>). Defaults to <code>ALL</code>.</td>\n<td>No</td>\n<td><code>\"ALL\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.min</code></td>\n<td>number</td>\n<td>Minimum order subtotal required for the discount. Defaults to 0.</td>\n<td>No</td>\n<td><code>0</code></td>\n</tr>\n<tr>\n<td><code>conditions.max</code></td>\n<td>number</td>\n<td>Maximum order subtotal allowed for the discount. Defaults to unlimited.</td>\n<td>No</td>\n<td><code>999999</code></td>\n</tr>\n<tr>\n<td><code>conditions.startDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount becomes active. Defaults to now.</td>\n<td>No</td>\n<td><code>null</code></td>\n</tr>\n<tr>\n<td><code>conditions.endDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount expires. Defaults to never.</td>\n<td>No</td>\n<td><code>null</code></td>\n</tr>\n<tr>\n<td><code>conditions.redemptionLimit</code></td>\n<td>integer</td>\n<td>Max number of times the code can be used in total. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>999999</code></td>\n</tr>\n<tr>\n<td><code>conditions.accountLimit</code></td>\n<td>integer</td>\n<td>Max number of times a single logged-in user can use the code. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>999999</code></td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response\">Response</h2>\n<p><strong>Success (200 OK):</strong><br />Returns the complete <code>Discount</code> object for the newly created discount code. The structure matches the <code>Discount</code> schema defined in the OpenAPI specification, including the generated <code>_id</code>.</p>\n<p><strong>Errors:</strong></p>\n<ul>\n<li><p><strong>400 Bad Request:</strong> Invalid input format, missing required fields, or invalid values (e.g., non-integer amounts).</p>\n</li>\n<li><p><strong>401 Unauthorized:</strong> Missing or invalid <code>Authorization</code> token.</p>\n</li>\n<li><p><strong>403 Forbidden:</strong> Missing or invalid <code>x-api-key</code>, or insufficient permissions.</p>\n</li>\n<li><p><strong>409 Conflict:</strong> A discount code with the provided <code>code</code> already exists.</p>\n</li>\n<li><p><strong>500 Internal Server Error:</strong> An unexpected server error.</p>\n</li>\n</ul>\n","urlObject":{"path":["discount-codes","flat-by-product-type"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"19c40232-7128-48d1-83fd-abc01322b5ad","name":"Success - Create Flat by Product Type Discount","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Success - Create Flat by Product Type Discount","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-12\",\n    \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"discountMethod\": \"CODE\",\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n        \"amountByProductType\": {\n            \"RECURRING\": 45,\n            \"NON_RECURRING\": 30\n        }\n    },\n    \"enabled\": true,\n    \"conditions\": {\n        \"productType\": \"ALL\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"redemptionLimit\": 999999,\n        \"accountLimit\": 999999\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat-by-product-type"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"703"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 18:01:19 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67ead86e-71d3404324f9f2e325937422"},{"key":"x-amzn-RequestId","value":"5c5c9f77-e977-48c8-9a75-3f934409fdf7"},{"key":"x-amz-apigw-id","value":"ITbBZEIIoAMEPpA="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 3deb8c79b706cdf9560d6be2907a5bae.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GIG51-P3"},{"key":"X-Amz-Cf-Id","value":"LBnrCHRSLWNqb23SOqgZK69WWdDkbDwocVYfZghPG6wEOlVe8k_-pA=="}],"cookie":[],"responseTime":null,"body":"{\n    \"_id\": \"16aafa29-2959-44ed-a6a3-4550f8619fc5\",\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-12\",\n    \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"recurrenceCycleLimit\": null,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"productType\": \"ALL\"\n    },\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n        \"amountByProductType\": {\n            \"RECURRING\": 45,\n            \"NON_RECURRING\": 30\n        }\n    },\n    \"transactions\": null\n}"},{"id":"d1cf1311-36d8-4dd7-93e8-176e8d3ee06e","name":"Error 400 - Invalid Amount","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 400 - Invalid Amount","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-999\",\n    \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"discountMethod\": \"CODE\",\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n        \"amountByProductType\": {\n            \"RECURRING\": -45,\n            \"NON_RECURRING\": -30\n        }\n    },\n    \"enabled\": true,\n    \"conditions\": {\n        \"productType\": \"ALL\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"redemptionLimit\": 999999,\n        \"accountLimit\": 999999\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat-by-product-type"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"1447"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:13:07 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eacd23-1556bef338de1e681cba9e9c"},{"key":"x-amzn-RequestId","value":"3d91d1ff-1b83-432f-9a67-43d3537586a0"},{"key":"x-amz-apigw-id","value":"ITT9lFIJoAMEivA="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 3bcdf4ca8e63ffb8832bc109ac2cd54c.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"vfsHNlkhTLolPhwgieXvN9mMnYXO7Opt_W4tcpgijLYSQ4L12cMx7g=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"\\\"calculation.amountByProductType.NON_RECURRING\\\" must be a positive number\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 65\n                }\n            ],\n            \"path\": [\n                \"createDiscountCode\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"_original\": {\n                        \"_id\": \"69744841-a241-43e9-aa6b-fce4d346e104\",\n                        \"shopId\": \"MRxLZSpu6AawLoRA9\",\n                        \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-999\",\n                        \"createdAt\": \"2025-03-31T17:13:07.436Z\",\n                        \"updatedAt\": \"2025-03-31T17:13:07.436Z\",\n                        \"calculation\": {\n                            \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n                            \"amountByProductType\": {\n                                \"RECURRING\": -45,\n                                \"NON_RECURRING\": -30\n                            }\n                        },\n                        \"conditions\": {\n                            \"accountLimit\": 999999,\n                            \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                            \"max\": 999999,\n                            \"min\": 100,\n                            \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                            \"redemptionLimit\": 999999,\n                            \"productType\": \"ALL\"\n                        },\n                        \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n                        \"discountMethod\": \"CODE\",\n                        \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n                        \"enabled\": true\n                    },\n                    \"details\": [\n                        {\n                            \"message\": \"\\\"calculation.amountByProductType.NON_RECURRING\\\" must be a positive number\",\n                            \"path\": [\n                                \"calculation\",\n                                \"amountByProductType\",\n                                \"NON_RECURRING\"\n                            ],\n                            \"type\": \"number.positive\",\n                            \"context\": {\n                                \"label\": \"calculation.amountByProductType.NON_RECURRING\",\n                                \"value\": -30,\n                                \"key\": \"NON_RECURRING\"\n                            }\n                        }\n                    ],\n                    \"stacktrace\": [\n                        \"ValidationError: \\\"calculation.amountByProductType.NON_RECURRING\\\" must be a positive number\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"createDiscountCode\": null\n    }\n}"},{"id":"9b68ccb5-1245-4bd5-b7cc-a1a7906db538","name":"Error 400 - Missing Required Field","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 400 - Missing Required Field","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-99\",\n    \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"enabled\": true\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat-by-product-type"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"847"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:09:26 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eacc45-22f7d974613f41463611cede"},{"key":"x-amzn-RequestId","value":"8fc7d08c-d4ea-4c26-a34d-7e4614ce7e94"},{"key":"x-amz-apigw-id","value":"ITTa9GMDoAMEf9w="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 49e61dba008b57f295ca0e252c7e09d0.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"jr9ELqrbE7ODaB01XiBWqI37ClEAR4spxjdTDxDiCkHFF6kU4png5w=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"\\\"discountMethod\\\" is required\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 65\n                }\n            ],\n            \"path\": [\n                \"createDiscountCode\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"_original\": {\n                        \"_id\": \"0f79b703-e24c-43dc-8f03-f26fe8113bc3\",\n                        \"shopId\": \"MRxLZSpu6AawLoRA9\",\n                        \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-99\",\n                        \"createdAt\": \"2025-03-31T17:09:26.132Z\",\n                        \"updatedAt\": \"2025-03-31T17:09:26.132Z\",\n                        \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n                        \"enabled\": true,\n                        \"conditions\": {\n                            \"productType\": \"NON_RECURRING\"\n                        }\n                    },\n                    \"details\": [\n                        {\n                            \"message\": \"\\\"discountMethod\\\" is required\",\n                            \"path\": [\n                                \"discountMethod\"\n                            ],\n                            \"type\": \"any.required\",\n                            \"context\": {\n                                \"label\": \"discountMethod\",\n                                \"key\": \"discountMethod\"\n                            }\n                        }\n                    ],\n                    \"stacktrace\": [\n                        \"ValidationError: \\\"discountMethod\\\" is required\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"createDiscountCode\": null\n    }\n}"},{"id":"fe9c33f4-9201-4526-923f-638a398f1a15","name":"Error 400 - Duplicate Code","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 409 - Duplicate Code","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO\",\n    \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"discountMethod\": \"CODE\",\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n        \"amountByProductType\": {\n            \"RECURRING\": 45,\n            \"NON_RECURRING\": 30\n        }\n    },\n    \"enabled\": true,\n    \"conditions\": {\n        \"productType\": \"ALL\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"redemptionLimit\": 999999,\n        \"accountLimit\": 999999\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat-by-product-type"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"120"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:09:02 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eacc2e-7c41b15c620294971dd45e1d"},{"key":"x-amzn-RequestId","value":"d3215025-d2d9-4b9c-93dd-c7f2639a96f1"},{"key":"x-amz-apigw-id","value":"ITTXSHdJIAMEACA="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 49e61dba008b57f295ca0e252c7e09d0.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"1SfeUIcvx8joqxGCnJHW2ie-8PnZ5p4Ee_xLtk8ojyTW5xXvdoVzmA=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"A discount code with this code already exists.\",\n            \"code\": \"DUPLICATE_DISCOUNT_CODE\"\n        }\n    ]\n}"},{"id":"e2b10a9d-efe1-4ef3-b637-1c8fc7a6650c","name":"Error 400 - Missing Auth Token","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"x-postman-example-name","value":"Error 400 - Missing Auth Token","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-10\",\n    \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"discountMethod\": \"CODE\",\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n        \"amountByProductType\": {\n            \"RECURRING\": 45,\n            \"NON_RECURRING\": 30\n        }\n    },\n    \"enabled\": true,\n    \"conditions\": {\n        \"productType\": \"ALL\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"redemptionLimit\": 999999,\n        \"accountLimit\": 999999\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat-by-product-type"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"1719"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:08:48 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eacc20-5ea37f2164f69a02702e0aff"},{"key":"x-amzn-RequestId","value":"818f22ba-0221-4c0b-b462-c95347c6dd05"},{"key":"x-amz-apigw-id","value":"ITTVHHggIAMEu2A="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 49e61dba008b57f295ca0e252c7e09d0.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"ICf0hvg9n9561oRWZkN1Z3mSsXjZ74dzP2m_R9THrrSGPv-KpMPgkw=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"Unauthorized - No authenticated user\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 65\n                }\n            ],\n            \"path\": [\n                \"createDiscountCode\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"stacktrace\": [\n                        \"Error: Unauthorized - No authenticated user\",\n                        \"    at file:///usr/local/yggdrasil/packages/authorization-tools/dist/src/tools/authorizeResolver.js:16:15\",\n                        \"    at file:///usr/local/yggdrasil/node_modules/.pnpm/graphql-middleware@6.1.35_graphql@15.8.0/node_modules/graphql-middleware/dist/applicator.mjs:5:112\",\n                        \"    at addResolverDataToLoggerMiddleware (file:///usr/local/yggdrasil/packages/plugins/logger-data/dist/src/middlewares/addResolverDataToLoggerMiddleware.js:23:12)\",\n                        \"    at file:///usr/local/yggdrasil/node_modules/.pnpm/graphql-middleware@6.1.35_graphql@15.8.0/node_modules/graphql-middleware/dist/applicator.mjs:5:39\",\n                        \"    at /usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:225:25\",\n                        \"    at exports.AsyncResource.runInAsyncScope (node:async_hooks:201:9)\",\n                        \"    at callInAsyncScope (/usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:223:13)\",\n                        \"    at resolveAsync (/usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:210:12)\",\n                        \"    at field.resolve (/usr/local/yggdrasil/node_modules/.pnpm/apollo-server-core@2.26.2_graphql@15.8.0/node_modules/apollo-server-core/dist/utils/schemaInstrumentation.js:52:26)\",\n                        \"    at resolveField (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/execute.js:464:18)\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"createDiscountCode\": null\n    }\n}"},{"id":"e7ad162b-dba4-420a-a679-15003ccd7a3a","name":"Error 403 - Missing API Key","originalRequest":{"method":"POST","header":[{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 403 - Missing API Key","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-10\",\n    \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes)\",\n    \"discountMethod\": \"CODE\",\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n        \"amountByProductType\": {\n            \"RECURRING\": 45,\n            \"NON_RECURRING\": 30\n        }\n    },\n    \"enabled\": true,\n    \"conditions\": {\n        \"productType\": \"ALL\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"redemptionLimit\": 999999,\n        \"accountLimit\": 999999\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat-by-product-type"},"status":"Forbidden","code":403,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"23"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:08:42 GMT"},{"key":"x-amz-apigw-id","value":"ITTUPGX4oAMEcuw="},{"key":"x-amzn-RequestId","value":"fd035666-68c1-4ea8-8f98-1e883419b796"},{"key":"x-amzn-ErrorType","value":"ForbiddenException"},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 49e61dba008b57f295ca0e252c7e09d0.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"LPYCLbfG7v-FAej6_fCxJNo8eFpEDRJyyJzU7mliXGB8cUWSLWSohQ=="}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Forbidden\"\n}"}],"_postman_id":"cca22d07-2766-4fe6-bb68-6829b9790301"},{"name":"Create Shipping Discount","event":[{"listen":"test","script":{"exec":["// --- Test Script for POST /discount-codes/shipping ---\r","\r","// Attempt to parse JSON response\r","let jsonData;\r","let isJson = false;\r","try {\r","    jsonData = pm.response.json();\r","    isJson = true;\r","} catch (e) {\r","    console.error('POST /discount-codes/shipping: Failed to parse JSON response.');\r","}\r","\r","// Get Status Code and Example Name\r","const statusCode = pm.response.code;\r","const requestName = pm.request.headers.get('x-postman-example-name') || 'Root Request';\r","\r","// Determine expected outcome from Example Name\r","const expectsSuccess = requestName.toLowerCase().includes('success') || requestName == 'Root Request';\r","const expects400 = requestName.toLowerCase().includes('400');\r","const expects403 = requestName.toLowerCase().includes('403') || requestName.toLowerCase().includes('missing api key');\r","const expects500 = requestName.toLowerCase().includes('500') || requestName.toLowerCase().includes('server error');\r","\r","// Specific Bad Request checks for this \r","const expectMissingAuth = requestName.toLowerCase().includes('missing auth');\r","const expectDuplicateCode = requestName.toLowerCase().includes('duplicate');\r","const expectsInvalidAmount = requestName.toLowerCase().includes('invalid amount');\r","const expectsMissingField = requestName.toLowerCase().includes('missing required field');\r","\r","// --- Shared Checks ---\r","// Ensure response is JSON unless it's an expected non-JSON 403\r","if (!isJson && !expects403) {\r","     pm.test(`[${requestName}] Response should be valid JSON`, () => {\r","         if (statusCode !== 403) { // Only fail if not an expected non-JSON 403\r","            pm.expect.fail('Response was not valid JSON.');\r","         } else {\r","             console.log(\"Skipping JSON check for expected 403 Forbidden response.\");\r","         }\r","     });\r","}\r","\r","// --- Success Case (200 OK) ---\r","if (expectsSuccess) {\r","    pm.test(`[${requestName}] Status code should be 200 OK`, () => {\r","        pm.expect(statusCode).to.equal(200);\r","    });\r","\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body should not contain 'errors' property`, () => {\r","            pm.expect(jsonData.errors).to.be.undefined;\r","        });\r","\r","        pm.test(`[${requestName}] Response body has core discount structure`, () => {\r","            pm.expect(jsonData).to.be.an('object');\r","            pm.expect(jsonData).to.have.property('_id').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('code').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('label');\r","            pm.expect(jsonData).to.have.property('enabled').that.is.a('boolean');\r","            pm.expect(jsonData).to.have.property('calculation').that.is.an('object');\r","            pm.expect(jsonData).to.have.property('conditions').that.is.an('object');\r","        });\r","\r","        pm.test(`[${requestName}] Calculation object has correct structure for Shipping Discount`, () => {\r","            pm.expect(jsonData.calculation).to.have.property('method').that.equals('SHIPPING');\r","            pm.expect(jsonData.calculation).to.have.property('fulfillmentOptionNames').that.is.an('array');\r","            pm.expect(jsonData.calculation).to.have.property('fulfillmentOptionNames').have.length.greaterThan(0);\r","        });\r","\r","    } else if (!isJson && statusCode === 200) {\r","         pm.test(`[${requestName}] Should have received JSON for success`, () => pm.expect.fail('Expected JSON body for 200 OK.'));\r","    }\r","}\r","\r","// --- Error Cases ---\r","\r","// Error 400 Bad Request (covers general 400, invalid amount, missing field)\r","if (expects400 || expectMissingAuth || expectDuplicateCode || expectsInvalidAmount || expectsMissingField) {\r","    const expectedStatus = 400;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Bad Request`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body should contain 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","        });\r","        \r","        if (jsonData.errors && jsonData.errors.length > 0) {\r","             pm.test(`[${requestName}] First error has 'message'`, () => {\r","                 const firstError = jsonData.errors[0];\r","                 pm.expect(firstError).to.have.property('message').that.is.a('string');\r","             });\r","\r","             if (expectMissingAuth) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"Unauthorized - No authenticated user\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.equal(expectedMessage);\r","                });\r","             }\r","\r","             if (expectDuplicateCode) {\r","                pm.test(`[${requestName}] First error has correct value for 'code'`, () => {\r","                    expectedCode = \"DUPLICATE_DISCOUNT_CODE\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('code').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('code').to.equal(expectedCode);\r","                });\r","            }\r","\r","             if (expectsInvalidAmount) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"must be a positive number\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","\r","             if (expectsMissingField) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"was not provided\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","        }\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should have received JSON for ${expectedStatus}`, () => pm.expect.fail(`Expected JSON body for ${expectedStatus} error.`));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 403 Forbidden\r","if (expects403) {\r","    const expectedStatus = 403;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Forbidden`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    // Check for standard \"Forbidden\" message (can be JSON or plain text)\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body contains 'message: Forbidden'`, () => {\r","             pm.expect(jsonData.message).to.equal(\"Forbidden\");\r","        });\r","    } else if (!isJson && statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Body text contains 'Forbidden'`, () => {\r","            pm.expect(pm.response.text()).to.include(\"Forbidden\");\r","        });\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should contain 'Forbidden' message`, () => pm.expect.fail('Expected \"Forbidden\" message in body for 403.'));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 500 Internal Server Error\r","if (expects500) {\r","    const expectedStatus = 500;\r","     pm.test(`[${requestName}] Status code should be ${expectedStatus} Internal Server Error`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","     if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body contains 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","             // Check if message indicates server error, but allow for variations\r","             const firstError = jsonData.errors[0];\r","             pm.expect(firstError.message.toLowerCase()).to.include('internal server error');\r","        });\r","    } // Don't strictly require JSON for 500\r","\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// --- General Check ---\r","// Flag if status code doesn't match any expected pattern for this endpoint\r","if (!expectsSuccess && !expects400 && !expects403 && !expects500 &&\r","    !expectMissingAuth && !expectDuplicateCode && !expectsInvalidAmount && !expectsMissingField) {\r","    pm.test(`[${requestName}] Received UNEXPECTED status code: ${statusCode}`, () => {\r","        // This test will fail if the status code wasn't one of the expected ones\r","        pm.expect.fail(`Received unexpected status code ${statusCode}. Check Example Name or API response.`);\r","    });\r","}"],"type":"text/javascript","packages":{},"id":"3c86ae6c-deee-40d6-9c0a-d51c9309eaae"}}],"id":"d62d6e4c-c0ae-457f-b4a8-bad634b4afc8","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS-000\",\n    \"label\": \"Frete grátis\",\n    \"description\": \"Frete grátis\",\n    \"discountMethod\": \"CODE\",\n    \"calculation\": {\n        \"method\": \"SHIPPING\",\n        \"fulfillmentOptionNames\": [\n            \"Correios Sedex\",\n            \"PAC Sedex\"\n        ]\n    },\n    \"enabled\": true,\n    \"conditions\": {\n        \"productType\": \"NON_RECURRING\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"redemptionLimit\": 999999,\n        \"accountLimit\": 999999\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/shipping","description":"<h2 id=\"request\">Request</h2>\n<p><strong>Purpose:</strong> Creates a new discount code that provides free shipping for specified fulfillment options.</p>\n<p><strong>How to use:</strong> Send a POST request with the required API key and Authorization headers, and the full discount code configuration in the request body.</p>\n<p><strong>Headers Required:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>x-api-key</code></td>\n<td><code>YourApiKey...</code></td>\n<td>Your partner-specific API key.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>Authorization</code></td>\n<td><code>YourToken...</code></td>\n<td>The access token obtained via <code>/auth/signin</code>.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Request Body (</strong><code>application/json</code><strong>):</strong></p>\n<p>The body should contain the full definition for the new free shipping discount code.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n<th>Required</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>string</td>\n<td>The discount code string. Will be trimmed and must be unique.</td>\n<td>Yes</td>\n<td><code>\"FREESHIPPING100\"</code></td>\n</tr>\n<tr>\n<td><code>label</code></td>\n<td>string</td>\n<td>A short, user-facing label for the discount.</td>\n<td>No</td>\n<td><code>\"Free Shipping Over R$100\"</code></td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>A more detailed description for internal use.</td>\n<td>No</td>\n<td><code>\"Free Sedex/PAC shipping on orders over R$100\"</code></td>\n</tr>\n<tr>\n<td><code>enabled</code></td>\n<td>boolean</td>\n<td>Whether the discount code should be active immediately upon creation.</td>\n<td>Yes</td>\n<td><code>true</code></td>\n</tr>\n<tr>\n<td><code>calculation</code></td>\n<td>object</td>\n<td>Defines how the discount value is calculated.</td>\n<td>Yes</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>calculation.method</code></td>\n<td>string</td>\n<td><strong>Must be</strong> <strong><code>\"SHIPPING\"</code></strong> <strong>for this endpoint.</strong></td>\n<td>Yes</td>\n<td><code>\"SHIPPING\"</code></td>\n</tr>\n<tr>\n<td><code>calculation.fulfillmentOptionNames</code></td>\n<td>array[string]</td>\n<td>List of exact fulfillment option names that will receive free shipping. Must contain at least one name.</td>\n<td>Yes</td>\n<td><code>[\"Correios Sedex\", \"PAC Sedex\"]</code></td>\n</tr>\n<tr>\n<td><code>conditions</code></td>\n<td>object</td>\n<td>Sets the conditions under which the discount applies. All are optional and have defaults.</td>\n<td>No</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>conditions.productType</code></td>\n<td>string</td>\n<td>Which product types this applies to (<code>ALL</code>, <code>RECURRING</code>, <code>NON_RECURRING</code>). Defaults to <code>ALL</code>.</td>\n<td>No</td>\n<td><code>\"ALL\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.min</code></td>\n<td>number</td>\n<td>Minimum order subtotal required for the discount. Defaults to 0.</td>\n<td>No</td>\n<td><code>100.0</code></td>\n</tr>\n<tr>\n<td><code>conditions.max</code></td>\n<td>number</td>\n<td>Maximum order subtotal allowed for the discount. Defaults to unlimited.</td>\n<td>No</td>\n<td><code>999999</code></td>\n</tr>\n<tr>\n<td><code>conditions.startDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount becomes active. Defaults to now.</td>\n<td>No</td>\n<td><code>null</code></td>\n</tr>\n<tr>\n<td><code>conditions.endDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount expires. Defaults to never.</td>\n<td>No</td>\n<td><code>null</code></td>\n</tr>\n<tr>\n<td><code>conditions.redemptionLimit</code></td>\n<td>integer</td>\n<td>Max number of times the code can be used in total. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>999999</code></td>\n</tr>\n<tr>\n<td><code>conditions.accountLimit</code></td>\n<td>integer</td>\n<td>Max number of times a single logged-in user can use the code. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>999999</code></td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response\">Response</h2>\n<p><strong>Success (200 OK):</strong><br />Returns the complete <code>Discount</code> object for the newly created discount code. The structure matches the <code>Discount</code> schema defined in the OpenAPI specification, including the generated <code>_id</code>.</p>\n<p><strong>Errors:</strong></p>\n<ul>\n<li><p><strong>400 Bad Request:</strong> Invalid input format, missing required fields, or invalid values (e.g., empty <code>fulfillmentOptionNames</code> array).</p>\n</li>\n<li><p><strong>401 Unauthorized:</strong> Missing or invalid <code>Authorization</code> token.</p>\n</li>\n<li><p><strong>403 Forbidden:</strong> Missing or invalid <code>x-api-key</code>, or insufficient permissions.</p>\n</li>\n<li><p><strong>409 Conflict:</strong> A discount code with the provided <code>code</code> already exists.</p>\n</li>\n<li><p><strong>500 Internal Server Error:</strong> An unexpected server error.</p>\n</li>\n</ul>\n","urlObject":{"path":["discount-codes","shipping"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"b81e284f-8cb4-4ec8-aa61-fb63faa39843","name":"Success - Create Shipping Discount","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Success - Create Shipping Discount","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS-7\",\n    \"label\": \"Frete grátis\",\n    \"description\": \"Frete grátis\",\n    \"discountMethod\": \"CODE\",\n    \"calculation\": {\n        \"method\": \"SHIPPING\",\n        \"fulfillmentOptionNames\": [\n            \"Correios Sedex\",\n            \"PAC Sedex\"\n        ]\n    },\n    \"enabled\": true,\n    \"conditions\": {\n        \"productType\": \"NON_RECURRING\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"redemptionLimit\": 999999,\n        \"accountLimit\": 999999\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/shipping"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"510"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 18:05:40 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67ead974-50d141986dbadc2819ea9522"},{"key":"x-amzn-RequestId","value":"01f76733-e723-47a3-afcc-686e5d468db7"},{"key":"x-amz-apigw-id","value":"ITbqNG5cIAMEs3w="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 74f4aae13b67b8952e8894793a95f8bc.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GIG51-P3"},{"key":"X-Amz-Cf-Id","value":"96qLCMh72XBEhQvilKLKru_8UZS2NWVk7Q2zHHjGmkyVbsAiKVJeFw=="}],"cookie":[],"responseTime":null,"body":"{\n    \"_id\": \"03ac4c5e-30c8-42b4-8250-1c06d7c4fd00\",\n    \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS-7\",\n    \"label\": \"Frete grátis\",\n    \"description\": \"Frete grátis\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"recurrenceCycleLimit\": null,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"productType\": \"NON_RECURRING\"\n    },\n    \"calculation\": {\n        \"method\": \"SHIPPING\",\n        \"fulfillmentOptionNames\": [\n            \"Correios Sedex\",\n            \"PAC Sedex\"\n        ]\n    },\n    \"transactions\": null\n}"},{"id":"0a276e8c-c5e8-4899-b2b7-725746c95f13","name":"Error 400 - Invalid Fulfillment Names","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 400 - Invalid Fulfillment Names","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS-99\",\n    \"label\": \"Frete grátis\",\n    \"description\": \"Frete grátis\",\n    \"discountMethod\": \"CODE\",\n    \"calculation\": {\n        \"method\": \"SHIPPING\",\n        \"fulfillmentOptionNames\": []\n    },\n    \"enabled\": true,\n    \"conditions\": {\n        \"productType\": \"NON_RECURRING\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"redemptionLimit\": 999999,\n        \"accountLimit\": 999999\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/shipping"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"1242"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:15:29 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eacdb1-4ba850395b4fbaf759b221a1"},{"key":"x-amzn-RequestId","value":"b84f6389-5f4a-49ea-a262-c0d2d1b35038"},{"key":"x-amz-apigw-id","value":"ITUT2FSJoAMEn7g="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 3bcdf4ca8e63ffb8832bc109ac2cd54c.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"JSsYWHYc72mSy4elqhgLRipuhcE_VWfRq1C6PmsnFKm7IXojYH5SzA=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"\\\"calculation.fulfillmentOptionNames\\\" does not contain 1 required value(s)\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 65\n                }\n            ],\n            \"path\": [\n                \"createDiscountCode\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"_original\": {\n                        \"_id\": \"fa5a9d21-9690-4b37-8136-395d766021da\",\n                        \"shopId\": \"MRxLZSpu6AawLoRA9\",\n                        \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS-99\",\n                        \"createdAt\": \"2025-03-31T17:15:29.935Z\",\n                        \"updatedAt\": \"2025-03-31T17:15:29.935Z\",\n                        \"calculation\": {\n                            \"method\": \"SHIPPING\",\n                            \"fulfillmentOptionNames\": []\n                        },\n                        \"conditions\": {\n                            \"accountLimit\": 999999,\n                            \"endDate\": \"2035-01-01T03:00:00.000Z\",\n                            \"max\": 999999,\n                            \"min\": 0,\n                            \"startDate\": \"2025-01-01T03:00:00.000Z\",\n                            \"redemptionLimit\": 999999,\n                            \"productType\": \"NON_RECURRING\"\n                        },\n                        \"description\": \"Frete grátis\",\n                        \"discountMethod\": \"CODE\",\n                        \"label\": \"Frete grátis\",\n                        \"enabled\": true\n                    },\n                    \"details\": [\n                        {\n                            \"message\": \"\\\"calculation.fulfillmentOptionNames\\\" does not contain 1 required value(s)\",\n                            \"path\": [\n                                \"calculation\",\n                                \"fulfillmentOptionNames\"\n                            ],\n                            \"type\": \"array.includesRequiredUnknowns\",\n                            \"context\": {\n                                \"unknownMisses\": 1,\n                                \"label\": \"calculation.fulfillmentOptionNames\",\n                                \"value\": [],\n                                \"key\": \"fulfillmentOptionNames\"\n                            }\n                        }\n                    ],\n                    \"stacktrace\": [\n                        \"ValidationError: \\\"calculation.fulfillmentOptionNames\\\" does not contain 1 required value(s)\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"createDiscountCode\": null\n    }\n}"},{"id":"7323e348-3ed0-45e5-ba32-72a7b3af4880","name":"Error 400 - Missing Required Field","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 400 - Missing Required Field","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS\",\n    \"label\": \"Frete grátis\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/shipping"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"1888"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:14:57 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eacd91-41743f6264b4946105eeb5fe"},{"key":"x-amzn-RequestId","value":"c59bde7a-7ffd-48e5-85e6-0d345914add6"},{"key":"x-amz-apigw-id","value":"ITUOuH1lIAMEACA="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 3bcdf4ca8e63ffb8832bc109ac2cd54c.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"SAtjOWRS0UdfTvTrCWszGZUCD51VyYDxGV2OA41qqm5ksLe-ep_3qA=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"Variable \\\"$input\\\" got invalid value { code: \\\"CUPOM-EXEMPLO-FRETE-GRATIS\\\", label: \\\"Frete grátis\\\" } at \\\"input.discountCode\\\"; Field \\\"enabled\\\" of required type \\\"Boolean!\\\" was not provided.\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 29\n                }\n            ],\n            \"extensions\": {\n                \"code\": \"BAD_USER_INPUT\",\n                \"exception\": {\n                    \"stacktrace\": [\n                        \"GraphQLError: Variable \\\"$input\\\" got invalid value { code: \\\"CUPOM-EXEMPLO-FRETE-GRATIS\\\", label: \\\"Frete grátis\\\" } at \\\"input.discountCode\\\"; Field \\\"enabled\\\" of required type \\\"Boolean!\\\" was not provided.\",\n                        \"    at /usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/values.js:116:15\",\n                        \"    at coerceInputValueImpl (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/utilities/coerceInputValue.js:99:11)\",\n                        \"    at coerceInputValueImpl (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/utilities/coerceInputValue.js:105:34)\",\n                        \"    at coerceInputValueImpl (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/utilities/coerceInputValue.js:54:14)\",\n                        \"    at coerceInputValue (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/utilities/coerceInputValue.js:37:10)\",\n                        \"    at _loop (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/values.js:109:69)\",\n                        \"    at coerceVariableValues (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/values.js:121:16)\",\n                        \"    at getVariableValues (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/values.js:50:19)\",\n                        \"    at buildExecutionContext (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/execute.js:203:61)\",\n                        \"    at executeImpl (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/execute.js:101:20)\"\n                    ]\n                }\n            }\n        }\n    ]\n}"},{"id":"3687e00e-813f-43df-8cd5-68d6a3ccf86f","name":"Error 400 - Duplicate Code","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 400 - Duplicate Code","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS\",\n    \"label\": \"Frete grátis\",\n    \"description\": \"Frete grátis\",\n    \"discountMethod\": \"CODE\",\n    \"calculation\": {\n        \"method\": \"SHIPPING\",\n        \"fulfillmentOptionNames\": [\n            \"Correios Sedex\",\n            \"PAC Sedex\"\n        ]\n    },\n    \"enabled\": true,\n    \"conditions\": {\n        \"productType\": \"NON_RECURRING\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"redemptionLimit\": 999999,\n        \"accountLimit\": 999999\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/shipping"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"120"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:14:21 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eacd6d-66edce084c6102c828342143"},{"key":"x-amzn-RequestId","value":"5dd5aeaf-b69a-454b-8c15-ad278d899b32"},{"key":"x-amz-apigw-id","value":"ITUJHG9lIAMEkjA="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 3bcdf4ca8e63ffb8832bc109ac2cd54c.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"GJwhLF4xkc5f6PZ38PP61gwu3laQfXXxVgi-Jk6HT8Zk02ZKvyxVUA=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"A discount code with this code already exists.\",\n            \"code\": \"DUPLICATE_DISCOUNT_CODE\"\n        }\n    ]\n}"},{"id":"4e973480-131b-4563-a542-21a6b96a819b","name":"Error 400 - Missing Auth Token","originalRequest":{"method":"POST","header":[{"key":"x-api-key","value":"{{api-key}}"},{"key":"x-postman-example-name","value":"Error 400 - Missing Auth Token","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS\",\n    \"label\": \"Frete grátis\",\n    \"description\": \"Frete grátis\",\n    \"discountMethod\": \"CODE\",\n    \"calculation\": {\n        \"method\": \"SHIPPING\",\n        \"fulfillmentOptionNames\": [\n            \"Correios Sedex\",\n            \"PAC Sedex\"\n        ]\n    },\n    \"enabled\": true,\n    \"conditions\": {\n        \"productType\": \"NON_RECURRING\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"redemptionLimit\": 999999,\n        \"accountLimit\": 999999\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/shipping"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"1719"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:14:02 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eacd59-03ad4edc723a459353d775bb"},{"key":"x-amzn-RequestId","value":"40bcca99-9106-4125-b7f3-3bebd684797c"},{"key":"x-amz-apigw-id","value":"ITUGGG20oAMEG7g="},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 3bcdf4ca8e63ffb8832bc109ac2cd54c.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"0QuseIG779kwXQLA913PQOnFvIUjNs-TpLoLQf2cJ7hdvl4ooBBSWQ=="}],"cookie":[],"responseTime":null,"body":"{\n    \"errors\": [\n        {\n            \"message\": \"Unauthorized - No authenticated user\",\n            \"locations\": [\n                {\n                    \"line\": 1,\n                    \"column\": 65\n                }\n            ],\n            \"path\": [\n                \"createDiscountCode\"\n            ],\n            \"extensions\": {\n                \"code\": \"INTERNAL_SERVER_ERROR\",\n                \"exception\": {\n                    \"stacktrace\": [\n                        \"Error: Unauthorized - No authenticated user\",\n                        \"    at file:///usr/local/yggdrasil/packages/authorization-tools/dist/src/tools/authorizeResolver.js:16:15\",\n                        \"    at file:///usr/local/yggdrasil/node_modules/.pnpm/graphql-middleware@6.1.35_graphql@15.8.0/node_modules/graphql-middleware/dist/applicator.mjs:5:112\",\n                        \"    at addResolverDataToLoggerMiddleware (file:///usr/local/yggdrasil/packages/plugins/logger-data/dist/src/middlewares/addResolverDataToLoggerMiddleware.js:23:12)\",\n                        \"    at file:///usr/local/yggdrasil/node_modules/.pnpm/graphql-middleware@6.1.35_graphql@15.8.0/node_modules/graphql-middleware/dist/applicator.mjs:5:39\",\n                        \"    at /usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:225:25\",\n                        \"    at exports.AsyncResource.runInAsyncScope (node:async_hooks:201:9)\",\n                        \"    at callInAsyncScope (/usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:223:13)\",\n                        \"    at resolveAsync (/usr/local/yggdrasil/node_modules/.pnpm/dd-trace@4.0.0/node_modules/dd-trace/packages/datadog-instrumentations/src/graphql.js:210:12)\",\n                        \"    at field.resolve (/usr/local/yggdrasil/node_modules/.pnpm/apollo-server-core@2.26.2_graphql@15.8.0/node_modules/apollo-server-core/dist/utils/schemaInstrumentation.js:52:26)\",\n                        \"    at resolveField (/usr/local/yggdrasil/node_modules/.pnpm/graphql@15.8.0/node_modules/graphql/execution/execute.js:464:18)\"\n                    ]\n                }\n            }\n        }\n    ],\n    \"data\": {\n        \"createDiscountCode\": null\n    }\n}"},{"id":"efc26925-8c2b-44dd-a862-979fd2f64033","name":"Error 403 - Missing API Key","originalRequest":{"method":"POST","header":[{"key":"Authorization","value":""},{"key":"x-postman-example-name","value":"Error 403 - Missing API Key","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS\",\n    \"label\": \"Frete grátis\",\n    \"description\": \"Frete grátis\",\n    \"discountMethod\": \"CODE\",\n    \"calculation\": {\n        \"method\": \"SHIPPING\",\n        \"fulfillmentOptionNames\": [\n            \"Correios Sedex\",\n            \"PAC Sedex\"\n        ]\n    },\n    \"enabled\": true,\n    \"conditions\": {\n        \"productType\": \"NON_RECURRING\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"redemptionLimit\": 999999,\n        \"accountLimit\": 999999\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/shipping"},"status":"Forbidden","code":403,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"23"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Mon, 31 Mar 2025 17:14:11 GMT"},{"key":"x-amz-apigw-id","value":"ITUHlHHPIAMEOiA="},{"key":"x-amzn-RequestId","value":"508910f4-3625-41e7-bca8-792f3f43ff6a"},{"key":"x-amzn-ErrorType","value":"ForbiddenException"},{"key":"X-Cache","value":"Error from cloudfront"},{"key":"Via","value":"1.1 3bcdf4ca8e63ffb8832bc109ac2cd54c.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"Nl_Fc3H1SJi6MN3-QwMIkhiuLJTJYFUmC9J4Mzu3BY4pH7_D3yWqjg=="}],"cookie":[],"responseTime":null,"body":"{\n    \"message\": \"Forbidden\"\n}"}],"_postman_id":"d62d6e4c-c0ae-457f-b4a8-bad634b4afc8"},{"name":"Update Percentage Discount","event":[{"listen":"test","script":{"id":"2a513534-52ab-4216-bb0d-369284227d96","exec":["// --- Test Script for PUT /discount-codes/percentage ---\r","\r","// Attempt to parse JSON response\r","let jsonData;\r","let isJson = false;\r","try {\r","    jsonData = pm.response.json();\r","    isJson = true;\r","} catch (e) {\r","    console.error('PUT /discount-codes/percentage: Failed to parse JSON response.');\r","}\r","\r","// Get Status Code and Example Name\r","const statusCode = pm.response.code;\r","const requestName = pm.request.headers.get('x-postman-example-name') || 'Root Request';\r","\r","// Determine expected outcome from Example Name\r","const expectsSuccess = requestName.toLowerCase().includes('success') || requestName == 'Root Request';\r","const expects400 = requestName.toLowerCase().includes('400');\r","const expects403 = requestName.toLowerCase().includes('403') || requestName.toLowerCase().includes('missing api key');\r","const expects500 = requestName.toLowerCase().includes('500') || requestName.toLowerCase().includes('server error');\r","\r","// Specific Bad Request checks for this endpoint\r","const expectMissingAuth = requestName.toLowerCase().includes('missing auth');\r","const expectsInvalidPercent = requestName.toLowerCase().includes('invalid percentage');\r","const expectsMissingField = requestName.toLowerCase().includes('missing required field');\r","\r","// --- Shared Checks ---\r","// Ensure response is JSON unless it's an expected non-JSON 403\r","if (!isJson && !expects403) {\r","     pm.test(`[${requestName}] Response should be valid JSON`, () => {\r","         if (statusCode !== 403) { // Only fail if not an expected non-JSON 403\r","            pm.expect.fail('Response was not valid JSON.');\r","         } else {\r","             console.log(\"Skipping JSON check for expected 403 Forbidden response.\");\r","         }\r","     });\r","}\r","\r","// --- Success Case (200 OK) ---\r","if (expectsSuccess) {\r","    pm.test(`[${requestName}] Status code should be 200 OK`, () => {\r","        pm.expect(statusCode).to.equal(200);\r","    });\r","\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body should not contain 'errors' property`, () => {\r","            pm.expect(jsonData.errors).to.be.undefined;\r","        });\r","\r","        pm.test(`[${requestName}] Response body has core discount structure (_id, code, calculation)`, () => {\r","            pm.expect(jsonData).to.be.an('object');\r","            pm.expect(jsonData).to.have.property('_id').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('code').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('label');\r","            pm.expect(jsonData).to.have.property('enabled').that.is.a('boolean');\r","            pm.expect(jsonData).to.have.property('calculation').that.is.an('object');\r","            pm.expect(jsonData).to.have.property('conditions').that.is.an('object');\r","        });\r","\r","        pm.test(`[${requestName}] Calculation object has correct structure for Percentage`, () => {\r","            pm.expect(jsonData.calculation).to.have.property('method').that.equals('DISCOUNT');\r","            pm.expect(jsonData.calculation).to.have.property('amountByProductType').that.is.an('object');\r","            pm.expect(jsonData.calculation.amountByProductType).to.have.property('NON_RECURRING').that.is.a('number');\r","             pm.expect(jsonData.calculation.amountByProductType).to.have.property('RECURRING').that.is.a('number');\r","        });\r","\r","    } else if (!isJson && statusCode === 200) {\r","         pm.test(`[${requestName}] Should have received JSON for success`, () => pm.expect.fail('Expected JSON body for 200 OK.'));\r","    }\r","}\r","\r","// --- Error Cases ---\r","\r","// Error 400 Bad Request (covers general 400, invalid percent, missing field)\r","if (expects400 || expectMissingAuth || expectsInvalidPercent || expectsMissingField) {\r","    const expectedStatus = 400;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Bad Request`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body should contain 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","        });\r","        \r","        if (jsonData.errors && jsonData.errors.length > 0) {\r","             pm.test(`[${requestName}] First error has 'message'`, () => {\r","                 const firstError = jsonData.errors[0];\r","                 pm.expect(firstError).to.have.property('message').that.is.a('string');\r","             });\r","\r","             if (expectMissingAuth) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"Unauthorized - No authenticated user\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.equal(expectedMessage);\r","                });\r","             }\r","\r","             if (expectsInvalidPercent) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"must be a positive number\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","\r","             if (expectsMissingField) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"is required\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","        }\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should have received JSON for ${expectedStatus}`, () => pm.expect.fail(`Expected JSON body for ${expectedStatus} error.`));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 403 Forbidden\r","if (expects403) {\r","    const expectedStatus = 403;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Forbidden`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    // Check for standard \"Forbidden\" message (can be JSON or plain text)\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body contains 'message: Forbidden'`, () => {\r","             pm.expect(jsonData.message).to.equal(\"Forbidden\");\r","        });\r","    } else if (!isJson && statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Body text contains 'Forbidden'`, () => {\r","            pm.expect(pm.response.text()).to.include(\"Forbidden\");\r","        });\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should contain 'Forbidden' message`, () => pm.expect.fail('Expected \"Forbidden\" message in body for 403.'));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 500 Internal Server Error\r","if (expects500) {\r","    const expectedStatus = 500;\r","     pm.test(`[${requestName}] Status code should be ${expectedStatus} Internal Server Error`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","     if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body contains 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","             // Check if message indicates server error, but allow for variations\r","             const firstError = jsonData.errors[0];\r","             pm.expect(firstError.message.toLowerCase()).to.include('internal server error');\r","        });\r","    } // Don't strictly require JSON for 500\r","\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// --- General Check ---\r","// Flag if status code doesn't match any expected pattern for this endpoint\r","if (!expectsSuccess && !expects400 && !expects403 && !expects500 &&\r","    !expectMissingAuth && !expectsInvalidPercent && !expectsMissingField) {\r","    pm.test(`[${requestName}] Received UNEXPECTED status code: ${statusCode}`, () => {\r","        // This test will fail if the status code wasn't one of the expected ones\r","        pm.expect.fail(`Received unexpected status code ${statusCode}. Check Example Name or API response.`);\r","    });\r","}"],"type":"text/javascript","packages":{}}}],"id":"89bfce1c-0f22-4a7b-95ea-485f765a6e8d","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"PUT","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-DESCONTO-28\",\n    \"label\": \"10% de desconto - UPDATED\",\n    \"description\": \"10% de desconto - UPDATED\",\n    \"enabled\": false,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"productType\": \"NON_RECURRING\"\n    },\n    \"calculation\": {\n        \"method\": \"DISCOUNT\",\n        \"amountByProductType\": {\n            \"NON_RECURRING\": 10,\n            \"RECURRING\": 0\n        }\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/percentage/:discountCodeId","description":"<h2 id=\"request\">Request</h2>\n<p><strong>Purpose:</strong> Updates an existing percentage-based discount code identified by its ID.</p>\n<p><strong>How to use:</strong> Send a PUT request with the discount code's ID in the URL path, the necessary authentication headers, and the complete updated discount code configuration in the request body. Even if you only want to change one field (e.g., <code>enabled</code>), you must provide the full configuration as defined below.</p>\n<p><strong>Headers Required:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>x-api-key</code></td>\n<td><code>YourApiKey...</code></td>\n<td>Your partner-specific API key.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>Authorization</code></td>\n<td><code>YourToken...</code></td>\n<td>The access token obtained via <code>/auth/signin</code>.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Path Parameters:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>discountCodeId</code></td>\n<td>string</td>\n<td>The opaque ID of the discount code to update.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Request Body:</strong> (<code>application/json</code>)</p>\n<p>The body should contain the full definition of the discount code as you want it to be after the update.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n<th>Required</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>string</td>\n<td>The discount code string. Will be trimmed. Must be unique if changing.</td>\n<td>Yes</td>\n<td><code>\"SAVE15PERCENT\"</code></td>\n</tr>\n<tr>\n<td><code>label</code></td>\n<td>string</td>\n<td>A short, user-facing label for the discount.</td>\n<td>No</td>\n<td><code>\"15% Off Everything\"</code></td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>A more detailed description for internal use.</td>\n<td>No</td>\n<td><code>\"Updated 15% off all items for winter sale\"</code></td>\n</tr>\n<tr>\n<td><code>enabled</code></td>\n<td>boolean</td>\n<td>Whether the discount code is currently active and usable.</td>\n<td>Yes</td>\n<td><code>true</code></td>\n</tr>\n<tr>\n<td><code>calculation</code></td>\n<td>object</td>\n<td>Defines how the discount value is calculated.</td>\n<td>Yes</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>calculation.method</code></td>\n<td>string</td>\n<td><strong>Must be</strong> <strong><code>\"DISCOUNT\"</code></strong> <strong>for this endpoint.</strong></td>\n<td>Yes</td>\n<td><code>\"DISCOUNT\"</code></td>\n</tr>\n<tr>\n<td><code>calculation.amountByProductType</code></td>\n<td>object</td>\n<td>Specifies the percentage discount for different product types.</td>\n<td>Yes</td>\n<td><code>{\"NON_RECURRING\": 15.0, \"RECURRING\": 15.0}</code></td>\n</tr>\n<tr>\n<td><code>calculation.amountByProductType.NON_RECURRING</code></td>\n<td>number</td>\n<td>Percentage discount for non-recurring products (0-100).</td>\n<td>Yes</td>\n<td><code>15.0</code></td>\n</tr>\n<tr>\n<td><code>calculation.amountByProductType.RECURRING</code></td>\n<td>number</td>\n<td>Percentage discount for recurring products (0-100).</td>\n<td>Yes</td>\n<td><code>15.0</code></td>\n</tr>\n<tr>\n<td><code>conditions</code></td>\n<td>object</td>\n<td>Sets the conditions under which the discount applies. All are optional and have defaults.</td>\n<td>No</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>conditions.productType</code></td>\n<td>string</td>\n<td>Which product types this applies to (<code>ALL</code>, <code>RECURRING</code>, <code>NON_RECURRING</code>). Defaults to <code>ALL</code>.</td>\n<td>No</td>\n<td><code>\"ALL\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.min</code></td>\n<td>number</td>\n<td>Minimum order subtotal required for the discount. Defaults to 0.</td>\n<td>No</td>\n<td><code>0</code></td>\n</tr>\n<tr>\n<td><code>conditions.max</code></td>\n<td>number</td>\n<td>Maximum order subtotal allowed for the discount. Defaults to unlimited.</td>\n<td>No</td>\n<td><code>999999</code></td>\n</tr>\n<tr>\n<td><code>conditions.startDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount becomes active. Defaults to now.</td>\n<td>No</td>\n<td><code>\"2025-01-01T00:00:00Z\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.endDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount expires. Defaults to never.</td>\n<td>No</td>\n<td><code>\"2026-01-01T00:00:00Z\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.redemptionLimit</code></td>\n<td>integer</td>\n<td>Max number of times the code can be used in total. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>500</code></td>\n</tr>\n<tr>\n<td><code>conditions.accountLimit</code></td>\n<td>integer</td>\n<td>Max number of times a single logged-in user can use the code. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>1</code></td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response\">Response</h2>\n<p><strong>Success (200 OK):</strong><br />Returns the complete, updated <code>Discount</code> object reflecting the changes made. The structure matches the <code>Discount</code> schema defined in the OpenAPI specification and includes fields like <code>_id</code>, <code>code</code>, <code>label</code>, <code>description</code>, <code>enabled</code>, <code>discountMethod</code>, <code>calculation</code>, <code>conditions</code>, and potentially <code>transactions</code> if any exist.</p>\n<p><strong>Errors:</strong></p>\n<ul>\n<li><p><strong>400 Bad Request:</strong> Invalid input format, missing required fields, or invalid values in the request body (e.g., percentage &gt; 100). The response body will contain details in the <code>errors</code> array.</p>\n</li>\n<li><p><strong>401 Unauthorized:</strong> Missing or invalid <code>Authorization</code> token.</p>\n</li>\n<li><p><strong>403 Forbidden:</strong> Missing or invalid <code>x-api-key</code>, or the authenticated user lacks permission.</p>\n</li>\n<li><p><strong>404 Not Found:</strong> No discount code exists with the provided <code>discountCodeId</code>.</p>\n</li>\n<li><p><strong>409 Conflict:</strong> The provided <code>code</code> value conflicts with another existing discount code.</p>\n</li>\n<li><p><strong>500 Internal Server Error:</strong> An unexpected error occurred on the server.</p>\n</li>\n</ul>\n","urlObject":{"path":["discount-codes","percentage",":discountCodeId"],"host":["{{base_url}}"],"query":[],"variable":[{"description":{"content":"<p>The ID of the discount code to update</p>\n","type":"text/plain"},"type":"any","value":"17215d29-ddec-4b68-bb13-5065e5737ced","key":"discountCodeId"}]}},"response":[{"id":"0854b13f-857c-4bb0-8524-b35c854b56e3","name":"Success - Update Percentage Discount","originalRequest":{"method":"PUT","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"},{"key":"x-postman-example-name","value":"Success - Update Percentage Discount","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-DESCONTO-28\",\n    \"label\": \"10% de desconto - UPDATED\",\n    \"description\": \"10% de desconto - UPDATED\",\n    \"enabled\": false,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"productType\": \"NON_RECURRING\"\n    },\n    \"calculation\": {\n        \"method\": \"DISCOUNT\",\n        \"amountByProductType\": {\n            \"NON_RECURRING\": 10,\n            \"RECURRING\": 0\n        }\n    }\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{base_url}}/discount-codes/percentage/:discountCodeId","host":["{{base_url}}"],"path":["discount-codes","percentage",":discountCodeId"],"variable":[{"key":"discountCodeId","value":"17215d29-ddec-4b68-bb13-5065e5737ced","description":"The ID of the discount code to update"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"531"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Thu, 03 Apr 2025 17:57:19 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eecbff-74f7e3a641eca86f2d00c2a9"},{"key":"x-amzn-RequestId","value":"536ddd55-3e65-40c2-ab46-fdf5c6b21a4d"},{"key":"x-amz-apigw-id","value":"IdTP_EwdoAMEbTA="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 1767c5e57b795f0eb82d3c7e5f8825e8.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"gCe1-6xUqOhOYAZHSWEJ4fY9bMIxrzniGyCaGDvaeVDaJ_qIqMByGg=="}],"cookie":[],"responseTime":null,"body":"{\n    \"_id\": \"17215d29-ddec-4b68-bb13-5065e5737ced\",\n    \"code\": \"CUPOM-EXEMPLO-DESCONTO-28\",\n    \"label\": \"10% de desconto - UPDATED\",\n    \"description\": \"10% de desconto - UPDATED\",\n    \"enabled\": false,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"recurrenceCycleLimit\": null,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"productType\": \"NON_RECURRING\"\n    },\n    \"calculation\": {\n        \"method\": \"DISCOUNT\",\n        \"amountByProductType\": {\n            \"RECURRING\": 0,\n            \"NON_RECURRING\": 10\n        }\n    },\n    \"transactions\": null\n}"}],"_postman_id":"89bfce1c-0f22-4a7b-95ea-485f765a6e8d"},{"name":"Update Flat Discount","event":[{"listen":"test","script":{"exec":["// --- Test Script for PUT /discount-codes/flat ---\r","\r","// Attempt to parse JSON response\r","let jsonData;\r","let isJson = false;\r","try {\r","    jsonData = pm.response.json();\r","    isJson = true;\r","} catch (e) {\r","    console.error('PUT /discount-codes/flat: Failed to parse JSON response.');\r","}\r","\r","// Get Status Code and Example Name\r","const statusCode = pm.response.code;\r","const requestName = pm.request.headers.get('x-postman-example-name') || 'Root Request';\r","\r","// Determine expected outcome from Example Name\r","const expectsSuccess = requestName.toLowerCase().includes('success') || requestName == 'Root Request';\r","const expects400 = requestName.toLowerCase().includes('400');\r","const expects403 = requestName.toLowerCase().includes('403') || requestName.toLowerCase().includes('missing api key');\r","const expects500 = requestName.toLowerCase().includes('500') || requestName.toLowerCase().includes('server error');\r","\r","// Specific Bad Request checks for this \r","const expectMissingAuth = requestName.toLowerCase().includes('missing auth');\r","const expectsInvalidAmount = requestName.toLowerCase().includes('invalid amount');\r","const expectsMissingField = requestName.toLowerCase().includes('missing required field');\r","\r","// --- Shared Checks ---\r","// Ensure response is JSON unless it's an expected non-JSON 403\r","if (!isJson && !expects403) {\r","     pm.test(`[${requestName}] Response should be valid JSON`, () => {\r","         if (statusCode !== 403) { // Only fail if not an expected non-JSON 403\r","            pm.expect.fail('Response was not valid JSON.');\r","         } else {\r","             console.log(\"Skipping JSON check for expected 403 Forbidden response.\");\r","         }\r","     });\r","}\r","\r","// --- Success Case (200 OK) ---\r","if (expectsSuccess) {\r","    pm.test(`[${requestName}] Status code should be 200 OK`, () => {\r","        pm.expect(statusCode).to.equal(200);\r","    });\r","\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body should not contain 'errors' property`, () => {\r","            pm.expect(jsonData.errors).to.be.undefined;\r","        });\r","\r","        pm.test(`[${requestName}] Response body has core discount structure (_id, code, calculation)`, () => {\r","            pm.expect(jsonData).to.be.an('object');\r","            pm.expect(jsonData).to.have.property('_id').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('code').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('label');\r","            pm.expect(jsonData).to.have.property('enabled').that.is.a('boolean');\r","            pm.expect(jsonData).to.have.property('calculation').that.is.an('object');\r","            pm.expect(jsonData).to.have.property('conditions').that.is.an('object');\r","        });\r","\r","        pm.test(`[${requestName}] Calculation object has correct structure for Flat Discount`, () => {\r","            pm.expect(jsonData.calculation).to.have.property('method').that.equals('CREDIT_OFF_FLAT');\r","            pm.expect(jsonData.calculation).to.have.property('amount').that.is.a('number');\r","        });\r","\r","    } else if (!isJson && statusCode === 200) {\r","         pm.test(`[${requestName}] Should have received JSON for success`, () => pm.expect.fail('Expected JSON body for 200 OK.'));\r","    }\r","}\r","\r","// --- Error Cases ---\r","\r","// Error 400 Bad Request (covers general 400, invalid amount, missing field)\r","if (expects400 || expectMissingAuth || expectsInvalidAmount || expectsMissingField) {\r","    const expectedStatus = 400;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Bad Request`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body should contain 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","        });\r","        \r","        if (jsonData.errors && jsonData.errors.length > 0) {\r","             pm.test(`[${requestName}] First error has 'message'`, () => {\r","                 const firstError = jsonData.errors[0];\r","                 pm.expect(firstError).to.have.property('message').that.is.a('string');\r","             });\r","\r","             if (expectMissingAuth) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"Unauthorized - No authenticated user\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.equal(expectedMessage);\r","                });\r","             }\r","\r","             if (expectsInvalidAmount) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"must be a positive number\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","\r","             if (expectsMissingField) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"is required\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","        }\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should have received JSON for ${expectedStatus}`, () => pm.expect.fail(`Expected JSON body for ${expectedStatus} error.`));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 403 Forbidden\r","if (expects403) {\r","    const expectedStatus = 403;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Forbidden`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    // Check for standard \"Forbidden\" message (can be JSON or plain text)\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body contains 'message: Forbidden'`, () => {\r","             pm.expect(jsonData.message).to.equal(\"Forbidden\");\r","        });\r","    } else if (!isJson && statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Body text contains 'Forbidden'`, () => {\r","            pm.expect(pm.response.text()).to.include(\"Forbidden\");\r","        });\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should contain 'Forbidden' message`, () => pm.expect.fail('Expected \"Forbidden\" message in body for 403.'));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 500 Internal Server Error\r","if (expects500) {\r","    const expectedStatus = 500;\r","     pm.test(`[${requestName}] Status code should be ${expectedStatus} Internal Server Error`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","     if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body contains 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","             // Check if message indicates server error, but allow for variations\r","             const firstError = jsonData.errors[0];\r","             pm.expect(firstError.message.toLowerCase()).to.include('internal server error');\r","        });\r","    } // Don't strictly require JSON for 500\r","\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// --- General Check ---\r","// Flag if status code doesn't match any expected pattern for this endpoint\r","if (!expectsSuccess && !expects400 && !expects403 && !expects500 &&\r","    !expectMissingAuth && !expectsInvalidAmount && !expectsMissingField) {\r","    pm.test(`[${requestName}] Received UNEXPECTED status code: ${statusCode}`, () => {\r","        // This test will fail if the status code wasn't one of the expected ones\r","        pm.expect.fail(`Received unexpected status code ${statusCode}. Check Example Name or API response.`);\r","    });\r","}"],"type":"text/javascript","packages":{},"id":"eb3c90ff-2d55-4ba8-b617-dd24581e7ab6"}}],"id":"5270c41e-1108-469b-82b9-c5c23d062473","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"PUT","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-00\",\n    \"label\": \"30 reais de desconto - UPDATED\",\n    \"description\": \"30 reais de desconto - UPDATED\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"productType\": \"ALL\"\n    },\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_FLAT\",\n        \"amount\": 30\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat/:discountCodeId","description":"<h2 id=\"request\">Request</h2>\n<p><strong>Purpose:</strong> Updates an existing flat amount discount code identified by its ID.</p>\n<p><strong>How to use:</strong> Send a PUT request with the discount code's ID in the URL path, the necessary authentication headers, and the complete updated discount code configuration in the request body. Even if you only want to change one field (e.g., <code>enabled</code>), you must provide the full configuration as defined below.</p>\n<p><strong>Headers Required:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>x-api-key</code></td>\n<td><code>YourApiKey...</code></td>\n<td>Your partner-specific API key.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>Authorization</code></td>\n<td><code>YourToken...</code></td>\n<td>The access token obtained via <code>/auth/signin</code>.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Path Parameters:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>discountCodeId</code></td>\n<td>string</td>\n<td>The opaque ID of the discount code to update.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Request Body:</strong> (<code>application/json</code>)</p>\n<p>The body should contain the full definition of the discount code as you want it to be after the update.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n<th>Required</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>string</td>\n<td>The discount code string. Will be trimmed. Must be unique if changing.</td>\n<td>Yes</td>\n<td><code>\"FLAT25OFF\"</code></td>\n</tr>\n<tr>\n<td><code>label</code></td>\n<td>string</td>\n<td>A short, user-facing label for the discount.</td>\n<td>No</td>\n<td><code>\"R$25 Off\"</code></td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>A more detailed description for internal use.</td>\n<td>No</td>\n<td><code>\"Updated R$25 flat discount\"</code></td>\n</tr>\n<tr>\n<td><code>enabled</code></td>\n<td>boolean</td>\n<td>Whether the discount code is currently active and usable.</td>\n<td>Yes</td>\n<td><code>true</code></td>\n</tr>\n<tr>\n<td><code>calculation</code></td>\n<td>object</td>\n<td>Defines how the discount value is calculated.</td>\n<td>Yes</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>calculation.method</code></td>\n<td>string</td>\n<td><strong>Must be</strong> <strong><code>\"CREDIT_OFF_FLAT\"</code></strong> <strong>for this endpoint.</strong></td>\n<td>Yes</td>\n<td><code>\"CREDIT_OFF_FLAT\"</code></td>\n</tr>\n<tr>\n<td><code>calculation.amount</code></td>\n<td>integer</td>\n<td>The fixed discount amount in <strong>Reais (R$)</strong>. Must be a whole number (integer).</td>\n<td>Yes</td>\n<td><code>25</code></td>\n</tr>\n<tr>\n<td><code>conditions</code></td>\n<td>object</td>\n<td>Sets the conditions under which the discount applies. All are optional and have defaults.</td>\n<td>No</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>conditions.productType</code></td>\n<td>string</td>\n<td>Which product types this applies to (<code>ALL</code>, <code>RECURRING</code>, <code>NON_RECURRING</code>). Defaults to <code>ALL</code>.</td>\n<td>No</td>\n<td><code>\"ALL\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.min</code></td>\n<td>number</td>\n<td>Minimum order subtotal required for the discount. Defaults to 0.</td>\n<td>No</td>\n<td><code>50.0</code></td>\n</tr>\n<tr>\n<td><code>conditions.max</code></td>\n<td>number</td>\n<td>Maximum order subtotal allowed for the discount. Defaults to unlimited.</td>\n<td>No</td>\n<td><code>999999</code></td>\n</tr>\n<tr>\n<td><code>conditions.startDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount becomes active. Defaults to now.</td>\n<td>No</td>\n<td><code>\"2025-01-01T00:00:00Z\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.endDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount expires. Defaults to never.</td>\n<td>No</td>\n<td><code>\"2026-01-01T00:00:00Z\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.redemptionLimit</code></td>\n<td>integer</td>\n<td>Max number of times the code can be used in total. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>1000</code></td>\n</tr>\n<tr>\n<td><code>conditions.accountLimit</code></td>\n<td>integer</td>\n<td>Max number of times a single logged-in user can use the code. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>5</code></td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response\">Response</h2>\n<p><strong>Success (200 OK):</strong><br />Returns the complete, updated <code>Discount</code> object reflecting the changes made. The structure matches the <code>Discount</code> schema defined in the OpenAPI specification and includes fields like <code>_id</code>, <code>code</code>, <code>label</code>, <code>description</code>, <code>enabled</code>, <code>discountMethod</code>, <code>calculation</code>, <code>conditions</code>, and potentially <code>transactions</code> if any exist.</p>\n<p><strong>Errors:</strong></p>\n<ul>\n<li><p><strong>400 Bad Request:</strong> Invalid input format, missing required fields, or invalid values (e.g., non-integer <code>amount</code>).</p>\n</li>\n<li><p><strong>401 Unauthorized:</strong> Missing or invalid <code>Authorization</code> token.</p>\n</li>\n<li><p><strong>403 Forbidden:</strong> Missing or invalid <code>x-api-key</code>, or insufficient permissions.</p>\n</li>\n<li><p><strong>404 Not Found:</strong> No discount code exists with the provided <code>discountCodeId</code>.</p>\n</li>\n<li><p><strong>409 Conflict:</strong> The provided <code>code</code> value conflicts with another existing discount code.</p>\n</li>\n<li><p><strong>500 Internal Server Error:</strong> An unexpected server error.</p>\n</li>\n</ul>\n","urlObject":{"path":["discount-codes","flat",":discountCodeId"],"host":["{{base_url}}"],"query":[],"variable":[{"id":"0feade84-1565-4959-824d-cf37ae298641","description":{"content":"<p>The ID of the discount code to update</p>\n","type":"text/plain"},"type":"any","value":"02b15da6-41b9-4bde-88c1-7cfaab5539d9","key":"discountCodeId"}]}},"response":[{"id":"83ce1b55-e1db-4fdb-87a3-52ced7c30493","name":"Success - Update Flat Discount","originalRequest":{"method":"PUT","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"},{"key":"x-postman-example-name","value":"Success - Update Flat Discount","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-00\",\n    \"label\": \"30 reais de desconto - UPDATED\",\n    \"description\": \"30 reais de desconto - UPDATED\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"productType\": \"ALL\"\n    },\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_FLAT\",\n        \"amount\": 30\n    }\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{base_url}}/discount-codes/flat/:discountCodeId","host":["{{base_url}}"],"path":["discount-codes","flat",":discountCodeId"],"variable":[{"key":"discountCodeId","value":"02b15da6-41b9-4bde-88c1-7cfaab5539d9","description":"The ID of the discount code to update"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"496"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Thu, 03 Apr 2025 18:12:36 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eecf94-0406840668638ea4691b3103"},{"key":"x-amzn-RequestId","value":"0902d3f6-f616-4f46-8be1-3bf9219c7f45"},{"key":"x-amz-apigw-id","value":"IdVfTEx_IAMEAYg="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 88b6c1d61a655deb962f2c00127e6658.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P8"},{"key":"X-Amz-Cf-Id","value":"bYTatnqvkMNtrw60FmPb5uzR6ejfeXOvkEQZN2Cx6bo6WiC7JZiARQ=="}],"cookie":[],"responseTime":null,"body":"{\n    \"_id\": \"02b15da6-41b9-4bde-88c1-7cfaab5539d9\",\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-00\",\n    \"label\": \"30 reais de desconto - UPDATED\",\n    \"description\": \"30 reais de desconto - UPDATED\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"recurrenceCycleLimit\": null,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"productType\": \"ALL\"\n    },\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_FLAT\",\n        \"amount\": 30\n    },\n    \"transactions\": null\n}"}],"_postman_id":"5270c41e-1108-469b-82b9-c5c23d062473"},{"name":"Update Flat By Product Type Discount","event":[{"listen":"test","script":{"exec":["// --- Test Script for PUT /discount-codes/flat-by-product-type ---\r","\r","// Attempt to parse JSON response\r","let jsonData;\r","let isJson = false;\r","try {\r","    jsonData = pm.response.json();\r","    isJson = true;\r","} catch (e) {\r","    console.error('PUT /discount-codes/flat-by-product-type: Failed to parse JSON response.');\r","}\r","\r","// Get Status Code and Example Name\r","const statusCode = pm.response.code;\r","const requestName = pm.request.headers.get('x-postman-example-name') || 'Root Request';\r","\r","// Determine expected outcome from Example Name\r","const expectsSuccess = requestName.toLowerCase().includes('success') || requestName == 'Root Request';\r","const expects400 = requestName.toLowerCase().includes('400');\r","const expects403 = requestName.toLowerCase().includes('403') || requestName.toLowerCase().includes('missing api key');\r","const expects500 = requestName.toLowerCase().includes('500') || requestName.toLowerCase().includes('server error');\r","\r","// Specific Bad Request checks for this \r","const expectMissingAuth = requestName.toLowerCase().includes('missing auth');\r","const expectsInvalidAmount = requestName.toLowerCase().includes('invalid amount');\r","const expectsMissingField = requestName.toLowerCase().includes('missing required field');\r","\r","// --- Shared Checks ---\r","// Ensure response is JSON unless it's an expected non-JSON 403\r","if (!isJson && !expects403) {\r","     pm.test(`[${requestName}] Response should be valid JSON`, () => {\r","         if (statusCode !== 403) { // Only fail if not an expected non-JSON 403\r","            pm.expect.fail('Response was not valid JSON.');\r","         } else {\r","             console.log(\"Skipping JSON check for expected 403 Forbidden response.\");\r","         }\r","     });\r","}\r","\r","// --- Success Case (200 OK) ---\r","if (expectsSuccess) {\r","    pm.test(`[${requestName}] Status code should be 200 OK`, () => {\r","        pm.expect(statusCode).to.equal(200);\r","    });\r","\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body should not contain 'errors' property`, () => {\r","            pm.expect(jsonData.errors).to.be.undefined;\r","        });\r","\r","        pm.test(`[${requestName}] Response body has core discount structure (_id, code, calculation)`, () => {\r","            pm.expect(jsonData).to.be.an('object');\r","            pm.expect(jsonData).to.have.property('_id').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('code').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('label');\r","            pm.expect(jsonData).to.have.property('enabled').that.is.a('boolean');\r","            pm.expect(jsonData).to.have.property('calculation').that.is.an('object');\r","            pm.expect(jsonData).to.have.property('conditions').that.is.an('object');\r","        });\r","\r","        pm.test(`[${requestName}] Calculation object has correct structure for Flat by Product Type Discount`, () => {\r","            pm.expect(jsonData.calculation).to.have.property('method').that.equals('CREDIT_OFF_BY_PRODUCT_TYPE');\r","            pm.expect(jsonData.calculation).to.have.property('amountByProductType').that.is.an('object');\r","            pm.expect(jsonData.calculation.amountByProductType).to.have.property('NON_RECURRING').that.is.a('number');\r","             pm.expect(jsonData.calculation.amountByProductType).to.have.property('RECURRING').that.is.a('number');\r","        });\r","\r","        pm.test(`[${requestName}] Conditions object has correct structure for Flat by Product Type Discount`, () => {\r","            pm.expect(jsonData.conditions).to.have.property('productType').that.equals('ALL');\r","        });\r","\r","    } else if (!isJson && statusCode === 200) {\r","         pm.test(`[${requestName}] Should have received JSON for success`, () => pm.expect.fail('Expected JSON body for 200 OK.'));\r","    }\r","}\r","\r","// --- Error Cases ---\r","\r","// Error 400 Bad Request (covers general 400, invalid amount, missing field)\r","if (expects400 || expectMissingAuth || expectsInvalidAmount || expectsMissingField) {\r","    const expectedStatus = 400;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Bad Request`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body should contain 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","        });\r","        \r","        if (jsonData.errors && jsonData.errors.length > 0) {\r","             pm.test(`[${requestName}] First error has 'message'`, () => {\r","                 const firstError = jsonData.errors[0];\r","                 pm.expect(firstError).to.have.property('message').that.is.a('string');\r","             });\r","\r","             if (expectMissingAuth) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"Unauthorized - No authenticated user\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.equal(expectedMessage);\r","                });\r","             }\r","\r","             if (expectsInvalidAmount) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"must be a positive number\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","\r","             if (expectsMissingField) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"is required\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","        }\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should have received JSON for ${expectedStatus}`, () => pm.expect.fail(`Expected JSON body for ${expectedStatus} error.`));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 403 Forbidden\r","if (expects403) {\r","    const expectedStatus = 403;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Forbidden`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    // Check for standard \"Forbidden\" message (can be JSON or plain text)\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body contains 'message: Forbidden'`, () => {\r","             pm.expect(jsonData.message).to.equal(\"Forbidden\");\r","        });\r","    } else if (!isJson && statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Body text contains 'Forbidden'`, () => {\r","            pm.expect(pm.response.text()).to.include(\"Forbidden\");\r","        });\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should contain 'Forbidden' message`, () => pm.expect.fail('Expected \"Forbidden\" message in body for 403.'));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 500 Internal Server Error\r","if (expects500) {\r","    const expectedStatus = 500;\r","     pm.test(`[${requestName}] Status code should be ${expectedStatus} Internal Server Error`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","     if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body contains 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","             // Check if message indicates server error, but allow for variations\r","             const firstError = jsonData.errors[0];\r","             pm.expect(firstError.message.toLowerCase()).to.include('internal server error');\r","        });\r","    } // Don't strictly require JSON for 500\r","\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// --- General Check ---\r","// Flag if status code doesn't match any expected pattern for this endpoint\r","if (!expectsSuccess && !expects400 && !expects403 && !expects500 &&\r","    !expectMissingAuth && !expectsInvalidAmount && !expectsMissingField) {\r","    pm.test(`[${requestName}] Received UNEXPECTED status code: ${statusCode}`, () => {\r","        // This test will fail if the status code wasn't one of the expected ones\r","        pm.expect.fail(`Received unexpected status code ${statusCode}. Check Example Name or API response.`);\r","    });\r","}"],"type":"text/javascript","packages":{},"id":"88b332ed-fbe2-4677-90f5-075baa2bdc99"}}],"id":"4b5f0b3a-3e52-438b-8124-43c60eddbbbf","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"PUT","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-12\",\n    \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes) - UPDATED\",\n    \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes) - UPDATED\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"productType\": \"ALL\"\n    },\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n        \"amountByProductType\": {\n            \"NON_RECURRING\": 30,\n            \"RECURRING\": 45\n        }\n    }\n}\n","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/flat-by-product-type/:discountCodeId","description":"<h2 id=\"request\">Request</h2>\n<p><strong>Purpose:</strong> Updates an existing discount code that applies different flat amounts based on product type (recurring vs. non-recurring).</p>\n<p><strong>How to use:</strong> Send a PUT request with the discount code's ID in the URL path, the necessary authentication headers, and the complete updated discount code configuration in the request body. Even if you only want to change one field (e.g., <code>enabled</code>), you must provide the full configuration as defined below.</p>\n<p><strong>Headers Required:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>x-api-key</code></td>\n<td><code>YourApiKey...</code></td>\n<td>Your partner-specific API key.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>Authorization</code></td>\n<td><code>YourToken...</code></td>\n<td>The access token obtained via <code>/auth/signin</code>.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Path Parameters:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>discountCodeId</code></td>\n<td>string</td>\n<td>The opaque ID of the discount code to update.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Request Body:</strong> (<code>application/json</code>)</p>\n<p>The body should contain the full definition of the discount code as you want it to be after the update.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n<th>Required</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>string</td>\n<td>The discount code string. Will be trimmed. Must be unique if changing.</td>\n<td>Yes</td>\n<td><code>\"FLATBYTYPE\"</code></td>\n</tr>\n<tr>\n<td><code>label</code></td>\n<td>string</td>\n<td>A short, user-facing label for the discount.</td>\n<td>No</td>\n<td><code>\"R$10 Non-Rec / R$20 Rec\"</code></td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>A more detailed description for internal use.</td>\n<td>No</td>\n<td><code>\"Updated R$10 off non-recurring, R$20 off recurring\"</code></td>\n</tr>\n<tr>\n<td><code>enabled</code></td>\n<td>boolean</td>\n<td>Whether the discount code is currently active and usable.</td>\n<td>Yes</td>\n<td><code>true</code></td>\n</tr>\n<tr>\n<td><code>calculation</code></td>\n<td>object</td>\n<td>Defines how the discount value is calculated.</td>\n<td>Yes</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>calculation.method</code></td>\n<td>string</td>\n<td><strong>Must be</strong> <strong><code>\"CREDIT_OFF_BY_PRODUCT_TYPE\"</code></strong> <strong>for this endpoint.</strong></td>\n<td>Yes</td>\n<td><code>\"CREDIT_OFF_BY_PRODUCT_TYPE\"</code></td>\n</tr>\n<tr>\n<td><code>calculation.amountByProductType</code></td>\n<td>object</td>\n<td>Specifies the flat discount amount in <strong>Reais (R$)</strong> for different product types.</td>\n<td>Yes</td>\n<td><code>{\"NON_RECURRING\": 10, \"RECURRING\": 20}</code></td>\n</tr>\n<tr>\n<td><code>calculation.amountByProductType.NON_RECURRING</code></td>\n<td>integer</td>\n<td>Fixed discount (R$) for non-recurring products. Must be a whole number.</td>\n<td>Yes</td>\n<td><code>10</code></td>\n</tr>\n<tr>\n<td><code>calculation.amountByProductType.RECURRING</code></td>\n<td>integer</td>\n<td>Fixed discount (R$) for recurring products. Must be a whole number.</td>\n<td>Yes</td>\n<td><code>20</code></td>\n</tr>\n<tr>\n<td><code>conditions</code></td>\n<td>object</td>\n<td>Sets the conditions under which the discount applies. All are optional and have defaults.</td>\n<td>No</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>conditions.productType</code></td>\n<td>string</td>\n<td>Which product types this applies to (<code>ALL</code>, <code>RECURRING</code>, <code>NON_RECURRING</code>). Defaults to <code>ALL</code>.</td>\n<td>No</td>\n<td><code>\"ALL\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.min</code></td>\n<td>number</td>\n<td>Minimum order subtotal required for the discount. Defaults to 0.</td>\n<td>No</td>\n<td><code>30.0</code></td>\n</tr>\n<tr>\n<td><code>conditions.max</code></td>\n<td>number</td>\n<td>Maximum order subtotal allowed for the discount. Defaults to unlimited.</td>\n<td>No</td>\n<td><code>999999</code></td>\n</tr>\n<tr>\n<td><code>conditions.startDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount becomes active. Defaults to now.</td>\n<td>No</td>\n<td><code>\"2025-01-01T00:00:00Z\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.endDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount expires. Defaults to never.</td>\n<td>No</td>\n<td><code>\"2026-01-01T00:00:00Z\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.redemptionLimit</code></td>\n<td>integer</td>\n<td>Max number of times the code can be used in total. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>1000</code></td>\n</tr>\n<tr>\n<td><code>conditions.accountLimit</code></td>\n<td>integer</td>\n<td>Max number of times a single logged-in user can use the code. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>5</code></td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response\">Response</h2>\n<p><strong>Success (200 OK):</strong><br />Returns the complete, updated <code>Discount</code> object reflecting the changes made. The structure matches the <code>Discount</code> schema defined in the OpenAPI specification and includes fields like <code>_id</code>, <code>code</code>, <code>label</code>, <code>description</code>, <code>enabled</code>, <code>discountMethod</code>, <code>calculation</code>, <code>conditions</code>, and potentially <code>transactions</code> if any exist.</p>\n<p><strong>Errors:</strong></p>\n<ul>\n<li><p><strong>400 Bad Request:</strong> Invalid input format, missing required fields, or invalid values (e.g., non-integer amounts).</p>\n</li>\n<li><p><strong>401 Unauthorized:</strong> Missing or invalid <code>Authorization</code> token.</p>\n</li>\n<li><p><strong>403 Forbidden:</strong> Missing or invalid <code>x-api-key</code>, or insufficient permissions.</p>\n</li>\n<li><p><strong>404 Not Found:</strong> No discount code exists with the provided <code>discountCodeId</code>.</p>\n</li>\n<li><p><strong>409 Conflict:</strong> The provided <code>code</code> value conflicts with another existing discount code.</p>\n</li>\n<li><p><strong>500 Internal Server Error:</strong> An unexpected server error.</p>\n</li>\n</ul>\n","urlObject":{"path":["discount-codes","flat-by-product-type",":discountCodeId"],"host":["{{base_url}}"],"query":[],"variable":[{"id":"b853054e-4b70-47fb-abb2-16d9e197a714","description":{"content":"<p>The ID of the discount code to update</p>\n","type":"text/plain"},"type":"any","value":"16aafa29-2959-44ed-a6a3-4550f8619fc5","key":"discountCodeId"}]}},"response":[{"id":"abc58f97-bed2-43f8-bd7b-1c9023fc1855","name":"Success - Update Flat By Product Type Discount","originalRequest":{"method":"PUT","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"},{"key":"x-postman-example-name","value":"Success - Update Flat By Product Type Discount","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-12\",\n    \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes) - UPDATED\",\n    \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes) - UPDATED\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"productType\": \"ALL\"\n    },\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n        \"amountByProductType\": {\n            \"NON_RECURRING\": 30,\n            \"RECURRING\": 45\n        }\n    }\n}\n","options":{"raw":{"language":"json"}}},"url":{"raw":"{{base_url}}/discount-codes/flat-by-product-type/:discountCodeId","host":["{{base_url}}"],"path":["discount-codes","flat-by-product-type",":discountCodeId"],"variable":[{"key":"discountCodeId","value":"16aafa29-2959-44ed-a6a3-4550f8619fc5","description":"The ID of the discount code to update"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"721"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Thu, 03 Apr 2025 18:24:21 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eed255-6ceeacfa5415edc75e540fb1"},{"key":"x-amzn-RequestId","value":"1020bea1-465e-4278-a612-e30ef77c78a8"},{"key":"x-amz-apigw-id","value":"IdXNcH5ToAMEtAA="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 7a33279947fc31cb4cb938b28ff6d688.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GIG51-P3"},{"key":"X-Amz-Cf-Id","value":"lxvFk-QMJHA-5556bzRUYWnGGy1MTqh2sXNbnldfB97bovDA5Vvm4Q=="}],"cookie":[],"responseTime":null,"body":"{\n    \"_id\": \"16aafa29-2959-44ed-a6a3-4550f8619fc5\",\n    \"code\": \"CUPOM-EXEMPLO-VALOR-FIXO-POR-TIPO-DE-PRODUTO-12\",\n    \"label\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes) - UPDATED\",\n    \"description\": \"30 reais de desconto (produtos não-recorrentes) - 45 reais de desconto (produtos recorrentes) - UPDATED\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"recurrenceCycleLimit\": null,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 100,\n        \"max\": 999999,\n        \"productType\": \"ALL\"\n    },\n    \"calculation\": {\n        \"method\": \"CREDIT_OFF_BY_PRODUCT_TYPE\",\n        \"amountByProductType\": {\n            \"RECURRING\": 45,\n            \"NON_RECURRING\": 30\n        }\n    },\n    \"transactions\": null\n}"}],"_postman_id":"4b5f0b3a-3e52-438b-8124-43c60eddbbbf"},{"name":"Update Shipping Discount","event":[{"listen":"test","script":{"exec":["// --- Test Script for PUT /discount-codes/shipping ---\r","\r","// Attempt to parse JSON response\r","let jsonData;\r","let isJson = false;\r","try {\r","    jsonData = pm.response.json();\r","    isJson = true;\r","} catch (e) {\r","    console.error('PUT /discount-codes/shipping: Failed to parse JSON response.');\r","}\r","\r","// Get Status Code and Example Name\r","const statusCode = pm.response.code;\r","const requestName = pm.request.headers.get('x-postman-example-name') || 'Root Request';\r","\r","// Determine expected outcome from Example Name\r","const expectsSuccess = requestName.toLowerCase().includes('success') || requestName == 'Root Request';\r","const expects400 = requestName.toLowerCase().includes('400');\r","const expects403 = requestName.toLowerCase().includes('403') || requestName.toLowerCase().includes('missing api key');\r","const expects500 = requestName.toLowerCase().includes('500') || requestName.toLowerCase().includes('server error');\r","\r","// Specific Bad Request checks for this \r","const expectMissingAuth = requestName.toLowerCase().includes('missing auth');\r","const expectsInvalidAmount = requestName.toLowerCase().includes('invalid amount');\r","const expectsMissingField = requestName.toLowerCase().includes('missing required field');\r","\r","// --- Shared Checks ---\r","// Ensure response is JSON unless it's an expected non-JSON 403\r","if (!isJson && !expects403) {\r","     pm.test(`[${requestName}] Response should be valid JSON`, () => {\r","         if (statusCode !== 403) { // Only fail if not an expected non-JSON 403\r","            pm.expect.fail('Response was not valid JSON.');\r","         } else {\r","             console.log(\"Skipping JSON check for expected 403 Forbidden response.\");\r","         }\r","     });\r","}\r","\r","// --- Success Case (200 OK) ---\r","if (expectsSuccess) {\r","    pm.test(`[${requestName}] Status code should be 200 OK`, () => {\r","        pm.expect(statusCode).to.equal(200);\r","    });\r","\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body should not contain 'errors' property`, () => {\r","            pm.expect(jsonData.errors).to.be.undefined;\r","        });\r","\r","        pm.test(`[${requestName}] Response body has core discount structure`, () => {\r","            pm.expect(jsonData).to.be.an('object');\r","            pm.expect(jsonData).to.have.property('_id').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('code').that.is.a('string');\r","            pm.expect(jsonData).to.have.property('label');\r","            pm.expect(jsonData).to.have.property('enabled').that.is.a('boolean');\r","            pm.expect(jsonData).to.have.property('calculation').that.is.an('object');\r","            pm.expect(jsonData).to.have.property('conditions').that.is.an('object');\r","        });\r","\r","        pm.test(`[${requestName}] Calculation object has correct structure for Shipping Discount`, () => {\r","            pm.expect(jsonData.calculation).to.have.property('method').that.equals('SHIPPING');\r","            pm.expect(jsonData.calculation).to.have.property('fulfillmentOptionNames').that.is.an('array');\r","            pm.expect(jsonData.calculation).to.have.property('fulfillmentOptionNames').have.length.greaterThan(0);\r","        });\r","\r","    } else if (!isJson && statusCode === 200) {\r","         pm.test(`[${requestName}] Should have received JSON for success`, () => pm.expect.fail('Expected JSON body for 200 OK.'));\r","    }\r","}\r","\r","// --- Error Cases ---\r","\r","// Error 400 Bad Request (covers general 400, invalid amount, missing field)\r","if (expects400 || expectMissingAuth || expectsInvalidAmount || expectsMissingField) {\r","    const expectedStatus = 400;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Bad Request`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body should contain 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","        });\r","        \r","        if (jsonData.errors && jsonData.errors.length > 0) {\r","             pm.test(`[${requestName}] First error has 'message'`, () => {\r","                 const firstError = jsonData.errors[0];\r","                 pm.expect(firstError).to.have.property('message').that.is.a('string');\r","             });\r","\r","             if (expectMissingAuth) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"Unauthorized - No authenticated user\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.equal(expectedMessage);\r","                });\r","             }\r","\r","             if (expectsInvalidAmount) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"must be a positive number\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","\r","             if (expectsMissingField) {\r","                pm.test(`[${requestName}] First error has correct value for 'message'`, () => {\r","                    expectedMessage = \"was not provided\";\r","                    const firstError = jsonData.errors[0];\r","                    pm.expect(firstError).to.have.property('message').that.is.a('string');\r","                    pm.expect(firstError).to.have.property('message').to.contain(expectedMessage);\r","                });\r","             }\r","        }\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should have received JSON for ${expectedStatus}`, () => pm.expect.fail(`Expected JSON body for ${expectedStatus} error.`));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 403 Forbidden\r","if (expects403) {\r","    const expectedStatus = 403;\r","    pm.test(`[${requestName}] Status code should be ${expectedStatus} Forbidden`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","    // Check for standard \"Forbidden\" message (can be JSON or plain text)\r","    if (isJson && jsonData) {\r","        pm.test(`[${requestName}] Body contains 'message: Forbidden'`, () => {\r","             pm.expect(jsonData.message).to.equal(\"Forbidden\");\r","        });\r","    } else if (!isJson && statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Body text contains 'Forbidden'`, () => {\r","            pm.expect(pm.response.text()).to.include(\"Forbidden\");\r","        });\r","    } else if (statusCode === expectedStatus) {\r","         pm.test(`[${requestName}] Should contain 'Forbidden' message`, () => pm.expect.fail('Expected \"Forbidden\" message in body for 403.'));\r","    }\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// Error 500 Internal Server Error\r","if (expects500) {\r","    const expectedStatus = 500;\r","     pm.test(`[${requestName}] Status code should be ${expectedStatus} Internal Server Error`, () => {\r","        pm.expect(statusCode).to.equal(expectedStatus);\r","    });\r","\r","     if (isJson && jsonData) {\r","         pm.test(`[${requestName}] Body contains 'errors' array`, () => {\r","            pm.expect(jsonData.errors).to.be.an('array').and.to.not.be.empty;\r","             // Check if message indicates server error, but allow for variations\r","             const firstError = jsonData.errors[0];\r","             pm.expect(firstError.message.toLowerCase()).to.include('internal server error');\r","        });\r","    } // Don't strictly require JSON for 500\r","\r","     pm.test(`[${requestName}] Status code should NOT be 200 OK`, () => {\r","        pm.expect(statusCode).to.not.equal(200);\r","    });\r","}\r","\r","// --- General Check ---\r","// Flag if status code doesn't match any expected pattern for this endpoint\r","if (!expectsSuccess && !expects400 && !expects403 && !expects500 &&\r","    !expectMissingAuth && !expectsInvalidAmount && !expectsMissingField) {\r","    pm.test(`[${requestName}] Received UNEXPECTED status code: ${statusCode}`, () => {\r","        // This test will fail if the status code wasn't one of the expected ones\r","        pm.expect.fail(`Received unexpected status code ${statusCode}. Check Example Name or API response.`);\r","    });\r","}"],"type":"text/javascript","packages":{},"id":"f91bcaf4-bb69-4162-98d1-6ba66f9b73b7"}}],"id":"83f22e2c-805f-4630-9f78-f057598bfe81","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"PUT","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS-7\",\n    \"label\": \"Frete grátis - UPDATED\",\n    \"description\": \"Frete grátis - UPDATED\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"productType\": \"NON_RECURRING\"\n    },\n    \"calculation\": {\n        \"method\": \"SHIPPING\",\n        \"fulfillmentOptionNames\": [\n            \"Correios Sedex\",\n            \"PAC Sedex\"\n        ]\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/discount-codes/shipping/:discountCodeId","description":"<h2 id=\"request\">Request</h2>\n<p><strong>Purpose:</strong> Updates an existing free shipping discount code identified by its ID.</p>\n<p><strong>How to use:</strong> Send a PUT request with the discount code's ID in the URL path, the necessary authentication headers, and the complete updated discount code configuration in the request body. Even if you only want to change one field (e.g., <code>enabled</code>), you must provide the full configuration as defined below.</p>\n<p><strong>Headers Required:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Example</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>x-api-key</code></td>\n<td><code>YourApiKey...</code></td>\n<td>Your partner-specific API key.</td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>Authorization</code></td>\n<td><code>YourToken...</code></td>\n<td>The access token obtained via <code>/auth/signin</code>.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Path Parameters:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Description</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>discountCodeId</code></td>\n<td>string</td>\n<td>The opaque ID of the discount code to update.</td>\n<td>Yes</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Request Body:</strong> (<code>application/json</code>)</p>\n<p>The body should contain the full definition of the discount code as you want it to be after the update.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n<th>Required</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>string</td>\n<td>The discount code string. Will be trimmed. Must be unique if changing.</td>\n<td>Yes</td>\n<td><code>\"FREESHIPNOW\"</code></td>\n</tr>\n<tr>\n<td><code>label</code></td>\n<td>string</td>\n<td>A short, user-facing label for the discount.</td>\n<td>No</td>\n<td><code>\"Free Shipping (Updated)\"</code></td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>string</td>\n<td>A more detailed description for internal use.</td>\n<td>No</td>\n<td><code>\"Updated free shipping for Sedex only\"</code></td>\n</tr>\n<tr>\n<td><code>enabled</code></td>\n<td>boolean</td>\n<td>Whether the discount code is currently active and usable.</td>\n<td>Yes</td>\n<td><code>true</code></td>\n</tr>\n<tr>\n<td><code>calculation</code></td>\n<td>object</td>\n<td>Defines how the discount value is calculated.</td>\n<td>Yes</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>calculation.method</code></td>\n<td>string</td>\n<td><strong>Must be</strong> <strong><code>\"SHIPPING\"</code></strong> <strong>for this endpoint.</strong></td>\n<td>Yes</td>\n<td><code>\"SHIPPING\"</code></td>\n</tr>\n<tr>\n<td><code>calculation.fulfillmentOptionNames</code></td>\n<td>array[string]</td>\n<td>List of exact fulfillment option names that will receive free shipping. Must contain at least one name.</td>\n<td>Yes</td>\n<td><code>[\"Correios Sedex\"]</code></td>\n</tr>\n<tr>\n<td><code>conditions</code></td>\n<td>object</td>\n<td>Sets the conditions under which the discount applies. All are optional and have defaults.</td>\n<td>No</td>\n<td><em>(See below)</em></td>\n</tr>\n<tr>\n<td><code>conditions.productType</code></td>\n<td>string</td>\n<td>Which product types this applies to (<code>ALL</code>, <code>RECURRING</code>, <code>NON_RECURRING</code>). Defaults to <code>ALL</code>.</td>\n<td>No</td>\n<td><code>\"ALL\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.min</code></td>\n<td>number</td>\n<td>Minimum order subtotal required for the discount. Defaults to 0.</td>\n<td>No</td>\n<td><code>100.0</code></td>\n</tr>\n<tr>\n<td><code>conditions.max</code></td>\n<td>number</td>\n<td>Maximum order subtotal allowed for the discount. Defaults to unlimited.</td>\n<td>No</td>\n<td><code>999999</code></td>\n</tr>\n<tr>\n<td><code>conditions.startDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount becomes active. Defaults to now.</td>\n<td>No</td>\n<td><code>\"2025-01-01T00:00:00Z\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.endDate</code></td>\n<td>string (ISO 8601)</td>\n<td>Date/time when the discount expires. Defaults to never.</td>\n<td>No</td>\n<td><code>\"2026-01-01T00:00:00Z\"</code></td>\n</tr>\n<tr>\n<td><code>conditions.redemptionLimit</code></td>\n<td>integer</td>\n<td>Max number of times the code can be used in total. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>1000</code></td>\n</tr>\n<tr>\n<td><code>conditions.accountLimit</code></td>\n<td>integer</td>\n<td>Max number of times a single logged-in user can use the code. Defaults to unlimited (999999).</td>\n<td>No</td>\n<td><code>5</code></td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response\">Response</h2>\n<p><strong>Success (200 OK):</strong><br />Returns the complete, updated <code>Discount</code> object reflecting the changes made. The structure matches the <code>Discount</code> schema defined in the OpenAPI specification and includes fields like <code>_id</code>, <code>code</code>, <code>label</code>, <code>description</code>, <code>enabled</code>, <code>discountMethod</code>, <code>calculation</code>, <code>conditions</code>, and potentially <code>transactions</code> if any exist.</p>\n<p><strong>Errors:</strong></p>\n<ul>\n<li><p><strong>400 Bad Request:</strong> Invalid input format, missing required fields, or invalid values (e.g., empty <code>fulfillmentOptionNames</code> array).</p>\n</li>\n<li><p><strong>401 Unauthorized:</strong> Missing or invalid <code>Authorization</code> token.</p>\n</li>\n<li><p><strong>403 Forbidden:</strong> Missing or invalid <code>x-api-key</code>, or insufficient permissions.</p>\n</li>\n<li><p><strong>404 Not Found:</strong> No discount code exists with the provided <code>discountCodeId</code>.</p>\n</li>\n<li><p><strong>409 Conflict:</strong> The provided <code>code</code> value conflicts with another existing discount code.</p>\n</li>\n<li><p><strong>500 Internal Server Error:</strong> An unexpected server error.</p>\n</li>\n</ul>\n","urlObject":{"path":["discount-codes","shipping",":discountCodeId"],"host":["{{base_url}}"],"query":[],"variable":[{"id":"b11cc433-522d-45f6-89b3-1714a4f22fc3","description":{"content":"<p>The ID of the discount code to update</p>\n","type":"text/plain"},"type":"any","value":"03ac4c5e-30c8-42b4-8250-1c06d7c4fd00","key":"discountCodeId"}]}},"response":[{"id":"0e649cb9-11ce-4945-8665-b37825adb711","name":"Success - Update Shipping Discount","originalRequest":{"method":"PUT","header":[{"key":"x-api-key","value":"{{api-key}}","type":"text"},{"key":"Authorization","value":"","type":"text"},{"key":"x-postman-example-name","value":"Success - Update Shipping Discount","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS-7\",\n    \"label\": \"Frete grátis - UPDATED\",\n    \"description\": \"Frete grátis - UPDATED\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"productType\": \"NON_RECURRING\"\n    },\n    \"calculation\": {\n        \"method\": \"SHIPPING\",\n        \"fulfillmentOptionNames\": [\n            \"Correios Sedex\",\n            \"PAC Sedex\"\n        ]\n    }\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{base_url}}/discount-codes/shipping/:discountCodeId","host":["{{base_url}}"],"path":["discount-codes","shipping",":discountCodeId"],"variable":[{"key":"discountCodeId","value":"03ac4c5e-30c8-42b4-8250-1c06d7c4fd00","description":"The ID of the discount code to update"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"},{"key":"Content-Length","value":"528"},{"key":"Connection","value":"keep-alive"},{"key":"Date","value":"Thu, 03 Apr 2025 18:28:29 GMT"},{"key":"X-Amzn-Trace-Id","value":"Root=1-67eed34d-245c3bd01206be7b09f765a9"},{"key":"x-amzn-RequestId","value":"c16a7074-9deb-4c70-92ec-368f696a8b54"},{"key":"x-amz-apigw-id","value":"IdX0NGxtIAMEY_g="},{"key":"X-Cache","value":"Miss from cloudfront"},{"key":"Via","value":"1.1 af58a750672a7cacf1a69ae0c9f3578a.cloudfront.net (CloudFront)"},{"key":"X-Amz-Cf-Pop","value":"GRU3-P7"},{"key":"X-Amz-Cf-Id","value":"RiScWtDw8j_onAaUECbY2s1E19C7y6pDem23UXLVz64ZZvW4OLgQpg=="}],"cookie":[],"responseTime":null,"body":"{\n    \"_id\": \"03ac4c5e-30c8-42b4-8250-1c06d7c4fd00\",\n    \"code\": \"CUPOM-EXEMPLO-FRETE-GRATIS-7\",\n    \"label\": \"Frete grátis - UPDATED\",\n    \"description\": \"Frete grátis - UPDATED\",\n    \"enabled\": true,\n    \"discountMethod\": \"CODE\",\n    \"conditions\": {\n        \"accountLimit\": 999999,\n        \"redemptionLimit\": 999999,\n        \"recurrenceCycleLimit\": null,\n        \"startDate\": \"2025-01-01T03:00:00.000Z\",\n        \"endDate\": \"2035-01-01T03:00:00.000Z\",\n        \"min\": 0,\n        \"max\": 999999,\n        \"productType\": \"NON_RECURRING\"\n    },\n    \"calculation\": {\n        \"method\": \"SHIPPING\",\n        \"fulfillmentOptionNames\": [\n            \"Correios Sedex\",\n            \"PAC Sedex\"\n        ]\n    },\n    \"transactions\": null\n}"}],"_postman_id":"83f22e2c-805f-4630-9f78-f057598bfe81"}],"id":"f6e0091f-6ba6-47fe-94f0-3d3c7ea08830","description":"<h2 id=\"discount-code-types\">Discount Code Types</h2>\n<p>The API supports four types of discount codes:</p>\n<ol>\n<li><p>Percentage-based discount - Applies a percentage discount to the shopping cart.</p>\n</li>\n<li><p>Flat amount discount - Applies a fixed amount discount to the shopping cart regardless of their Product Type. Can be limited to work only with Recurring Items, Not Recurring items or with both.</p>\n</li>\n<li><p>Flat amount by product type - Applies different fixed discounts to both recurring and non-recurring products.</p>\n</li>\n<li><p>Free shipping discount - Makes specific shipping methods free.</p>\n</li>\n</ol>\n<p>Each type has its own endpoint for creation, and all types are returned on the listing endpoint.</p>\n<p>The <code>calculation.method</code> field map each code to one of these types, by using the following pattern:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>DISCOUNT</td>\n<td>Applies a percentage discount to the shopping cart.  <br />  <br />Uses the <code>calculations.amountByProductType</code> structure to apply different percentage discounts to recurring and non-recurring products. The <code>conditions.productType</code> still controls which items the discount can be applied to.</td>\n</tr>\n<tr>\n<td>CREDIT_OFF_FLAT</td>\n<td>Applies a fixed amount discount to the shopping cart.  <br />  <br />The <code>conditions.productType</code> determines whether this discount applies to carts with recurring items, non-recurring items, or both.</td>\n</tr>\n<tr>\n<td>CREDIT_OFF_BY_PRODUCT_TYPE</td>\n<td>Applies different fixed discounts to recurring and non-recurring products.  <br />  <br />The <code>conditions.productType</code> determines whether this discount applies to carts with recurring items, non-recurring items, or both.</td>\n</tr>\n<tr>\n<td>SHIPPING</td>\n<td>Makes specific shipping methods free.  <br />  <br />The <code>conditions.productType</code> determines which types of products must be in the cart for the free shipping to apply.</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"product-type\">Product Type</h2>\n<p>The <code>conditions.productType</code> field is crucial for defining which types of products a discount code can be applied to. This setting determines whether the discount will affect regular products, subscription-based products, or both.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>ALL</td>\n<td>Applies to all products in the cart, including both recurring and non-recurring items.</td>\n</tr>\n<tr>\n<td>RECURRING</td>\n<td>Applies only to subscription/recurring products. These are products that customers receive on a regular schedule and are billed for repeatedly (e.g., monthly subscriptions). The discount will not affect one-time purchases in the same cart.</td>\n</tr>\n<tr>\n<td>NON_RECURRING</td>\n<td>Applies only to regular/non-recurring products. These are standard one-time purchases. The discount will not affect any subscription items in the same cart.</td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"f6e0091f-6ba6-47fe-94f0-3d3c7ea08830"},{"name":"Webhook","item":[],"id":"cacff629-4f81-4bdd-931c-14f7c0da0a66","description":"<h2 id=\"receiving-and-authenticating-webhooks\">Receiving and Authenticating Webhooks</h2>\n<p>Webhook calls will be made via <code>POST</code> and contain the following information in the request body:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>_id</td>\n<td>string</td>\n<td>Unique identifier for this specific webhook call.</td>\n</tr>\n<tr>\n<td>type</td>\n<td>string</td>\n<td>The type of event that triggered this call. If <code>PING</code>, it's a test call.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Data relevant to the event. The structure varies depending on the event type.</td>\n</tr>\n<tr>\n<td>createdAt</td>\n<td>string</td>\n<td>Timestamp (ISO 8601) indicating when the webhook event was created.</td>\n</tr>\n</tbody>\n</table>\n</div><p>Additionally, each call includes a signature header called <code>X-Unbox-Signature</code>. This header contains a hash that proves the request was genuinely made by Unbox.</p>\n<p><strong>Example Call:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-http\">POST /test HTTP/1.1\nHost: your-webhook-endpoint.com\nContent-Type: application/json\nX-Unbox-Signature: 90294d29f6f5543bcd4fcbf512b3ba89456f4a90a2d1c985c42d58f7fdc1ece4\n{\n   \"_id\":\"37bcbd71-14ec-489a-a54d-92b47e583d02\",\n   \"type\":\"PING\",\n   \"data\":{\n      \"ping\":\"ping\"\n   },\n   \"createdAt\":\"2025-03-24T19:29:14.040Z\"\n}\n\n</code></pre>\n<h3 id=\"to-verify-call-authenticity\">To Verify Call Authenticity</h3>\n<p>(For more details, see: <a href=\"https://webhooks.fyi/security/hmac\">https://webhooks.fyi/security/hmac</a>)</p>\n<p>The signature is a Hash-based Message Authentication Code (HMAC), generated using the SHA-256 algorithm. It is composed of the raw request body and the <code>secret</code> key provided when the webhook was subscribed to via the <code>SubscribeToWebhook</code> mutation. If the shop owner loses this secret, it can be retrieved from the <code>WebhookSubscribers</code> collection in the database.</p>\n<p>To verify the authenticity of the <code>X-Unbox-Signature</code> header, you must recreate the hash on your end using the same algorithm, the received request body, and your secret key. Compare your generated hash with the value provided in the <code>X-Unbox-Signature</code> header. If the values match exactly, the request can be considered authentic and secure.</p>\n<p>In the example above, the <code>X-Unbox-Signature</code> value is <code>90294d29f6f5543bcd4fcbf512b3ba89456f4a90a2d1c985c42d58f7fdc1ece4</code>. To arrive at this same value, you would use the secret obtained during subscription (<code>16f32031c2aa9913d1c65ec840367b1d</code> in this example) and the exact string of the request body.</p>\n<p>Then, create an HMAC using the SHA-256 algorithm, with the secret as the key, and encode the result in hexadecimal format.</p>\n<p>Here is an example using Node.js's native <code>crypto</code> library:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">// secret = '16f32031c2aa9913d1c65ec840367b1d'\n// data = '{\"_id\":\"37bcbd71-14ec-489a-a54d-92b47e583d02\",\"type\":\"PING\",\"data\":{\"ping\":\"ping\"},\"createdAt\":\"2025-03-24T19:29:14.040Z\"}'\nimport crypto from \"node:crypto\";\nconst generatedHash = crypto\n    .createHmac(\"sha256\", secret)\n    .update(data, \"utf-8\")\n    .digest(\"hex\");\n// Result should be: 90294d29f6f5543bcd4fcbf512b3ba89456f4a90a2d1c985c42d58f7fdc1ece4\nconsole.log(generatedHash);\n\n</code></pre>\n<p>You can also test this process online using tools like: <a href=\"https://www.devglan.com/online-tools/hmac-sha256-online\">https://www.devglan.com/online-tools/hmac-sha256-online</a></p>\n<h2 id=\"failures-and-retries\">Failures and Retries</h2>\n<p>We consider a webhook delivery to have <strong>failed</strong> when:</p>\n<ol>\n<li><p>We receive any HTTP response status code other than <code>200 OK</code>.</p>\n</li>\n<li><p>We do not receive a response from your endpoint within 30 seconds (timeout).</p>\n</li>\n</ol>\n<p>After an initial failure, Unbox will automatically attempt to redeliver the webhook <strong>three</strong> more times.</p>\n<p>The time between each retry attempt follows an <strong>exponential back-off</strong> strategy. The waiting period increases by a factor of 5 after each failure:</p>\n<ul>\n<li><p><strong>1st Retry:</strong> After 5 seconds</p>\n</li>\n<li><p><strong>2nd Retry:</strong> After 25 seconds (from the 1st retry failure)</p>\n</li>\n<li><p><strong>3rd Retry:</strong> After 125 seconds (from the 2nd retry failure)</p>\n</li>\n</ul>\n<p>If any of the retry attempts receive a <code>200 OK</code> response, the process stops. If all three retry attempts fail, Unbox will make no further delivery attempts for that specific event.</p>\n<h2 id=\"event-types\">Event Types</h2>\n<h3 id=\"order_created\"><code>ORDER_CREATED</code></h3>\n<p>Triggered when a new order is successfully created.</p>\n<h3 id=\"order_status_update\"><code>ORDER_STATUS_UPDATE</code></h3>\n<p>Triggered when an order undergoes any status change after its initial creation. This includes changes to the order status itself and potentially changes to the payment status.</p>\n<hr />\n<p>Both <code>ORDER_CREATED</code> and <code>ORDER_STATUS_UPDATE</code> events share the same payload structure described below:</p>\n<p><strong>Payload (</strong><code>data</code> <strong>object):</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>orderId</td>\n<td>string</td>\n<td>The unique ID of the order.</td>\n</tr>\n<tr>\n<td>shopSlug</td>\n<td>string</td>\n<td>The shop's name slug (used in URLs).</td>\n</tr>\n<tr>\n<td>shopDomain</td>\n<td>string (optional)</td>\n<td>The shop's custom domain, if configured.</td>\n</tr>\n<tr>\n<td>discountLabel*</td>\n<td>string (optional)</td>\n<td>*<b>DEPRECATED</b>  <br />The label displayed for the discount applied to the order.</td>\n</tr>\n<tr>\n<td>discountCode*</td>\n<td>string (optional)</td>\n<td>*<b>DEPRECATED</b>  <br />The code used for the discount, if applicable.</td>\n</tr>\n<tr>\n<td>discountMethod*</td>\n<td><code>DiscountMethodEnum</code></td>\n<td>*<b>DEPRECATED</b>  <br />The method by which the discount was applied (e.g., <code>CODE</code>).</td>\n</tr>\n<tr>\n<td>discounts</td>\n<td><code>OrderDiscountWebhookData</code></td>\n<td>A list of discounts applied to the order</td>\n</tr>\n<tr>\n<td>paymentSummary</td>\n<td><code>OrderPaymentSummaryData</code></td>\n<td>An object containing a summary of the order's payment details.</td>\n</tr>\n<tr>\n<td>paymentStatus</td>\n<td><code>PaymentStatusEnum</code></td>\n<td>The current status of the order's payment.</td>\n</tr>\n<tr>\n<td>paymentTransactionId</td>\n<td>string</td>\n<td>The transaction ID from the payment provider.</td>\n</tr>\n<tr>\n<td>paymentType</td>\n<td><code>PaymentTypeEnum</code></td>\n<td>The type of payment method used (e.g., <code>credit</code>, <code>boleto</code>, <code>pix</code>).</td>\n</tr>\n<tr>\n<td>orderCreatedAt</td>\n<td>string (ISO date)</td>\n<td>The date and time when the order was created.</td>\n</tr>\n<tr>\n<td>orderUpdatedAt</td>\n<td>string (ISO date)</td>\n<td>The date and time when the order was last updated.</td>\n</tr>\n<tr>\n<td>orderStatus</td>\n<td><code>OrderStatusEnum</code></td>\n<td>The current status of the order itself.</td>\n</tr>\n<tr>\n<td>utmParameters</td>\n<td><code>UTMParameters</code> (optional)</td>\n<td>An object containing UTM parameters captured from the client side.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong><code>OrderDiscountWebhookData</code></strong> <strong>Structure:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>string (optional)</td>\n<td>The code used for the discount, if applicable</td>\n</tr>\n<tr>\n<td>label</td>\n<td>string (optional)</td>\n<td>The label displayed for the discount applied to the order.</td>\n</tr>\n<tr>\n<td>description</td>\n<td>string (optional)</td>\n<td>The description displayed for the discount applied to the order.</td>\n</tr>\n<tr>\n<td>method</td>\n<td><code>DiscountMethodEnum</code></td>\n<td>The method by which the discount was applied (e.g., <code>CODE</code> or <code>SHOP_SALE</code>)</td>\n</tr>\n<tr>\n<td>type</td>\n<td><code>DiscountCalculationMethodEnum</code></td>\n<td>Discount calculation type (e.g. <code>CREDIT_OFF_FLAT</code>)</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong><code>OrderPaymentSummaryData</code></strong> <strong>Structure:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>discountTotal</td>\n<td>number</td>\n<td>The total value discounted from the order.</td>\n</tr>\n<tr>\n<td>providerShippingCost</td>\n<td>number</td>\n<td>The shipping cost quoted by the shipping provider.</td>\n</tr>\n<tr>\n<td>finalShippingCost</td>\n<td>number</td>\n<td>The actual shipping cost paid by the customer (after discounts).</td>\n</tr>\n<tr>\n<td>itemsSubtotal</td>\n<td>number</td>\n<td>The subtotal of all items in the order before shipping/discounts.</td>\n</tr>\n<tr>\n<td>orderTotal</td>\n<td>number</td>\n<td>The final total value the customer paid for the order.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong><code>UTMParameters</code></strong> <strong>Structure:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>campaignName</td>\n<td>string</td>\n<td>Equivalent to <code>utm_campaign</code> (e.g., <code>black_friday</code>).</td>\n</tr>\n<tr>\n<td>source</td>\n<td>string</td>\n<td>Equivalent to <code>utm_source</code> (e.g., <code>facebook</code>, <code>newsletter</code>).</td>\n</tr>\n<tr>\n<td>marketingMedium</td>\n<td>string</td>\n<td>Equivalent to <code>utm_medium</code> (e.g., <code>paid_traffic</code>, <code>organic_traffic</code>).</td>\n</tr>\n<tr>\n<td>targetContent</td>\n<td>string (optional)</td>\n<td>Equivalent to <code>utm_content</code> (e.g., <code>top_side_banner</code>, <code>video_ad</code>).</td>\n</tr>\n<tr>\n<td>searchTerms</td>\n<td>string (optional)</td>\n<td>Equivalent to <code>utm_terms</code>, often used for search engine keywords in AdWords, etc.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong><code>DiscountMethodEnum</code></strong> <strong>Values:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>CODE</code></td>\n<td>The discount was activated using a specific discount code.</td>\n</tr>\n<tr>\n<td><code>SHOP_SALE</code></td>\n<td>The discount is a shop-wide sale requiring no code.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong><code>PaymentStatusEnum</code></strong> <strong>Values:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Description</th>\n<th>Applicable To</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>CREATED</code></td>\n<td>Payment successfully initiated.</td>\n<td>All</td>\n</tr>\n<tr>\n<td><code>AUTHORIZED</code></td>\n<td>Credit card payment authorized but not yet captured.</td>\n<td>Credit Card</td>\n</tr>\n<tr>\n<td><code>CAPTURED</code></td>\n<td>Authorized credit card payment has been captured.</td>\n<td>Credit Card</td>\n</tr>\n<tr>\n<td><code>PAID</code></td>\n<td>Payment completed successfully.</td>\n<td>Boleto / Pix</td>\n</tr>\n<tr>\n<td><code>REFUNDED</code></td>\n<td>Payment was previously <code>AUTHORIZED</code>/<code>CAPTURED</code>/<code>PAID</code> and has been fully refunded.</td>\n<td>All</td>\n</tr>\n<tr>\n<td><code>CANCELED</code></td>\n<td>Payment method was canceled.</td>\n<td>All</td>\n</tr>\n<tr>\n<td><code>PENDING</code></td>\n<td>Payment is awaiting confirmation.</td>\n<td>Boleto / Pix</td>\n</tr>\n<tr>\n<td><code>EXPIRED</code></td>\n<td>Payment time limit expired before completion.</td>\n<td>Boleto / Pix</td>\n</tr>\n<tr>\n<td><code>CHARGED_BACK</code></td>\n<td>Payment was disputed by the card owner and the value refunded.</td>\n<td>All</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong><code>PaymentTypeEnum</code></strong> <strong>Values:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>credit</code></td>\n<td>Credit Card payment</td>\n</tr>\n<tr>\n<td><code>boleto</code></td>\n<td>Boleto Bancário</td>\n</tr>\n<tr>\n<td><code>pix</code></td>\n<td>Pix Transfer</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong><code>OrderStatusEnum</code></strong> <strong>Values:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>CANCELED</code></td>\n<td>The order was canceled (often due to payment expiration or failure).</td>\n</tr>\n<tr>\n<td><code>COMPLETED</code></td>\n<td>The order completed successfully (paid and processed).</td>\n</tr>\n<tr>\n<td><code>FAILED</code></td>\n<td>The order creation failed for some reason.</td>\n</tr>\n<tr>\n<td><code>PENDING</code></td>\n<td>The order has pending payments or actions required before processing.</td>\n</tr>\n<tr>\n<td><code>PROCESSING</code></td>\n<td>The order payment is complete, and the order is being processed for fulfillment.</td>\n</tr>\n<tr>\n<td><code>REFUNDED</code></td>\n<td>The order was fully refunded after completion.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"full-request-example-order_created\">Full Request Example (ORDER_CREATED)</h3>\n<p>This example shows a typical <code>POST</code> request for an <code>ORDER_CREATED</code> event, including headers and the JSON payload.</p>\n<p><strong>Headers:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-http\">POST /your-webhook-endpoint HTTP/1.1\nHost: your-server.com\nUser-Agent: axios/0.20.0\nAccept: application/json, text/plain, */*\nContent-Type: application/json\nX-Unbox-Signature: d4c04436ea689af9bfd2ac512f404d4ddd56d5b2a7aed42abab154d37d4752a0\nContent-Length: 521\n\n</code></pre>\n<p><strong>Request Body:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"_id\": \"76edfa38-776a-449e-87d7-1cf8a89749c3\",\n  \"type\": \"ORDER_CREATED\",\n  \"data\": {\n    \"orderId\": \"r6RCEDp8Hitykh2oJ\",\n    \"shopSlug\": \"unbox-teste\",\n    \"paymentSummary\": {\n      \"discountTotal\": 0,\n      \"providerShippingCost\": 11.51,\n      \"finalShippingCost\": 20,\n      \"itemsSubtotal\": 284.4,\n      \"orderTotal\": 304.4\n    },\n    \"paymentStatus\": \"PAID\",\n    \"paymentTransactionId\": \"4c0da2d328964f2cb5af5b5074b2e4f5\",\n    \"paymentType\": \"boleto\",\n    \"orderCreatedAt\": \"2025-03-26T17:47:01.562Z\",\n    \"orderUpdatedAt\": \"2025-03-26T17:47:36.538Z\",\n    \"orderStatus\": \"PROCESSING\"\n  },\n  \"createdAt\": \"2025-03-26T17:47:39.975Z\"\n}\n\n</code></pre>\n<p>Remember that the <code>X-Unbox-Signature</code> value will change for every request and must be validated using your specific secret key.</p>\n","_postman_id":"cacff629-4f81-4bdd-931c-14f7c0da0a66"}],"event":[{"listen":"prerequest","script":{"type":"text/javascript","packages":{},"exec":[""],"id":"0bb4c6e9-fe33-4725-9992-158dc7fdb2ff"}},{"listen":"test","script":{"type":"text/javascript","packages":{},"exec":["// Global Tests - Applied to ALL requests in the collection","","pm.test(\"[Global] Response time is acceptable (< 3s)\", function() {","    pm.expect(pm.response.responseTime).to.be.below(3000);","});","","// Attempt to parse JSON only if Content-Type suggests it","let jsonData = null;","const contentType = pm.response.headers.get('Content-Type');","let isJson = false;","if (contentType && contentType.includes('application/json')) {","    isJson = true;","    try {","        jsonData = pm.response.json();","        pm.test(\"[Global] Response is valid JSON (if applicable)\", function () {","            // Test passes if parsing succeeds, fails if pm.response.json() throws","            pm.expect(true).to.be.true; // Assertion to ensure the test runs","        });","    } catch (e) {","        pm.test(\"[Global] Response is valid JSON (if applicable)\", function () {","            // Force test failure if JSON parsing fails","            console.error('JSON Parsing Error:', e);","            pm.expect.fail('Response body could not be parsed as JSON.');","        });","    }","}","","// Check status code appropriateness based on presence of errors (if JSON)","if (isJson && jsonData) {","    const hasErrors = jsonData.errors && Array.isArray(jsonData.errors) && jsonData.errors.length > 0;","    if (hasErrors) {","        pm.test(\"[Global] Status code is NOT 200 when errors ARE returned\", function () {","            pm.expect(pm.response.code).to.not.equal(200, 'Expected non-200 status for errors');","        });","    } else {","        // Only check for 200 if it's not an expected error status code (like 4xx/5xx HTTP errors)","        if (pm.response.code < 400) { ","           pm.test(\"[Global] Status code is 2xx/3xx when no errors are returned\", function () {","               pm.expect(pm.response.code).to.be.below(400, 'Expected 2xx/3xx status without errors');","           });","        }","    }","}","","// Log errors if present (debugging aid, not a strict test)","if (isJson && jsonData && jsonData.errors) {","    console.error('[Global] Errors Detected:', JSON.stringify(jsonData.errors));","}"],"id":"e3aa6a8f-2710-403f-9b17-72e02d121ad4"}}],"variable":[{"key":"authorization","value":""},{"key":"tokenExpiry","value":""},{"key":"stage-authorization","value":""},{"key":"stage-tokenExpiry","value":""}]}