Sell licence keys automatically: SellAuth, Stripe, Shoppex or your own store
Connect the shop you sell from and every paid order gets its licence keys at once, with nobody pressing anything. Refunds and chargebacks ban the keys by themselves. Setup for SellAuth, Stripe, Shoppex and your own server

Selling software by hand gets old fast: a payment arrives, you open the panel, make a key, copy it, send it, and hope you didn't mix up two buyers. And a refund at 3 a.m. means a key that keeps working until you wake up. Connect your store to PWF Auth and that whole loop runs by itself: every paid order gets its keys straight away, and refunds take them back
PWF Auth never touches the money. Your store takes the payment and tells PWF Auth, which makes the keys and hands them back
Connect a store
- Open Stores in your panel, pick the application and choose the store. It gets its own address, like
https://pwfauth.com/api/store/webhook.php?c=sc_… - Follow the steps shown under that store (below) and paste the store's webhook secret in Settings. Every call must be signed with it: unsigned or wrongly signed calls are refused and counted on the page
- Add every product you sell there: its id in the store, and the keys it makes (length, PCs per key, and keys per item bought)
SellAuth
- Copy your shop's webhook secret from Storefront → Configure → Miscellaneous and paste it in Settings
- Set each product's deliverables to Dynamic, with the store's address as the dynamic webhook
- The product id is SellAuth's product id, or
productId:variantIdfor a single variant
SellAuth shows the keys to the buyer right after paying. It has no refund call, so when you refund there, mark the order Refunded in PWF Auth and its keys are banned
Stripe
- In Stripe, Developers → Webhooks → Add endpoint with the store's address. Pick
checkout.session.completed,checkout.session.async_payment_succeeded,charge.refundedandcharge.dispute.created - Paste the endpoint's signing secret (
whsec_…) in Settings - The product id is the Payment Link id (
plink_…). With your own Checkout Sessions, setmetadata.pwf_product
Stripe has no page to show the keys on, so they go to the buyer by email. A full refund or a chargeback bans the order's keys by itself, and test-mode orders work too, marked Test
Shoppex
- Turn on dynamic delivery on the product, with the store's address as its webhook
- Shoppex gives each product its own signing secret: paste it when you add that product in PWF Auth
Your own server
Selling from your own website, a script or an automation tool? Send one signed POST per paid order:
POST https://pwfauth.com/api/store/webhook.php?c=sc_…
Content-Type: application/json
X-PWF-Timestamp: 1760262000
X-PWF-Signature: <hex HMAC-SHA256(timestamp + "." + body, your secret)>
{"type": "paid", "order_id": "1001", "product": "pro-30", "email": "buyer@mail.com", "quantity": 1, "amount": 9.99, "currency": "USD"}The answer is {"success": true, "keys": ["…"]}. Sending the same order_id again returns the same keys, so a retry never makes two sets. A refund is the same call with "type": "refund"
Every order on the record
The Stores page lists the last 50 orders and refunds, with the product, the buyer's email, the amount and the keys. From there you can deliver an order that waited for a missing product, email the keys again, or mark an order refunded, which bans its keys and closes the running copies. Keys from a store carry the store and the order in their note, and start counting the first time they're used
Every delivered order also reaches your webhooks as order.completed, so your own sales sheet stays up to date. Selling through people instead of a shop? See resellers
The full guide is in Stores


