# Checkout

Checkout é a solução integrada da easypay para recolher pagamentos em qualquer website com o mínimo esforço de desenvolvimento.

## Visão Geral

Checkout é um formulário de pagamento pré-construído que pode ser incorporado diretamente no seu website. Trata de todo o fluxo de pagamento, incluindo:

- Recolha de informações do cliente
- Seleção de método de pagamento
- Recolha de informações de pagamento
- Invocação de APIs de pagamento
- Exibição de feedback de pagamento


![Checkout Overview](https://easypay-cdn-delivery.s3.eu-central-1.amazonaws.com/docs/checkout/overview-v1.1.0.png)

## Principais Benefícios

- **Sem programação extensiva necessária**: Incorpore com apenas algumas linhas de código
- **Todos os métodos de pagamento suportados**: Cartões de crédito, MB WAY, Apple Pay, Google Pay, Samsung Pay, Multibanco, Débito Direto, IBAN Virtual
- **Todos os tipos de pagamento suportados**: Pagamentos únicos, frequentes e subscrições
- **Totalmente personalizável**: Personalize de acordo com a sua marca com opções de estilo extensas
- **Responsivo em dispositivos móveis**: Funciona perfeitamente em todos os dispositivos
- **Múltiplos métodos de integração**: Script tag ou pacote NPM


## Demonstração ao Vivo

Explore a [demonstração ao vivo do Checkout](https://checkout-demo.easypay.pt) para ver a solução em ação e experimentar diferentes fluxos de pagamento.

Veja o [código-fonte no GitHub](https://github.com/Easypay/checkout-demo) com instruções para executar localmente.

## Como Funciona

### 1. Criar uma Sessão de Checkout (Lado do Servidor)

Faça um pedido POST servidor-para-servidor para criar uma sessão de checkout:


```bash
curl -X POST 'https://api.test.easypay.pt/2.0/checkout' \
  -H 'AccountId: YOUR_ACCOUNT_ID' \
  -H 'ApiKey: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": ["single"],
    "payment": {
      "methods": ["cc", "mb", "mbw", "dd", "vi"],
      "type": "sale",
      "currency": "EUR",
      "capture: { "descriptive": "Purchase in MyStore" }
    },
    "order": {
      "items": [
        {
          "description": "T-shirt",
          "quantity": 1,
          "key": "t-shirt",
          "value": 12.50
        }
      ],
      "key": "order-123",
      "value": 12.50
    }
  }'
```

Resposta:


```json
{
  "id": "57cc19e9-f393-4cfa-9516-8807763b5096",
  "session": "8zoaBOC0Mj5Mg_YAbdRCqY...",
  "config": null
}
```

Esta resposta é chamada de **manifesto do Checkout**.

### 2. Exibir o Formulário de Checkout (Lado do Cliente)

#### Opção A: Script Tag (Mais Simples)


```html
<!-- Include the SDK -->
<script src="https://cdn.easypay.pt/checkout/2.9.1/"></script>

<!-- Prepare a container -->
<div id="easypay-checkout"></div>

<script>
  // Get the manifest from your server
  const manifest = await getManifestFromServer();

  // Initialize Checkout
  easypayCheckout.startCheckout(manifest);
</script>
```

#### Opção B: Pacote NPM


```bash
npm install --save @easypaypt/checkout-sdk
```


```javascript
import { startCheckout } from "@easypaypt/checkout-sdk";

const manifest = await getManifestFromServer();
startCheckout(manifest);
```

## Casos de Uso Comuns

### Pagamento Único

Para compras únicas:


```json
{
  "type": ["single"],
  "payment": {
    "methods": ["cc", "mbw", "mb"],
    "type": "sale",
    "currency": "EUR"
  },
  "order": {
    "items": [
      { "description": "Product", "quantity": 1, "value": 29.99 }
    ],
    "value": 29.99
  }
}
```

### Pagamento Frequente (Tokenização)

Para guardar detalhes de pagamento para uso futuro:


```json
{
  "type": ["frequent"],
  "payment": {
    "methods": ["cc", "mbw", "dd"],
    "currency": "EUR"
  }
}
```

Trate o callback de sucesso para obter o ID do pagamento:


```javascript
startCheckout(manifest, {
  onSuccess: (checkoutInfo) => {
    // Save checkoutInfo.payment.id for later captures
    saveTokenToServer(checkoutInfo.payment.id);
  }
});
```

Mais tarde, capture fundos usando o ID guardado:


```bash
POST /capture/:id
{
  "value": 50.00,
  "descriptive": "Purchase in MyStore"
}
```

### Pagamento de Subscrição

Para pagamentos recorrentes:


```json
{
  "type": ["subscription"],
  "payment": {
    "methods": ["cc", "dd"],
    "type": "sale",
    "frequency": "1M",
    "start_time": "2024-02-01 00:00",
    "max_captures": 12
  },
  "order": {
    "items": [
      { "description": "Monthly Subscription", "value": 9.99 }
    ],
    "value": 9.99
  }
}
```

![Subscription Confirmation](https://easypay-cdn-delivery.s3.eu-central-1.amazonaws.com/docs/checkout/subscription.png)

## Funcionalidades Avançadas

### Modos de Exibição

**Modo Inline** (padrão): Incorpora o formulário de checkout na sua página


```javascript
startCheckout(manifest, {
  display: "inline"
});
```

**Modo Popup**: Abre o checkout numa janela popup/modal


```html
<button id="checkout-button">Pay Now</button>

<script>
easypayCheckout.startCheckout(manifest, {
  id: "checkout-button",
  display: "popup"
});
</script>
```

![Popup Mode](https://user-images.githubusercontent.com/30448483/172881494-7265ff97-d142-4fee-9a2b-047b986dbefc.png)

### Manipuladores de Eventos

Reaja a eventos de pagamento:


```javascript
startCheckout(manifest, {
  onSuccess: (checkoutInfo) => {
    console.log('Payment successful:', checkoutInfo);
    // checkoutInfo contains payment details, method, status, etc.
  },

  onError: (error) => {
    console.error('Unrecoverable error:', error);
    if (error.code === 'checkout-expired') {
      // Create new session
    }
  },

  onPaymentError: (error) => {
    console.log('Recoverable payment error:', error);
    // User can retry
  },

  onClose: () => {
    console.log('Checkout closed');
    // Clean up or redirect
  }
});
```

### Personalização

Personalize de acordo com a sua marca com opções de estilo extensas:


```javascript
startCheckout(manifest, {
  logoUrl: "https://yoursite.com/logo.png",
  accentColor: "#FF6B35",
  backgroundColor: "#F7F7F7",
  buttonBackgroundColor: "#FF6B35",
  buttonBorderRadius: 5,
  inputBorderRadius: 5,
  fontFamily: "Arial, sans-serif",
  baseFontSize: 12
});
```

Exemplo de personalização:

![Custom Styling](https://easypay-cdn-delivery.s3.eu-central-1.amazonaws.com/docs/checkout/stylingapi.png)

Opções de personalização disponíveis:

- Logótipo da empresa
- Cores de fundo
- Cores de destaque
- Cores de botões e estilos
- Cores de campos de entrada e estilos
- Família de fontes e tamanho
- Raio das bordas
- Sombras de caixa


## Testes

Para testar sem transações reais:


```javascript
startCheckout(manifest, {
  display: "inline",
  testing: true  // Use test environment
});
```

**Importante**:

- Crie sessões usando `https://api.test.easypay.pt`
- Use métodos de pagamento de teste (consulte o [guia de Métodos de Pagamento](/docs/guides/payment-methods))
- Remova `testing: true` quando for para produção


## Gerir Instância do Checkout

Guarde a instância para gerenciamento posterior:


```javascript
const checkoutInstance = startCheckout(manifest, {
  onSuccess: (info) => {
    // Payment successful, clean up
    checkoutInstance.unmount();
    showThankYouMessage();
  }
});

// Later, manually remove checkout
checkoutInstance.unmount();
```

## Expiração da Sessão

As sessões de checkout expiram após **30 minutos**. Trate a expiração com elegância:


```javascript
startCheckout(manifest, {
  onError: async (error) => {
    if (error.code === 'checkout-expired') {
      // Create a new session
      const newManifest = await createNewSession();
      startCheckout(newManifest);
    }
  }
});
```

## Códigos de Erro

| Código de Erro | Causa | Solução |
|  --- | --- | --- |
| `checkout-expired` | Sessão expirada (>30 min) | Criar nova sessão |
| `already-paid` | Checkout já foi concluído | Confirmar estado do pagamento |
| `checkout-canceled` | Checkout foi cancelado | Criar nova sessão |
| `generic-error` | Erro geral antes do pagamento | Permitir repetição |
| `payment-failure` | Erro durante o pagamento | Permitir repetição, verificar detalhes |


## Idiomas Suportados

Checkout detecta automaticamente o idioma do navegador do utilizador, mas pode substituir:


```javascript
startCheckout(manifest, {
  language: "pt_PT"  // Portuguese
  // Options: "en", "pt_PT", "es_ES"
});
```

## Boas Práticas

1. **Sempre Criar Sessões no Lado do Servidor**: Nunca exponha as suas chaves API no código do cliente
2. **Tratar Todos os Casos de Erro**: Implemente manipuladores de erro para melhor experiência do utilizador
3. **Usar Webhooks**: Não confie apenas em callbacks de sucesso no lado do cliente para lógica crítica
4. **Testar Completamente**: Use o ambiente de teste extensivamente antes de ir para produção
5. **Personalizar para a Sua Marca**: Personalize o Checkout de acordo com o aspecto e comportamento do seu website
6. **Mobile First**: Teste em vários dispositivos e tamanhos de ecrã
7. **Verificar Pagamentos**: Sempre verifique o estado do pagamento no seu servidor usando a API


## Próximos Passos

- [Referência da API do Checkout](/openapi#tag/Checkout) - Documentação completa da API
- [Guia de Webhooks](/docs/guides/webhooks) - Receber notificações de pagamento
- [Métodos de Pagamento](/docs/guides/payment-methods) - Saiba mais sobre os métodos de pagamento disponíveis
- [Tipos de Pagamento](/docs/guides/payment-types) - Compreenda pagamentos únicos, frequentes e subscrições
- [Demonstração do GitHub](https://github.com/Easypay/checkout-demo) - Exemplo completo funcionando


## Referência do SDK

Para opções e parâmetros completos do SDK, consulte a [Referência da API do Checkout](/openapi#tag/Checkout).

Métodos-chave do SDK:

- `startCheckout(manifest, options)` - Inicializar checkout
- `checkoutInstance.unmount()` - Remover checkout do DOM


Para documentação detalhada do SDK, incluindo todas as opções de personalização, parâmetros de callback e exemplos, consulte a [Referência da API](/openapi#tag/Checkout/SDK).