{
  "info": {
    "name": "Missio Shop API - Complete",
    "_postman_id": "missio-customer-api-v2",
    "description": "Complete API documentation for Missio Shop Module customer endpoints.\n\n**Required Headers:**\n- `X-Host`: Company identifier (required for all requests)\n- `Authorization`: Bearer token (for authenticated endpoints)\n- `Content-Type`: application/json (for POST/PUT requests)\n\n**Authentication Flow:**\n1. Get company hash from your Missio instance\n2. Call Signup or Login with X-Host header\n3. Store the returned access_token\n4. Use token in Authorization header for authenticated requests\n\n**Customer Status:**\n- `1` = Active\n- `0` = Inactive (login will return 403)\n\nFor full documentation, see: docs/API_DOCUMENTATION.md",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "version": "2.0.0"
  },
  "variable": [
    {
      "key": "base_url",
      "value": "http://portal.missio.local.io",
      "type": "string",
      "description": "Base URL for the API (no trailing slash)"
    },
    {
      "key": "x_host",
      "value": "REPLACE_WITH_COMPANY_HASH",
      "type": "string",
      "description": "Company hash from companies table. Required for all requests."
    },
    {
      "key": "token",
      "value": "",
      "type": "string",
      "description": "Bearer token auto-captured from login/signup responses"
    },
    {
      "key": "payment_intent_id",
      "value": "",
      "type": "string",
      "description": "Stripe PaymentIntent ID auto-captured from payment-intent response"
    },
    {
      "key": "client_secret",
      "value": "",
      "type": "string",
      "description": "Stripe client secret auto-captured from payment-intent response"
    },
    {
      "key": "cart_token",
      "value": "",
      "type": "string",
      "description": "Cart token from cart creation/response - set manually or auto-captured from cart endpoints"
    }
  ],
  "item": [
    {
      "name": "Authentication",
      "description": "Customer authentication endpoints: signup, login, token refresh, and logout.",
      "item": [
        {
          "name": "Signup",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "// Auto-capture token from response",
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "",
                  "if (json.access_token) {",
                  "    pm.collectionVariables.set('token', json.access_token);",
                  "    console.log('Token captured:', json.access_token.substring(0, 20) + '...');",
                  "}",
                  "",
                  "// Tests",
                  "pm.test('Status is success', () => {",
                  "    pm.expect(json.status).to.equal('success');",
                  "});",
                  "",
                  "pm.test('Returns access token', () => {",
                  "    pm.expect(json.access_token).to.be.a('string');",
                  "});",
                  "",
                  "pm.test('Returns customer object', () => {",
                  "    pm.expect(json.customer).to.be.an('object');",
                  "    pm.expect(json.customer).to.have.property('id');",
                  "    pm.expect(json.customer).to.have.property('email');",
                  "});",
                  "",
                  "pm.test('Returns company info', () => {",
                  "    pm.expect(json.company).to.be.an('object');",
                  "    pm.expect(json.company).to.have.property('id');",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"fname\": \"John\",\n  \"lname\": \"Doe\",\n  \"email\": \"john.doe+{{$timestamp}}@example.com\",\n  \"password\": \"secret123\",\n  \"username\": \"johndoe{{$timestamp}}\",\n  \"phone\": \"+1234567890\",\n  \"address\": \"123 Main Street\",\n  \"city\": \"Boston\",\n  \"state\": \"MA\",\n  \"country\": \"US\",\n  \"zip_code\": \"02101\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/api/auth/signup",
              "host": ["{{base_url}}"],
              "path": ["api", "auth", "signup"]
            },
            "description": "Create a new customer account.\n\n**Required Fields:**\n- `fname` (string, max: 100)\n- `lname` (string, max: 100)\n- `email` (email, max: 255, unique per company)\n- `password` (string, min: 6)\n\n**Optional Fields:**\n- `username` (string, max: 150) - defaults to email if not provided\n- `phone` (string, max: 50)\n- `address`, `city`, `state`, `country` (defaults to US), `zip_code`\n\n**Response:**\n- `access_token`: Bearer token for authentication\n- `customer`: Customer object with all details\n- `company`: Company info (id, name)\n\n**Error Codes:**\n- 422: Missing X-Host or validation errors\n- 500: Server error"
          },
          "response": [
            {
              "name": "Success Example",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "x-host",
                    "value": "abc123def456"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"fname\": \"John\",\n  \"lname\": \"Doe\",\n  \"email\": \"john.doe@example.com\",\n  \"password\": \"secret123\",\n  \"phone\": \"+1234567890\"\n}"
                },
                "url": {
                  "raw": "{{base_url}}/api/auth/signup",
                  "host": ["{{base_url}}"],
                  "path": ["api", "auth", "signup"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": \"success\",\n  \"message\": \"Signup successfully\",\n  \"access_token\": \"1|abcdef123456789...\",\n  \"token_type\": \"Bearer\",\n  \"customer\": {\n    \"id\": 1,\n    \"company_id\": 5,\n    \"fname\": \"John\",\n    \"lname\": \"Doe\",\n    \"slug\": \"john-doe\",\n    \"email\": \"john.doe@example.com\",\n    \"username\": \"john.doe@example.com\",\n    \"phone\": \"+1234567890\",\n    \"status\": \"1\",\n    \"email_verified_at\": \"2026-01-07 12:00:00\",\n    \"created_at\": \"2026-01-07T12:00:00.000000Z\",\n    \"updated_at\": \"2026-01-07T12:00:00.000000Z\"\n  },\n  \"company\": {\n    \"id\": 5,\n    \"name\": \"Acme Corporation\"\n  }\n}"
            },
            {
              "name": "Missing Company Hash",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"fname\": \"John\",\n  \"lname\": \"Doe\",\n  \"email\": \"john@example.com\",\n  \"password\": \"secret123\"\n}"
                },
                "url": {
                  "raw": "{{base_url}}/api/auth/signup",
                  "host": ["{{base_url}}"],
                  "path": ["api", "auth", "signup"]
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": \"error\",\n  \"message\": \"Missing or invalid X-Host header.\"\n}"
            },
            {
              "name": "Validation Error",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "x-host",
                    "value": "abc123"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"fname\": \"John\",\n  \"email\": \"invalid-email\",\n  \"password\": \"123\"\n}"
                },
                "url": {
                  "raw": "{{base_url}}/api/auth/signup",
                  "host": ["{{base_url}}"],
                  "path": ["api", "auth", "signup"]
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": \"error\",\n  \"message\": \"The given data was invalid.\",\n  \"errors\": {\n    \"lname\": [\"The lname field is required.\"],\n    \"email\": [\"The email must be a valid email address.\"],\n    \"password\": [\"The password must be at least 6 characters.\"]\n  }\n}"
            }
          ]
        },
        {
          "name": "Login",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "// Auto-capture token",
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "",
                  "if (json.access_token) {",
                  "    pm.collectionVariables.set('token', json.access_token);",
                  "    console.log('Token captured and saved');",
                  "}",
                  "",
                  "// Tests",
                  "pm.test('Status is success', () => {",
                  "    pm.expect(json.status).to.equal('success');",
                  "});",
                  "",
                  "pm.test('Returns access token', () => {",
                  "    pm.expect(json.access_token).to.be.a('string');",
                  "});",
                  "",
                  "pm.test('Returns customer data', () => {",
                  "    pm.expect(json.customer).to.be.an('object');",
                  "    pm.expect(json.customer.email).to.be.a('string');",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"email\": \"john.doe@example.com\",\n  \"password\": \"secret123\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/api/auth/login",
              "host": ["{{base_url}}"],
              "path": ["api", "auth", "login"]
            },
            "description": "Authenticate an existing customer.\n\n**Required Fields:**\n- `email` OR `username` (one required)\n- `password` (string)\n\n**Alternative Login:**\nYou can use `username` instead of `email`:\n```json\n{\n  \"username\": \"johndoe\",\n  \"password\": \"secret123\"\n}\n```\n\n**Response:**\n- `access_token`: Bearer token\n- `customer`: Customer details\n- `company`: Company info\n\n**Error Codes:**\n- 401: Invalid credentials\n- 403: Account inactive\n- 422: Missing X-Host or validation error"
          },
          "response": [
            {
              "name": "Success Example",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "x-host",
                    "value": "abc123"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"email\": \"john.doe@example.com\",\n  \"password\": \"secret123\"\n}"
                },
                "url": {
                  "raw": "{{base_url}}/api/auth/login",
                  "host": ["{{base_url}}"],
                  "path": ["api", "auth", "login"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "body": "{\n  \"status\": \"success\",\n  \"message\": \"Login successful\",\n  \"access_token\": \"2|xyz789...\",\n  \"token_type\": \"Bearer\",\n  \"customer\": {\n    \"id\": 1,\n    \"email\": \"john.doe@example.com\",\n    \"fname\": \"John\",\n    \"lname\": \"Doe\"\n  },\n  \"company\": {\n    \"id\": 5,\n    \"name\": \"Acme Corporation\"\n  }\n}"
            },
            {
              "name": "Invalid Credentials",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "x-host",
                    "value": "abc123"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"email\": \"john@example.com\",\n  \"password\": \"wrongpass\"\n}"
                },
                "url": {
                  "raw": "{{base_url}}/api/auth/login",
                  "host": ["{{base_url}}"],
                  "path": ["api", "auth", "login"]
                }
              },
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "body": "{\n  \"status\": \"error\",\n  \"message\": \"Invalid credentials\"\n}"
            },
            {
              "name": "Inactive Account",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "x-host",
                    "value": "abc123"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"email\": \"inactive@example.com\",\n  \"password\": \"secret123\"\n}"
                },
                "url": {
                  "raw": "{{base_url}}/api/auth/login",
                  "host": ["{{base_url}}"],
                  "path": ["api", "auth", "login"]
                }
              },
              "status": "Forbidden",
              "code": 403,
              "_postman_previewlanguage": "json",
              "body": "{\n  \"status\": \"error\",\n  \"message\": \"Your account is not active. Please contact support.\"\n}"
            }
          ]
        },
        {
          "name": "Refresh Token",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "// Auto-capture new token",
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "",
                  "if (json.access_token) {",
                  "    pm.collectionVariables.set('token', json.access_token);",
                  "    console.log('New token captured');",
                  "}",
                  "",
                  "pm.test('Status is success', () => {",
                  "    pm.expect(json.status).to.equal('success');",
                  "});",
                  "",
                  "pm.test('Returns new access token', () => {",
                  "    pm.expect(json.access_token).to.be.a('string');",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Required: Current bearer token"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/api/auth/refresh",
              "host": ["{{base_url}}"],
              "path": ["api", "auth", "refresh"]
            },
            "description": "Refresh the authentication token.\n\n**Behavior:**\n- Revokes the current token\n- Issues a new token\n- Updates collection variable automatically\n\n**Headers Required:**\n- `Authorization: Bearer {current_token}`\n- `X-Host`\n\n**Response:**\n- `access_token`: New bearer token\n- `token_type`: \"Bearer\"\n\n**Error Codes:**\n- 401: Invalid or missing token"
          },
          "response": [
            {
              "name": "Success Example",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Authorization",
                    "value": "Bearer 1|oldtoken..."
                  },
                  {
                    "key": "x-host",
                    "value": "abc123"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/api/auth/refresh",
                  "host": ["{{base_url}}"],
                  "path": ["api", "auth", "refresh"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "body": "{\n  \"status\": \"success\",\n  \"message\": \"Token refreshed\",\n  \"access_token\": \"3|newtoken123...\",\n  \"token_type\": \"Bearer\"\n}"
            }
          ]
        },
        {
          "name": "Logout",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "",
                  "pm.test('Status is success', () => {",
                  "    pm.expect(json.status).to.equal('success');",
                  "});",
                  "",
                  "pm.test('Message confirms logout', () => {",
                  "    pm.expect(json.message).to.include('Logged out');",
                  "});",
                  "",
                  "// Optionally clear token after logout",
                  "// pm.collectionVariables.set('token', '');"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Required: Bearer token"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/api/auth/logout",
              "host": ["{{base_url}}"],
              "path": ["api", "auth", "logout"]
            },
            "description": "Revoke the current authentication token.\n\n**Behavior:**\n- Deletes the current access token\n- User must login again to get a new token\n\n**Headers Required:**\n- `Authorization: Bearer {token}`\n- `X-Host`\n\n**Response:**\n- Success message confirming logout\n\n**Error Codes:**\n- 401: Invalid or missing token"
          },
          "response": [
            {
              "name": "Success Example",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Authorization",
                    "value": "Bearer 1|token..."
                  },
                  {
                    "key": "x-host",
                    "value": "abc123"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/api/auth/logout",
                  "host": ["{{base_url}}"],
                  "path": ["api", "auth", "logout"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "body": "{\n  \"status\": \"success\",\n  \"message\": \"Logged out\"\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Profile",
      "description": "Customer profile management endpoints.",
      "item": [
        {
          "name": "Get Profile",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "",
                  "pm.test('Status is success', () => {",
                  "    pm.expect(json.status).to.equal('success');",
                  "});",
                  "",
                  "pm.test('Returns customer object', () => {",
                  "    pm.expect(json.customer).to.be.an('object');",
                  "    pm.expect(json.customer).to.have.property('id');",
                  "    pm.expect(json.customer).to.have.property('email');",
                  "    pm.expect(json.customer).to.have.property('fname');",
                  "    pm.expect(json.customer).to.have.property('lname');",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Required: Bearer token"
              },
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/me",
              "host": ["{{base_url}}"],
              "path": ["api", "me"]
            },
            "description": "Retrieve the authenticated customer's profile.\n\n**Headers Required:**\n- `Authorization: Bearer {token}`\n- `X-Host`\n\n**Response:**\nReturns full customer object including:\n- Personal info (fname, lname, email, username, phone)\n- Address (address, city, state, country, zip_code)\n- Account details (status, email_verified_at, created_at)\n- Additional fields (about, photo, etc.)\n\n**Error Codes:**\n- 401: Invalid or missing token"
          },
          "response": [
            {
              "name": "Success Example",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Authorization",
                    "value": "Bearer token..."
                  },
                  {
                    "key": "x-host",
                    "value": "abc123"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/api/me",
                  "host": ["{{base_url}}"],
                  "path": ["api", "me"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "body": "{\n  \"status\": \"success\",\n  \"message\": \"Profile\",\n  \"customer\": {\n    \"id\": 1,\n    \"company_id\": 5,\n    \"fname\": \"John\",\n    \"lname\": \"Doe\",\n    \"slug\": \"john-doe\",\n    \"email\": \"john.doe@example.com\",\n    \"username\": \"johndoe\",\n    \"phone\": \"+1234567890\",\n    \"address\": \"123 Main Street\",\n    \"city\": \"Boston\",\n    \"state\": \"MA\",\n    \"country\": \"US\",\n    \"zip_code\": \"02101\",\n    \"about\": \"Software developer\",\n    \"status\": \"1\",\n    \"email_verified_at\": \"2026-01-07 12:00:00\",\n    \"created_at\": \"2026-01-07T12:00:00.000000Z\",\n    \"updated_at\": \"2026-01-07T12:00:00.000000Z\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Update Profile",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "",
                  "pm.test('Status is success', () => {",
                  "    pm.expect(json.status).to.equal('success');",
                  "});",
                  "",
                  "pm.test('Returns updated customer', () => {",
                  "    pm.expect(json.customer).to.be.an('object');",
                  "});",
                  "",
                  "pm.test('Message confirms update', () => {",
                  "    pm.expect(json.message).to.include('updated');",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Required: Bearer token"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"fname\": \"John\",\n  \"lname\": \"Smith\",\n  \"phone\": \"+1987654321\",\n  \"email\": \"john.smith@example.com\",\n  \"username\": \"johnsmith\",\n  \"address\": \"456 Oak Avenue\",\n  \"city\": \"Cambridge\",\n  \"state\": \"MA\",\n  \"country\": \"US\",\n  \"zip_code\": \"02139\",\n  \"about\": \"Full stack developer\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/api/me",
              "host": ["{{base_url}}"],
              "path": ["api", "me"]
            },
            "description": "Update the authenticated customer's profile.\n\n**Headers Required:**\n- `Authorization: Bearer {token}`\n- `X-Host`\n- `Content-Type: application/json`\n\n**Optional Fields (all):**\n- `fname` (string, max: 100)\n- `lname` (string, max: 100)\n- `phone` (string, max: 50)\n- `email` (email, max: 255)\n- `username` (string, max: 150)\n- `address` (string)\n- `city`, `state`, `country`, `zip_code`\n- `about` (text)\n- `photo` (string - path or URL)\n\n**Note:** Send only fields you want to update.\n\n**Response:**\n- Updated customer object\n\n**Error Codes:**\n- 401: Invalid token\n- 422: Validation errors"
          },
          "response": [
            {
              "name": "Success Example",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Authorization",
                    "value": "Bearer token..."
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "x-host",
                    "value": "abc123"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"fname\": \"John\",\n  \"lname\": \"Smith\",\n  \"phone\": \"+1987654321\"\n}"
                },
                "url": {
                  "raw": "{{base_url}}/api/me",
                  "host": ["{{base_url}}"],
                  "path": ["api", "me"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "body": "{\n  \"status\": \"success\",\n  \"message\": \"Profile updated\",\n  \"customer\": {\n    \"id\": 1,\n    \"fname\": \"John\",\n    \"lname\": \"Smith\",\n    \"phone\": \"+1987654321\",\n    \"updated_at\": \"2026-01-07T14:30:00.000000Z\"\n  }\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Addresses",
      "description": "Customer address management endpoints.",
      "item": [
        {
          "name": "Get Addresses",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "",
                  "pm.test('Status is success', () => {",
                  "    pm.expect(json.status).to.equal('success');",
                  "});",
                  "",
                  "pm.test('Returns addresses object', () => {",
                  "    pm.expect(json.addresses).to.be.an('object');",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Required: Bearer token"
              },
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/addresses",
              "host": ["{{base_url}}"],
              "path": ["api", "addresses"]
            },
            "description": "Retrieve the authenticated customer's address.\n\n**Headers Required:**\n- `Authorization: Bearer {token}`\n- `X-Host`\n\n**Response:**\nReturns address object with:\n- `address` (street address)\n- `city`\n- `state`\n- `country`\n- `zip_code`\n\n**Error Codes:**\n- 401: Invalid or missing token"
          },
          "response": [
            {
              "name": "Success Example",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Authorization",
                    "value": "Bearer token..."
                  },
                  {
                    "key": "x-host",
                    "value": "abc123"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/api/addresses",
                  "host": ["{{base_url}}"],
                  "path": ["api", "addresses"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "body": "{\n  \"status\": \"success\",\n  \"message\": \"Addresses\",\n  \"addresses\": {\n    \"address\": \"123 Main Street\",\n    \"country\": \"US\",\n    \"state\": \"MA\",\n    \"city\": \"Boston\",\n    \"zip_code\": \"02101\"\n  }\n}"
            }
          ]
        },
        {
          "name": "Update Addresses",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "",
                  "pm.test('Status is success', () => {",
                  "    pm.expect(json.status).to.equal('success');",
                  "});",
                  "",
                  "pm.test('Returns updated addresses', () => {",
                  "    pm.expect(json.addresses).to.be.an('object');",
                  "});",
                  "",
                  "pm.test('Message confirms update', () => {",
                  "    pm.expect(json.message).to.include('updated');",
                  "});"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Required: Bearer token"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"address\": \"456 Oak Avenue\",\n  \"city\": \"Cambridge\",\n  \"state\": \"MA\",\n  \"country\": \"US\",\n  \"zip_code\": \"02139\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/api/addresses",
              "host": ["{{base_url}}"],
              "path": ["api", "addresses"]
            },
            "description": "Update the authenticated customer's address.\n\n**Headers Required:**\n- `Authorization: Bearer {token}`\n- `X-Host`\n- `Content-Type: application/json`\n\n**Optional Fields (all):**\n- `address` (string, max: 500)\n- `country` (string, max: 150)\n- `state` (string, max: 150)\n- `city` (string, max: 150)\n- `zip_code` (string, max: 20)\n\n**Note:** Send only fields you want to update.\n\n**Response:**\n- Updated addresses object\n\n**Error Codes:**\n- 401: Invalid token\n- 422: Validation errors"
          },
          "response": [
            {
              "name": "Success Example",
              "originalRequest": {
                "method": "PUT",
                "header": [
                  {
                    "key": "Authorization",
                    "value": "Bearer token..."
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "x-host",
                    "value": "abc123"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"address\": \"456 Oak Avenue\",\n  \"city\": \"Cambridge\",\n  \"zip_code\": \"02139\"\n}"
                },
                "url": {
                  "raw": "{{base_url}}/api/addresses",
                  "host": ["{{base_url}}"],
                  "path": ["api", "addresses"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "body": "{\n  \"status\": \"success\",\n  \"message\": \"Addresses updated\",\n  \"addresses\": {\n    \"address\": \"456 Oak Avenue\",\n    \"country\": \"US\",\n    \"state\": \"MA\",\n    \"city\": \"Cambridge\",\n    \"zip_code\": \"02139\"\n  }\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Catalog",
      "description": "Company-scoped catalog endpoints for mobile apps (no auth token required, X-Host is mandatory).",
      "item": [
        {
          "name": "Categories",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "pm.test('Status is success', () => pm.expect(json.status).to.equal('success'));",
                  "pm.test('Returns categories array', () => pm.expect(json.categories || json.data?.categories).to.be.an('array'))" 
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/catalog/categories",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "catalog",
                "categories"
              ]
            },
            "description": "Fetch category tree (top-level with children) for the company.\n\n**Response includes:**\n- Category ID, name, slug, image URL\n- Nested children (recursive)\n- Position-based ordering"
          }
        },
        {
          "name": "Products (list)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "pm.test('Status is success', () => pm.expect(json.status).to.equal('success'));",
                  "pm.test('Returns products data', () => pm.expect(json.products || json.data?.products).to.exist)"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/catalog/products?search=shoe&category_slug=&min_price=&max_price=&sort=name&page=1&per_page=20",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "catalog",
                "products"
              ],
              "query": [
                { "key": "search", "value": "shoe", "description": "Full-text search on name/description" },
                { "key": "category_slug", "value": "", "description": "Filter by category slug (includes descendants)" },
                { "key": "category_id", "value": "", "description": "Alternative filter by category id" },
                { "key": "min_price", "value": "", "description": "Minimum price" },
                { "key": "max_price", "value": "", "description": "Maximum price" },
                { "key": "sort", "value": "name", "description": "name|date|price|price-desc|popularity" },
                { "key": "page", "value": "1", "description": "Page number" },
                { "key": "per_page", "value": "20", "description": "Items per page (1-100)" }
              ]
            },
            "description": "List products with search, category filter, price range, and sorting.\n\n**Returns:**\n- Paginated product list (id, name, slug, price, min_price, max_price)\n- Product images (sm, md, lg, original)\n- Short description\n- Categories\n- Views count\n\n**Note:** Variants and files are NOT included in list view (use detail endpoint)."
          }
        },
        {
          "name": "Product detail",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "pm.test('Status is success', () => pm.expect(json.status).to.equal('success'));",
                  "pm.test('Returns product object', () => pm.expect(json.product || json.data?.product).to.be.an('object'));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/catalog/products/sample-slug",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "api",
                "catalog",
                "products",
                "sample-slug"
              ]
            },
            "description": "Fetch a single product by slug or id (includes variants and all images).\n\n**Supports both:**\n- Slug: `/api/catalog/products/my-product-name`\n- ID: `/api/catalog/products/1008`\n\n**Returns:**\n- Complete product details (description, specifications, packaging, etc.)\n- All images with multiple sizes (default + additional files)\n- Product variants with their images\n- Categories\n- Stock, SKU, pricing info"
          }
        }
      ]
    },
    {
      "name": "Cart",
      "description": "Shopping cart management endpoints for adding items, applying coupons, and managing cart totals.\n\n**Authentication:**\n- All cart endpoints support BOTH guest and authenticated users\n- **Guest Cart:** Omit Authorization header (cart stored in session via cookies)\n- **Authenticated Cart:** Include `Authorization: Bearer {token}` header (cart linked to customer_id)\n\n**Benefits of Authenticated Carts:**\n- Cart persists across devices\n- Per-customer coupon usage tracking\n- Order history integration\n- Personalized promotions\n\n**Note:** To enable authenticated carts, first login via `/api/auth/login` to get a bearer token, then include it in the Authorization header for cart requests.",
      "item": [
        {
          "name": "Create Cart",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "pm.test('Status is success', () => pm.expect(json.status).to.equal('success'));",
                  "pm.test('Returns cart_id', () => pm.expect(json.data?.cart_id).to.be.a('string'));",
                  "if (json.data?.cart_id) {",
                  "  pm.collectionVariables.set('cart_token', json.data.cart_id);",
                  "  console.log('Cart token auto-captured:', json.data.cart_id);",
                  "}"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Optional: For authenticated customers (cart will be linked to customer_id)",
                "disabled": true
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/api/catalog/cart",
              "host": ["{{base_url}}"],
              "path": ["api", "catalog", "cart"]
            },
            "description": "Create or retrieve existing cart session.\n\n**Authentication:**\n- Optional: Include Authorization header with bearer token to link cart to customer\n- Guest carts: Omit Authorization header (cart_id stored in session)\n\n**Returns:**\n- cart_id (session identifier)\n- customer_id (if authenticated, otherwise null)\n- items array\n- totals (subtotal, discount, tax, shipping, total)"
          }
        },
        {
          "name": "Get Cart",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "pm.test('Status is success', () => pm.expect(json.status).to.equal('success'));",
                  "pm.test('Returns items array', () => pm.expect(json.data?.items).to.be.an('array'));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Optional: For authenticated customers",
                "disabled": true
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/catalog/cart?cart_token={{cart_token}}",
              "host": ["{{base_url}}"],
              "path": ["api", "catalog", "cart"],
              "query": [
                {
                  "key": "cart_token",
                    "value": "{{cart_token}}",
                  "description": "Optional: For guest checkout, pass cart_token to identify cart",
                  "disabled": true
                }
              ]
            },
            "description": "Retrieve current cart with items and totals.\n\n**Authentication:**\n- Optional: Include Authorization header to get authenticated cart\n- Optional: Pass cart_token query parameter for guest checkout\n\n**Returns:**\n- cart_token (store this for subsequent requests)\n- customer_id (if authenticated, otherwise null)\n- items array (id, product_id, variant_id, name, sku, quantity, unit_price, amount, attributes, image)\n- coupon_code (if applied)\n- totals (subtotal, discount, tax, shipping, total, items_count)"
          }
        },
        {
          "name": "Add Item to Cart",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "pm.test('Status is success', () => pm.expect(json.status).to.equal('success'));",
                  "pm.test('Returns item object', () => pm.expect(json.data?.item).to.be.an('object'));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Optional: For authenticated customers",
                "disabled": true
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"product_id\": 990,\n  \"attributes\": {\n    \"19\": \"674\",\n    \"20\": \"1136\"\n  },\n  \"quantity\": 2,\n  \"cart_token\": \"\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/api/catalog/cart/items",
              "host": ["{{base_url}}"],
              "path": ["api", "catalog", "cart", "items"]
            },
            "description": "Add a product to cart with optional attributes.\n\n**Authentication:**\n- Optional: Include Authorization header to link cart items to customer\n\n**Body:**\n- `product_id` (required): Product ID\n- `attributes` (optional): Object mapping attribute IDs to value IDs (e.g., {\"19\": \"674\", \"20\": \"1136\"})\n- `quantity` (optional, default 1): Item quantity\n- `cart_token` (optional): For guest checkout, pass cart_token from previous response\n\n**Behavior:**\n- If item with same product_id and attributes exists, quantity is incremented or set (if quantity provided)\n- Automatically finds matching variant based on attributes\n- Validates product belongs to company\n- Prevents mixing recurring and one-time products\n- Prevents mixing missio_owned products with regular products\n\n**Returns:**\n- cart_token (store this for subsequent requests)\n- Added/updated item with variant details\n- Updated totals"
          }
        },
        {
          "name": "Remove Cart Item",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "pm.test('Status is success', () => pm.expect(json.status).to.equal('success'));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Optional: For authenticated customers",
                "disabled": true
              }
            ],
            "url": {
              "raw": "{{base_url}}/api/catalog/cart/items?cart_token={{cart_token}}",
              "host": ["{{base_url}}"],
              "path": ["api", "catalog", "cart", "items", ":item_id"],
              "query": [
                {
                  "key": "cart_token",
                    "value": "{{cart_token}}",
                  "description": "Optional: For guest checkout, pass cart_token to identify cart",
                  "disabled": true
                }
              ],
              "variable": [
                {
                  "key": "item_id",
                  "value": "123",
                  "description": "Cart item ID or 'all' to clear entire cart"
                }
              ]
            },
            "description": "Remove specific item from cart, or clear entire cart.\n\n**Authentication:**\n- Optional: Include Authorization header for authenticated carts\n\n**Query Parameters:**\n- `cart_token` (optional): For guest checkout, pass cart_token to identify cart\n\n**URL Parameters:**\n- `item_id`: Cart item ID, or use 'all' to clear cart\n\n**Behavior:**\n- Removes item from cart\n- Removes applied coupon (if any)\n- If 'all', clears entire cart and session\n\n**Returns:**\n- Updated totals"
          }
        }
      ]
    },
    {
      "name": "Checkout",
      "description": "Checkout endpoint for saving billing/shipping information.",
      "item": [
        {
          "name": "Save Checkout Form",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "pm.test('Status is success', () => pm.expect(json.status).to.equal('success'));",
                  "pm.test('Returns next_step', () => pm.expect(json.data?.next_step).to.equal('payment'));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Optional: For authenticated customers",
                "disabled": true
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"_token\": \"xxOsb97nIMwq3D5KmQiqyHFqPfBlENTPZSAN6Xts\",\n  \"PhysicalProductinList\": \"1\",\n  \"billing_first_name\": \"John\",\n  \"billing_last_name\": \"Doe66\",\n  \"billing_email\": \"john.doe@example.com\",\n  \"billing_company_name\": \"\",\n  \"billing_address\": \"123 Main Street\",\n  \"billing_address2\": \"\",\n  \"billing_city\": \"Boston\",\n  \"billing_country\": \"US\",\n  \"billing_state\": \"Arkansas\",\n  \"billing_zip\": \"02101\",\n  \"billing_phone\": \"(123) 456-7890\",\n  \"shipping_first_name\": \"John\",\n  \"shipping_last_name\": \"Doe66\",\n  \"shipping_email\": \"john.doe@example.com\",\n  \"shipping_company_name\": \"\",\n  \"shipping_address\": \"123 Main Street\",\n  \"shipping_address2\": \"\",\n  \"shipping_city\": \"Boston\",\n  \"shipping_country\": \"US\",\n  \"shipping_state\": \"Arkansas\",\n  \"shipping_zip\": \"02101\",\n  \"shipping_phone\": \"(123) 456-7890\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/api/catalog/checkout?cart_token={{cart_token}}",
              "host": ["{{base_url}}"],
              "path": ["api", "catalog", "checkout"],
              "query": [
                {
                  "key": "cart_token",
                    "value": "{{cart_token}}",
                  "description": "Cart token from cart response"
                }
              ]
            },
            "description": "Save checkout form data with billing and shipping information.\n\n**Required Headers:**\n- `X-Host`: Company identifier\n- `Content-Type`: application/json\n\n**Required Fields (always):**\n- `billing_first_name`: First name\n- `billing_last_name`: Last name\n- `billing_email`: Email address\n- `billing_phone`: Phone number\n\n**Body:**\nInclude all form data as-is, including:\n- `_token`: CSRF token from form\n- `PhysicalProductinList`: \"1\" if physical products, \"0\" otherwise\n- `billing_*`: All billing address fields\n- `shipping_*`: All shipping address fields\n- `cart_token`: Cart token from previous requests\n\n**Returns:**\n- cart_token: For next step\n- next_step: 'payment' (proceed to payment page)\n\n**Validation:**\n- Email fields must be valid\n- Phone must be present and valid\n- First/last name required\n- Data is saved to order_carts.checkoutData column as JSON"
          }
        }
      ]
    },
    {
      "name": "Payment",
      "description": "Two-step Stripe payment flow with coupon support: 1) Apply Coupon, 2) Create PaymentIntent, 3) Confirm Payment",
      "item": [
        {
          "name": "Apply Coupon (Optional)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "pm.test('Status is success', () => pm.expect(json.status).to.equal('success'));",
                  "pm.test('Returns discount_amount', () => pm.expect(json.data?.discount_amount).to.exist);",
                  "pm.test('Returns new_total', () => pm.expect(json.data?.new_total).to.exist);"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Bearer token for authenticated customers"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"coupon_code\": \"SAVE10\",\n  \"cart_token\": \"\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/api/shop/apply-coupon",
              "host": ["{{base_url}}"],
              "path": ["api", "shop", "apply-coupon"]
            },
            "description": "Apply a coupon code to the cart to get a discount.\n\n**Request Body:**\n- `coupon_code`: Valid coupon code\n- `cart_token`: Cart token from cart creation\n\n**Returns:**\n- `coupon_code`: Applied coupon code\n- `discount_type`: 'percentage' or 'fixed'\n- `discount_value`: Discount percentage or amount\n- `discount_amount`: Actual discount in currency\n- `subtotal`: Original subtotal\n- `new_total`: Total after discount\n\n**Validation:**\n- Coupon must exist and be active\n- Coupon must not be expired\n- Only one coupon per cart\n- Discount cannot exceed subtotal"
          }
        },
        {
          "name": "Step 1: Create Payment Intent",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "pm.test('Status is success', () => pm.expect(json.status).to.equal('success'));",
                  "pm.test('Returns client_secret', () => pm.expect(json.data?.client_secret).to.exist);",
                  "pm.test('Returns payment_intent_id', () => pm.expect(json.data?.payment_intent_id).to.exist);",
                  "if (json.data?.payment_intent_id) {",
                  "  pm.collectionVariables.set('payment_intent_id', json.data.payment_intent_id);",
                  "  pm.collectionVariables.set('client_secret', json.data.client_secret);",
                  "}"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Bearer token for authenticated customers"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/api/shop/payment-intent?cart_token={{cart_token}}",
              "host": ["{{base_url}}"],
              "path": ["api", "shop", "payment-intent"],
              "query": [
                {
                  "key": "cart_token",
                    "value": "{{cart_token}}",
                                "raw": "{\\n  \\\"coupon_code\\\": \\\"SAVE10\\\",\\n  \\\"cart_token\\\": \\\"{{cart_token}}\\\"\\n}",
                                "raw": "{\\n  \\\"payment_intent_id\\\": \\\"{{payment_intent_id}}\\\",\\n  \\\"cart_token\\\": \\\"{{cart_token}}\\\"\\n}",
                  "description": "Cart token from cart response"
                }
              ]
            },
            "description": "Create a Stripe PaymentIntent for the current cart.\n\n**Returns:**\n- `client_secret`: Secret for Stripe.js confirmPayment()\n- `payment_intent_id`: PaymentIntent ID for confirmation step\n- `amount`: Total amount to be charged\n\n**Next Step:**\nUse client_secret with Stripe.js to confirm payment on client-side, then call Step 2 confirmation endpoint."
          }
        },
        {
          "name": "Step 2: Confirm Payment",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "pm.test('Status is success', () => pm.expect(json.status).to.equal('success'));",
                  "pm.test('Returns order_id', () => pm.expect(json.data?.order_id).to.exist);",
                  "pm.test('Returns order_number', () => pm.expect(json.data?.order_number).to.exist);",
                  "pm.test('Returns transaction_id', () => pm.expect(json.data?.transaction_id).to.exist);"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Bearer token for authenticated customers"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"payment_intent_id\": \"{{payment_intent_id}}\",\n  \"cart_token\": \"\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/api/shop/payment-confirm",
              "host": ["{{base_url}}"],
              "path": ["api", "shop", "payment-confirm"]
            },
            "description": "Confirm Stripe payment and create Order.\n\n**Prerequisites:**\n1. Call Step 1: Create Payment Intent\n2. Use client_secret with Stripe.js confirmPayment() on mobile client\n3. Stripe will redirect/callback when payment confirmed\n4. Then call this endpoint with payment_intent_id\n\n**Request Body:**\n- `payment_intent_id`: From Step 1 response (auto-captured in Postman)\n- `cart_token`: Cart token from cart creation\n\n**Returns on Success:**\n- `order_id`: Created order ID\n- `order_number`: Order reference number (ODR#00...)\n- `transaction_id`: Stripe PaymentIntent ID\n\n**On Success:**\n- Order record created with all items\n- Payment transaction recorded\n- Cart cleared\n- Ready for fulfillment"
          }
        },
        {
          "name": "TEST: Confirm Payment (with Test Card)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "let json = {};",
                  "try { json = pm.response.json(); } catch (e) {}",
                  "pm.test('Status is success', () => pm.expect(json.status).to.equal('success'));",
                  "pm.test('Returns order_id', () => pm.expect(json.data?.order_id).to.exist);",
                  "pm.test('Returns order_number', () => pm.expect(json.data?.order_number).to.exist);",
                  "pm.test('Returns transaction_id', () => pm.expect(json.data?.transaction_id).to.exist);"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "x-host",
                "value": "{{x_host}}",
                "type": "text",
                "description": "Required: Company identifier"
              },
              {
                "key": "Authorization",
                "value": "Bearer {{token}}",
                "type": "text",
                "description": "Bearer token for authenticated customers"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"payment_intent_id\": \"{{payment_intent_id}}\",\n  \"cart_token\": \"{{cart_token}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/api/shop/test-payment-confirm",
              "host": ["{{base_url}}"],
              "path": ["api", "shop", "test-payment-confirm"]
            },
            "description": "**POSTMAN TESTING ONLY** - Confirm payment with automatic test card confirmation.\n\nUse this endpoint instead of Step 2 when testing in Postman. It automatically:\n1. Confirms payment with Stripe test card (pm_card_visa)\n2. Creates the order on your backend\n3. Clears the cart\n\n**Prerequisites:**\n1. Call Step 1: Create Payment Intent - will return payment_intent_id\n2. Call this TEST endpoint - it handles client-side confirmation automatically\n\n**Test Card Details:**\n- Card Number: 4242 4242 4242 4242\n- Expiry: Any future date (e.g., 12/25)\n- CVC: Any 3 digits (e.g., 123)\n\n**Note:**\nThis endpoint is for development/testing only. Mobile apps should use the regular Step 2 endpoint (payment-confirm) after client-side Stripe confirmation.\n\n**Returns:**\n- `order_id`: Created order ID\n- `order_number`: Order reference number\n- `transaction_id`: Stripe PaymentIntent ID"
          }
        }
      ]
    }
  ]
}
