{
  "info": {
    "name": "Bizflow eTIMS Sandbox",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "description": "Preview. Set a sandbox key locally. Run registration and poll it before invoicing. Preserve runId and request timestamps when replaying."
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{apiKey}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "runId",
      "value": ""
    },
    {
      "key": "issuedAt",
      "value": ""
    },
    {
      "key": "productId",
      "value": ""
    },
    {
      "key": "invoiceId",
      "value": ""
    },
    {
      "key": "creditId",
      "value": ""
    }
  ],
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "if (!pm.collectionVariables.get('runId')) pm.collectionVariables.set('runId', 'sandbox-' + Date.now());",
          "if (!pm.collectionVariables.get('issuedAt')) pm.collectionVariables.set('issuedAt', new Date().toISOString());"
        ]
      }
    }
  ],
  "item": [
    {
      "name": "Tax categories",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": "{{baseUrl}}/reference-data?type=TAX_TYPE"
      }
    },
    {
      "name": "Register service",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Idempotency-Key",
            "value": "{{runId}}-register-service"
          }
        ],
        "url": "{{baseUrl}}/products",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"externalReference\": \"{{runId}}-service\",\n  \"name\": \"Consultation\",\n  \"description\": \"Consultation service\",\n  \"type\": \"SERVICES\",\n  \"taxCategory\": \"B\",\n  \"classificationCode\": \"85121600\",\n  \"unitCode\": \"U\",\n  \"packagingCode\": \"NT\",\n  \"originCountry\": \"KE\",\n  \"unitPrice\": \"116.00\"\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Request accepted\", () => pm.expect([200,202]).to.include(pm.response.code));",
              "if ([200,202].includes(pm.response.code)) pm.collectionVariables.set('productId', pm.response.json().id);"
            ]
          }
        }
      ]
    },
    {
      "name": "Product status",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": "{{baseUrl}}/products/{{productId}}"
      }
    },
    {
      "name": "Fixed discount invoice",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Idempotency-Key",
            "value": "{{runId}}-fixed-discount-invoice"
          }
        ],
        "url": "{{baseUrl}}/invoices",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"externalReference\": \"{{runId}}-fixed\",\n  \"issuedAt\": \"{{issuedAt}}\",\n  \"currency\": \"KES\",\n  \"paymentMethod\": \"01\",\n  \"buyer\": {\n    \"name\": \"Walk-in customer\"\n  },\n  \"items\": [\n    {\n      \"productId\": \"{{productId}}\",\n      \"quantity\": \"3\",\n      \"unitPrice\": \"116.00\",\n      \"discount\": {\n        \"type\": \"FIXED\",\n        \"value\": \"34.80\"\n      }\n    }\n  ]\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Request accepted\", () => pm.expect([200,202]).to.include(pm.response.code));",
              "if ([200,202].includes(pm.response.code)) pm.collectionVariables.set('fixedInvoiceId', pm.response.json().id);"
            ]
          }
        }
      ]
    },
    {
      "name": "Percentage discount invoice",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Idempotency-Key",
            "value": "{{runId}}-percentage-discount-invoice"
          }
        ],
        "url": "{{baseUrl}}/invoices",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"externalReference\": \"{{runId}}-percentage\",\n  \"issuedAt\": \"{{issuedAt}}\",\n  \"currency\": \"KES\",\n  \"paymentMethod\": \"01\",\n  \"buyer\": {\n    \"name\": \"Walk-in customer\"\n  },\n  \"items\": [\n    {\n      \"productId\": \"{{productId}}\",\n      \"quantity\": \"3\",\n      \"unitPrice\": \"116.00\",\n      \"discount\": {\n        \"type\": \"PERCENTAGE\",\n        \"value\": \"10.00\"\n      }\n    }\n  ]\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Request accepted\", () => pm.expect([200,202]).to.include(pm.response.code));",
              "if ([200,202].includes(pm.response.code)) pm.collectionVariables.set('invoiceId', pm.response.json().id);"
            ]
          }
        }
      ]
    },
    {
      "name": "Invoice status",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": "{{baseUrl}}/invoices/{{invoiceId}}"
      }
    },
    {
      "name": "Invoice PDF",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/pdf"
          }
        ],
        "url": "{{baseUrl}}/documents/{{invoiceId}}/pdf"
      }
    },
    {
      "name": "Partial credit",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Idempotency-Key",
            "value": "{{runId}}-partial-credit"
          }
        ],
        "url": "{{baseUrl}}/credit-notes",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"externalReference\": \"{{runId}}-credit\",\n  \"originalInvoiceId\": \"{{invoiceId}}\",\n  \"issuedAt\": \"{{issuedAt}}\",\n  \"reasonCode\": \"01\",\n  \"items\": [\n    {\n      \"originalSequence\": 1,\n      \"quantity\": \"1\"\n    }\n  ]\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Request accepted\", () => pm.expect([200,202]).to.include(pm.response.code));",
              "if ([200,202].includes(pm.response.code)) pm.collectionVariables.set('creditId', pm.response.json().id);"
            ]
          }
        }
      ]
    },
    {
      "name": "Credit status",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": "{{baseUrl}}/credit-notes/{{creditId}}"
      }
    },
    {
      "name": "Credit PDF",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/pdf"
          }
        ],
        "url": "{{baseUrl}}/documents/{{creditId}}/pdf"
      }
    },
    {
      "name": "Set goods stock",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Idempotency-Key",
            "value": "{{runId}}-set-goods-stock"
          }
        ],
        "url": "{{baseUrl}}/stock-balances",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"externalReference\": \"{{runId}}-stock\",\n  \"productId\": \"{{goodsProductId}}\",\n  \"expectedBalance\": \"0.000000\",\n  \"balance\": \"20.000000\"\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Request accepted\", () => pm.expect([200,202]).to.include(pm.response.code));",
              "if ([200,202].includes(pm.response.code)) pm.collectionVariables.set('stockId', pm.response.json().id);"
            ]
          }
        }
      ]
    },
    {
      "name": "Stock status",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": "{{baseUrl}}/stock-balances/{{stockId}}"
      }
    }
  ]
}
