# Testing Guide

### Overview

This guide provides comprehensive testing scenarios for KOIN payment integration. All examples use the sandbox environment where no real money is processed.

### Sandbox Environment

* **Base URL**: `https://api.firstoken-staging.co/v1/payments/`
* **Environment**: Complete simulation of production KOIN processing
* **Test Cards**: Any valid card format works in sandbox
* **Real-time Testing**: All flows work exactly like production

### Test Card Numbers

For KOIN testing, you can use any valid card number format. The payment processing is simulated based on other request parameters.

#### Test Card Numbers

For KOIN testing, you can use any valid card number format. The system will simulate the payment flow:

| Card Brand           | Number              | CVV         | Notes                |
| -------------------- | ------------------- | ----------- | -------------------- |
| **Visa**             | 4111 1111 1111 1111 | Any 3-digit | Standard test        |
| **Mastercard**       | 5555 5555 5555 4444 | Any 3-digit | Standard test        |
| **American Express** | 3782 8224 6310 005  | Any 4-digit | Requires 4-digit CVV |

**Important Notes:**

* Use any expiration date in the future (MM/YYYY format)
* Cardholder name can be any valid name format
* All cards work in sandbox for testing different scenarios

### Amount-Based Testing

Control transaction outcomes by using specific amounts in your test requests. KOIN uses transaction amounts to simulate different scenarios:

| Amount Range (cents) | Final Status | Description       |
| -------------------- | ------------ | ----------------- |
| 1 - 5000             | Collected    | Success           |
| 5001 - 10000         | Failed       | ChannelRejected   |
| 10001 - 15000        | Failed       | InsufficientFunds |
| 15001 - 20000        | Failed       | InvalidCard       |
| 20001 - 25000        | Failed       | InvalidData       |
| 25001 - 30000        | Failed       | Referred          |
| 30001 - 35000        | Failed       | ExpiredCard       |
| 35001 - 40000        | Failed       | StolenCard        |
| 40001 - 45000        | Failed       | ConnectionRefused |
| 50001 - 55000        | Authorized   | Undefined         |
| 60000 - 65000        | Authorized   | Success           |
| 65001 - 70000        | Authorized   | Success           |
| + 150000             | Collected    | Success           |

**Example**: To test a successful payment, use amount `1000` . To test antifraud review, use amount `42000` .

### Antifraud Testing with Email Patterns

Test different antifraud scenarios using specific email patterns in `cardholder_info.email` and `bill_to.email`:

<table><thead><tr><th width="420.15234375">Email Pattern</th><th>Antifraud Behavior</th><th>Description</th></tr></thead><tbody><tr><td><code>{username}+autoaccept@{emailprovider}</code></td><td>Automatically accepted</td><td>Transaction will be accepted</td></tr><tr><td><code>{username}+autoreject@{emailprovider}</code></td><td>Automatically rejected</td><td>Transaction will be rejected</td></tr><tr><td><code>{username}_prereject@{emailprovider}</code></td><td>Rejected at authorization</td><td>Transaction will be rejected at the authorization stage</td></tr><tr><td><code>{username}+preaccept_autoaccept@{emailprovider}</code></td><td>Accepted at all stages</td><td>Transaction will be accepted at all stages</td></tr><tr><td><code>{username}+preaccept_autoreject@{emailprovider}</code></td><td>Mixed result</td><td>Accepted at authorization, rejected at evaluation</td></tr></tbody></table>

#### Example Email Patterns

json

```json
// Auto-accept scenario
"email": "john+autoaccept@test.com"

// Auto-reject scenario  
"email": "john+autoreject@test.com"

// Pre-reject scenario
"email": "john+prereject@test.com"

// Pre-accept then auto-accept
"email": "john+preaccept_autoaccept@test.com"

// Pre-accept then auto-reject
"email": "john+preaccept_autoreject@test.com"
```

### Complete Test Scenarios

#### 1. Successful Payment Flow

```bash
curl -X POST https://api.firstoken.co/v1/payments/ \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "transaction_info": {
      "type": "payment",
      "reference_code": "ref_{{$guid}}"
    },
    "card": {
      "number": "4111111111111111",
      "expiration_date": "12/2030",
      "security_code": "123",
      "holder": "João Silva"
    },
    "order_info": {
      "amount_details": {
        "total_amount": 1500,
        "currency": "BRL",
        "items_amount": 1500
      },
      "installments": 1,
      "descriptor": "Teste Payment"
    },
    "cardholder_info": {
      "first_name": "João",
      "last_name": "Silva",
      "document": {
        "type": "CPF",
        "number": "12345678901",
        "nationality": "BR"
      },
      "country": "BR",
      "address_1": "Rua Teste, 123",
      "city": "São Paulo",
      "state": "SP",
      "postal_code": "01234-567",
      "email": "joao.silva@test.com",
      "phone_number": "11987654321",
      "phone_type": "Mobile",
      "phone_area_code": "11"
    },
    "bill_to": {
      "id": "customer_test_123",
      "first_name": "João",
      "last_name": "Silva",
      "document": {
        "type": "CPF",
        "number": "12345678901",
        "nationality": "BR"
      },
      "country": "BR",
      "address_1": "Rua Teste, 123",
      "city": "São Paulo",
      "state": "SP",
      "postal_code": "01234-567",
      "email": "joao.silva@test.com",
      "phone_number": "11987654321",
      "phone_type": "Mobile",
      "phone_area_code": "11",
      "profile": "test_customer"
    },
    "line_items": [
    {
      "category": {
        "id": "1",
        "name": "Category 1"
      },
      "discount_amount": 10,
      "id": "1",
      "name": "Item 1",
      "price": 1500,
      "quantity": 1,
      "seller_id": "seller id",
      "service_date": "2025-07-01",
      "type": "Generic"
    }
  ],
    "device_info": {
      "ip_address": "192.168.1.100"
    }
  }'
```

#### 2. Authorization + Capture Flow

**Step 1: Authorization**

```bash
curl -X POST https://api.firstoken.co/v1/payments/ \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "transaction_info": {
      "type": "authorization",
      "reference_code": "test_auth_ref_{{$guid}}"
    },
    "card": {
      "number": "5555555555554444",
      "expiration_date": "12/2030",
      "security_code": "123",
      "holder": "Maria Santos"
    },
    "order_info": {
      "amount_details": {
        "total_amount": 5000,
        "currency": "BRL",
        "items_amount": 5000
      },
      "installments": 1,
      "descriptor": "Teste Authorization"
    },
    "cardholder_info": {
      "first_name": "Maria",
      "last_name": "Santos",
      "document": {
        "type": "CPF",
        "number": "54672396002",
        "nationality": "BR"
      },
      "country": "BR",
      "address_1": "Avenida Teste, 456",
      "city": "Rio de Janeiro",
      "state": "RJ",
      "postal_code": "20000-000",
      "email": "maria.santos@test.com",
      "phone_number": "21987654321",
      "phone_type": "Mobile",
      "phone_area_code": "21"
    },
    "bill_to": {
      "id": "customer_maria_456",
      "first_name": "Maria",
      "last_name": "Santos",
      "document": {
        "type": "CPF",
        "number": "54672396002",
        "nationality": "BR"
      },
      "country": "BR",
      "address_1": "Avenida Teste, 456",
      "city": "Rio de Janeiro",
      "state": "RJ",
      "postal_code": "20000-000",
      "email": "maria.santos@test.com",
      "phone_number": "21987654321",
      "phone_type": "Mobile",
      "phone_area_code": "21",
      "profile": "premium_customer"
    },
    "line_items": [
    {
      "category": {
        "id": "1",
        "name": "Category 1"
      },
      "discount_amount": 10,
      "id": "1",
      "name": "Item 1",
      "price": 1500,
      "quantity": 1,
      "seller_id": "seller id",
      "service_date": "2025-07-01",
      "type": "Generic"
    }
  ],
    "device_info": {
      "fingerprint_session_id": "test_auth_session_' $(date +%s) '",
      "ip_address": "203.0.113.50"
    }
  }'
```

**Step 2: Capture (use transaction\_id from step 1)**

```bash
curl -X POST https://api.firstoken.co/v1/payments/{TRANSACTION_ID_FROM_STEP_1}/capture \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "transaction_info": {
      "type": "capture",
      "reference_code": "test_capture_{{$guid}}"
    },
    "capture_info": {
      "amount_details": {
        "total_amount": 5000,
        "currency": "BRL"
      },
      "installments": 1
    },
    "device_info": {
      "ip_address": "203.0.113.50"
    }
  }'
```

#### 3. Authorization + Void Flow

**Step 1: Authorization (same as above)**

**Step 2: Void (use transaction\_id from step 1)**

```bash
curl -X POST https://api.firstoken.co/v1/payments/{TRANSACTION_ID_FROM_STEP_1}/void \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "transaction_info": {
      "type": "authorization_void",
      "reference_code": "test_void_{{$guid}}"
    },
    "device_info": {
      "ip_address": "203.0.113.50"
    }
  }'
```

#### 4. Payment + Refund Flow

**Step 1: Payment (use payment example above)**

**Step 2: Void (use transaction\_id from step 1)**

```bash
curl -X POST https://api.firstoken.co/v1/payments/{TRANSACTION_ID_FROM_STEP_1}/void \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "transaction_info": {
      "type": "payment_refund",
      "reference_code": "test_refund_{{$guid}}"
    },
    "refund_info": {
        "amount_details": {
            "total_amount": 1000,
            "currency": "BRL"
        },
        "installments": 1
    },
    "device_info": {
      "ip_address": "192.168.1.100"
    }
  }'
```

### Error Testing Scenarios

#### 1. Missing Required Fields

```bash
# Test missing CPF
curl -X POST https://api.firstoken.co/v1/payments/ \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "transaction_info": {
      "type": "payment",
      "reference_code": "test_error_ref"
    },
    "card": {
      "number": "4111111111111111",
      "expiration_date": "12/2030",
      "security_code": "123",
      "holder": "Test User"
    },
    "order_info": {
      "amount_details": {
        "total_amount": 1000,
        "currency": "BRL",
        "items_amount": 1000
      },
      "installments": 1,
      "descriptor": "Test Error"
    },
    "cardholder_info": {
      "first_name": "Test",
      "last_name": "User",
      "country": "BR",
      "email": "test@example.com"
      // Missing document field - should cause error
    }
  }'
```

#### 2. Invalid CPF Format

```bash
# Test invalid CPF
curl -X POST https://api.firstoken.co/v1/payments/ \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "transaction_info": {
      "type": "payment",
      "reference_code": "test_invalid_cpf_ref"
    },
    "cardholder_info": {
      "first_name": "Test",
      "last_name": "User",
      "document": {
        "type": "CPF",
        "number": "00000000000",
        "nationality": "BR"
      },
      "country": "BR",
      "email": "test@example.com"
    }
    // ... rest of required fields
  }'
```

### Best Practices for Testing

1. **Use Unique IDs**: Always generate unique transaction IDs
2. **Test All Flows**: Test complete workflows, not just individual endpoints
3. **Error Handling**: Test both success and failure scenarios
4. **Documentation**: Document test cases and expected results
5. **Environment Separation**: Keep test data clearly separated from production


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://firstoken.gitbook.io/api-docs/api-reference/payments/payments-api-koin/testing-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
