Skip to main content

Paddle Billing ExecModule

Overview

PaddleModule connects ValkyrAI workflows to the current Paddle Billing API through the native map I/O ExecModule ABI. Workflow Studio discovers it as PaddleModule. A server-side Paddle API key resolves only from an encrypted IntegrationAccount; workflow inputs cannot supply credentials or arbitrary endpoints.

The initial operation set covers the core SaaS revenue graph:

  • list_products, get_product, create_product, update_product
  • list_customers, get_customer, create_customer, update_customer
  • list_subscriptions, get_subscription
  • list_transactions, get_transaction

All list operations use Paddle cursor pagination and bounded outputs. Only GET requests retry automatically. Product and customer writes run once so an ambiguous timeout cannot create or mutate a resource twice.

Usage

  1. In Paddle, create a server-side API key under Developer tools → Authentication.
  2. Grant only the product, customer, subscription, and transaction permissions required by the workflow.
  3. Store the API key in the encrypted apiKey field of an IntegrationAccount and set its status to READY.
  4. Bind the account through ExecModuleConfig.authConfig.integrationAccount.
  5. Select production or sandbox; the module maps this choice to a fixed Paddle host.
  6. Read the target resource before an update and reconcile Paddle state before repeating any write after an ambiguous failure.

Paddle client-side tokens are not accepted. They are intended for Paddle.js and do not authorize the server-side Billing API operations exposed here.

Inputs

NameTypeRequirementDefaultDescription and constraints
operationstringRequiredNoneOne of the 12 documented operations.
resourceIdstringGet/update operationsNoneTyped Paddle ID: pro_…, ctm_…, sub_…, or txn_…, according to the operation.
resourceobject or JSON stringProduct/customer create or updateNoneAllowlisted payload, maximum 256 KiB.
environmentstringOptionalproductionproduction or sandbox; maps only to an official fixed API host.
statusFilterstringOptional list filterNoneComma-separated allowlisted statuses for the selected resource.
customerIdstringOptional subscription/transaction filterNoneTyped ctm_… Paddle customer ID.
subscriptionIdstringOptional transaction filterNoneTyped sub_… Paddle subscription ID.
afterCursorstringOptional list continuationNoneOpaque typed Paddle ID from nextCursor.
limitintegerOptional50Maximum emitted resources, 1–10,000.
returnAllbooleanOptionalfalseFollow validated provider continuation pages until exhaustion or the result cap.

Product payloads accept only name, tax_category, description, image_url, custom_data, and status. Product creation requires name. image_url must be a public HTTPS URL.

Customer payloads accept only email, name, locale, custom_data, and status. Customer creation requires a valid bounded email. custom_data, when present, must be an object or null.

Outputs

NameTypeWhen presentDescription
statusstringAlwayssuccess or error.
operationstringAlwaysNormalized operation name.
attemptsintegerAlwaysProvider attempts across all pages.
httpStatusintegerProvider respondedLast Paddle HTTP status.
dataobjectSingle-resource/write successPaddle resource from the response data object.
idstringResource response includes itSafe Paddle resource identity.
resourceStatusstringResource response includes statusPaddle resource lifecycle status without replacing the module status.
items / countarray / integerList successBounded resources and emitted count.
hasMorebooleanList successWhether Paddle reported another page.
nextCursorstringAnother page existsValidated typed after cursor from Paddle's meta.pagination.next URL.
requestIdstringPaddle returns oneSafe request-trace reference.
errorobjectFailureSafe {code, message, httpStatus?, retryable} details.

API keys and authorization headers never enter outputs. Provider error details are bounded and passed through ValkyrAI's sensitive-data redaction policy.

IntegrationAccount Requirements

SettingRequirement
ProviderPaddle Billing server-side API
PermissionsLeast-privilege read/write for products and customers; read for subscriptions and transactions
apiKeyPaddle server-side API key in an encrypted SecureField
passwordLegacy encrypted key fallback only; prefer apiKey
statusMust be READY

New-format Paddle keys identify their environment (live or sdbx). The workflow environment must match the key's intended environment. Key creation, expiry, rotation, revocation, and permission changes belong to the platform integration-account lifecycle.

Configuration

{
"version": "1.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:paddle-revenue-ops"
},
"retryPolicy": {
"maxAttempts": 3,
"backoffStrategy": "EXPONENTIAL",
"initialDelayMs": 1000,
"maxDelayMs": 60000,
"jitter": false
},
"executionConfig": {"timeoutMs": 30000},
"payloadConfig": {
"parameters": "{\"operation\":\"list_subscriptions\",\"environment\":\"production\",\"statusFilter\":\"active\",\"limit\":50}"
}
}

The integration-account value is symbolic. Persisted workflows use the generated relationship rather than a plaintext key.

Operations

OperationPaddle behaviorSide effect
list_productsLists bounded catalog products with optional status/cursor filters.Read-only; safe retries.
get_productReads one typed product ID.Read-only; safe retries.
create_productCreates one allowlisted product; name is required.Catalog creation; single attempt.
update_productApplies an allowlisted partial product update.Catalog mutation; single attempt.
list_customersLists bounded customers with optional status/cursor filters.Read-only; safe retries.
get_customerReads one typed customer ID.Read-only; safe retries.
create_customerCreates one customer with a valid email.Customer creation; single attempt.
update_customerApplies an allowlisted partial customer update.Customer mutation; single attempt.
list_subscriptionsLists subscriptions, optionally filtered by customer and status.Read-only; safe retries.
get_subscriptionReads one typed subscription ID.Read-only; safe retries.
list_transactionsLists transactions, optionally filtered by customer, subscription, and status.Read-only; safe retries.
get_transactionReads one typed transaction ID.Read-only; safe retries.

Errors and Failure Modes

CodeTypical causeRetryableResolution
VALIDATION_ERRORMissing/invalid ID, environment, filter, email, URL, or payload field.NoCorrect input; no unsafe request was sent.
UNSUPPORTED_OPERATIONUnknown operation.NoSelect a documented operation.
INTEGRATION_ACCOUNT_REQUIREDNo bound account.NoBind a Paddle IntegrationAccount.
INTEGRATION_ACCOUNT_NOT_READYAccount status is not READY.NoRepair or reconnect the account.
PADDLE_HTTP_400Paddle rejected a field or business rule.NoInspect the safe error detail and correct the request.
PADDLE_HTTP_401 / 403Key invalid/expired or permission missing.NoRotate or reauthorize the IntegrationAccount with least privilege.
PADDLE_HTTP_404Resource is absent or invisible to the key.NoRe-read/list with the same environment and account.
PADDLE_HTTP_409Provider state conflicts with the requested update.NoRead current state and rebuild the mutation.
PADDLE_HTTP_429 / 5xxRate limit or transient provider failure.Yes for readsHonor Retry-After; reconcile writes before repeating them.
NETWORK_ERRORTimeout, DNS, TLS, or connectivity failure.Yes for readsVerify connectivity and Paddle status.
RESPONSE_TOO_LARGEResponse exceeded 5 MiB.NoLower the limit or split the workflow.
INVALID_PROVIDER_RESPONSEExpected data/pagination shape was absent or the continuation URL was untrusted.NoUse requestId to verify API compatibility; never follow the rejected URL.

Example

Create a catalog product for an approved automation package:

{
"operation": "create_product",
"resource": {
"name": "ValkyrAI Governed Operations",
"description": "Production workflow automation package",
"tax_category": "standard",
"custom_data": {
"workflowFamily": "governed-operations",
"source": "valkyrai"
}
}
}

Expected result:

{
"status": "success",
"operation": "create_product",
"attempts": 1,
"httpStatus": 201,
"id": "pro_01h00000000000000000000000",
"data": {
"id": "pro_01h00000000000000000000000",
"name": "ValkyrAI Governed Operations",
"status": "active"
}
}

Notes

  • Pagination: Paddle list endpoints use cursor-based pagination. The module requests at most 200 resources per page (30 for transactions), checks meta.pagination.has_more, validates the next URL against the selected fixed Paddle host, and emits only its typed after cursor. It never follows a caller-supplied URL. Total output is capped at 10,000 resources.
  • Rate limits: reads retry HTTP 408, 429, 500, 502, 503, and 504 according to RetryPolicy, honoring numeric Retry-After. Writes never retry automatically.
  • API limits: provider responses are capped at 5 MiB and structured write payloads at 256 KiB. Text, email, URL, status, cursor, and ID fields have explicit local bounds.
  • Idempotency: product/customer creates and updates are single-attempt. Use caller-owned custom_data correlation fields where appropriate, and reconcile Paddle state after an ambiguous timeout before resubmitting.
  • Destructive behavior: this release exposes no archive/delete, subscription pause/cancel/resume, transaction creation/revision, adjustment/refund, payment-method deletion, or notification-setting mutation operations.
  • Security: only official production/sandbox Paddle hosts are selectable. API keys remain in IntegrationAccount SecureFields; typed IDs, allowlisted fields, trusted continuation validation, response bounds, and redacted provider faults prevent arbitrary routing and secret reflection.
  • External verification: request construction, cursor handling, retry safety, validation, response mapping, redaction, and metadata discovery have deterministic local tests. Live Paddle permissions, catalog rules, tax behavior, customer deduplication, rate limits, and billing effects require separately authorized provider credentials and are not exercised in repository tests.
  • Deferred operations: prices, discounts, addresses, businesses, subscription mutations, transaction creation/revision, adjustments/refunds, reports, metrics, events, notifications, customer portals, simulations, webhook triggers, key rotation, and arbitrary API calls.
  • Functional references: n8n Paddle node, Paddle API reference, Paddle authentication, and Paddle pagination.