Server SDKs
Integrate from any backend
Three first-party server SDKs. Each one demonstrates the same end-to-end flow: create a customer, create a payment, issue a refund, and verify webhook signatures.
Install
The server SDKs are available from the private registry. Until they're published, you can use the raw HTTP snippets below — every endpoint documented in the API reference is reachable from any language.
Authentication
All server requests use a secret key passed in the Authorization header. Idempotency is enforced by the Idempotency-Key header on every POST.
curl -X POST "https://api.paymenthooks.com/v1/api/v1/payments" \
-H "Authorization: Bearer phk_test_replace_with_your_key" \
-H "Idempotency-Key: order-12345" \
-H "Content-Type: application/json" \
-d '{ "customerId": "cus_abc", "amount": 9500, "currency": "USD", "originalCurrency": "USD", "paymentMethod": "card" }'Quickstart
Each example creates a customer, charges them, lists recent payments, and issues a refund — the canonical four-call happy path.
// ─── PaymentHooks Node.js SDK Usage Example ───────────────────────────────────
// The full SDK package can be installed from your private npm registry:
// npm install @paymenthooks/node
//
// For this example we use the built-in fetch API (Node 18+). For older Node,
// swap in `node-fetch`.
const PAYMENTHOOKS_API_BASE = "https://api.paymenthooks.com/v1";
const PAYMENTHOOKS_SECRET_KEY = process.env.PAYMENTHOOKS_SECRET_KEY || "phk_test_replace_with_your_key";
async function paymenthooksRequest(path, options = {}) {
const url = `${PAYMENTHOOKS_API_BASE}${path}`;
const headers = {
"Authorization": `Bearer ${PAYMENTHOOKS_SECRET_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": options.idempotencyKey || `${Date.now()}-${Math.random()}`,
...(options.headers || {}),
};
const res = await fetch(url, {
method: options.method || "GET",
headers,
body: options.body ? JSON.stringify(options.body) : undefined,
});
const json = await res.json();
if (!res.ok) {
throw new Error(`PaymentHooks API error [${res.status}]: ${json.error?.message}`);
}
return json.data;
}
async function main() {
// 1) Create or fetch a customer
const customer = await paymenthooksRequest("/api/v1/customers", {
method: "POST",
body: {
email: "[email protected]",
name: "Jane Doe",
country: "US",
},
});
console.log("Customer created:", customer.id);
// 2) Create a payment intent (idempotent)
const payment = await paymenthooksRequest("/api/v1/payments", {
method: "POST",
idempotencyKey: "order-12345",
body: {
customerId: customer.id,
amount: 9500, // 9500 USD cents = USD 95.00
currency: "USD",
originalCurrency: "USD",
paymentMethod: "card",
description: "Order #12345",
},
});
console.log("Payment created:", payment.id, "status:", payment.status);
// 3) List recent payments
const list = await paymenthooksRequest("/api/v1/payments?pageSize=5", { method: "GET" });
console.log(`Found ${list.length} recent payments`);
// 4) Issue a refund
const refund = await paymenthooksRequest(`/api/v1/refunds`, {
method: "POST",
body: { paymentId: payment.id, amount: 9500, reason: "requested_by_customer" },
});
console.log("Refund issued:", refund.id, "status:", refund.status);
}
main().catch((err) => {
console.error("Failed:", err.message);
process.exit(1);
});
// ─── Webhook signature verification ──────────────────────────────────────────
// Use this on your webhook receiver endpoint to verify authenticity.
const crypto = require("crypto");
function verifyWebhookSignature(rawBody, signatureHeader, webhookSecret) {
if (!signatureHeader || !webhookSecret) return false;
const expected = crypto
.createHmac("sha256", webhookSecret)
.update(rawBody, "utf-8")
.digest("hex");
// Constant-time comparison
const a = Buffer.from(signatureHeader);
const b = Buffer.from(expected);
if (a.length !== b.length) return false;
return crypto.timingSafeEqual(a, b);
}
// Express example:
// app.post("/webhooks/paymenthooks", express.raw({ type: "application/json" }), (req, res) => {
// const sig = req.headers["x-paymenthooks-signature"];
// if (!verifyWebhookSignature(req.body, sig, process.env.PAYMENTHOOKS_WEBHOOK_SECRET)) {
// return res.status(401).end();
// }
// const event = JSON.parse(req.body.toString("utf-8"));
// // handle event.type ... event.data ...
// res.status(200).end();
// });
Webhook signature verification
Every webhook payload is signed with HMAC-SHA256 using the secret you configured on the endpoint. Verify the X-PaymentHooks-Signature header before acting on the event. The quickstart snippets above include ready-to-use verifier functions for each language.