> For the complete documentation index, see [llms.txt](https://firstoken.gitbook.io/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://firstoken.gitbook.io/api-docs/api-reference/payments/payments-api-koin/testing-guide.md).

# 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
