Card Validation

Overview

The Card Validation endpoint allows you to perform card verification with fraud prevention in a single Firstoken API call.

What Happens Internally

Client Request → Firstoken API → [Tokenization + Antifraud + Authorization +. Void] → Response
  1. Tokenization: Card data is tokenized with KOIN

  2. Anti-fraud validation

  3. Authorization with a micro amount

  4. Immediate cancellation (void) of the authorization

  5. Response: Transaction details returned

This process validates the card's authenticity while providing fraud risk assessment, without permanently charging the cardholder.

Request Body

The request format is identical to the Authorization endpoint, but with "type": "validation" instead of "type": "authorization".


Customer Experience

  • Temporary hold: The customer will see a temporary block for the specified amount on their card

  • Immediate release: The amount is automatically released after validation

  • Error handling: If there's an error during the void process, the hold will be automatically released within 7 business days

Response Flow

The validation process can result in different outcomes:

┌─────────────────────────────────────────┐
│     Card Validation Request Sent        │
└───────────────┬─────────────────────────┘


┌─────────────────────────────────────────┐
│      1. Tokenization with KOIN          │
└───────────────┬─────────────────────────┘


┌─────────────────────────────────────────┐
│      2. Anti-Fraud Validation           │
└───────────────┬─────────────────────────┘

        ┌───────┴────────┐
        │                │
        ▼                ▼
   ✅ Approved      ❌ Declined
        │                │
        │                └─────► status: "Declined"
        │                        risk_info.status: "Declined"
        │                        (No authorization attempted)


┌─────────────────────────────────────────┐
│      3. Authorization with Micro-Amount │
└───────────────┬─────────────────────────┘

        ┌───────┴────────┐
        │                │
        ▼                ▼
   ✅ Authorized    ❌ Declined
        │                │
        │                └─────► status: "Declined"
        │                        risk_info.status: "Approved"
        │                        error_info present
        │                        (e.g., InsufficientFunds)


┌─────────────────────────────────────────┐
│      4. Immediate Void (Cancellation)   │
└───────────────┬─────────────────────────┘


           ✅ Success

                └─────► status: "Validated"
                        risk_info.status: "Approved"
                        void_info.status: "Voided"

Endpoint

POST /v1/payments/


Field Specifications

transaction_info (Required)

Parameter
Type
Required
Description

type

string

Yes

Must be "validation" for card validation requests

reference_code

string

Yes

Unique reference code for the transaction

card (Required)

Parameter
Type
Required
Description

number

string

Yes

Card number (PAN)

expiration_date

string

Yes

Card expiration date in format MM/YYYY

security_code

string

Yes

Card CVV/CVC security code

holder

string

Yes

Cardholder name as it appears on the card

Note: Use a Firstoken token instead of card details; simply apply the token directly as follow

Order Info

Parameter
Type
Required
Description

amount_details

object

Yes

Contains amount and currency information

amount_details.total_amount

number

Yes

Total amount for validation (typically 1 or minimal amount)

amount_details.currency

string

Yes

Currency code (e.g., "BRL", "USD", "COP")

amount_details.items_amount

number

Yes

Items amount

installments

number

Yes

Number of installments (use 1 for validation)

descriptor

string

Yes

Description that appears on statement

Cardholder Info

Parameter
Type
Required
Description

first_name

string

Yes

Cardholder first name

last_name

string

Yes

Cardholder last name

document

object

Yes

Document information

document.type

string

Yes

Document type (e.g., "CPF", "CC", "DNI")

document.number

string

Yes

Document number

document.nationality

string

Yes

Nationality code (ISO 3166-1 alpha-2)

country

string

Yes

Country code (ISO 3166-1 alpha-2)

address_1

string

Yes

Primary address line

city

string

Yes

City name

state

string

Yes

State or province code

postal_code

string

Yes

Postal/ZIP code

email

string

Yes

Email address

phone_number

string

Yes

Phone number

phone_type

string

Yes

Phone type (e.g., "Mobile", "Home")

phone_area_code

string

Yes

Phone area code

Bill To

Contains billing information with the same structure as cardholder_info, plus:

Parameter
Type
Required
Description

id

string

Yes

Billing ID

profile

string

Yes

Profile identifier

Line Items

Array of purchase items (at least one required):

Parameter
Type
Required
Description

category

object

Yes

Item category information

category.id

string

Yes

Category ID

category.name

string

Yes

Category name

id

string

Yes

Item ID

name

string

Yes

Item name

price

number

Yes

Item unit price

quantity

number

Yes

Quantity

type

string

Yes

Item type (e.g., "Generic")

Device Info

Parameter
Type
Required
Description

ip_address

string

Yes

Customer's IP address

fingerprint_session_id*

string

Yes

A unique numerical ID generated for each user session on a website.

(*) The fingerprint_session_id is generated using a Koin script that is called from the webpage.


Example Request

curl --location 'https://api.firstoken.co/v1/payments' \
--header 'Content-Type: application/json' \
--header 'x-api-key: YOUR_API_KEY' \
--data-raw '{
  "transaction_info": {
    "type": "validation",
    "reference_code": "1753550023570"
  },
  "card": {
    "number": "4225289837059229",
    "expiration_date": "01/2030",
    "security_code": "123",
    "holder": "John Doe Jones"
  },
  "order_info": {
    "amount_details": {
      "total_amount": 1,
      "currency": "BRL",
      "items_amount": 1
    },
    "installments": 1,
    "descriptor": "Test Payment"
  },
  "cardholder_info": {
    "first_name": "John",
    "last_name": "Doe",
    "document": {
      "type": "CPF",
      "number": "54672396002",
      "nationality": "BR"
    },
    "country": "BR",
    "address_1": "123 Main St",
    "city": "Sao Paulo",
    "state": "SP",
    "postal_code": "04001-000",
    "email": "john@test.com",
    "phone_number": "4158880000",
    "phone_type": "Mobile",
    "phone_area_code": "22"
  },
  "bill_to": {
    "id": "1234567890",
    "first_name": "John",
    "last_name": "Doe",
    "document": {
      "type": "CPF",
      "number": "54672396002",
      "nationality": "BR"
    },
    "country": "BR",
    "address_1": "123 Main St",
    "city": "Sao Paulo",
    "state": "SP",
    "postal_code": "04001-000",
    "email": "test@cybs.com",
    "phone_number": "4158880000",
    "phone_type": "Mobile",
    "phone_area_code": "22",
    "profile": "1"
  },
  "line_items": [
    {
      "category": {
        "id": "1",
        "name": "Category 2"
      },
      "id": "1",
      "name": "Item ",
      "price": 1500,
      "quantity": 1,
      "type": "Generic"
    }
  ],
  "device_info": {
    "ip_address": "127.0.0.1",
    "fingerprint_session_id": "cf01cee443d8529475f4841a3a78348c"
  }
}'

Response Structure

Success Response - Card Validated

{
  "status": "success",
  "message": "Validation successful",
  "data": {
    "transaction_info": {
      "type": "validation_response",
      "reference_code": "1753550023570",
      "transaction_id": "0001761666589459054367",
      "request_id": "6d488360-ce28-47c7-9722-6bebd1c5d8c9",
      "status": "Validated",
      "response_code": "777775",
      "created_at": "2025-10-28T15:49:57.331Z"
    },
    "order_info": {
      "amount_details": {
        "authorized_amount": 1,
        "currency": "BRL"
      }
    },
    "risk_info": {
      "status": "Approved",
      "date": "2025-10-28T15:50:03.000Z",
      "strategies": []
    },
    "void_info": {
      "request_id": "6d488360-ce28-47c7-9722-6bebd1c5d8c9",
      "status": "Voided"
    }
  }
}

Declined Response - Authorization Failed

When the card passes anti-fraud validation but the authorization is declined (e.g., insufficient funds), no void is generated since authorization was not completed:

{
  "status": "success",
  "message": "Payment failed",
  "data": {
    "transaction_info": {
      "type": "validation_response",
      "reference_code": "1753550023570",
      "transaction_id": "0001761674061485235739",
      "request_id": "de70f9d6-b85b-49dd-b205-3f374ed9d7de",
      "status": "Declined",
      "created_at": "2025-10-28T17:54:27.272Z"
    },
    "order_info": {
      "amount_details": {
        "authorized_amount": 10001,
        "currency": "BRL"
      }
    },
    "risk_info": {
      "status": "Approved",
      "date": "2025-10-28T17:54:26.000Z",
      "strategies": []
    },
    "error_info": {
      "reason": "InsufficientFunds",
      "message": "Transaction failed"
    }
  }
}

Note: When transaction_info.status is "Declined", there will be no void_info in the response because the authorization was not completed. An error_info object will be present instead with the reason for the decline.

Response Fields

Transaction Info

Field
Type
Description

type

string

Response type: "validation_response"

reference_code

string

Your original reference code

transaction_id

string

Unique transaction identifier assigned by KOIN

request_id

string

Unique request identifier

status

string

Validation status: "Validated" or "Declined"

response_code

string

Response code from the processor

created_at

string

Timestamp of transaction creation (ISO 8601)

Order Info

Field
Type
Description

amount_details.authorized_amount

number

Amount that was authorized

amount_details.currency

string

Currency code

Risk Info

Contains anti-fraud analysis results:

Field
Type
Description

status

string

Risk assessment result: "Approved" or "Declined"

date

string

Timestamp of risk analysis (ISO 8601)

strategies

array

Array of risk strategies applied (if any)

Void Info

Contains cancellation status:

Field
Type
Description

request_id

string

Request ID for the void operation

status

string

Void status: "Voided" indicates successful cancellation

Note: The void_info object is only present when the authorization was successful. If authorization fails, an error_info object will be present instead.

Error Info

Contains error details when authorization is declined (only present when transaction_info.status is "Declined"):

Field
Type
Description

reason

string

Reason code for the decline (e.g., "InsufficientFunds", "CardExpired", "InvalidCard")

message

string

Human-readable error message


Response Status Values

Transaction Status

  • Validated: Card validation successful, authorization completed and voided

  • Declined: Card validation failed OR authorization was declined

    • When declined with risk_info.status: "Approved": Authorization failed (e.g., insufficient funds, card blocked)

    • When declined with risk_info.status: "Declined": Anti-fraud checks failed

Risk Status

  • Approved: Passed anti-fraud checks

  • Declined: Failed anti-fraud checks

Void Status

  • Voided: Authorization successfully cancelled

  • Error: Error during void process

  • Not present: When authorization was not completed (transaction declined before authorization)

Error Reasons (in error_info.reason)

Common decline reasons when authorization fails:

Reason
Description

InsufficientFunds

Card has insufficient funds for the transaction

CardExpired

Card expiration date has passed

InvalidCard

Card number is invalid or card is not active

CardBlocked

Card has been blocked by the issuer

ExceedsLimit

Transaction exceeds card limit

IssuerUnavailable

Card issuer system is temporarily unavailable

StolenCard

Card has been reported as stolen

LostCard

Card has been reported as lost

RestrictedCard

Card has restrictions that prevent this transaction


Error Handling

Error Response Example

{
  "status": "fail",
  "message": "Invalid request",
  "data": {
    "description": "Must be a valid credit card number or token",
    "path": "card.number"
  }
}

Error Response Fields

Field
Type
Description

status

string

Always "fail" for error responses

message

string

General error message

data.description

string

Detailed description of the error

data.path

string

Field path that caused the error


Testing

Test Scenarios

  1. Successful Validation

    • Use approved test card (4225289837059229)

    • Use low amount (e.g., 1)

    • Verify transaction_info.status: "Validated"

    • Verify risk_info.status: "Approved"

    • Confirm void_info.status: "Voided"

    • Expected: Complete flow with void

  2. Authorization Declined - Insufficient Funds

    • Use approved test card

    • Use high amount (e.g., 10001 or higher)

    • Verify transaction_info.status: "Declined"

    • Verify risk_info.status: "Approved" (passes fraud check)

    • Confirm error_info.reason: "InsufficientFunds"

    • Confirm void_info is NOT present

    • Expected: Fraud passes but authorization fails

  3. Fraud Decline

    • Use email: john_autoreject@test.com

    • Verify transaction_info.status: "Declined"

    • Verify risk_info.status: "Declined"

    • Confirm void_info is NOT present

    • Expected: Fails at fraud validation, no authorization attempted

  4. Invalid Card

    • Use invalid card number (e.g., 1234567890123456)

    • Verify appropriate error response with status: "fail"

    • Check data.path: "card.number"

    • Expected: Request validation error


Last updated

Was this helpful?