Payments API
Record payments from any provider with POST /api/payment and optional visitor attribution fields.
Use the Payments API when you process orders outside Stripe/Polar — WordPress plugins, Paddle webhooks, manual backends — and still want revenue in XPmetric with optional visitor attribution.
Get your API secret
- Open Settings → Integrations for the site.
- Generate an API secret (
xpm_sk_…) — shown once; store it securely. - Never use your public site token (
data-siteinp.js) for this endpoint.
Record a payment
curl -X POST https://xpmetric.com/api/payment \
-H "Authorization: Bearer xpm_sk_YOUR_API_SECRET" \
-H "Content-Type: application/json" \
-d '{
"amount_cents": 2900,
"currency": "usd",
"external_id": "order_123",
"type": "one_time",
"visitor_id": "VISITOR_HASH_FROM_xpmetric.v",
"session_id": "SESSION_ID_FROM_xpmetric.s"
}'Request body
| Field | Required | Description |
|---|---|---|
amount_cents | Yes | Integer cents (negative for refunds) |
currency | Yes | ISO code, e.g. usd |
external_id | Yes | Your unique charge/order id |
type | No | new, renewal, one_time, refund (default one_time) |
visitor_id | No | window.xpmetric.v at purchase time |
session_id | No | window.xpmetric.s at purchase time |
email | No | Buyer email for the opt-in fallback when no visitor ID resolves to a first-touch |
occurred_at | No | ISO 8601 timestamp (default now) |
Auth & limits
- Header:
Authorization: Bearer xpm_sk_… - Rate limit: 120 requests/minute per site
- Idempotent within the site on
external_id— safe to retry. Other sites can use the same ID independently.
Attribution
When visitor_id is set, XPmetric looks up first-touch channel, referrer, UTM, and landing path from ClickHouse and stores them on the PaymentEvent row.
With the default cookieless p.js, first-touch attribution is scoped to the UTC day of the visitor ID you send. A delayed API call can still match that day's visit when it carries the ID; a later visit gets a new ID. For cross-day first-touch, choose cookie mode in Settings → Sites: its p.cookie.js script uses the first-party _xpm_id cookie. Compare tracking modes.
Email attribution fallback
The optional email field is a recovery path for a confirmed payment that has no visitor ID, or whose visitor ID has no matching first-touch. XPmetric always tries a resolvable visitor_id first and uses email only when metadata attribution has no result.
Enable Email attribution fallback for the site in Settings → Integrations. It is off by default. Email fallback also requires the XPmetric server to be configured for it. The buyer's browser must first create a visitor link on the confirmed thank-you page:
// On the confirmed thank-you page, pass an email already available to your app.
function identifyPaidBuyer(buyerEmail) {
if (typeof buyerEmail !== "string" || !buyerEmail.trim()) return;
window.xpmetric?.identify?.(buyerEmail);
}
// Replace this example with your app's confirmed order/session email:
// identifyPaidBuyer(order.customerEmail);Use the buyer email from your own confirmed order data. This browser call sends the email to XPmetric over TLS so it can link the current browser visit; it does not use browser storage. Keep the Payments API request server-to-server and its API secret out of browser code. Do not put email in URLs or logs. If there is no buyer browser context to call identify, an email value in the payment request alone cannot create a visitor link.
The raw email is normalized and used transiently over TLS. XPmetric stores only a site-scoped HMAC link for up to 30 days after its last capture; this is pseudonymous personal data, not anonymous data. Turning the site option off deletes its links. Cookieless matching is limited to the purchase's UTC day, even when payment ingestion is delayed. Cookie mode may match across days only when the link was captured in cookie mode.
As the site owner, update your privacy notice and establish an appropriate legal basis before sending buyer emails. Enabling the setting is not visitor consent.
XP
New non-refund payments award +100 XP to the site (same as Stripe/Polar sync).
Related
- Settings → Integrations — generate your API secret and check attribution for your site
- Stripe Checkout — zero-code path for Stripe
- Custom goals — track the conversion event before payment