PayLynks

PayLynks agent skill

Instructions for AI coding agents adding PayLynks payments to an app. Also served at https://paylynks.io/SKILL.md.

Setup

  1. Run npx paylynks init in the project root. It writes PAYLYNKS_SECRET_KEY to .env.local and, for Next.js, adds:
    • app/api/paylynks/checkout/route.ts — creates a payment intent on the server
    • components/PayLynksCheckout.tsx — mounts the secure checkout
    • app/checkout/page.tsx — a demo page
    • app/api/paylynks/webhook/route.ts — verifies and handles webhooks
  2. Non-Next.js apps: call the MCP tool get_snippet (kinds: react, supabase, html, node, webhook) or read https://paylynks.io/docs/checkout.md.

Do

  • Create payment intents on the server with the secret key: POST https://paylynks.io/api/v1/payment_intents with Authorization: Bearer $PAYLYNKS_SECRET_KEY.
  • Look prices up on the server from a product id. The browser sends {"product": "pro-plan"}, never an amount.
  • Send only the client_secret to the browser and mount checkout with PayLynks().mountCheckout(el, { clientSecret }) from https://paylynks.io/js/v1.js.
  • Use integer cents everywhere: 2500 is $25.00.
  • Send an Idempotency-Key header on POSTs (a UUID or your order id).
  • Fulfil orders from the payment_intent.succeeded webhook, and verify the PayLynks-Signature header against the raw body first. Handle duplicates.
  • Treat processing as "not paid yet": bank (ACH) payments stay processing for up to 4 business days before succeeded or payment_failed.
  • Send PayLynks-Version: 2026-10-21 so later API changes don't change your integration.
  • For donations, create a donation page (POST /api/v1/donation_pages or the MCP tool create_donation_page) and link to its url instead of building a giving form.
  • To let customers manage cards and subscriptions, redirect them to a portal link from POST /api/v1/customers/:id/portal_sessions.
  • Keep .env.local out of git.

Don't

  • Don't put sk_test_ / sk_live_ keys in client code, NEXT_PUBLIC_* / VITE_* variables, or the repo.
  • Don't build your own card form or collect card numbers. Checkout's iframe does that (PCI).
  • Don't trust onSuccess in the browser as proof of payment. Confirm with the webhook or GET /api/v1/payment_intents/:id (status succeeded).
  • Don't add a surcharge yourself. PayLynks applies the merchant's surcharge or dual-pricing rules and shows the disclosure.
  • Don't invent endpoints. The full list is at https://paylynks.io/docs/api-reference.md.

Test cards

Card Result
4242 4242 4242 4242 Visa credit, succeeds (surcharge applies if the merchant surcharges)
4000 0566 5566 5556 Visa debit, succeeds, never surcharged
4000 0000 0000 0002 Declined

Any future expiry, any CVC, any ZIP.

Common errors

Message Fix
Provide an API key as Authorization: Bearer <key> Missing or malformed header; check the env var is loaded on the server.
This endpoint requires a secret key. You used a pk_ key on a server endpoint.
Invalid client_secret Pass the whole pi_…_secret_… value from the intent you just created.
This payment_intent is succeeded and cannot be confirmed. Create a new intent for each checkout attempt.
The total is now X (was Y) You sent expected_total and pricing changed (often credit vs debit); show the new total and retry.
Idempotency-Key reused with a different request Use a new key for a different request.
Bank payments need the payer's authorization. Confirming a bank payment from your server: pass mandate: {ip_address, user_agent} from the payer's request.
Unknown PayLynks-Version Use a version listed at https://paylynks.io/docs/security.md.

View as markdown