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

# Credit Card Payments with CertoPay: Visa, Mastercard, Elo

> Process Visa, Mastercard, and Elo credit cards with installments. Use card tokenization for repeat customers and recurring charges.

CertoPay supports credit card payments for the three most widely issued card brands in Brazil — Visa, Mastercard, Elo, Hipercard, Hiper, American Express, Diners Club, JCB, Aura, Discover. Charges are authorized and captured in a single step, so an approved response with `status: CAPTURED` means funds are already reserved. You can split payments into up to 12 installments (`parcelamento`), and for repeat customers or subscription products you can tokenize the card and charge the stored token on future orders without asking the buyer to re-enter their details.

## Supported Brands

| Brand           | Single charge | Installments | Tokenization |
| --------------- | ------------- | ------------ | ------------ |
| Visa            | ✅             | ✅ Up to 12×  | ✅            |
| Mastercard      | ✅             | ✅ Up to 12×  | ✅            |
| Elo             | ✅             | ✅ Up to 12×  | ✅            |
| Hipercard       | ✅             | ✅ Up to 12×  | ✅            |
| Hiper           | ✅             | ✅ Up to 12×  | ✅            |
| American Expess | ✅             | ✅ Up to 12×  | ✅            |
| Diners Club     | ✅             | ✅ Up to 12×  | ✅            |
| JCB             | ✅             | ✅ Up to 12×  | ✅            |
| Aura            | ✅             | ✅ Up to 12×  | ✅            |
| Discover        | ✅             | ✅ Up to 12×  | ✅            |

## Two Ways to Charge a Card

<Tabs>
  <Tab title="Option A — Direct Card Data">
    Send the full card details in the payment request. This is the simplest integration path for one-time purchases.

    <Warning>
      Your server must handle raw card numbers only over HTTPS. Never log or store card numbers, CVVs, or expiry dates — this is a PCI DSS requirement. For repeat customers, use **Option B (tokenization)** instead.
    </Warning>

    ### Request

    ```http theme={null}
    POST /api/payment-gateway/process
    X-Api-Key: sk_live_sua_chave_aqui
    Idempotency-Key: 550e8400-e29b-41d4-a716-446655440003
    Content-Type: application/json

    {
      "orderId": "uuid-do-pedido",
      "method": "CARD",
      "amount": 29700,
      "installments": 3,
      "cardHolderName": "JOAO DA SILVA",
      "cardNumber": "4111111111111111",
      "cardExpirationMonth": "12",
      "cardExpirationYear": "28",
      "cardSecurityCode": "123",
      "cardBrand": "Visa",
      "buyerDoc": "12345678900",
      "buyerBirthdate": "1990-05-20",
      "buyerCellNumber": "(11) 99999-9999",
      "buyerAddress": {
        "postal_code": "01310930",
        "street": "Avenida Paulista",
        "number": "100",
        "neighborhood": "Bela Vista",
        "city": "São Paulo",
        "state": "SP"
      }
    }
    ```

    ### Request Fields

    <ParamField body="orderId" type="string" required>
      The unique identifier for the order, obtained from `POST /api/orders`.
    </ParamField>

    <ParamField body="method" type="string" required>
      Must be `"CARD"` to route the charge through the credit card rail.
    </ParamField>

    <ParamField body="amount" type="integer" required>
      The total charge amount in **centavos**. Example: R\$ 297,00 → `29700`.
    </ParamField>

    <ParamField body="installments" type="integer" required>
      Number of installments. Use `1` for a single charge, or `2`–`12` to split the payment. The total `amount` is divided equally across installments.
    </ParamField>

    <ParamField body="cardHolderName" type="string" required>
      Cardholder name exactly as printed on the card, in uppercase. Example: `"JOAO DA SILVA"`.
    </ParamField>

    <ParamField body="cardNumber" type="string" required>
      Full card number, digits only, no spaces or dashes. Example: `"4111111111111111"`.
    </ParamField>

    <ParamField body="cardExpirationMonth" type="string" required>
      Two-digit expiration month. Example: `"12"`.
    </ParamField>

    <ParamField body="cardExpirationYear" type="string" required>
      Two-digit expiration year. Example: `"28"` for 2028.
    </ParamField>

    <ParamField body="cardSecurityCode" type="string" required>
      Card security code (CVV/CVC) — 3 digits for Visa/Mastercard/Elo. Never store this value.
    </ParamField>

    <ParamField body="cardBrand" type="string" required>
      Card brand. Accepted values: `"Visa"`, `"Mastercard"`, `"Elo"`.
    </ParamField>

    <ParamField body="buyerDoc" type="string" required>
      Buyer's CPF — exactly 11 numeric digits, no punctuation. Example: `"12345678900"`.
    </ParamField>

    <ParamField body="buyerBirthdate" type="string" required>
      Buyer's date of birth in `YYYY-MM-DD` format. Example: `"1990-05-20"`.
    </ParamField>

    <ParamField body="buyerCellNumber" type="string" required>
      Buyer's mobile phone number with area code (DDD). Example: `"(11) 99999-9999"`.
    </ParamField>

    <ParamField body="buyerAddress" type="object" required>
      Buyer's billing address.

      <Expandable title="buyerAddress fields">
        <ParamField body="postal_code" type="string" required>
          Brazilian postal code (CEP), 8 digits. Example: `"01310930"`.
        </ParamField>

        <ParamField body="street" type="string" required>
          Street name. Example: `"Avenida Paulista"`.
        </ParamField>

        <ParamField body="number" type="string" required>
          Street number. Example: `"100"`.
        </ParamField>

        <ParamField body="neighborhood" type="string" required>
          Neighborhood (bairro). Example: `"Bela Vista"`.
        </ParamField>

        <ParamField body="city" type="string" required>
          City name. Example: `"São Paulo"`.
        </ParamField>

        <ParamField body="state" type="string" required>
          Two-letter state abbreviation (UF). Example: `"SP"`.
        </ParamField>
      </Expandable>
    </ParamField>
  </Tab>

  <Tab title="Option B — Card Token (Recurring)">
    Tokenize the card once, then charge the stored token on every subsequent order. The buyer only enters card details one time, and you never store raw card data on your servers.

    <Tip>
      Card tokenization is **strongly recommended** for subscription products, membership sites, and any checkout flow where buyers return for repeat purchases. It improves conversion rates (no re-entry friction) and keeps your PCI DSS scope minimal.
    </Tip>

    ### Step 1 — Tokenize the Card

    Call the tokenize endpoint when the buyer saves their card (e.g., during account setup or their first checkout):

    ```http theme={null}
    POST /api/payment-gateway/tokenize-card
    X-Api-Key: sk_live_sua_chave_aqui
    Content-Type: application/json

    {
      "customerId": "uuid-do-customer",
      "doc": "12345678900",
      "holderName": "JOAO DA SILVA",
      "cardNumber": "4111111111111111",
      "brand": "Visa",
      "expirationMonth": "12",
      "expirationYear": "28",
      "securityCode": "123",
      "birthdate": "1990-05-20",
      "cellNumber": "(11) 99999-9999",
      "address": {
        "postal_code": "01310930",
        "street": "Avenida Paulista",
        "number": "100",
        "neighborhood": "Bela Vista",
        "city": "São Paulo",
        "state": "SP"
      }
    }
    ```

    **Tokenize response:**

    ```json theme={null}
    {
      "cardToken": "tok_abc123..."
    }
    ```

    Store `cardToken` against the customer record in your database. This token represents the card and can be reused for any number of future charges.

    #### Tokenize Request Fields

    <ParamField body="customerId" type="string" required>
      Your internal customer UUID. CertoPay links the token to this customer ID so you can manage multiple saved cards per customer.
    </ParamField>

    <ParamField body="doc" type="string" required>
      Customer's CPF — 11 numeric digits. Example: `"12345678900"`.
    </ParamField>

    <ParamField body="holderName" type="string" required>
      Cardholder name in uppercase, as printed on the card.
    </ParamField>

    <ParamField body="cardNumber" type="string" required>
      Full card number, digits only.
    </ParamField>

    <ParamField body="brand" type="string" required>
      Card brand: `"Visa"`, `"Mastercard"`, or `"Elo"`.
    </ParamField>

    <ParamField body="expirationMonth" type="string" required>
      Two-digit expiration month. Example: `"12"`.
    </ParamField>

    <ParamField body="expirationYear" type="string" required>
      Two-digit expiration year. Example: `"28"`.
    </ParamField>

    <ParamField body="securityCode" type="string" required>
      Card CVV — 3 digits. Used only during tokenization; never stored by CertoPay.
    </ParamField>

    <ParamField body="birthdate" type="string" required>
      Customer's date of birth in `YYYY-MM-DD` format.
    </ParamField>

    <ParamField body="cellNumber" type="string" required>
      Customer's mobile phone number with area code.
    </ParamField>

    <ParamField body="address" type="object" required>
      Customer's billing address (same sub-fields as `buyerAddress`: `postal_code`, `street`, `number`, `neighborhood`, `city`, `state`).
    </ParamField>

    ***

    ### Step 2 — Charge Using the Token

    On every subsequent order, send `cardToken` instead of raw card fields. No CVV or card number needed:

    ```http theme={null}
    POST /api/payment-gateway/process
    X-Api-Key: sk_live_sua_chave_aqui
    Idempotency-Key: 550e8400-e29b-41d4-a716-446655440004
    Content-Type: application/json

    {
      "orderId": "uuid-do-pedido",
      "method": "CARD",
      "amount": 29700,
      "installments": 1,
      "cardToken": "tok_abc123..."
    }
    ```

    #### Token Charge Fields

    <ParamField body="orderId" type="string" required>
      The unique identifier for the new order.
    </ParamField>

    <ParamField body="method" type="string" required>
      Must be `"CARD"`.
    </ParamField>

    <ParamField body="amount" type="integer" required>
      Charge amount in centavos.
    </ParamField>

    <ParamField body="installments" type="integer" required>
      Number of installments (`1`–`12`). Use `1` for full-amount subscription charges.
    </ParamField>

    <ParamField body="cardToken" type="string" required>
      The token returned by `POST /api/payment-gateway/tokenize-card`. Replaces all raw card fields.
    </ParamField>
  </Tab>
</Tabs>

## Response

Both Option A and Option B return the same response shape:

```json theme={null}
{
  "transactionId": "uuid-da-transacao",
  "status": "CAPTURED",
  "method": "CARD",
  "amount": 29700,
  "installments": 3
}
```

### Response Fields

<ResponseField name="transactionId" type="string">
  CertoPay's unique identifier for this transaction. Store this for refund requests and dispute resolution.
</ResponseField>

<ResponseField name="status" type="string">
  The outcome of the charge attempt:

  * `CAPTURED` — The card was approved and funds have been reserved. Fulfill the order.
  * `REFUSED` — The card issuer declined the charge. Prompt the buyer to try a different card.
</ResponseField>

<ResponseField name="method" type="string">
  Echoes back `"CARD"`.
</ResponseField>

<ResponseField name="amount" type="integer">
  Total charge amount in centavos, as submitted.
</ResponseField>

<ResponseField name="installments" type="integer">
  Number of installments the charge was split into.
</ResponseField>

## Handling Declined Cards

When a card is declined, the response returns `status: REFUSED`:

```json theme={null}
{
  "transactionId": "uuid-da-transacao",
  "status": "REFUSED",
  "method": "CARD",
  "amount": 29700,
  "installments": 3
}
```

<Warning>
  A `REFUSED` status means the issuing bank rejected the charge. Do **not** retry the same card automatically — show the buyer a message and invite them to use a different card or payment method. Repeated automatic retries on a declined card may result in the card being permanently blocked by the issuer.
</Warning>

Common reasons for refusal include insufficient credit limit, security blocks from the issuing bank, or incorrect card details. You should not expose the raw decline reason to the buyer — a generic "cartão recusado" message is sufficient.
