{
  "info": {
    "_postman_id": "7a9f3e5c-617e-4c6f-92a8-3de25ef1cc71",
    "name": "KatFacil Business Cards API",
    "description": "Complete white-label collection for KatFacil Business Cards API v1.\n\nQUICK START\n1. Obtain approval and API credentials from the KatFacil Business dashboard.\n2. Set base_url, api_key and api_secret in collection variables.\n3. Before the first successful qualifying deposit, test credentials are active and financial operations remain locked.\n4. After the qualifying deposit, use the live key pair shown in the dashboard.\n5. Send a unique UUID in Idempotency-Key for every create, recharge or status-changing request. Never reuse it for a different operation.\n\nAUTHENTICATION\nEvery request sends X-KatFacil-Key and X-KatFacil-Secret. HTTP Basic Auth with the key as username and secret as password is also supported. Never expose the secret in frontend code.\n\nCARD PRODUCTS\nmastercard_virtual and visa_virtual.\n\nSTANDARD RESPONSE\nSuccessful and failed responses contain data and message. The X-Request-ID response header identifies the request for support and audit logs.\n\nLIVE ACTIVATION\nGET /cards and GET /cards/charges return live_activation. Card creation, recharge and status changes require live activation.\n\nRATE LIMITS\nLimits are configured per business. HTTP 429 includes a machine-readable code and retry information.\n\nSECURITY\nAll examples use KatFacil public names only. Sensitive card data is never returned by this API collection.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "apikey",
    "apikey": [
      { "key": "key", "value": "X-KatFacil-Key", "type": "string" },
      { "key": "value", "value": "{{api_key}}", "type": "string" },
      { "key": "in", "value": "header", "type": "string" }
    ]
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "if (!pm.variables.get('request_uuid')) {",
          "  pm.variables.set('request_uuid', pm.variables.replaceIn('{{$guid}}'));",
          "}"
        ]
      }
    },
    {
      "listen": "test",
      "script": {
        "type": "text/javascript",
        "exec": [
          "pm.test('Response has a valid HTTP status', function () { pm.expect(pm.response.code).to.be.oneOf([200, 201, 401, 403, 422, 429]); });",
          "pm.test('Request ID is returned', function () { if (pm.response.code !== 401) pm.expect(pm.response.headers.get('X-Request-ID')).to.exist; });"
        ]
      }
    }
  ],
  "variable": [
    { "key": "base_url", "value": "https://katfacil.com/api/v1", "type": "string" },
    { "key": "api_key", "value": "kf_test_replace_me", "type": "secret" },
    { "key": "api_secret", "value": "replace_me", "type": "secret" },
    { "key": "card_id", "value": "1", "type": "string" },
    { "key": "card_product", "value": "mastercard_virtual", "type": "string" },
    { "key": "recharge_amount", "value": "25.00", "type": "string" },
    { "key": "callback_url", "value": "https://example.com/webhooks/katfacil", "type": "string" },
    { "key": "webhook_secret", "value": "replace_me", "type": "secret" }
  ],
  "item": [
    {
      "name": "1 - Account and pricing",
      "description": "Run these requests first to verify credentials, API mode, activation state and current fees.",
      "item": [
        {
          "name": "List cards and API status",
          "request": {
            "method": "GET",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "X-KatFacil-Secret", "value": "{{api_secret}}", "type": "text" }
            ],
            "url": { "raw": "{{base_url}}/cards", "host": ["{{base_url}}"], "path": ["cards"] },
            "description": "Lists non-demo cards and returns api_mode, live activation requirements and the card creation limit. Safe to call in test mode."
          },
          "response": [
            {
              "name": "200 - Cards returned",
              "originalRequest": { "method": "GET", "header": [], "url": { "raw": "{{base_url}}/cards", "host": ["{{base_url}}"], "path": ["cards"] } },
              "status": "OK", "code": 200, "_postman_previewlanguage": "json",
              "header": [{ "key": "Content-Type", "value": "application/json" }, { "key": "X-Request-ID", "value": "9a54d19c-76f6-4bf5-bfbe-d431ea714e88" }],
              "body": "{\n  \"data\": {\n    \"api_mode\": \"test\",\n    \"live_activation\": {\n      \"activated\": false,\n      \"first_deposit_required\": true,\n      \"minimum_first_deposit\": 25,\n      \"currency\": \"USD\"\n    },\n    \"card_create_limit\": 25,\n    \"cards\": []\n  },\n  \"message\": {\n    \"success\": [\"Business cards fetched successfully\"]\n  }\n}"
            }
          ]
        },
        {
          "name": "Get charges",
          "request": {
            "method": "GET",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "X-KatFacil-Secret", "value": "{{api_secret}}", "type": "text" }
            ],
            "url": { "raw": "{{base_url}}/cards/charges", "host": ["{{base_url}}"], "path": ["cards", "charges"] },
            "description": "Returns the authenticated business subscription plan and creation/recharge charges for every supported card product. Always display these fees before confirmation."
          },
          "response": [
            {
              "name": "200 - Pricing returned",
              "originalRequest": { "method": "GET", "header": [], "url": { "raw": "{{base_url}}/cards/charges", "host": ["{{base_url}}"], "path": ["cards", "charges"] } },
              "status": "OK", "code": 200, "_postman_previewlanguage": "json", "header": [{ "key": "Content-Type", "value": "application/json" }],
              "body": "{\n  \"data\": {\n    \"api_mode\": \"live\",\n    \"wallet_currency\": \"USD\",\n    \"subscription_plan\": \"regular\",\n    \"products\": [\n      {\n        \"card_product\": \"mastercard_virtual\",\n        \"brand\": \"Mastercard\",\n        \"creation\": {\"initial_load\": 1, \"fixed_charge\": 2, \"percent_rate\": 0, \"total_charge\": 2, \"payable\": 3},\n        \"recharge\": {\"fixed_charge\": 1, \"percent_rate\": 1, \"min_amount\": 1, \"max_amount\": 2500}\n      }\n    ]\n  },\n  \"message\": {\"success\": [\"Business card charges fetched successfully\"]}\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "2 - Cards",
      "item": [
        {
          "name": "Create card",
          "event": [{ "listen": "prerequest", "script": { "type": "text/javascript", "exec": ["pm.variables.set('request_uuid', pm.variables.replaceIn('{{$guid}}'));"] } }, { "listen": "test", "script": { "type": "text/javascript", "exec": ["if (pm.response.code === 201) { const json = pm.response.json(); if (json.data && json.data.card) pm.collectionVariables.set('card_id', String(json.data.card.id)); }"] } }],
          "request": {
            "method": "POST",
            "header": [
              { "key": "Accept", "value": "application/json" },
              { "key": "Content-Type", "value": "application/json" },
              { "key": "X-KatFacil-Secret", "value": "{{api_secret}}", "type": "text" },
              { "key": "Idempotency-Key", "value": "{{request_uuid}}", "type": "text" }
            ],
            "body": { "mode": "raw", "raw": "{\n  \"card_product\": \"{{card_product}}\"\n}", "options": { "raw": { "language": "json" } } },
            "url": { "raw": "{{base_url}}/cards/create", "host": ["{{base_url}}"], "path": ["cards", "create"] },
            "description": "Creates a card for the authenticated business account. Requires active subscription, live API activation, sufficient wallet balance and a unique UUID Idempotency-Key. Replaying the same key returns the prior result instead of creating a second card."
          },
          "response": [{ "name": "201 - Card created", "originalRequest": { "method": "POST", "header": [], "url": { "raw": "{{base_url}}/cards/create", "host": ["{{base_url}}"], "path": ["cards", "create"] }, "body": { "mode": "raw", "raw": "{\"card_product\":\"mastercard_virtual\"}" } }, "status": "Created", "code": 201, "_postman_previewlanguage": "json", "header": [{ "key": "Content-Type", "value": "application/json" }], "body": "{\n  \"data\": {\n    \"card\": {\"id\": 145, \"external_id\": \"card_8f2d\", \"card_product\": \"mastercard_virtual\", \"brand\": \"Mastercard Virtual\", \"name_on_card\": \"JEAN ROODY DIE\", \"balance\": 1, \"currency\": \"USD\", \"masked_pan\": \"**** **** **** 1041\", \"expiry\": \"09/29\", \"status\": \"ACTIVE\"},\n    \"transaction_id\": \"PGB123456789\",\n    \"charge_summary\": {\"initial_load\": 1, \"fixed_charge\": 2, \"percent_charge\": 0, \"total_charge\": 2, \"payable\": 3}\n  },\n  \"message\": {\"success\": [\"Business card created successfully\"]}\n}" }]
        },
        {
          "name": "Get card details",
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }, { "key": "X-KatFacil-Secret", "value": "{{api_secret}}", "type": "text" }], "url": { "raw": "{{base_url}}/cards/{{card_id}}", "host": ["{{base_url}}"], "path": ["cards", "{{card_id}}"] }, "description": "Returns one card owned by the authenticated business. Sensitive PAN, CVV and provider information are never included." },
          "response": [{ "name": "200 - Card details", "originalRequest": { "method": "GET", "header": [], "url": { "raw": "{{base_url}}/cards/{{card_id}}", "host": ["{{base_url}}"], "path": ["cards", "{{card_id}}"] } }, "status": "OK", "code": 200, "_postman_previewlanguage": "json", "header": [{ "key": "Content-Type", "value": "application/json" }], "body": "{\n  \"data\": {\n    \"card\": {\"id\": 145, \"external_id\": \"card_8f2d\", \"card_product\": \"mastercard_virtual\", \"brand\": \"Mastercard Virtual\", \"name_on_card\": \"JEAN ROODY DIE\", \"balance\": 25, \"currency\": \"USD\", \"masked_pan\": \"**** **** **** 1041\", \"expiry\": \"09/29\", \"status\": \"ACTIVE\"}\n  },\n  \"message\": {\"success\": [\"Business card details fetched successfully\"]}\n}" }]
        },
        {
          "name": "Get card transactions",
          "request": { "method": "GET", "header": [{ "key": "Accept", "value": "application/json" }, { "key": "X-KatFacil-Secret", "value": "{{api_secret}}", "type": "text" }], "url": { "raw": "{{base_url}}/cards/{{card_id}}/transactions?page=1", "host": ["{{base_url}}"], "path": ["cards", "{{card_id}}", "transactions"], "query": [{ "key": "page", "value": "1" }] }, "description": "Returns sanitized card transactions. Merchant, amount, currency, status and creation time can be returned; upstream provider fields are removed." },
          "response": [{ "name": "200 - Transactions", "originalRequest": { "method": "GET", "header": [], "url": { "raw": "{{base_url}}/cards/{{card_id}}/transactions?page=1", "host": ["{{base_url}}"], "path": ["cards", "{{card_id}}", "transactions"], "query": [{ "key": "page", "value": "1" }] } }, "status": "OK", "code": 200, "_postman_previewlanguage": "json", "header": [{ "key": "Content-Type", "value": "application/json" }], "body": "{\n  \"data\": {\n    \"card\": {\"id\": 145, \"masked_pan\": \"**** **** **** 1041\"},\n    \"transactions\": [{\"id\": \"txn_9281\", \"type\": \"purchase\", \"amount\": 12.5, \"currency\": \"USD\", \"merchant\": \"Example Store\", \"status\": \"COMPLETED\", \"created_at\": \"2026-09-12T12:00:00Z\"}]\n  },\n  \"message\": {\"success\": [\"Business card transactions fetched successfully\"]}\n}" }]
        },
        {
          "name": "Recharge card",
          "event": [{ "listen": "prerequest", "script": { "type": "text/javascript", "exec": ["pm.variables.set('request_uuid', pm.variables.replaceIn('{{$guid}}'));"] } }],
          "request": {
            "method": "POST",
            "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }, { "key": "X-KatFacil-Secret", "value": "{{api_secret}}", "type": "text" }, { "key": "Idempotency-Key", "value": "{{request_uuid}}", "type": "text" }],
            "body": { "mode": "raw", "raw": "{\n  \"card_id\": {{card_id}},\n  \"amount\": {{recharge_amount}}\n}", "options": { "raw": { "language": "json" } } },
            "url": { "raw": "{{base_url}}/cards/fund", "host": ["{{base_url}}"], "path": ["cards", "fund"] },
            "description": "Moves the requested amount to the card and charges the business wallet according to its subscription plan. Requires live activation, sufficient wallet balance, configured min/max limits and a unique UUID Idempotency-Key."
          },
          "response": [{ "name": "200 - Card recharged", "originalRequest": { "method": "POST", "header": [], "url": { "raw": "{{base_url}}/cards/fund", "host": ["{{base_url}}"], "path": ["cards", "fund"] }, "body": { "mode": "raw", "raw": "{\"card_id\":145,\"amount\":25}" } }, "status": "OK", "code": 200, "_postman_previewlanguage": "json", "header": [{ "key": "Content-Type", "value": "application/json" }], "body": "{\n  \"data\": {\n    \"card\": {\"id\": 145, \"balance\": 26, \"currency\": \"USD\", \"status\": \"ACTIVE\"},\n    \"transaction_id\": \"PGB123456790\",\n    \"charge_summary\": {\"requested_amount\": 25, \"fixed_charge\": 1, \"percent_rate\": 1, \"percent_charge\": 0.25, \"total_charge\": 1.25, \"payable\": 26.25}\n  },\n  \"message\": {\"success\": [\"Business card funded successfully\"]}\n}" }]
        },
        {
          "name": "Change card status",
          "event": [{ "listen": "prerequest", "script": { "type": "text/javascript", "exec": ["pm.variables.set('request_uuid', pm.variables.replaceIn('{{$guid}}'));"] } }],
          "request": { "method": "PUT", "header": [{ "key": "Accept", "value": "application/json" }, { "key": "Content-Type", "value": "application/json" }, { "key": "X-KatFacil-Secret", "value": "{{api_secret}}", "type": "text" }, { "key": "Idempotency-Key", "value": "{{request_uuid}}", "type": "text" }], "body": { "mode": "raw", "raw": "{\n  \"status\": \"frozen\"\n}", "options": { "raw": { "language": "json" } } }, "url": { "raw": "{{base_url}}/cards/{{card_id}}/status", "host": ["{{base_url}}"], "path": ["cards", "{{card_id}}", "status"] }, "description": "Single endpoint for card status changes. Send frozen to temporarily prevent card use or active to restore it. Use a new UUID for each new change. Requires live activation." },
          "response": [{ "name": "200 - Status updated", "originalRequest": { "method": "PUT", "header": [], "url": { "raw": "{{base_url}}/cards/{{card_id}}/status", "host": ["{{base_url}}"], "path": ["cards", "{{card_id}}", "status"] }, "body": { "mode": "raw", "raw": "{\"status\":\"active\"}" } }, "status": "OK", "code": 200, "_postman_previewlanguage": "json", "header": [{ "key": "Content-Type", "value": "application/json" }], "body": "{\n  \"data\": {\n    \"card\": {\"id\": 145, \"masked_pan\": \"**** **** **** 1041\", \"status\": \"ACTIVE\"}\n  },\n  \"message\": {\"success\": [\"Business card status updated successfully\"]}\n}" }]
        }
      ]
    },
    {
      "name": "3 - Webhooks",
      "description": "KatFacil sends selected events to the HTTPS callback configured in the Business dashboard. Verify X-KatFacil-Signature against the exact raw request body using HMAC SHA-256 and your signing secret. Store X-KatFacil-Delivery and ignore duplicates. Return HTTP 2xx quickly, then process asynchronously. Documented events include katfacil.webhook.test, katfacil.card.created, katfacil.card.authorization_requested, katfacil.card.transaction_updated, katfacil.card.funding_requested, katfacil.card.funding_approved and katfacil.card.status_updated.",
      "item": [
        {
          "name": "Example webhook delivery (local receiver test)",
          "request": {
            "auth": { "type": "noauth" },
            "method": "POST",
            "header": [
              { "key": "Content-Type", "value": "application/json" },
              { "key": "X-KatFacil-Delivery", "value": "{{$guid}}" },
              { "key": "X-KatFacil-Signature", "value": "sha256=replace_with_hmac_of_raw_body", "description": "HMAC SHA-256 of the exact raw body using your signing secret." }
            ],
            "body": { "mode": "raw", "raw": "{\n  \"id\": \"0e56876e-33a8-42f9-a969-acde01234567\",\n  \"event\": \"katfacil.card.funding_approved\",\n  \"created_at\": \"2026-09-12T12:00:00Z\",\n  \"data\": {\n    \"card\": {\"id\": 145, \"masked_pan\": \"**** **** **** 1041\", \"balance\": 26, \"currency\": \"USD\"},\n    \"transaction_id\": \"PGB123456790\",\n    \"amount\": 25,\n    \"currency\": \"USD\"\n  }\n}", "options": { "raw": { "language": "json" } } },
            "url": { "raw": "{{callback_url}}", "host": ["{{callback_url}}"] },
            "description": "This request targets your own callback URL and is only a receiver example. Generate the signature from the exact raw JSON body before sending. Do not send secrets in webhook payloads."
          },
          "response": [{ "name": "Recommended receiver response", "originalRequest": { "method": "POST", "header": [], "url": { "raw": "{{callback_url}}", "host": ["{{callback_url}}"] } }, "status": "OK", "code": 200, "_postman_previewlanguage": "json", "header": [{ "key": "Content-Type", "value": "application/json" }], "body": "{\"received\":true}" }]
        }
      ]
    },
    {
      "name": "4 - Error examples",
      "description": "Common errors clients must handle.\n\n401: missing or invalid key pair.\n403 BUSINESS_API_APPROVAL_REQUIRED: administrator approval is pending.\n403 LIVE_API_ACTIVATION_REQUIRED: complete the qualifying first deposit, then switch to the live key pair.\n422: validation failure or missing/invalid UUID Idempotency-Key.\n429 API_RATE_LIMIT_EXCEEDED: wait retry_after seconds.\n429 CARD_DAILY_LIMIT_EXCEEDED or FUND_DAILY_LIMIT_EXCEEDED: daily business limit reached.\n\nExample LIVE activation error:\n{\n  \"data\": {\"code\": \"LIVE_API_ACTIVATION_REQUIRED\", \"api_mode\": \"test\", \"live_activation\": {\"minimum_first_deposit\": 25, \"currency\": \"USD\"}},\n  \"message\": {\"error\": [\"Complete a successful first deposit to activate live API operations.\"]}\n}\n\nExample rate limit error:\n{\n  \"data\": {\"code\": \"API_RATE_LIMIT_EXCEEDED\", \"request_id\": \"uuid\", \"retry_after\": 42},\n  \"message\": {\"error\": [\"Too many API requests. Please try again shortly.\"]}\n}"
    }
  ]
}
