Pronto para copiar e colar

Integre Pix em minutos

Exemplos completos para os principais stacks. Cole no seu projeto, troque a chave e está pronto.

Node.js + Express
Backend completo: cria cobrança e recebe webhook de confirmação.
// server.js — npm i express
import express from "express";
import crypto from "crypto";

const app = express();
const SKINPAY_KEY = process.env.SKINPAY_KEY;
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;

// 1. Criar cobrança Pix
app.post("/checkout", express.json(), async (req, res) => {
  const { amount, orderId } = req.body;

  const r = await fetch("https://skinpay.pro/api/public/v1/charges", {
    method: "POST",
    headers: {
      "x-api-key": SKINPAY_KEY,
      "Content-Type": "application/json",
      "Idempotency-Key": orderId,
    },
    body: JSON.stringify({
      amount,
      external_id: orderId,
      description: `Pedido #${orderId}`,
      expires_in: 3600,
    }),
  });

  const { data } = await r.json();
  res.json({
    chargeId: data.id,
    qrCode: data.pix_qr_code,
    copyPaste: data.pix_copy_paste,
  });
});

// 2. Receber webhook (Pix confirmado)
app.post("/webhook/skinpay", express.raw({ type: "application/json" }), (req, res) => {
  const sig = req.headers["x-skinpay-signature"];
  const [tsPart, v1Part] = sig.split(",");
  const ts = tsPart.split("=")[1];
  const v1 = v1Part.split("=")[1];

  const expected = crypto
    .createHmac("sha256", WEBHOOK_SECRET)
    .update(`${ts}.${req.body}`)
    .digest("hex");

  if (expected !== v1) return res.status(401).end();

  const event = JSON.parse(req.body);
  if (event.event === "charge.paid") {
    console.log("Pix recebido:", event.data.external_id);
    // libera o pedido no banco
  }
  res.status(200).end();
});

app.listen(3000);
PHP puro
Sem framework, ideal para sites WordPress/Laravel/CodeIgniter.
<?php
// checkout.php
$SKINPAY_KEY = getenv("SKINPAY_KEY");
$orderId = "pedido_" . time();
$amount = 9990; // R$ 99,90 em centavos

$payload = json_encode([
  "amount" => $amount,
  "external_id" => $orderId,
  "description" => "Pedido #$orderId",
  "expires_in" => 3600,
]);

$ch = curl_init("https://skinpay.pro/api/public/v1/charges");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => $payload,
  CURLOPT_HTTPHEADER => [
    "x-api-key: $SKINPAY_KEY",
    "Content-Type: application/json",
    "Idempotency-Key: $orderId",
  ],
  CURLOPT_RETURNTRANSFER => true,
]);

$res = json_decode(curl_exec($ch), true);
$data = $res["data"];
?>

<h2>Pague com Pix</h2>
<img src="<?= htmlspecialchars($data['pix_qr_code']) ?>" alt="QR Pix" />
<input type="text" readonly value="<?= htmlspecialchars($data['pix_copy_paste']) ?>" />

<?php
// webhook.php — receber confirmação
$WEBHOOK_SECRET = getenv("WEBHOOK_SECRET");
$body = file_get_contents("php://input");
$sig = $_SERVER["HTTP_X_SKINPAY_SIGNATURE"] ?? "";

[$tsPart, $v1Part] = explode(",", $sig);
$ts = explode("=", $tsPart)[1];
$v1 = explode("=", $v1Part)[1];

$expected = hash_hmac("sha256", "$ts.$body", $WEBHOOK_SECRET);
if (!hash_equals($expected, $v1)) { http_response_code(401); exit; }

$event = json_decode($body, true);
if ($event["event"] === "charge.paid") {
  // libera pedido por external_id
}
http_response_code(200);
Python + Flask
Backend Python para Django, Flask ou FastAPI.
# app.py — pip install flask requests
import os, hmac, hashlib, requests
from flask import Flask, request, jsonify

app = Flask(__name__)
SKINPAY_KEY = os.environ["SKINPAY_KEY"]
WEBHOOK_SECRET = os.environ["WEBHOOK_SECRET"]

@app.post("/checkout")
def checkout():
    body = request.json
    order_id = body["order_id"]

    r = requests.post(
      "https://skinpay.pro/api/public/v1/charges",
      json={
        "amount": body["amount"],
        "external_id": order_id,
        "description": f"Pedido #{order_id}",
        "expires_in": 3600,
      },
      headers={
        "x-api-key": SKINPAY_KEY,
        "Idempotency-Key": order_id,
      },
    )
    data = r.json()["data"]
    return jsonify({
      "qr": data["pix_qr_code"],
      "copy_paste": data["pix_copy_paste"],
    })

@app.post("/webhook/skinpay")
def webhook():
    sig = request.headers.get("X-SkinPay-Signature", "")
    ts_part, v1_part = sig.split(",")
    ts = ts_part.split("=")[1]
    v1 = v1_part.split("=")[1]

    body = request.get_data(as_text=True)
    expected = hmac.new(
      WEBHOOK_SECRET.encode(),
      f"{ts}.{body}".encode(),
      hashlib.sha256,
    ).hexdigest()

    if not hmac.compare_digest(expected, v1):
      return "", 401

    event = request.json
    if event["event"] == "charge.paid":
      print("Pix confirmado:", event["data"]["external_id"])
    return "", 200
HTML + JavaScript
Página de checkout simples chamando seu backend.
<!DOCTYPE html>
<html>
<head>
  <title>Checkout Pix</title>
  <style>
    body { font-family: system-ui; max-width: 480px; margin: 40px auto; padding: 20px; }
    img { width: 256px; }
    input { width: 100%; padding: 8px; font-family: monospace; }
    button { background: #00d68f; border: 0; padding: 12px 20px; border-radius: 8px; cursor: pointer; }
  </style>
</head>
<body>
  <h1>Pedido #<span id="order"></span></h1>
  <p>Valor: <strong>R$ 99,90</strong></p>

  <button onclick="gerarPix()">Pagar com Pix</button>

  <div id="pix" style="display:none">
    <img id="qr" />
    <p>Ou copie:</p>
    <input id="copy" readonly />
  </div>

  <script>
    async function gerarPix() {
      const orderId = "ped_" + Date.now();
      document.getElementById("order").textContent = orderId;

      const r = await fetch("/checkout", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ amount: 9990, orderId }),
      });
      const { qrCode, copyPaste } = await r.json();

      document.getElementById("qr").src = qrCode;
      document.getElementById("copy").value = copyPaste;
      document.getElementById("pix").style.display = "block";
    }
  </script>
</body>
</html>