> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tonder.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a Payment with Raw Card Data

> Process card payments directly without tokenization for PCI DSS Level 1 certified merchants

This guide shows you how to process payments directly with raw card data without tokenization. This approach is designed for merchants who already have full PCI DSS Level 1 compliance and want to eliminate the multi-step tokenization process.

<Warning>
  **Availability Restriction**

  This process is only available for clients who are fully PCI DSS compliant. You must maintain enterprise-grade security and handle raw card data according to all PCI DSS requirements.

  You must share your Attestation of Compliance (AOC) with Tonder before we activate production access to the raw card endpoints.
</Warning>

## Prerequisites

Before you begin, ensure you have full PCI DSS Level 1 certification, which is mandatory for handling raw card data.

<Info>
  **When to Use This Approach**

  Raw card processing is recommended for:

  * Large enterprise merchants already PCI Level 1 certified.
  * Payment processors operating under existing PCI compliance.
  * High-volume businesses with existing PCI infrastructure.
  * Systems where reduced latency is critical.

  It is not recommended for:

  * Small to medium businesses without PCI compliance.
  * New payment integrations.
  * Cost-conscious merchants (compliance maintenance is expensive).
</Info>

## Step 1: Get an Access Token

Before you can process raw card payments, you must obtain a short-lived access token. This token, along with your API key, authenticates your requests to the raw card processing endpoint.

Send a `POST` request to the tokenization auth endpoint:

<Tabs>
  <Tab title="Sandbox">
    ```bash theme={null}
    curl -X POST https://stage.tonder.io/tokenization/auth \
      -H "Authorization: Token <YOUR_API_KEY>"
    ```
  </Tab>

  <Tab title="Production">
    ```bash theme={null}
    curl -X POST https://app.tonder.io/tokenization/auth \
      -H "Authorization: Token <YOUR_API_KEY>"
    ```
  </Tab>
</Tabs>

The server will respond with a JWT access token:

```json theme={null}
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

You will use this `access_token` as the `X-Skyflow-Authorization` header value in the next step.

## Step 2: Process the Payment

Send a `POST` request with raw card data directly to the PCI-compliant endpoint. Include **both authorization tokens** from Step 1 in your request headers.

<Tabs>
  <Tab title="Sandbox">
    ```
    POST https://process-sandbox.tonder.io/raw-data
    ```
  </Tab>

  <Tab title="Production">
    ```
    POST https://process.tonder.io/raw-data
    ```
  </Tab>
</Tabs>

<Info>
  For testing, use the card numbers and test data available in our [Testing Data guide](/direct-integration/testing-data) to ensure your integration works correctly before going live.
</Info>

### Required Headers

<Note>
  Both `Authorization` and `X-Skyflow-Authorization` are required. The `X-Skyflow-Authorization` token is the JWT obtained from the authentication endpoint in Step 1 and is necessary for secure card data handling through Skyflow's tokenization service.
</Note>

| Header                    | Description                  | Example                                   |
| ------------------------- | ---------------------------- | ----------------------------------------- |
| `Authorization`           | Your public API key          | `Token {{API_KEY_PUBLIC}}`                |
| `X-Skyflow-Authorization` | JWT access token from Step 1 | `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...` |
| `Content-Type`            | Request content type         | `application/json`                        |

### Request Parameters

| Parameter          | Type   | Required | Description                                                 |
| ------------------ | ------ | -------- | ----------------------------------------------------------- |
| `operation_type`   | string | ✓        | Must be `"payment"` to process a payment                    |
| `amount`           | number | ✓        | Payment amount (e.g., `150.00`)                             |
| `currency`         | string | ✓        | Currency code (e.g., `"MXN"` for Mexican Peso)              |
| `customer`         | object | ✓        | Customer information containing `name` and `email`          |
| `payment_method`   | object | ✓        | Payment method details including `type` and raw card fields |
| `client_reference` | string | ✓        | Your unique reference for this transaction                  |
| `return_url`       | string |          | URL where customer returns after 3DS authentication         |

### Example Request

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST https://process-sandbox.tonder.io/raw-data \
      -H "Authorization: Token {{API_KEY_PUBLIC}}" \
      -H "X-Skyflow-Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
      -H "Content-Type: application/json" \
      -d '{
        "operation_type": "payment",
        "amount": 150.00,
        "currency": "MXN",
        "customer": {
          "name": "Ana María Rodríguez",
          "email": "ana.rodriguez@email.com"
        },
        "payment_method": {
          "type": "CARD",
          "card_number": "4444444444444455",
          "cardholder_name": "Ana María Rodríguez",
          "cvv": "123",
          "expiration_year": "26",
          "expiration_month": "07"
        },
        "client_reference": "order-789",
        "return_url": "https://mystore.com/payment/return"
      }'
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const response = await fetch('https://process-sandbox.tonder.io/raw-data', {
      method: 'POST',
      headers: {
        'Authorization': 'Token {{API_KEY_PUBLIC}}',
        'X-Skyflow-Authorization': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        operation_type: 'payment',
        amount: 150.00,
        currency: 'MXN',
        customer: {
          name: 'Ana María Rodríguez',
          email: 'ana.rodriguez@email.com'
        },
        payment_method: {
          type: 'CARD',
          card_number: '4444444444444455',
          cardholder_name: 'Ana María Rodríguez',
          cvv: '123',
          expiration_year: '26',
          expiration_month: '07'
        },
        client_reference: 'order-789',
        return_url: 'https://mystore.com/payment/return'
      })
    });

    const data = await response.json();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import requests

    response = requests.post(
        'https://process-sandbox.tonder.io/raw-data',
        headers={
            'Authorization': 'Token {{API_KEY_PUBLIC}}',
            'X-Skyflow-Authorization': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
            'Content-Type': 'application/json'
        },
        json={
            'operation_type': 'payment',
            'amount': 150.00,
            'currency': 'MXN',
            'customer': {
                'name': 'Ana María Rodríguez',
                'email': 'ana.rodriguez@email.com'
            },
            'payment_method': {
                'type': 'CARD',
                'card_number': '4444444444444455',
                'cardholder_name': 'Ana María Rodríguez',
                'cvv': '123',
                'expiration_year': '26',
                'expiration_month': '07'
            },
            'client_reference': 'order-789',
            'return_url': 'https://mystore.com/payment/return'
        }
    )

    data = response.json()
    ```
  </Tab>
</Tabs>

## Step 3: Handle the Response

Always check the `status` field in your response and implement appropriate logic based on the status value received.

The table below details the fields returned in the response:

| Field              | Type    | Description                       |
| ------------------ | ------- | --------------------------------- |
| `id`               | string  | Unique transaction identifier     |
| `operation_type`   | string  | Always `"payment"`                |
| `status`           | string  | Transaction status                |
| `amount`           | decimal | Transaction amount                |
| `currency`         | string  | Currency code                     |
| `client_reference` | string  | Your reference identifier         |
| `payment_id`       | integer | Internal payment ID               |
| `transaction_id`   | integer | Internal transaction ID           |
| `provider`         | string  | Payment provider used             |
| `created_at`       | string  | ISO 8601 timestamp                |
| `status_code`      | integer | HTTP status code                  |
| `next_action`      | object  | Required actions (3DS, redirects) |

<Warning>
  **Validate `id` and `status` fields**

  For proper payment validation, you must check:

  * `id` is the unique transaction identifier — store this for future reference.
  * `status` is the current payment state — determines next actions.

  Never rely on HTTP status codes alone for payment validation.
</Warning>

## Next Steps

After implementing PCI-compliant raw card processing:

* Set up [webhooks](/direct-integration/webhooks/how-webhooks-works) for real-time payment status updates.
* Implement [3D Secure authentication](/direct-integration/guides/create-payments/create-a-payment-with-3ds) for enhanced security.
* Review [HTTP response codes](/direct-integration/http-response-codes) for comprehensive error handling.
* Test your implementation using [testing data](/direct-integration/testing-data).
