Use payment links
A payment link is a Frame-hosted URL that handles the entire checkout. The customer opens the link, lands on a Frame-hosted page with the configured product(s), enters their payment details, completes the charge — your platform never sees a card. You receive a transfer.succeeded webhook when the payment lands.
Payment links are managed entirely from the Frame Dashboard. There is no V1 API for creating them; the integration work is webhook handling.
Reach for payment links when you need accepting-payments capability without building a checkout UI:
- One-off sales conversations where you send a URL by email or chat.
- Social media or marketing campaigns with a shared "buy now" link.
- Quick MVPs that need payment acceptance before the full storefront is built.
For programmatic checkout where you control the UX, use the accept-a-payment flow instead.
Prerequisites
| Requirement | Details |
|---|---|
| Dashboard access | A user on your Frame account with permission to manage payment links. |
| Products configured | Each link's line items reference existing Product records. Set them up under Products in the dashboard first. |
| Active billing agreement | Your platform's charge-category billing agreement must be active — same prereq as any payment acceptance. |
| Webhook endpoint registered | To react to completed payments, register an endpoint under Developers → Webhooks in the dashboard. |
1. Create the link in the dashboard
- Open Payment Links in the dashboard.
- Click New payment link.
- Add one or more line items, each referencing a Product. Set quantity bounds per item if you want the customer to pick a quantity at checkout.
- Configure optional fields:
- Shipping address collection — adds an address form to the hosted page.
- Phone number collection — adds a phone field. Only enable if you actually need it; required fields cost conversion.
- (Optional) Set a
client_reference_idto correlate this link with your internal record (an order ID, a CRM contact ID, etc.). It rides along on the resulting charge so you can match the webhook back to your context. - Save. The dashboard shows the customer-facing URL.
2. Share the URL
The URL is short and stable for the life of the link:
https://checkout.framepayments.com/<link_id>
<link_id> is the short slug shown on the link's dashboard row. Send it by email, paste it into a chat, link it from your site, post it to social — anywhere a URL works.
The same URL is reusable across customers. Each customer who pays generates a fresh charge attached to the same parent link.
3. Customer pays via the link
When the customer opens the URL, Frame's hosted page renders the line items, collects payment info, runs the charge — including Sonar risk evaluation and 3D Secure if triggered — and on success shows a Frame-hosted confirmation. Your platform isn't in the request path.
Your branding (logo, colors, merchant name) appears on the hosted page automatically based on your dashboard settings.
4. React to the payment via webhooks
Completed payments arrive on your registered webhook endpoint as a transfer.succeeded event. From the transfer payload, walk the FK chain back to identify the source payment link:
Transfer
└─ charge_intent_id → ChargeIntent
└─ payment_link → PaymentLink (carries client_reference_id)
Typical handler shape:
- Listen for
transfer.succeeded. - Read the transfer's
charge_intent_idand retrieve the ChargeIntent. - Follow
payment_linkon the ChargeIntent to identify which link was paid. - Match the link's
client_reference_idto your internal record and fulfill the order.
See events and webhooks for delivery semantics, signature verification, and retry behavior.
Disabling a link
Open the link in the dashboard and click Disable. Disabled links return a "not available" message to customers — existing URLs stop working but the link record is preserved. Re-enabling restores it at the same URL.
To remove a link permanently, use Delete. The link_id becomes invalid; the same slug won't be reissued.
Common variations
Subscription links. A link tied to a recurring product creates a subscription on payment. The customer's card is stored and billed on the subscription's cycle. See the subscriptions guide for the product-side setup.
Multi-product baskets. Add multiple line items to a single link. Each item carries its own quantity bounds; the customer chooses quantities within those bounds at checkout.
Account dedup by email. Frame matches the paying customer to an existing Account by the email entered at checkout. If the same customer pays through multiple links, they show up as the same Account with the new payment method attached.
Gotchas
Symptom: the URL 404s when the customer clicks it. Why: the link was disabled or deleted, or the slug was copied with a typo. Fix: verify the link is active in the dashboard and the URL matches https://checkout.framepayments.com/<link_id> exactly.
Symptom: the customer paid but transfer.succeeded didn't fire on your endpoint. Why: webhook endpoint not registered, signature verification failing, or your endpoint rejected the delivery. Fix: check Developers → Webhooks in the dashboard for the endpoint's delivery log; resend failed events from there.
Symptom: duplicate Accounts appear for the same customer who paid through multiple links. Why: the customer entered different email addresses, so Frame's email-based dedup treats them as different Accounts. Fix: manual reconciliation in the dashboard, or accept the noise if it's rare.
Next steps
- Accept a payment — programmatic checkout when you control the UI.
- Build a custom payment page — embed Frame's card element in your own UI.
- Build subscriptions — recurring billing tied to payment links or direct API flows.