Authentication overview
Paddle's API authentication mechanisms are designed to secure interactions with its platform, safeguarding sensitive payment and subscription data. The primary method for authenticating direct API requests involves using API keys. These keys act as unique identifiers and provide the necessary credentials to authorize operations such as creating subscriptions, processing payments, or retrieving customer information. For asynchronous event notifications, Paddle employs webhook signatures, which allow developers to verify the authenticity and integrity of incoming webhook payloads from Paddle's services.
The choice of authentication method depends on the interaction type: direct API calls typically use API keys, while receiving event data from Paddle leverages webhook secrets for signature verification. This dual approach ensures that both outgoing requests from a developer's application and incoming notifications from Paddle are authenticated and trusted. Implementing these methods correctly is crucial for maintaining the security and reliability of any integration with the Paddle platform.
Supported authentication methods
Paddle supports distinct authentication methods tailored for different types of interactions within its ecosystem. Direct API requests for managing resources are authenticated using API keys, while incoming webhook events from Paddle are secured through HMAC-SHA256 signatures.
API Key Authentication (Bearer Token)
For making direct API calls to the Paddle API, API keys are used to authenticate requests. These keys function as a Bearer Token, which must be included in the Authorization header of every HTTP request. This method grants access to perform actions on behalf of your Paddle account, such as creating products, managing customers, or processing transactions.
- When to use: For programmatic interactions where your application initiates requests to Paddle's API endpoints. This includes operations like fetching subscription details, updating customer records, or creating new checkouts.
- Security level: High, when API keys are kept confidential and managed securely. Access control can be granular depending on the scope of the key.
Webhook Signature Verification (HMAC-SHA256)
When Paddle sends event notifications to your configured webhook endpoints, it includes an Paddle-Signature header. This signature is generated using an HMAC-SHA256 algorithm, incorporating the webhook payload and a shared secret key that you configure. Your application must verify this signature to confirm that the webhook payload originated from Paddle and has not been tampered with during transit.
- When to use: For receiving and processing asynchronous event notifications from Paddle, such as subscription created, payment succeeded, or invoice issued events. Verification is essential to prevent spoofing and ensure data integrity.
- Security level: High, as it verifies both authenticity and integrity of the webhook payload, protecting against replay attacks and unauthorized data injection. Securely managing the webhook secret is paramount.
The following table summarizes Paddle's authentication methods:
| Method | Purpose | When to Use | Security Level Considerations |
|---|---|---|---|
| API Key (Bearer Token) | Authenticates direct API requests to Paddle's REST API. | Making server-side calls for data retrieval, resource creation, or updates. | High, requires strict confidentiality. Compromised keys lead to unauthorized API access. |
| Webhook Signature (HMAC-SHA256) | Verifies authenticity and integrity of incoming webhook payloads. | Processing asynchronous event notifications from Paddle to your application. | High, prevents spoofing and tampering. Requires secure management of the webhook secret. |
Getting your credentials
To interact with the Paddle API and receive secure webhooks, you will need to obtain specific credentials from your Paddle dashboard. These credentials include your API Key (also referred to as a Bearer Token) for direct API requests and a Webhook Secret for verifying incoming webhook events.
API Key
- Log in to your Paddle Dashboard.
- Navigate to the Developer Tools section.
- Select Authentication.
- You will find your API Key here. Paddle typically provides a single, long-lived API key for your account. Treat this key as a sensitive password.
- Copy the API Key. This will be used in the
Authorization: Bearer <YOUR_API_KEY>header for your API requests.
Webhook Secret
The webhook secret is generated when you configure a webhook endpoint in your Paddle account.
- In your Paddle Dashboard, go to Developer Tools.
- Select Webhooks.
- Click New Webhook to create a new endpoint, or edit an existing one.
- When setting up or editing a webhook, Paddle will display a Signing Secret. This secret is vital for verifying the authenticity of webhook payloads.
- Copy the Webhook Secret. You will use this secret to compute the expected HMAC-SHA256 signature and compare it against the
Paddle-Signatureheader sent with each webhook.
It is important to store these credentials securely and never expose them in client-side code or public repositories. For server-side applications, environment variables or a secure secret management service are recommended practices for storing API keys and secrets.
Authenticated request example
This example demonstrates how to make an authenticated request to Paddle's API using an API key (Bearer Token) and how to verify a webhook signature using Python. For more comprehensive examples, refer to the Paddle API reference.
Example: Making an API Key Authenticated Request (Python)
This Python example fetches a list of products from the Paddle API.
import requests
import os
# Retrieve your API key securely from environment variables
PADDLE_API_KEY = os.environ.get("PADDLE_API_KEY")
if not PADDLE_API_KEY:
raise ValueError("PADDLE_API_KEY environment variable not set.")
api_url = "https://api.paddle.com/products"
headers = {
"Authorization": f"Bearer {PADDLE_API_KEY}",
"Content-Type": "application/json"
}
try:
response = requests.get(api_url, headers=headers)
response.raise_for_status() # Raise an HTTPError for bad responses (4xx or 5xx)
products = response.json()
print("Successfully fetched products:")
for product in products['data']:
print(f" ID: {product['id']}, Name: {product['name']}")
except requests.exceptions.HTTPError as err:
print(f"HTTP error occurred: {err}")
except Exception as err:
print(f"An error occurred: {err}")
Example: Verifying a Webhook Signature (Python)
This Python example outlines the process for verifying an incoming Paddle webhook. This code would typically be part of a server-side endpoint that receives webhooks.
import hmac
import hashlib
import json
import os
from flask import Flask, request
app = Flask(__name__)
# Retrieve your Webhook Secret securely from environment variables
PADDLE_WEBHOOK_SECRET = os.environ.get("PADDLE_WEBHOOK_SECRET")
@app.route('/paddle-webhook', methods=['POST'])
def paddle_webhook():
if not PADDLE_WEBHOOK_SECRET:
return "Webhook secret not configured", 500
# 1. Get the raw request body
payload_bytes = request.get_data()
# 2. Get the signature from the header
# Paddle sends signature as 'Paddle-Signature: t=TIMESTAMP;h=HMAC_SIGNATURE'
paddle_signature_header = request.headers.get('Paddle-Signature')
if not paddle_signature_header:
return "Missing Paddle-Signature header", 400
# Parse the timestamp and hash from the header
parts = dict(item.split('=') for item in paddle_signature_header.split(';'))
timestamp = parts.get('t')
received_signature = parts.get('h')
if not timestamp or not received_signature:
return "Invalid Paddle-Signature header format", 400
# 3. Construct the signed payload string
# The string to sign is 'timestamp:request_body'
# Ensure the timestamp is an integer or string representation of integer
signed_payload_string = f"{timestamp}:{payload_bytes.decode('utf-8')}"
# 4. Compute the expected HMAC-SHA256 signature
expected_signature = hmac.new(
PADDLE_WEBHOOK_SECRET.encode('utf-8'),
signed_payload_string.encode('utf-8'),
hashlib.sha256
).hexdigest()
# 5. Compare the signatures
if hmac.compare_digest(expected_signature, received_signature):
print("Webhook signature verified successfully!")
# Process the webhook payload here
webhook_data = json.loads(payload_bytes)
print(f"Received event type: {webhook_data['event_type']}")
return "Webhook received and verified", 200
else:
print("Webhook signature verification failed.")
return "Signature verification failed", 403
if __name__ == '__main__':
# For local testing, ensure PADDLE_API_KEY and PADDLE_WEBHOOK_SECRET are set
# e.g., in your shell: export PADDLE_API_KEY="pk_test_..."
# export PADDLE_WEBHOOK_SECRET="webhook_secret_..."
app.run(port=5000, debug=True)
Security best practices
Securing your Paddle integration involves diligent management of your API keys and webhook secrets, along with careful implementation of authentication mechanisms. Adhering to these best practices helps protect your system and customer data from unauthorized access and manipulation.
API Key Management
- Keep Keys Confidential: Never hardcode API keys directly into your application's source code. Store them as environment variables, in a secure configuration management system, or using a secret management service (e.g., AWS Secrets Manager, Google Secret Manager, Azure Key Vault).
- Restrict Access: Ensure that only authorized personnel and systems have access to your API keys. Implement strict access controls for any environment where these keys are stored or used.
- Avoid Client-Side Exposure: Do not expose your Paddle API key in client-side code (e.g., JavaScript in a browser). Direct API calls should always originate from your secure backend server. Client-side interactions requiring Paddle functionality should use Paddle.js for secure checkout experiences, which handle tokenization securely without exposing your main API key.
- Rotation: Regularly rotate your API keys, especially if there's any suspicion of compromise or as part of a routine security policy. This limits the window of opportunity for a compromised key to be exploited.
- Dedicated Keys (if available): If Paddle offers different types of API keys with varying permissions (e.g., read-only vs. read-write), use the least privileged key necessary for each function of your application. While Paddle typically provides a single account-wide key, this is a general security principle for APIs.
Webhook Security
- Always Verify Signatures: It is critical to verify the
Paddle-Signatureheader on every incoming webhook event. This confirms the request originated from Paddle and that the payload has not been altered. Failure to verify signatures can lead to processing fraudulent or malicious data. The Paddle documentation details the verification process. - Store Secrets Securely: Just like API keys, your webhook secret must be stored securely (e.g., environment variables, secret manager) and never hardcoded or exposed publicly.
- Implement Replay Attack Protection: The
t(timestamp) component of thePaddle-Signatureheader can be used to mitigate replay attacks. You should reject webhook events if the timestamp is significantly older or newer than your server's current time (e.g., more than 5 minutes difference). - Use HTTPS for Webhook Endpoints: Ensure your webhook endpoints are served over HTTPS. This encrypts the communication channel between Paddle and your server, protecting the payload in transit. This is also a general best practice for any API endpoint, as outlined by the Mozilla Web Security documentation for secure contexts.
- Idempotency: Design your webhook processing logic to be idempotent. This means that processing the same webhook event multiple times will have the same effect as processing it once. This protects against duplicate processing if Paddle retries sending an event or if your system receives duplicates due to network issues.
General API Security
- Error Handling: Implement robust error handling for API requests and webhook processing. Avoid revealing sensitive information in error messages.
- Logging: Log API request and webhook activity for auditing and debugging purposes. Be careful not to log sensitive credentials.
- Regular Audits: Periodically review your authentication implementation and access policies to ensure they align with current security standards and your application's requirements.