Skip to main content
Every Paddle purchase must be linked to a Qonversion user so Qonversion can grant entitlements and attribute revenue. There are two ways to do it:
  • Automatic (recommended) — tag the Paddle Checkout with the Qonversion user in custom_data. Qonversion reads it from the Paddle webhook and grants entitlements automatically, including for later renewals, refunds, and cancellations. No purchase-submission call is required.
  • Explicit — submit the completed purchase yourself from your server (REST API) or the browser (Web SDK), passing the Qonversion user in the request.
When you open the Paddle Checkout, set custom_data.qonversion_client_uid to the buyer’s Qonversion User ID. Paddle stores it on the resulting transaction and includes it in every webhook it sends — that is how Qonversion maps the purchase (and all future events on the same subscription) to the user.
Paddle.Checkout.open({
  items: [{ priceId: 'pri_01hv4rrk', quantity: 1 }],
  customData: {
    qonversion_client_uid: '<QONVERSION_USER_ID>',
  },
});
The key must be exactly qonversion_client_uid. Its value is the Qonversion User ID — see Getting the Qonversion User ID.
If you create transactions or subscriptions with the Paddle API instead of the overlay checkout, set the same qonversion_client_uid key on the request’s custom_data.

Customer-level fallback

If a webhook payload does not carry custom_data.qonversion_client_uid, Qonversion falls back to the Paddle customer’s custom_data. You can set it when you create or update the customer:
curl --request PATCH \
  --url https://api.paddle.com/customers/{customer_id} \
  --header 'Authorization: Bearer {paddle_api_key}' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "custom_data": {
      "qonversion_client_uid": "<QONVERSION_USER_ID>"
    }
  }'
If neither the transaction nor the customer carries qonversion_client_uid, Qonversion acknowledges the Paddle webhook but cannot map the purchase to a user, so no entitlement is granted. Set it at checkout (or on the customer) before the first payment.

Getting the Qonversion User ID

The Qonversion User ID is the value you place in qonversion_client_uid (and in the {user_id} of the REST call below). Obtain it in one of two ways:
  • From the SDK — call the userInfo() method and use the qonversionId property from the result. See User Identifiers for details.
  • Via API — create a user by calling POST /v3/users/{id}. See the API reference for details.

2. Submit the purchase explicitly

If you prefer to push purchases yourself instead of relying on the automatic webhook mapping, send the completed purchase to Qonversion after a successful payment. Capture the Paddle identifiers from the completed transaction and call:
The client-side checkout.completed event gives you the transaction_id (txn_) and product_id (pro_), but not the subscription_id — Paddle creates the subscription asynchronously a few seconds later. For a subscription purchase, read the subscription_id server-side from the transaction.completed / subscription.created webhook (or GET /transactions/{id}) before submitting. For subscriptions, prefer the automatic custom_data flow above, which has no such timing constraint.
curl -X POST \
  https://api.qonversion.io/v3/users/{user_id}/purchases \
  -H "Authorization: Bearer {project_key}" \
  -H "Content-Type: application/json" \
  -d '{
    "currency": "USD",
    "price": "9.99",
    "paddle_store_data": {
      "type": "subscription",
      "transaction_id": "{paddle_transaction_id}",
      "subscription_id": "{paddle_subscription_id}",
      "product_id": "{paddle_product_id}"
    }
  }'
Replace {paddle_transaction_id} and {paddle_subscription_id} with the values from the completed Paddle transaction, and {paddle_product_id} with the Paddle product ID. The {user_id} is the Qonversion User ID (see above).
FieldSource
currencytransaction currency code
pricetransaction total
paddle_store_data.typesubscription for recurring products, non_recurring for one-time purchases
paddle_store_data.transaction_idPaddle transaction id (txn_)
paddle_store_data.subscription_idPaddle subscription id (sub_). Required for subscription; omit for non_recurring
paddle_store_data.product_idPaddle product id (pro_)

Web SDK

If you are using Qonversion on the web, you can also use the Qonversion Web SDK to submit the purchase. After a successful Paddle payment, pass the purchase data to sendPaddlePurchase.
The Web SDK object differs from the REST body above. Its fields are camelCase (transactionId, productId, subscriptionId), and the one-time type value is inapp, not non_recurring (the SDK maps it to non_recurring on the wire for you).
const purchase = await qonversionInstance.sendPaddlePurchase({
  price: '9.99',
  currency: 'USD',
  transactionId: 'txn_01hv4rrk',
  productId: 'pro_01hv4rrk',
  type: 'subscription',           // or 'inapp' for one-time purchases
  subscriptionId: 'sub_01hv4rrk', // required for 'subscription'; omit for 'inapp'
});
See the full Paddle Integration guide for details.