For vendors using Usakey

Connect sales services

Issue, renew, suspend, and revoke licenses automatically from purchases in Shopify, Square, KOMOJU, Paddle, Lemon Squeezy, or your own system.

Plans
Personal Team Enterprise
Who does this
Owner Admin

How it works

You receive payments for your software in the sales service you use (Shopify, Square, KOMOJU, Paddle, or Lemon Squeezy). Usakey never holds the money. Usakey receives the sales service's notifications and issues, renews, suspends, resumes, and revokes licenses to match purchases, renewals, cancellations, and refunds. Your own system or an automation service can send requests to the signed generic endpoint.

Usakey never calls a sales service's API, so it never cancels a subscription there. Revoking or suspending a license, archiving the customer or stopping the integration does not stop the subscription or the buyer's charges. Cancel the subscription in the sales service to stop charging. Purchased through on the license page shows where it was bought.

  • Usakey verifies each notification's signature with the sales service's official method and uses only notifications that match. Usakey does not call the sales service's API and keeps only the notification signing secret.
  • A notification that arrives more than once issues a license only once. When notifications arrive out of order, each purchase follows the newest state. When a refund arrives before the purchase, no license is issued.
  • A test integration can map only test products, and a live integration only live products. Try it in test first.
  • Available from Evaluation. Owners and admins set this up.
  • Evaluation supports test environments only. New licenses issued on Evaluation are valid for at most one hour from issuance, including after renewal. Quantity and policy limits still apply. A license issued on a paid plan keeps its existing expiry after a downgrade to Evaluation, but cannot be extended beyond that expiry.
How a purchase in a sales service becomes a licenseWhen a buyer pays in your sales service, the money goes to your account, and the service sends a signed notification to the integration's receiving URL. Usakey verifies the signature with the service's official method and the secret you registered, and does not record notifications that fail. Each notification is applied only once, and each purchase follows its newest state, so older notifications don't change the license. Next, the item identifier selects the item mapping; for an unmapped item, only a record is kept. A paid purchase or an active subscription issues the license or updates its expiry, and resumes a license the integration suspended. Past due, paused, and charged-back purchases suspend the license, and a refund, cancellation, or ended subscription revokes it. When a notification can succeed later, for example while the product signing key is being prepared or when a plan limit is reached, it is marked “Deferred” and processed again when the service resends it.Usakey (each integration's receiving URL)Your sales serviceShopify, Square, KOMOJU, Paddle, Lemon SqueezyWhen the buyer pays, it sends a signednotification. The money goes to your accountVerify thesignatureWith the service'sofficial methodand yourregistered secret.Failed notificationsare not recordedApply onceEach notificationonly once. Eachpurchase followsits newest state;older notificationschange nothingFind the itemmappingThe item identifierselects the policyto issue. Without amapping, only arecord is keptPaid orsubscription activeIssue or updatethe expiryResumes licensesthe integrationsuspendedPast due, paused,or chargebackSuspendRefund, cancellation,or subscription endedRevokeWhen a notification can succeed later, for example while the productsigning key is being prepared or when a plan limit is reached, it ismarked “Deferred” and processed again when the service resends itHow a purchase in a sales service becomes a licenseWhen a buyer pays in your sales service, the money goes to your account, and the service sends a signed notification to the integration's receiving URL. Usakey verifies the signature with the service's official method and the secret you registered, and does not record notifications that fail. Each notification is applied only once, and each purchase follows its newest state, so older notifications don't change the license. Next, the item identifier selects the item mapping; for an unmapped item, only a record is kept. A paid purchase or an active subscription issues the license or updates its expiry, and resumes a license the integration suspended. Past due, paused, and charged-back purchases suspend the license, and a refund, cancellation, or ended subscription revokes it. When a notification can succeed later, for example while the product signing key is being prepared or when a plan limit is reached, it is marked “Deferred” and processed again when the service resends it.Usakey (each integration'sreceiving URL)Your sales serviceShopify, Square,KOMOJU, Paddle,Lemon SqueezyWhen the buyer pays, itsends a signednotification. The moneygoes to your accountVerify the signatureWith the service's officialmethod and your registeredsecret. Failed notificationsare not recordedApply onceEach notification onlyonce. Each purchasefollows its newest state;older notificationschange nothingFind the item mappingThe item identifierselects the policy toissue. Without a mapping,only a record is keptPaid or subscription activeIssue or updatethe expiryResumes licenses theintegration suspendedPast due, paused,or chargebackSuspendRefund, cancellation,or subscription endedRevokeWhen a notification cansucceed later, forexample while theproduct signing key isbeing prepared or whena plan limit is reached, itis marked “Deferred” andprocessed again whenthe service resends it
Usakey uses only notifications whose signature verifies, and keeps each license in line with the newest state of its purchase. Check the results in the notification history on the integration page.

Supported sales services

ServiceNotifications appliedItem identifier
ShopifyOrder paid, updated, and canceled (one-time; refunds are read from the order state); disputes (Shopify Payments chargebacks) created and updatedVariant ID, product ID, or SKU
SquareSubscription created and updated (active, paused, canceled); automatic payment of a subscription invoice failed or paidSubscription plan variation ID
KOMOJUPayment captured and fully refunded (one-time)usakey_item in the payment metadata
PaddleTransaction completed; subscription created, updated, past due, paused, resumed, and canceled; full approved refunds and chargebacksPrice ID (pri_) or product ID (pro_)
Lemon SqueezyOrder created and refunded; subscription created, updated, canceled, resumed, expired, and pausedVariant ID or product ID
Generic (signed)Issue, plan change, renew, suspend, resume, and revoke (as requested)item in the JSON you send

You can connect a sales service that is not in the table, or your own system, by sending to the generic endpoint or the Management API. See Send to the generic endpoint and Use automation services and CRMs for how to send.

Where each sender sends to UsakeySales services with a receiver (Shopify, Square, KOMOJU, Paddle, Lemon Squeezy) send notifications signed with the service's method to the integration's receiving URL. Your own system and automation services that can compute a signature use the generic endpoint. The signature is computed over timestamp.event_id.body with a secret Usakey creates, and Usakey takes care of applying each purchase only once. Services that cannot compute a signature call the Management API with an API key and issue or suspend licenses directly; on this route, the caller prevents duplicates.UsakeySales services with a receiverShopify, Square, KOMOJU,Paddle, Lemon SqueezyReceiving URLVerifies the service'ssignature. The itemmapping decides thelicense to issueSenders that can signYour own system, n8n, Make,Zapier, Salesforce ApexGeneric endpointSigntimestamp.event_id.bodywith the secret Usakeycreates. Usakey handlesduplicates and orderSenders that cannot signPower Automate, Yoom, kintone,HubSpot, Salesforce flowsManagement APICall license operationssuch as issue andsuspend with an APIkey. The callerprevents duplicatesWhere each sender sends to UsakeySales services with a receiver (Shopify, Square, KOMOJU, Paddle, Lemon Squeezy) send notifications signed with the service's method to the integration's receiving URL. Your own system and automation services that can compute a signature use the generic endpoint. The signature is computed over timestamp.event_id.body with a secret Usakey creates, and Usakey takes care of applying each purchase only once. Services that cannot compute a signature call the Management API with an API key and issue or suspend licenses directly; on this route, the caller prevents duplicates.Sales serviceswith a receiverShopify, Square,KOMOJU, Paddle,Lemon SqueezyUsakeyReceiving URLVerifies the service'ssignature. The item mappingdecides the license to issueSenders that can signYour own system,n8n, Make, Zapier,Salesforce ApexUsakeyGeneric endpointSign timestamp.event_id.bodywith the secret Usakeycreates. Usakey handlesduplicates and orderSenders that cannot signPower Automate, Yoom,kintone, HubSpot,Salesforce flowsUsakeyManagement APICall license operationssuch as issue and suspendwith an API key. The callerprevents duplicates
Sales services with a receiver send to the integration's URL, senders that can sign send to the generic endpoint, and senders that cannot sign call the Management API with an API key.

Register an integration

  1. Step 1Choose the sales service

    Open Payment and sales integrations in the left menu and choose the service under Add an integration. Register test and live as separate integrations.

  2. Step 2Register the receiving URL in the sales service

    Register the Receiving URL shown on the registration page as the destination of the service's notifications (webhooks), and select the events listed on the page. Square includes this URL in the signature, so register it without changing a single character.

    • Shopify: Under Settings > Notifications > Webhooks in your admin, create JSON webhooks for Order payment, Order update, and Order cancellation. To follow Shopify Payments chargebacks, also create webhooks for disputes/create and disputes/update with the same URL. If the admin does not offer them, create all the webhooks, orders included, in a custom app (with the read_shopify_payments_disputes access scope) and use the app's client secret as the signing key.
    • Square: Add a subscription under Webhooks in the Developer Console and select subscription.created, subscription.updated, invoice.scheduled_charge_failed, and invoice.payment_made. Invoice notifications need the INVOICES_READ permission.
    • KOMOJU: Add a webhook in the dashboard, select payment.captured and payment.refunded, and choose a secret token.
    • Paddle: Create a destination under Developer tools > Notifications and select the transaction, subscription, adjustment, and customer events. Sandbox and live use separate destinations.
    • Lemon Squeezy: Add a webhook under Settings > Webhooks, choose a signing secret, and select the order and subscription events.
  3. Step 3Enter the signing secret and register

    Enter the service's signing secret (the Shopify webhook signing key, the Square signature key, the KOMOJU secret token, the Paddle destination secret key, or the Lemon Squeezy signing secret) and select Register integration. Secrets are not shown after saving. For the generic endpoint, Usakey creates the secret and shows it once right after registration.

You can also register and change integrations through the Management API (/mgmt/v1/sales-integrations) and AI assistant connections (MCP). Reading needs products:read; changes need products:write and licenses:write. AI assistants never handle a sales service's signing secret. An integration an AI assistant registers shows Waiting for the signing secret; enter the secret with Enter the secret on the settings page on the integration page. No notifications are accepted until the secret is entered.

Map items to licenses

On the integration page, use Add mapping to map an item identifier from the sales service to the policy of the license to issue. When an unmapped item is purchased, the notification history records it but no license is issued. However, when a purchase carries the buyer's app challenge (usakey_claim_challenge) and none of its items is mapped, the notification is deferred; add the mapping, and the license is issued when the sales service resends it.

  • Perpetual policies issue licenses without an expiry.
  • For time-limited policies, Square, Paddle, and Lemon Squeezy use the end of the billing period as the expiry (if you enter a duration, it counts days from the purchase). Shopify and KOMOJU subscriptions are not applied, so a duration is required.
  • Trial policies and unmanaged offline perpetual policies cannot be used.
  • Quantities are not used. Each purchase (each order line in Shopify) issues one license; device and user limits follow the policy.
  • Map subscription items (Paddle, Lemon Squeezy, Square) to time-limited policies. A subscription notification whose item is mapped to a perpetual policy fails as a setting error.
  • If you change a mapping's item identifier, the next notification of a subscription that still uses the old identifier is treated as a plan change. When no mapping matches, the license is suspended.

Deliver license keys to buyers

You can hand over the issued license key in one of these ways.

  • The buyer's app picks it up (secure pickup): Before the purchase, the app creates a 43-character claim_verifier and puts usk_claim_v1_ followed by its SHA-256 in usakey_claim_challenge in the purchase's custom data (a cart attribute in Shopify, metadata in KOMOJU, customData in Paddle, checkout[custom] in Lemon Squeezy). After the purchase, the app sends the verifier to the Pickup URL on the integration page and receives the key. This is the same mechanism as the Stripe integration, and the key can be picked up for 72 hours. Square cannot pass custom data, so this is not available there.
  • From the generic endpoint's response: An issue request returns the license key in the response. Resending with the same event ID returns the same key for 72 hours.
  • You hand it over: Check the key on the license page and send it to the buyer.
How the buyer's app picks up the license key safelyBefore the purchase, the buyer's app creates a verifier, keeps it, and opens the checkout with the verifier's SHA-256 in the purchase's custom data. When the buyer pays, the sales service sends Usakey a signed notification that includes the custom data. Usakey issues the license and holds the key for up to 72 hours. When the app sends the verifier to the “Pickup URL”, the key is returned, and when the app confirms that it saved the key, Usakey deletes the key it held. Only the buyer's app knows the verifier, so no one else can pick up the key. The generic endpoint returns the key in its response to an issue request. Square cannot pass custom data, so check the key on the license page and send it to the buyer yourself.Buyer's appSalesserviceUsakeyBefore the purchaseCreate a verifierand keep it1Open thecheckout with theverifier's SHA-256in custom data2PurchaseThe buyer pays3Signednotification (withthe custom data)4Issue the licenseand hold the keyfor up to 72 hours5After the purchaseSend the verifier to the “Pickup URL”6License key7Confirm the key was saved8Delete the held key9The generic endpoint returns the key in its response to anissue request. Square cannot pass custom data, so checkthe key on the license page and send it to the buyer yourselfHow the buyer's app picks up the license key safelyBefore the purchase, the buyer's app creates a verifier, keeps it, and opens the checkout with the verifier's SHA-256 in the purchase's custom data. When the buyer pays, the sales service sends Usakey a signed notification that includes the custom data. Usakey issues the license and holds the key for up to 72 hours. When the app sends the verifier to the “Pickup URL”, the key is returned, and when the app confirms that it saved the key, Usakey deletes the key it held. Only the buyer's app knows the verifier, so no one else can pick up the key. The generic endpoint returns the key in its response to an issue request. Square cannot pass custom data, so check the key on the license page and send it to the buyer yourself.Before the purchase1Buyer's appCreate a verifier and keep it2Buyer's appSales serviceOpen the checkout withthe verifier's SHA-256in custom dataPurchase3Sales serviceThe buyer pays4Sales serviceUsakeySigned notification(with the custom data)5UsakeyIssue the license and holdthe key for up to 72 hoursAfter the purchase6Buyer's appUsakeySend the verifier tothe “Pickup URL”7UsakeyBuyer's appLicense key8Buyer's appUsakeyConfirm the key was saved9UsakeyDelete the held keyThe generic endpointreturns the key in itsresponse to an issuerequest. Square cannotpass custom data, socheck the key on thelicense page and sendit to the buyer yourself
Only the app that created the verifier before the purchase can pick up the key. The key can be picked up for 72 hours, and Usakey deletes it once the app confirms it was saved.

What happens after a purchase

Licenses follow the subscription, payment, and refund states in the sales service as below. Only licenses the integration suspended are resumed. A license you suspended in the console or through the Management API is not resumed by sales service notifications, even after it expires while suspended (only its expiry and policy follow the service).

Suspension, resumption, and revocation notifications received before a purchase are recorded and reconciled when its license is issued. A full refund of the first purchase remains effective even if an active subscription notification arrives later. Square tracks unpaid invoices separately; paying another invoice does not release a hold. Shopify does not reopen a resolved dispute on a delayed opening notification. Removing a Paddle subscription item suspends its license; adding it again resumes the same license. If the first Paddle transaction is not yet known, a refund suspends the license until that transaction arrives: a full refund of the first transaction revokes it, while a renewal refund releases that hold. Other suspension reasons still apply.

EventLicenseDifferences by service
Renewal paymentThe expiry is set to the end of the billing period, and a license the integration suspended is resumed.Paddle and Lemon Squeezy use the end of the billing period. Square uses the last day it invoiced (charged_through_date), which is not the payment date. Shopify and KOMOJU subscriptions are not applied, so the mapping's duration sets the expiry.
Failed payment (expired or declined card)The license is suspended right away (there is no grace period) and resumed once paid. Buyers update their card in the sales service.Paddle and Lemon Squeezy suspend on past_due or unpaid and resume when the subscription is active again. Square keeps an unpaid subscription active, so invoice.scheduled_charge_failed suspends and only a full payment (invoice.payment_made) resumes. A payment made after the expiry may not resume the license automatically; resume it in the console.
Plan changeThe same license key switches to the policy mapped to the new item. Rights become those of the new policy, and rights you added to the license are kept. The expiry follows the sales service. A change to an unmapped item, an item of another product, or a policy that is not time-limited suspends the license so the previous plan's rights do not remain; fix the mapping, and the next notification switches and resumes it.The switch happens when the plan changes in the sales service (for a scheduled change, when it takes effect). Paddle subscriptions with several items are handled per item. The generic endpoint sends change.
CancellationA cancellation at the end of the period keeps the license until then and revokes it when the subscription ends. An immediate cancellation revokes it at once. Undoing a cancellation within the period keeps it active.Paddle uses the scheduled cancellation (scheduled_change) as the expiry and revokes on canceled. Lemon Squeezy keeps a cancelled subscription until ends_at and revokes on expired. Square revokes on CANCELED or COMPLETED.
RefundA full refund revokes the license. A partial refund changes nothing.Shopify revokes every line when the order is refunded, canceled, or voided, and only a line whose full quantity was refunded otherwise. KOMOJU revokes only on a full refund (payment.refunded). Paddle revokes only on a full, approved refund of the first transaction; refunds of renewals change nothing. Lemon Squeezy revokes on an order refund, including the subscription that started from that order; renewal refund notifications are not handled.
Dispute (chargeback)The license is suspended when a dispute opens and revoked when it is lost. When the dispute is won or withdrawn, a license the integration suspended is resumed. Order and subscription updates do not resume it. If the license was already suspended, for example because the subscription is past due, it is resumed only after both reasons are cleared. If one order has two disputes, it is resumed only after both are over.Shopify uses disputes/create and disputes/update and does not suspend at the inquiry stage. Paddle suspends on chargeback and resumes on chargeback_reverse. Lemon Squeezy revokes fraudulent orders. KOMOJU sends no dispute notifications, so disputes are not applied (suspend the license in the console if needed). Square disputes are not handled.
Usakey plan limitsRenewals and resumptions of issued licenses are not refused solely because a downgrade puts usage over a quantity limit. Expiry limits still apply. Limits are checked only for new licenses and for plan changes that use more license units; if they are short, the notification is deferred (the license stays on the previous plan meanwhile).The same for every service.
  • Buyers are matched by the sales service's customer ID (Shopify, Square, Paddle, Lemon Squeezy) and by customer.reference on the generic endpoint, never by email address. KOMOJU notifications carry no customer ID, so each purchase creates a new customer. When a buyer matches an archived customer, the license is issued to that customer and the notification history says so.
  • Separate purchases (buying in two tabs, or one person starting two subscriptions) each get a license. Usakey cannot stop a double payment, so check for an existing subscription in the sales service before opening checkout. One challenge picks up one key: a second purchase with the same challenge still gets a license, but you hand over its key.
  • Cancel subscriptions and refund in the sales service. Revoking a license or archiving a customer in Usakey does not stop the subscription or its billing in the sales service.
  • KOMOJU notifications do not say whether they are test or live. Use separate webhooks and secret tokens for test and live (whether test payment notifications can reach a live webhook has not been confirmed).

Send to the generic endpoint

POST JSON from your own system to the Receiving URL on the integration page. The signature has the same form as Usakey webhook notifications.

  • X-Usakey-Event-Id: A unique ID chosen by the sender (letters, digits, and . _ : -, up to 128 characters). Use the same value when you resend.
  • X-Usakey-Timestamp: The time you sent the request (Unix seconds). Timestamps within 300 seconds are accepted.
  • X-Usakey-Signature: v1= followed by the hex HMAC-SHA256 of timestamp.event_id.body with the signing secret.
{
  "action": "issue",
  "purchase_id": "order-1001",
  "item": "pro-yearly",
  "customer": {"email": "buyer@example.com", "name": "Taro Yamada", "reference": "crm-42"},
  "expires_at": "2027-10-18T00:00:00Z"
}

action is issue, change (plan change), renew, suspend, resume, or revoke. After the first request, purchase_id alone points to the same license. change takes the new item's code in item and switches the same license key to that mapping's policy. If the item is not mapped to a time-limited policy of the same product, the event fails and the license does not change. suspend, resume, and revoke accept a reason, which is kept in the audit log. See the API reference for the results (applied, no change, failed, deferred) and every field. Send a deferred (503) event again later with the same event ID.

Use automation services and CRMs

Services that can compute a signature send to the generic endpoint; services that cannot send to the Management API with an API key. Create an API key with only the permissions the task needs.

  • n8n: Import the workflow file (Import from File). A Crypto node signs the request and an HTTP Request node sends it to the generic endpoint. Put the signing secret in the Crypto credential.
  • Make: Put the body (a JSON string), the time (formatDate(now; "X")) and an event ID in variables, and make the signature v1= followed by sha256(time + "." + event ID + "." + body; "hex"; signing secret). Send it to the generic endpoint with HTTP Make a request, a Raw application/json body and the three headers.
  • Zapier: Sign in Code by Zapier (JavaScript; Node.js crypto and fetch are available) and send to the generic endpoint with fetch in the same step.
  • Power Automate: Expressions have no HMAC function, so send to the Management API with the HTTP action (premium) and Authorization: Bearer with an API key.
  • Yoom: Send to the Management API from a trigger such as a new order in your store. Check Yoom's help for how to call an arbitrary API.
  • kintone: kintone webhooks cannot add an authentication header, so receive them in Zapier or Power Automate, or store the API key with kintone.plugin.app.setProxyConfig in a plugin and call the Management API with kintone.plugin.app.proxy (users cannot see the stored value).
  • HubSpot: In a workflow's Send a webhook action (Data Hub Professional or above), choose API key authentication in the Authorization request header and send to the Management API.
  • Salesforce: Add the Authorization header with an external credential and a named credential, and send to the Management API with a flow HTTP callout. In Apex, Crypto.generateMac can sign requests for the generic endpoint.

Troubleshooting

  • If nothing appears in the notification history, check the signing secret and the receiving URL. Notifications with a wrong signature are not recorded. An integration showing Waiting for the signing secret accepts no notifications until you enter the secret.
  • Editing a policy moves its active mappings to the new version. Retiring a policy defers issuing for its mappings; choose a policy in use in the mapping, and the license is issued when the sales service retries.
  • Deferred means the notification can succeed later, for example while the product signing key is prepared or when a plan limit is reached. It is processed again when the sales service resends it.
  • An unmapped item bought without a challenge is not issued by the same notification even after you add the mapping. Issue the license by hand or send issue to the generic endpoint.
  • Sales services resend only for a limited time (a few minutes for Lemon Squeezy, 4 hours for Shopify, 24 hours for Square, 3 days for Paddle, 25 days for KOMOJU). For notifications that passed that time while the integration was stopped or deferred, resend them from the sales service or fix the licenses by hand. Shopify may remove an app's webhook after repeated failures, so check it after you resume.
  • A license you suspended in the console or through the Management API is not resumed by sales service notifications.
  • Test notifications that reach a live integration (Shopify test, Lemon Squeezy test_mode) are not applied.

Ask AI to implement or configure

Copy the request for your task into an AI assistant connected to MCP, or select the same task from the MCP prompt list. Connection steps are on the product integration page. Add license checks to your app

Sales services other than Stripe
Use the Usakey MCP server and distributed skills for this task. First read the relevant skill VERSION, SKILL.md and references below. If the local MCP cannot serve resources, read the same files from the distribution ZIP advertised by the connected server. Confirm product, environment, language and existing settings; never invent missing values. Use the official SDK in product apps and never embed a Management API key. Keep management operations within the approved access and plan. Keep secrets out of chat, screens and logs. Write expected behavior as tests before implementation and report actual verification and unverified surfaces.

Identify the sales service and implement its integration and post-purchase license delivery using the documented event format and identity verification. Test duplicate notifications, cancellation/refunds, pending results, key recovery and ACK. Guide the user through Console steps that require secrets.

References
skill://usakey-stripe-integration/references/other-sales-services.md
skill://usakey-stripe-integration/references/license-key-claim.md
skill://usakey-stripe-integration/references/test-matrix.md

Management tools for configuration and checks
list_sales_integrations
create_sales_integration
update_sales_integration
list_sales_integration_events

Screenshots were taken in a test environment with sample data. IDs such as product IDs, license keys, and activation tokens are masked. Some details may change as we improve the screens.