# Internacional (Paycore)

> Botão de pagamento internacional embutido na sua página.

Fonte: https://app.thronecorporate.com/docs/internacional

## Visão geral

O Internacional (Paycore) é um botão de pagamento embutido na sua página. O comprador conclui o pagamento com carteira digital internacional ou cartão internacional, dentro do checkout do Throne. É um trilho separado do [cartão](/docs/cartao), e os dois podem ficar habilitados ao mesmo tempo.

Diferenças importantes em relação ao cartão:

| Item | Internacional (Paycore) | Cartão (Sterling, Imperium, NovaCorp, Eminence, Apex, ShadowBank, Vortex) |
|---|---|---|
| Endpoint | `POST /global/checkout` | `POST /elements/checkout` |
| Como embutir | `iframe` com o `checkout_url` | Script `throne-elements.js` |
| Moedas | 22 | 48 |
| Cotação que credita o seu saldo | Fixada na aprovação | Fixada na criação |
| Recusa | A venda continua `pending` e o comprador tenta de novo | A venda continua `pending`; o checkout fecha 10 minutos depois de uma recusa sem nova tentativa |

O `transaction_id` de um trilho não funciona no outro.

## 1. Criar o checkout

```bash cURL
curl -X POST https://app.thronecorporate.com/api/v1/global/checkout \
  -H "Authorization: Bearer $THRONE_PK:$THRONE_SK" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "amount_cents": 2000, "currency": "usd", "customer": { "name": "John Carter", "email": "john@example.com" } }'
```
```js Node.js
import { randomUUID } from 'node:crypto';

const res = await fetch('https://app.thronecorporate.com/api/v1/global/checkout', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.THRONE_PK}:${process.env.THRONE_SK}`,
    'Content-Type': 'application/json',
    Accept: 'application/json',
    'Idempotency-Key': randomUUID(),
  },
  body: JSON.stringify({ amount_cents: 2000, currency: 'usd', customer: { name: 'John Carter', email: 'john@example.com' } }),
});
const { transaction_id, checkout_url } = await res.json(); // res.status === 201
```
```python Python
import os, uuid, requests

r = requests.post(
    "https://app.thronecorporate.com/api/v1/global/checkout",
    headers={
        "Authorization": f"Bearer {os.environ['THRONE_PK']}:{os.environ['THRONE_SK']}",
        "Accept": "application/json",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={"amount_cents": 2000, "currency": "usd",
          "customer": {"name": "John Carter", "email": "john@example.com"}},
    timeout=20,
)
checkout = r.json()  # r.status_code == 201
```

| Campo | Obrigatório | Regra |
|---|---|---|
| `amount_cents` | Sim | Na menor unidade da moeda (US$ 20,00 = `2000`). Mínimo `50` (US$ 0,50). Em JPY, HUF e TWD é a unidade inteira, com mínimo 1 |
| `currency` | Sim | Uma destas 22: AUD, BRL, CAD, CHF, CZK, DKK, EUR, GBP, HKD, HUF, ILS, JPY, MXN, NOK, NZD, PHP, PLN, SEK, SGD, THB, TWD, USD |
| `customer.name` | Não | Nome do comprador |
| `customer.email` | Não | E-mail do comprador |

Outros campos (metadata, itens, documento, endereço) são ignorados neste endpoint. Guarde o `transaction_id` para ligar a venda ao seu pedido.

Resposta `201 Created`:

```json
{
  "transaction_id": "5f0a2c1e-8d3b-4c7a-9e21-6b4d8f2a1c90",
  "status": "pending",
  "checkout_url": "https://app.thronecorporate.com/global/5f0a2c1e-8d3b-4c7a-9e21-6b4d8f2a1c90"
}
```

## 2. Embutir na sua página

Coloque o `checkout_url` num `iframe`, com `embed=1` e, se quiser, a aparência:

```html
<iframe id="pagamento-internacional"
        src="CHECKOUT_URL?embed=1&color=%237c3aed&theme=light&radius=10"
        allow="payment"
        title="Pagamento"
        style="width:100%; border:0; min-height:520px"></iframe>
```

- `color`: cor no formato `#rrggbb` (na URL, `#` vira `%23`).
- `theme`: `light` ou `dark`.
- `radius`: cantos arredondados, de 0 a 32.
- Mantenha `allow="payment"`: sem ele, a carteira digital pode não funcionar dentro do iframe.

O checkout avisa a sua página por `postMessage`. Escute as mensagens para ajustar a altura e reagir ao pagamento:

```js
const frame = document.getElementById('pagamento-internacional');
const origemThrone = new URL(frame.src).origin;

window.addEventListener('message', (ev) => {
  if (ev.origin !== origemThrone || !ev.data || typeof ev.data.type !== 'string') return;
  switch (ev.data.type) {
    case 'throne-elements:resize':
      frame.style.height = ev.data.height + 'px';
      break;
    case 'throne-elements:paid':
      // o comprador concluiu: mostre o "obrigado"
      break;
    case 'throne-elements:error':
      // ev.data.message: o comprador pode tentar de novo
      break;
  }
});
```

Como no cartão, esses eventos são sinais de tela. A confirmação que vale é o webhook `transaction.paid` ou a consulta.

## 3. Confirmar a venda

A venda vira `paid` quando o pagamento é capturado. Isso pode levar alguns instantes depois de o comprador concluir. Você recebe o webhook `transaction.paid`, no mesmo formato do cartão:

- `payment_method` vem sempre `credit_card`, inclusive quando o comprador pagou com carteira digital. `card_brand` e `card_last4` vêm `null`.
- `currency` e `native_amount_cents` são a moeda e o valor que você mandou.
- `amount_cents` é o valor bruto creditado no seu saldo, em reais (a moeda da sua conta), e `net_amount_cents` o líquido, já descontada a taxa de cartão da sua conta.
- `fx_rate` é a cotação usada para creditar o seu saldo (reais por 1 unidade da moeda da venda), fixada na aprovação. Em venda criada em BRL, `fx_rate` vale 1.

Antes do pagamento, a consulta mostra `amount_cents` igual a 0 e `fx_rate` nulo.

## Recusas, estornos e contestações

- **Recusa** não encerra a venda: ela continua `pending` e o comprador pode tentar de novo no mesmo checkout.
- **Estorno** total deixa a venda `refunded`; o parcial mantém `paid` com o valor reduzido.
- **Contestação** deixa a venda `chargeback`.
- Nenhum desses eventos gera webhook. Acompanhe pelo `GET /transactions/{id}`.

## Erros

| Status | `error` | O que fazer |
|---|---|---|
| `422` | `global_not_enabled` | O Internacional não está habilitado na sua conta. Fale com o suporte |
| `422` | `unsupported_currency` | A moeda não é aceita. O campo `supported` traz a lista |
| `422` | `currency_not_enabled` | A sua conta aceita só algumas moedas. O campo `enabled` traz a lista |
| `422` | `amount_too_small` | Abaixo do mínimo. O campo `minimum` traz o valor |
| `400` | `idempotency_key_required` | Envie o header `Idempotency-Key` |
| `422` | `idempotency_key_mismatch` | Mesma `Idempotency-Key` com corpo diferente. Use uma nova |

Trate pelo campo `error`; o texto de `message` pode mudar.
