# Shopify, integração Renkopay

A Shopify tem regras próprias para meios de pagamento no checkout. Para atuar como gateway nativo no checkout Shopify, normalmente é necessário construir um Payment App dentro do ecossistema Shopify e cumprir os requisitos da Shopify para provedores de pagamento.

Para desenvolvimento inicial, existem três caminhos possíveis:

## 1. Payment App Shopify

Uso recomendado quando a Renkopay será exibida como método de pagamento nativo no checkout.

Pontos de atenção:

```text
Requer app no Shopify Partner Dashboard.
Pode exigir aprovação da Shopify para operar como provedor de pagamento.
Precisa implementar fluxos de autorização, captura, cancelamento, reembolso e webhooks conforme especificação Shopify.
O client_secret da Renkopay fica no backend do app, nunca no tema da loja.
```

## 2. Custom App com pedido externo

Uso recomendado para lojas com fluxo customizado, portal próprio ou headless commerce.

Fluxo:

```text
Loja Shopify -> Custom App backend -> Renkopay Gateway -> QR Code PIX -> cliente paga -> webhook Renkopay -> backend atualiza pedido Shopify
```

## 3. Manual Payment Method com instrução PIX

Uso simples para MVP.

Fluxo:

```text
Cliente escolhe método manual PIX no checkout.
Backend ou operador gera PIX no painel Renkopay.
Webhook confirma pagamento e o pedido é marcado como pago via Admin API.
```

## Exemplo Node.js, backend de Custom App

```js
import express from 'express';
import crypto from 'crypto';
import { RenkoPayClient } from '../../snippets/nodejs/renkopay-client.mjs';

const app = express();
app.use(express.json({ type: '*/*' }));

const renkopay = new RenkoPayClient({
  baseUrl: process.env.RENKOPAY_BASE_URL,
  clientId: process.env.RENKOPAY_CLIENT_ID,
  clientSecret: process.env.RENKOPAY_CLIENT_SECRET,
});

app.post('/shopify/create-pix', async (req, res) => {
  const { orderId, total, customer } = req.body;

  const pix = await renkopay.createPixCharge({
    external_id: `shopify-${orderId}`,
    amount: Number(total),
    description: `Pedido Shopify ${orderId}`,
    expires_in: 3600,
    customer: {
      name: customer.name,
      document: customer.document,
      email: customer.email,
    },
    metadata: {
      shopify_order_id: orderId,
    },
  });

  res.json(pix);
});

app.post('/webhooks/renkopay', express.raw({ type: 'application/json' }), async (req, res) => {
  const body = req.body.toString('utf8');
  const signature = req.header('X-Gateway-Signature') || '';
  const match = signature.match(/t=(\d+),v1=([a-f0-9]+)/);

  if (!match) {
    return res.status(401).send('assinatura ausente');
  }

  const expected = crypto
    .createHmac('sha256', process.env.RENKOPAY_WEBHOOK_SECRET)
    .update(`${match[1]}.${body}`)
    .digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(match[2]))) {
    return res.status(401).send('assinatura inválida');
  }

  const payload = JSON.parse(body);

  if (payload.data?.status === 'PAID' && payload.data?.external_id?.startsWith('shopify-')) {
    const orderId = payload.data.external_id.replace('shopify-', '');
    // Chamar Shopify Admin API para registrar pagamento ou atualizar pedido.
    // A implementação depende do tipo de app e permissões concedidas.
    console.log('Pagamento confirmado para pedido Shopify', orderId);
  }

  res.send('ok');
});

app.listen(3000);
```

## URL de webhook

Configure no painel Renkopay a URL do backend do app:

```text
https://app.seudominio.com.br/webhooks/renkopay
```

## Importante

Não inserir `client_secret` em tema Liquid, JavaScript do tema, checkout extension pública ou qualquer arquivo entregue ao navegador.
