PayLynks agent skill
Instructions for AI coding agents adding PayLynks payments to an app. Also served at https://paylynks.io/SKILL.md.
Setup
- Run
npx paylynks initin the project root. It writesPAYLYNKS_SECRET_KEYto.env.localand, for Next.js, adds:app/api/paylynks/checkout/route.ts— creates a payment intent on the servercomponents/PayLynksCheckout.tsx— mounts the secure checkoutapp/checkout/page.tsx— a demo pageapp/api/paylynks/webhook/route.ts— verifies and handles webhooks
- 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_intentswithAuthorization: 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_secretto the browser and mount checkout withPayLynks().mountCheckout(el, { clientSecret })fromhttps://paylynks.io/js/v1.js. - Use integer cents everywhere:
2500is $25.00. - Send an
Idempotency-Keyheader on POSTs (a UUID or your order id). - Fulfil orders from the
payment_intent.succeededwebhook, and verify thePayLynks-Signatureheader against the raw body first. Handle duplicates. - Treat
processingas "not paid yet": bank (ACH) payments stayprocessingfor up to 4 business days beforesucceededorpayment_failed. - Send
PayLynks-Version: 2026-10-21so later API changes don't change your integration. - For donations, create a donation page (
POST /api/v1/donation_pagesor the MCP toolcreate_donation_page) and link to itsurlinstead 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.localout 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
onSuccessin the browser as proof of payment. Confirm with the webhook orGET /api/v1/payment_intents/:id(statussucceeded). - 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. |