What you'll need
A Thexly API key (create one under Settings → API keys), and the ability to make a server-side request from wherever you process the payment.
Request
Send a POST request to /api/payments/manual, authenticated with your API key via an Authorization: Bearer header (or an x-thexly-api-key header, if you'd rather not use the Bearer scheme).
curl -X POST https://thexly.com/api/payments/manual \
-H "Authorization: Bearer YOUR_THEXLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"websiteId": "your-website-id",
"transactionId": "order_12345",
"amount": 49.00,
"currency": "USD",
"sessionId": "s_..."
}'Fields
- 1
websiteIdandtransactionId(required): the Thexly website to record against, and your own unique identifier for this payment (recording the sametransactionIdtwice won't duplicate it). - 2
amountandcurrency(required): the payment amount and a 3+ character currency code (e.g.USD). - 3
sessionId: the visitor session this payment should be attributed to. Callwindow.thexly.getSessionId()from the page where the visitor checked out to get it, and pass it through to wherever you make this request from. Without it, the payment is still recorded, but won't be matched to a specific visit. - 4
emailoremailHash,providerCustomerId,externalCustomerId,occurredAt: optional identifiers and timestamp, useful if you're backfilling historical payments or want customer-level matching as a fallback when there's no session id.
What Thexly does with this data
Once recorded, this payment is matched and attributed exactly like one pulled in from a connected processor; see how Thexly assigns revenue to a channel. There's no live processor connection behind this data, so nothing syncs or updates on its own. Each payment is exactly what you sent, when you sent it.
Troubleshooting
- 401 Unauthorized: check the API key is valid and hasn't been revoked under Settings → API keys.
- 403 Forbidden: the API key you're using is scoped to a different website than the
websiteIdin the request. - Payment recorded but not attributed to a session: check that the
sessionIdyou sent matches whatwindow.thexly.getSessionId()returned on the same visit; sessions expire after 30 minutes of inactivity.