Help · Integrations
Integrations
Connect your website, your own till system and your back office to Aida. Set everything up in the Aida dashboard under Integrations (Owner or Admin).
Website checkout
Add a Pay with Aida button to any page. When a customer clicks it, Aida creates a secure card checkout on your own payment account and sends the customer to it. The payment appears in Payments with the channel Website, and the standard Aida fee applies (see Pricing).
- Under Integrations → Website, add your website's origin (for example
https://shop.example.com). Requests from any other website are refused. - Optionally set a success and cancel URL (https only). Aida adds
aida_refandaida_resultto them. - Create a payment link (fixed amount) or use a product id, then paste the snippet:
<script src="https://www.pipelineiq.eu/aida.js"
data-merchant="pk_aida_…"
data-link="YOUR_LINK_ID"></script>
| Attribute | Meaning |
|---|---|
data-merchant | Your publishable key (pk_aida_…). It is safe to show on your website. |
data-link | A payment link id: the price comes from Aida, not from the page. |
data-product + data-qty | A product from your Aida catalogue, priced by Aida. |
data-amount + data-description | Only if you turn on Allow custom amounts. Amount in minor units (øre/cents). Anyone can change a page's HTML, so use links or products for fixed prices. |
data-label | Button text (default "Pay with Aida"). |
Payment links
A payment link is a hosted page at https://www.pipelineiq.eu/l/<id> with a fixed amount. Share it by email, chat or QR code, or use its id in the website snippet. You can switch a link off at any time; old links then show "not active".
POS API: send sales from your own till
If you take payments on another till or terminal, send each sale to Aida so your ledger, customers, rewards and analytics stay complete. These sales are recorded as paid by your system: Aida does not move money for them and charges no Aida fee on them.
Endpoint: POST https://www.pipelineiq.eu/api/integrations/pos/transactions
Authentication and signing
- Create a secret key under Integrations → POS API. It looks like
sk_aida_…and is shown once. Aida stores only a hash of it. Revoke a key at any time; it stops working immediately. - Send
Authorization: Bearer sk_aida_…. - Send
Aida-Timestamp: the current Unix time in seconds (must be within 5 minutes). - Send
Aida-Signature: v1=<hex>, where hex is HMAC-SHA256 oftimestamp + "." + raw request body, keyed with your secret key. - Send
Idempotency-Key(8 to 100 characters, required). Retrying with the same key and body returns the first response (headerIdempotent-Replayed: true); the same key with a different body returns 409.
// Node.js 18+
import crypto from "node:crypto";
const key = process.env.AIDA_SECRET_KEY; // sk_aida_…
const body = JSON.stringify({
type: "sale", external_id: "till-7-000123",
amount_minor: 12500, currency: "DKK", method: "card",
customer: { email: "customer@example.com" }
});
const ts = Math.floor(Date.now() / 1000).toString();
const sig = crypto.createHmac("sha256", key).update(ts + "." + body).digest("hex");
const res = await fetch("https://www.pipelineiq.eu/api/integrations/pos/transactions", {
method: "POST",
headers: { "content-type": "application/json", authorization: "Bearer " + key,
"aida-timestamp": ts, "aida-signature": "v1=" + sig, "idempotency-key": "till-7-000123" },
body
});
Sale
| Field | Required | Notes |
|---|---|---|
type | no | sale (default) or refund |
external_id | yes | Your receipt or transaction id. Unique per merchant: sending it again returns the existing sale (200, duplicate: true). |
amount_minor | yes, unless items | Total in minor units |
items | no | [{ name, qty, unit_price_minor, vat_pct }]. If you also send amount_minor it must match the total. |
currency | yes | Must match the store's currency |
method | no | card (default) or cash |
store_id | no | Defaults to the store chosen under Integrations, else your first store |
customer | no | { email, phone, name }: links the sale to a customer profile and earns rewards |
Refund
Send type: "refund" with original_external_id (or original_transaction_id) and optionally amount_minor for a partial refund (default: the full amount left). Only sales sent through the POS API can be refunded this way. Refund Aida card payments from Payments.
Responses
| Status | Meaning |
|---|---|
| 201 | Recorded. The body has transaction with id, ref, status and amounts. |
| 200 | Already recorded (same external_id) |
| 400 | Invalid request (the code says why) |
| 401 | Missing, invalid or revoked key, bad signature or old timestamp |
| 404 | Original transaction not found. Keys only see their own merchant's data. |
| 409 | Idempotency conflict, or a refund that is not allowed |
Webhooks
Add an https URL under Integrations → Webhooks. Aida sends payment.paid, payment.refunded and payment.disputed as JSON POSTs. Use Send test event to try it (test.ping).
{ "id": "evt_…", "type": "payment.paid", "created": 1790790000, "livemode": true,
"merchant_id": "…", "data": { "object": { "id": "…", "ref": "…", "status": "paid",
"channel": "online", "amount_minor": 12500, "currency": "DKK", "aida_fee_minor": 150, … } } }
Verify every request. The header Aida-Signature: t=<unix>,v1=<hex> is HMAC-SHA256 of t + "." + raw body, keyed with your signing secret (whsec_aida_…, shown once; rotate it any time). Reject old timestamps and use id to ignore repeats.
const [t, v1] = header.split(",").map((p) => p.split("=")[1]);
const ok = crypto.timingSafeEqual(Buffer.from(v1, "hex"),
crypto.createHmac("sha256", secret).update(t + "." + rawBody).digest());
Retries: any answer other than 2xx within 8 seconds is retried after about 1 minute, 10 minutes, 1 hour, 6 hours and 24 hours (6 attempts). Recent deliveries and their status are listed under Integrations.
How payments are confirmed
Card payments through the website, payment links, QR codes and the POS count as paid only when Aida receives the payment provider's signed confirmation, never because a page or browser says so. Sales from the POS API are recorded as reported by your own signed request.
Questions: hello@pipelineiq.eu · Help