Skip to content

Integrations

What connects today, and what does not

Plinth is an API and a checkout page. Everything marked available exists and is tested in the repository. Everything else is labelled as exactly that.

Available now

Code exists, is covered by tests in the repository, and runs on testnets.

  • Checkout page

    A payment page with two methods: pay with a connected wallet (gasless, one signature) or send USDC to a unique address. Status comes from the backend only.

    AvailableSee it in the demo
  • Payment links

    Reusable fixed-amount links at /l/{slug}. Opening one creates a fresh payment.

    AvailableUse cases
  • Invoices

    Numbered invoices with line items and a due date, shared as a link. They are not emailed by Plinth.

    AvailableUse cases
  • REST API and OpenAPI

    Versioned under /v1 with an OpenAPI 3.1 document generated from the same route definitions the server registers. Exact decimal amounts, structured errors, idempotency keys.

    AvailableDevelopers
  • Signed webhooks

    13 event types, HMAC-SHA256 signature, 8 retries over about 10 hours, a delivery log and manual retry.

    AvailableWebhook guide
  • API keys and team roles

    Hashed test and live keys, rotation, four team roles and an audit log.

    AvailableSecurity

In progress

Groundwork is in the repository, but it is not usable end to end.

  • Arc Testnet and Base Sepolia

    Two testnets configured with the official USDC and probed. Contracts for Base Sepolia are not deployed yet.

    In progressNetworks
  • Cross-chain consolidation (CCTP)

    Circle CCTP domains are recorded per network. The transfer lifecycle is designed but not implemented.

    In progress
  • KMS or HSM relayer signer

    Signing goes through a SignerProvider interface. Only an environment-key implementation exists.

    In progress

Planned

Noted as a limitation or design in the repository. No committed date.

  • E-commerce plugins

    No plugin code exists in the repository. Today you integrate through the API.

    Planned
  • Official SDKs

    No SDK exists. The OpenAPI document can be used to generate a client.

    Planned
  • WalletConnect and mobile wallets

    Checkout discovers browser-injected wallets only (EIP-6963). Mobile wallets can use the address flow.

    Planned
  • Smart-contract wallet payers

    Contract wallets need an EIP-1271 path on the gasless route. They can use the address flow today.

    Planned
  • Email delivery

    Invoices and receipts are shared as links; the platform sends no email.

    Planned
  • Solana

    Would be a separate adapter, since it cannot reuse CREATE2 or EIP-3009. Not started.

    Planned
  • Gateway Nanopayments

    A different model from invoice checkout. Support on the target networks is unconfirmed, so nothing is integrated.

    Planned

Connect in two calls

Create a payment, then verify and act on the webhook. Replace PLINTH_API with your API host and use an sk_test_ key on testnets.

cURL
# 1. Create a payment (idempotent)
curl -X POST $PLINTH_API/v1/payment-intents \
  -H "Authorization: Bearer $PLINTH_KEY" \
  -H "Idempotency-Key: order-1042" \
  -H "Content-Type: application/json" \
  -d '{ "amount": "25.00", "order_reference": "order-1042" }'

# 2. Register a webhook endpoint (the secret is shown once)
curl -X POST $PLINTH_API/v1/webhook-endpoints \
  -H "Authorization: Bearer $PLINTH_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://YOUR_DOMAIN/plinth/webhook", "events": ["payment.confirmed", "payment.completed"] }'
Node.js (v22, Express)
import crypto from "node:crypto";
import express from "express";

// Create a payment and send the customer to payment.checkout_url
const res = await fetch(process.env.PLINTH_API + "/v1/payment-intents", {
  method: "POST",
  headers: {
    Authorization: "Bearer " + process.env.PLINTH_KEY,
    "Idempotency-Key": "order-1042",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ amount: "25.00", order_reference: "order-1042" }),
});
const payment = await res.json();

// Verify the signature on the raw body, then fulfil on payment.confirmed
const app = express();
app.post("/plinth/webhook", express.raw({ type: "application/json" }), (req, res) => {
  const parts = Object.fromEntries(
    (req.get("Plinth-Signature") ?? "").split(",").map((p) => p.split("=")),
  );
  const mac = crypto
    .createHmac("sha256", process.env.PLINTH_WEBHOOK_SECRET)
    .update(parts.t + "." + req.body)
    .digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
  const ok = fresh && mac.length === (parts.v1 ?? "").length &&
    crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(parts.v1));
  if (!ok) return res.sendStatus(400);

  const event = JSON.parse(req.body.toString());
  // De-duplicate on event.id, then act on event.type
  res.sendStatus(200);
});

These samples follow docs/api-guide.md and the reference verifier in the repository. They are illustrative and have not been published as an SDK.

Missing an integration you need?

Planned items have no dates. Knowing which one blocks you helps decide what to build first.