# Shopify → PrintFlow TR bağlantı kılavuzu

Shopify bir "sipariş oluşturuldu" webhook'unu bizim ucumuz olmadığı için doğrudan
PrintFlow'ye gönderemez (PrintFlow'ye dış istek için `Authorization` başlığı gerekir).
Bu yüzden araya küçük bir **aktarıcı (forwarder)** koyarız:

```
Shopify  --(orders/create webhook)-->  Aktarıcı (aşağıdaki Node betiği)  --(API)-->  PrintFlow TR
```

## 1) PrintFlow'de API anahtarı üret
Panel → **API & Webhook** → yeni anahtar (`pf_live_...`). Anahtar yalnız bir kez gösterilir.

## 2) Aktarıcıyı çalıştır
Aşağıdaki betiği herhangi bir Node.js 18+ ortamına (kendi sunucun, bir VPS, Render,
Fly.io vb.) koy ve ortam değişkenlerini ayarla:

- `PRINTFLOW_BASE` — ör. `https://printflowtr.com`
- `PRINTFLOW_API_KEY` — `pf_live_...`
- `SHOPIFY_WEBHOOK_SECRET` — Shopify webhook imza anahtarı (opsiyonel ama önerilir)
- `PORT` — varsayılan `8787`

```js
// forwarder.js — Node 18+
import http from "node:http";
import crypto from "node:crypto";

const BASE = (process.env.PRINTFLOW_BASE || "").replace(/\/$/, "");
const KEY = process.env.PRINTFLOW_API_KEY || "";
const SECRET = process.env.SHOPIFY_WEBHOOK_SECRET || "";

function verify(raw, hmacHeader) {
  if (!SECRET) return true; // secret ayarlanmadıysa imza denetimi atlanır
  const digest = crypto.createHmac("sha256", SECRET).update(raw).digest("base64");
  try {
    return crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(hmacHeader || ""));
  } catch {
    return false;
  }
}

const server = http.createServer(async (req, res) => {
  if (req.method !== "POST" || req.url !== "/shopify/order") {
    res.writeHead(404).end();
    return;
  }
  const chunks = [];
  for await (const chunk of req) chunks.push(chunk);
  const raw = Buffer.concat(chunks);
  if (!verify(raw, req.headers["x-shopify-hmac-sha256"])) {
    res.writeHead(401).end();
    return;
  }

  let order;
  try {
    order = JSON.parse(raw.toString("utf8"));
  } catch {
    res.writeHead(400).end();
    return;
  }

  const item = (order.line_items && order.line_items[0]) || {};
  const payload = {
    customerName: [order.customer?.first_name, order.customer?.last_name].filter(Boolean).join(" ") || "Shopify müşterisi",
    customerEmail: order.email || order.customer?.email || "",
    customerCity: order.shipping_address?.city || order.billing_address?.city || "",
    title: item.title || `Shopify #${order.name}`,
    quantity: item.quantity || 1,
    unitPrice: Number(order.total_price || 0),
    shippingPrice: Number((order.total_shipping_price_set?.shop_money?.amount) || 0),
    note: order.note || "",
    externalId: `shopify-${order.id}`,
  };

  try {
    const resp = await fetch(`${BASE}/api/v1/orders`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${KEY}`,
        "Content-Type": "application/json",
        "Idempotency-Key": `shopify-${order.id}`,
      },
      body: JSON.stringify(payload),
    });
    if (!resp.ok) console.error("PrintFlow yanıtı:", resp.status, await resp.text());
  } catch (err) {
    console.error("PrintFlow'ye ulaşılamadı:", err);
  }
  res.writeHead(200).end();
});

server.listen(Number(process.env.PORT || 8787), () => {
  console.log("Shopify forwarder çalışıyor");
});
```

## 3) Shopify'de webhook tanımla
Shopify Admin → **Ayarlar → Bildirimler → Webhook'lar** → "Webhook oluştur":

- Olay: **Sipariş oluşturuldu (orders/create)**
- Biçim: **JSON**
- URL: `https://<aktarıcı-adresin>/shopify/order`

## 4) Doğrula
Bir test siparişi oluştur; PrintFlow panelinde **Siparişler** listesinde görünmeli
(ve tanımlıysa `order.created` webhook'u size de gitmiş olmalı).

> Not: Aynı sipariş iki kez gönderilse bile PrintFlow tarafında `Idempotency-Key`
> sayesinde çift kayıt oluşmaz.
