Skip to content

Linking your users to BTC Direct accounts

Pass an optional identifier on the checkout call to link the user in your system to their BTC Direct account. Once linked, returning users skip the BTC Direct sign-in screen on every following checkout, and orders, callbacks, and user-level API calls trace back to the same person on your side.

  • No re-login. Returning users skip the BTC Direct sign-in screen on every checkout. They go from your app straight to the payment step.
  • Traceability. Orders, status callbacks, and follow-up API calls map cleanly back to the same person in your system.
  • One-step setup. No separate register-identifier call needed; pass the identifier on the checkout request you’re already making.

Pass an identifier whenever you can recognise the same person across visits. The recogniser does not have to be a user account in the traditional sense. Anything stable per user works.

ExampleWhat you pass as identifier
Platforms with user accounts (exchanges, custodial services, brokers)Your user UUID, account ID, or opaque user reference from your auth system.
Hardware wallet appsA hash of the user’s XPUB, device serial, or wallet UUID. You may have no name and no email on your side, and that’s fine: BTC Direct collects the user details on signup, you only need to provide the recogniser.
Self-custodial wallets and dappsA wallet address, public key, or session-bound wallet identifier. The user owns the wallet across visits, so the identifier stays stable.
Repeat customersWhatever identifier you already have. The user buys BTC today, ETH next month, sells ETH next year, and every checkout opens straight to their BTC Direct account with no sign-in.
Affiliate or loyalty trackingA user or wallet reference. You can tie purchase volume to a specific person without joining on email or name.
Customer support and reportingThe same record key you already use. Support agents and dashboards see BTC Direct orders mapped to the user record they already know.

The point: the identifier is your side’s recogniser, not the user’s identity. BTC Direct still collects email and KYC on signup; you don’t need to know any of that.

If your product genuinely can’t recognise the same person across visits (a pure embedded widget on an anonymous landing page, for example), omit the field. Users sign in or sign up on the BTC Direct page as before and the checkout still works.

  1. Pick an identifier per user. 36 to 255 characters, stable for the lifetime of the user (a UUID, hashed wallet key, or opaque user reference) and unique per user. It doubles as an authentication credential, so prefer an opaque reference and keep PII out of it (see Common pitfalls).
  2. Pass it as identifier on POST /api/v2/buy/checkout, in the request body. This is the only place you supply the raw value.
  3. BTC Direct encrypts it into the returned checkoutUrl. Redirect the customer to that URL exactly as returned — never build the checkout URL yourself or put a raw identifier in it. Only the encrypted token travels in the browser (URL, headers, storage); the raw value stays server-side.
  4. On the checkout page:
    • First-time user: they sign up on the checkout page. The identifier is linked to their new BTC Direct account during signup.
    • Returning user: the identifier is already linked, so the sign-in screen is skipped and they continue straight to checkout.
  5. BTC Direct calls the user_identifier_linked webhook once the link succeeds, echoing your original (raw) identifier. We strongly recommend consuming it — see When the identifier becomes usable.
  6. For any later direct API call on behalf of that user, authenticate them with the same identifier in the User-Identifier header. See User authentication, Option 2.
sequenceDiagram
    participant P as Your backend
    participant API as BTC Direct
    participant B as Customer browser
    participant H as Your webhook endpoint
    P->>API: POST /api/v2/buy/checkout (identifier: raw, in body)
    API-->>P: checkoutUrl (identifier encrypted inside)
    P->>B: redirect to checkoutUrl
    B->>API: open checkout (encrypted token only)
    Note over B,API: first-time user signs up & consents → linked<br/>returning user: already linked → sign-in skipped
    API->>H: user_identifier_linked webhook (raw identifier)
    Note over P,H: from here the identifier authenticates the user
    P->>API: later calls — User-Identifier: raw identifier
Terminal window
curl -X POST https://api-sandbox.btcdirect.eu/api/v2/buy/checkout \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"baseCurrency": "BTC",
"quoteCurrency": "EUR",
"paymentMethod": "creditCard",
"quoteCurrencyAmount": 50,
"walletAddress": "bc1...",
"identifier": "partner-unique-user-id-at-least-36-characters-long"
}'
Try it out

Create a checkout session linked to a partner-supplied user identifier.

RuleDetail
Length36 to 255 characters. Shorter values return ER102.
TypeString. Other types return ER053.
Empty stringTreated as invalid (returns ER053 / ER102). Omit the field if you have no identifier for this user.
StabilityMust be stable for the lifetime of the user. Changing it for the same person creates a new, unlinked BTC Direct account.
UniquenessMust be unique per user. Reusing the same identifier across different users would point them all at the same BTC Direct account.

The identifier only authenticates a user after it has been linked — which happens when the customer signs up or consents during checkout, not when you send it on the checkout call. Subscribe to the user_identifier_linked webhook to know when that happens:

  • Before the webhook: the link may not exist yet (the customer may not have finished checkout). Keep routing the customer through the checkoutUrl; don’t rely on the User-Identifier header yet.
  • After the webhook: the identifier is linked. You can authenticate the user directly with the User-Identifier header on user-level endpoints.

Once the identifier is linked, you can call user-level endpoints (order history, user info, payment accounts) by sending the identifier as a header. The full pattern is documented under User authentication, Option 2; the short version is:

Authorization: Bearer {partner_token}
User-Identifier: {identifier}

No separate user-login token round-trip needed.

If your integration today calls POST /api/v1/user/register-identifier before redirecting the user to checkout, you can drop that call and pass the same identifier directly on POST /api/v2/buy/checkout. Behaviour for new and returning users is identical; the only difference is one fewer round-trip.

The legacy register-identifier endpoint stays available and continues to work for non-checkout flows.