KatFacil Developer documentation
Business PortalAPI JSON
Business Cards API · v1

Everything you need to issue and manage cards.

This guide walks your team through authentication, card creation, funding, transactions and webhooks—with working requests you can adapt to your backend.

https://katfacil.com/api/v1

Start here

If this is your first integration, begin with your test credentials. You can move to live mode after approval and the required first deposit.

Authentication

Keep both credentials on your backend. Every request must use the matching key and secret for the current account mode.

X-KatFacil-Key: YOUR_API_KEY
X-KatFacil-Secret: YOUR_API_SECRET
Accept: application/json
Content-Type: application/json

From test to live

Safe reads work in test mode. Financial operations unlock when administrator approval and the configured first-deposit requirement are satisfied.

Get approvedAdministrator approves API access and limits.
Use test keysRead API status and current charges.
Make first depositMeet the minimum shown by live_activation.
Switch to live keysCreate, recharge and manage cards.

API reference

All URLs below are relative to https://katfacil.com/api/v1. A unique UUID Idempotency-Key is required for POST and PUT operations.

GET/cards

List cards and API status

Returns all non-demo cards owned by the authenticated business, the active API mode, live activation state and card creation limit. This safe read is available with valid test credentials.

Request example
curl --request GET \
  --url 'https://katfacil.com/api/v1/cards' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'X-KatFacil-Key: YOUR_API_KEY' \
  --header 'X-KatFacil-Secret: YOUR_API_SECRET'
const response = await fetch('https://katfacil.com/api/v1/cards', {
  method: 'GET',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'X-KatFacil-Key': 'YOUR_API_KEY',
    'X-KatFacil-Secret': 'YOUR_API_SECRET'
  }
});

const data = await response.json();
<?php

$curl = curl_init('https://katfacil.com/api/v1/cards');

curl_setopt_array($curl, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => [
        'Accept: application/json',
        'Content-Type: application/json',
        'X-KatFacil-Key: YOUR_API_KEY',
        'X-KatFacil-Secret: YOUR_API_SECRET'
    ]
]);

$response = curl_exec($curl);
import json
import requests

response = requests.request(
    'GET',
    'https://katfacil.com/api/v1/cards',
    headers={
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-KatFacil-Key': 'YOUR_API_KEY',
        'X-KatFacil-Secret': 'YOUR_API_SECRET'
    }
)

data = response.json()
Example response
{
    "data": {
        "api_mode": "live",
        "live_activation": {
            "activated": true,
            "first_deposit_required": true,
            "minimum_first_deposit": 25,
            "currency": "USD"
        },
        "card_create_limit": 25,
        "cards": [
            {
                "id": 145,
                "external_id": "card_8f2d",
                "card_product": "mastercard_virtual",
                "brand": "Mastercard Virtual",
                "name_on_card": "JEAN ROODY DIE",
                "balance": 26,
                "currency": "USD",
                "masked_pan": "**** **** **** 1041",
                "expiry": "09/29",
                "status": "ACTIVE",
                "created_at": "2026-09-12T12:00:00Z"
            }
        ]
    },
    "message": {
        "success": [
            "Business cards fetched successfully"
        ]
    }
}
GET/cards/charges

Get current card charges

Returns the authenticated business subscription plan and creation/recharge pricing for all supported products. Retrieve this resource before displaying or confirming a financial operation.

Request example
curl --request GET \
  --url 'https://katfacil.com/api/v1/cards/charges' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'X-KatFacil-Key: YOUR_API_KEY' \
  --header 'X-KatFacil-Secret: YOUR_API_SECRET'
const response = await fetch('https://katfacil.com/api/v1/cards/charges', {
  method: 'GET',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'X-KatFacil-Key': 'YOUR_API_KEY',
    'X-KatFacil-Secret': 'YOUR_API_SECRET'
  }
});

const data = await response.json();
<?php

$curl = curl_init('https://katfacil.com/api/v1/cards/charges');

curl_setopt_array($curl, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => [
        'Accept: application/json',
        'Content-Type: application/json',
        'X-KatFacil-Key: YOUR_API_KEY',
        'X-KatFacil-Secret: YOUR_API_SECRET'
    ]
]);

$response = curl_exec($curl);
import json
import requests

response = requests.request(
    'GET',
    'https://katfacil.com/api/v1/cards/charges',
    headers={
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-KatFacil-Key': 'YOUR_API_KEY',
        'X-KatFacil-Secret': 'YOUR_API_SECRET'
    }
)

data = response.json()
Example response
{
    "data": {
        "api_mode": "live",
        "live_activation": {
            "activated": true,
            "first_deposit_required": true,
            "minimum_first_deposit": 25,
            "currency": "USD"
        },
        "wallet_currency": "USD",
        "subscription_plan": "regular",
        "products": [
            {
                "card_product": "mastercard_virtual",
                "brand": "Mastercard",
                "creation": {
                    "requested_amount": 1,
                    "initial_load": 1,
                    "fixed_charge": 2,
                    "percent_rate": 0,
                    "percent_charge": 0,
                    "bank_cost": 0,
                    "total_charge": 2,
                    "payable": 3
                },
                "recharge": {
                    "requested_amount": 0,
                    "fixed_charge": 1,
                    "percent_rate": 1,
                    "percent_charge": 0,
                    "bank_cost": 0,
                    "total_charge": 1,
                    "payable": 1,
                    "min_amount": 1,
                    "max_amount": 2500
                }
            }
        ]
    },
    "message": {
        "success": [
            "Business card charges fetched successfully"
        ]
    }
}
POST/cards/create

Create a card

Creates one card for the verified business account. Requires an active subscription, live API activation, sufficient wallet balance and a unique UUID Idempotency-Key. Repeating an identical request with the same key returns the original result and does not create a duplicate card.

Request body

{
    "card_product": "mastercard_virtual"
}
Request example
curl --request POST \
  --url 'https://katfacil.com/api/v1/cards/create' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'X-KatFacil-Key: YOUR_API_KEY' \
  --header 'X-KatFacil-Secret: YOUR_API_SECRET' \
  --data '{
    "card_product": "mastercard_virtual"
}'
const response = await fetch('https://katfacil.com/api/v1/cards/create', {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'X-KatFacil-Key': 'YOUR_API_KEY',
    'X-KatFacil-Secret': 'YOUR_API_SECRET'
  },
  body: JSON.stringify({
    "card_product": "mastercard_virtual"
})
});

const data = await response.json();
<?php

$curl = curl_init('https://katfacil.com/api/v1/cards/create');

curl_setopt_array($curl, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Accept: application/json',
        'Content-Type: application/json',
        'X-KatFacil-Key: YOUR_API_KEY',
        'X-KatFacil-Secret: YOUR_API_SECRET'
    ],
    CURLOPT_POSTFIELDS => '{\"card_product\":\"mastercard_virtual\"}'
]);

$response = curl_exec($curl);
import json
import requests

response = requests.request(
    'POST',
    'https://katfacil.com/api/v1/cards/create',
    headers={
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-KatFacil-Key': 'YOUR_API_KEY',
        'X-KatFacil-Secret': 'YOUR_API_SECRET'
    },
    json=json.loads('''{
    "card_product": "mastercard_virtual"
}''')
)

data = response.json()
Example response
{
    "data": {
        "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",
            "created_at": "2026-09-12T12:00:00Z"
        },
        "transaction_id": "PGB123456789",
        "charge_summary": {
            "requested_amount": 1,
            "initial_load": 1,
            "fixed_charge": 2,
            "percent_rate": 0,
            "percent_charge": 0,
            "bank_cost": 0,
            "total_charge": 2,
            "payable": 3
        }
    },
    "message": {
        "success": [
            "Business card created successfully"
        ]
    }
}
GET/cards/{id}

Get card details

Returns a card owned by the authenticated business. Full PAN, CVV, PIN, secrets, tokens and upstream service information are not returned.

Request example
curl --request GET \
  --url 'https://katfacil.com/api/v1/cards/{id}' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'X-KatFacil-Key: YOUR_API_KEY' \
  --header 'X-KatFacil-Secret: YOUR_API_SECRET'
const response = await fetch('https://katfacil.com/api/v1/cards/{id}', {
  method: 'GET',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'X-KatFacil-Key': 'YOUR_API_KEY',
    'X-KatFacil-Secret': 'YOUR_API_SECRET'
  }
});

const data = await response.json();
<?php

$curl = curl_init('https://katfacil.com/api/v1/cards/{id}');

curl_setopt_array($curl, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => [
        'Accept: application/json',
        'Content-Type: application/json',
        'X-KatFacil-Key: YOUR_API_KEY',
        'X-KatFacil-Secret: YOUR_API_SECRET'
    ]
]);

$response = curl_exec($curl);
import json
import requests

response = requests.request(
    'GET',
    'https://katfacil.com/api/v1/cards/{id}',
    headers={
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-KatFacil-Key': 'YOUR_API_KEY',
        'X-KatFacil-Secret': 'YOUR_API_SECRET'
    }
)

data = response.json()
Example response
{
    "data": {
        "card": {
            "id": 145,
            "external_id": "card_8f2d",
            "card_product": "mastercard_virtual",
            "brand": "Mastercard Virtual",
            "name_on_card": "JEAN ROODY DIE",
            "balance": 26,
            "currency": "USD",
            "masked_pan": "**** **** **** 1041",
            "expiry": "09/29",
            "status": "ACTIVE",
            "created_at": "2026-09-12T12:00:00Z"
        }
    },
    "message": {
        "success": [
            "Business card details fetched successfully"
        ]
    }
}
GET/cards/{id}/transactions

Get card transactions

Returns sanitized transactions for a card owned by the authenticated business.

Request example
curl --request GET \
  --url 'https://katfacil.com/api/v1/cards/{id}/transactions' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'X-KatFacil-Key: YOUR_API_KEY' \
  --header 'X-KatFacil-Secret: YOUR_API_SECRET'
const response = await fetch('https://katfacil.com/api/v1/cards/{id}/transactions', {
  method: 'GET',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'X-KatFacil-Key': 'YOUR_API_KEY',
    'X-KatFacil-Secret': 'YOUR_API_SECRET'
  }
});

const data = await response.json();
<?php

$curl = curl_init('https://katfacil.com/api/v1/cards/{id}/transactions');

curl_setopt_array($curl, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => [
        'Accept: application/json',
        'Content-Type: application/json',
        'X-KatFacil-Key: YOUR_API_KEY',
        'X-KatFacil-Secret: YOUR_API_SECRET'
    ]
]);

$response = curl_exec($curl);
import json
import requests

response = requests.request(
    'GET',
    'https://katfacil.com/api/v1/cards/{id}/transactions',
    headers={
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-KatFacil-Key': 'YOUR_API_KEY',
        'X-KatFacil-Secret': 'YOUR_API_SECRET'
    }
)

data = response.json()
Example response
{
    "data": {
        "card": {
            "id": 145,
            "external_id": "card_8f2d",
            "card_product": "mastercard_virtual",
            "brand": "Mastercard Virtual",
            "name_on_card": "JEAN ROODY DIE",
            "balance": 26,
            "currency": "USD",
            "masked_pan": "**** **** **** 1041",
            "expiry": "09/29",
            "status": "ACTIVE",
            "created_at": "2026-09-12T12:00:00Z"
        },
        "transactions": [
            {
                "id": "txn_9281",
                "type": "purchase",
                "amount": 12.5,
                "currency": "USD",
                "merchant": "Example Store",
                "status": "COMPLETED",
                "created_at": "2026-09-12T12:00:00Z"
            }
        ]
    },
    "message": {
        "success": [
            "Business card transactions fetched successfully"
        ]
    }
}
POST/cards/fund

Recharge a card

Moves the requested amount to a card. The business wallet must cover the amount plus applicable plan charges. Requires live activation and a unique UUID Idempotency-Key.

Request body

{
    "card_id": 145,
    "amount": 25
}
Request example
curl --request POST \
  --url 'https://katfacil.com/api/v1/cards/fund' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'X-KatFacil-Key: YOUR_API_KEY' \
  --header 'X-KatFacil-Secret: YOUR_API_SECRET' \
  --data '{
    "card_id": 145,
    "amount": 25
}'
const response = await fetch('https://katfacil.com/api/v1/cards/fund', {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'X-KatFacil-Key': 'YOUR_API_KEY',
    'X-KatFacil-Secret': 'YOUR_API_SECRET'
  },
  body: JSON.stringify({
    "card_id": 145,
    "amount": 25
})
});

const data = await response.json();
<?php

$curl = curl_init('https://katfacil.com/api/v1/cards/fund');

curl_setopt_array($curl, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Accept: application/json',
        'Content-Type: application/json',
        'X-KatFacil-Key: YOUR_API_KEY',
        'X-KatFacil-Secret: YOUR_API_SECRET'
    ],
    CURLOPT_POSTFIELDS => '{\"card_id\":145,\"amount\":25}'
]);

$response = curl_exec($curl);
import json
import requests

response = requests.request(
    'POST',
    'https://katfacil.com/api/v1/cards/fund',
    headers={
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-KatFacil-Key': 'YOUR_API_KEY',
        'X-KatFacil-Secret': 'YOUR_API_SECRET'
    },
    json=json.loads('''{
    "card_id": 145,
    "amount": 25
}''')
)

data = response.json()
Example response
{
    "data": {
        "card": {
            "id": 145,
            "external_id": "card_8f2d",
            "card_product": "mastercard_virtual",
            "brand": "Mastercard Virtual",
            "name_on_card": "JEAN ROODY DIE",
            "balance": 26,
            "currency": "USD",
            "masked_pan": "**** **** **** 1041",
            "expiry": "09/29",
            "status": "ACTIVE",
            "created_at": "2026-09-12T12:00:00Z"
        },
        "transaction_id": "PGB123456790",
        "charge_summary": {
            "requested_amount": 25,
            "fixed_charge": 1,
            "percent_rate": 1,
            "percent_charge": 0.25,
            "bank_cost": 0,
            "total_charge": 1.25,
            "payable": 26.25,
            "min_amount": 1,
            "max_amount": 2500
        }
    },
    "message": {
        "success": [
            "Business card funded successfully"
        ]
    }
}
PUT/cards/{id}/status

Change card status

Single status operation for both directions. Send frozen to temporarily prevent card use or active to restore normal card use. Do not implement separate freeze, unfreeze or activation endpoints.

frozen
Temporarily prevent card use
active
Restore normal card use

Request body

{
    "status": "frozen"
}
Request example
curl --request PUT \
  --url 'https://katfacil.com/api/v1/cards/{id}/status' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'X-KatFacil-Key: YOUR_API_KEY' \
  --header 'X-KatFacil-Secret: YOUR_API_SECRET' \
  --data '{
    "status": "frozen"
}'
const response = await fetch('https://katfacil.com/api/v1/cards/{id}/status', {
  method: 'PUT',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'X-KatFacil-Key': 'YOUR_API_KEY',
    'X-KatFacil-Secret': 'YOUR_API_SECRET'
  },
  body: JSON.stringify({
    "status": "frozen"
})
});

const data = await response.json();
<?php

$curl = curl_init('https://katfacil.com/api/v1/cards/{id}/status');

curl_setopt_array($curl, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_HTTPHEADER => [
        'Accept: application/json',
        'Content-Type: application/json',
        'X-KatFacil-Key: YOUR_API_KEY',
        'X-KatFacil-Secret: YOUR_API_SECRET'
    ],
    CURLOPT_POSTFIELDS => '{\"status\":\"frozen\"}'
]);

$response = curl_exec($curl);
import json
import requests

response = requests.request(
    'PUT',
    'https://katfacil.com/api/v1/cards/{id}/status',
    headers={
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-KatFacil-Key': 'YOUR_API_KEY',
        'X-KatFacil-Secret': 'YOUR_API_SECRET'
    },
    json=json.loads('''{
    "status": "frozen"
}''')
)

data = response.json()
Example response
{
    "data": {
        "card": {
            "id": 145,
            "external_id": "card_8f2d",
            "card_product": "mastercard_virtual",
            "brand": "Mastercard Virtual",
            "name_on_card": "JEAN ROODY DIE",
            "balance": 26,
            "currency": "USD",
            "masked_pan": "**** **** **** 1041",
            "expiry": "09/29",
            "status": "FROZEN",
            "created_at": "2026-09-12T12:00:00Z"
        }
    },
    "message": {
        "success": [
            "Business card status updated successfully"
        ]
    }
}

Signed webhooks

Verify X-KatFacil-Signature against the exact raw request body, store X-KatFacil-Delivery to reject duplicates, and return a 2xx response quickly.

{
    "id": "0e56876e-33a8-42f9-a969-acde01234567",
    "event": "katfacil.card.funding_approved",
    "created_at": "2026-09-12T12:00:00Z",
    "data": {
        "card": {
            "id": 145,
            "masked_pan": "**** **** **** 1041",
            "balance": 26,
            "currency": "USD"
        },
        "transaction_id": "PGB123456790",
        "amount": 25,
        "currency": "USD"
    }
}

Errors to handle

Save the X-Request-ID response header for troubleshooting.

401
Missing or invalid credentials
403
Approval or first-deposit activation required
422
Invalid fields or idempotency UUID
429
Rate or daily limit reached

Downloads

Download the KatFacil API specification for documentation tools or code generation, and use the Postman collection for manual testing.