Payment Links (no-code)
Use the URL your merchant created in the dashboard. Embed it on a site, drop it in an email, print a QR code, or listen for paid events with a webhook.
Payment Links are a no-code feature. They're created in the dashboard, not via the API. This page covers what to do with the link once it exists: how to drop it into your own surfaces, what the URL looks like, and how to confirm payments programmatically if you want to.
The link URL
Every Payment Link has a URL of the form:
https://checkout.xpay.app/p/{paymentLinkId}The paymentLinkId is the link's ID from the dashboard, prefixed plink_test_* in test mode and plink_live_* in live mode. The hostname is the same in both modes; the prefix tells you which environment a link belongs to.
Open the link's detail page in the dashboard and click Copy link to grab the URL, or Show QR code to download a printable QR.
Use the link
The URL is a regular HTTPS URL. Use it anywhere a URL works.
Anchor or button on your site
<a href="https://checkout.xpay.app/p/plink_..."> opens the hosted checkout in the same tab. Add target="_blank" to open in a new tab.
QR code on print or screen
The dashboard generates a printable QR. Stick it on a poster, a flyer, a restaurant table, or display it on a register screen.
Email, chat, social
Drop the URL into a transactional email, a Slack message, an Instagram bio, a WhatsApp text. The link works in any channel that renders URLs.
Webflow, Wix, Squarespace, Shopify
Most no-code site builders accept a custom URL on a button or image. Paste the link there. No script tag, no SDK, no embed.
One link, many customers
The same Payment Link is accepted by an unlimited number of customers. Each customer's interaction stands on its own: their own card, their own form, their own receipt.
This is useful for invoices you re-send, posters that hang for weeks, or evergreen "Buy now" buttons. It's a problem if the link gates a single sale or a limited slot. For one-of-a-kind sales, deactivate the link after the customer pays (list page, bulk action) so the URL stops accepting new payments.
Confirm payments programmatically (optional)
You don't need code to take payments through a Payment Link. The dashboard already shows you every transaction, every customer, and every payout that came through it.
Reach for code only when you need an automated reaction to each successful payment: granting access, sending a tracked-email receipt, posting to your warehouse system, updating an internal CRM. For that, set up a webhook endpoint and listen for checkout.session.completed events.
The event is the same one every other XPay integration emits. The session payload carries a paymentLinkId field telling you which Payment Link the customer paid through, so you can branch your handler based on the link.
The minimum your handler needs to do:
- Verify the
XPay-Signatureheader. - Parse the JSON body.
- If
event.type === "checkout.session.completed"andevent.data.object.paymentLinkId === "plink_...", do whatever fulfillment you want for that link.
For the full setup (creating an endpoint, getting the signing secret, the verification recipe in Node and Python), see the Webhooks group.
Set up a webhook endpoint
Add an endpoint in the dashboard and grab the whsec_* signing secret.
Verify signatures
HMAC-SHA256 signature verification with replay protection.
Where to next
Create a payment link
The dashboard walkthrough: products, collection, confirmation, share.
Test mode and test cards
Open a plink_test_* URL with a test card to run an end-to-end payment without spending money.
Need code-driven checkout?
If you want full programmatic control over each session, look at Hosted Checkout, Drop-in, or Elements.