From a Bitcoin Transaction to a Paid AI Subscription — Without Holding Private Keys
Building a paid AI assistant sounds straightforward.
Define a price, add a checkout button, verify the payment, and unlock the premium features.
But when we started building the monetization layer for Zorgax, the AI assistant inside MyZubster, one question quickly became more important than the pricing itself:
How can an application verify a cryptocurrency payment without becoming a custodian of the user's funds?
That question has shaped the latest development of Zorgax.
The goal
Zorgax currently has three planned access levels:
Zorgax Free, Zorgax Pro (€9.90 monthly equivalent) and Zorgax Developer (€29.90 monthly equivalent).
The broader payment architecture is designed around multiple crypto assets, including BTC, ETH, XMR and TARI.
But there is an important rule:
Zorgax should coordinate and verify payments — not control the user's wallet.
That means no seed phrases in the application.
No private keys in the frontend.
No transaction signing by Zorgax.
A payment button isn't enough
Imagine a user selects Zorgax Pro and chooses Bitcoin.
The application knows:
Plan: Zorgax Pro
Price: €9.90
Asset: BTC
A server-side quote can calculate the corresponding BTC amount.
The naive approach would then be to trust information coming back from the client:
"I paid this address."
"This is the amount."
"This is my transaction."
"Activate my subscription."
That's exactly what we don't want.
A client should never be the authority deciding what it was supposed to pay.
So we introduced another layer.
The Payment Intent
Before the user pays anything, Zorgax creates a persistent Payment Intent.
It records information such as:
intent ID
authenticated owner
selected plan
crypto asset
destination address
expected crypto amount
EUR value
quote timestamp
expiration
settlement status
The important part is that this information is stored server-side.
Later, when the user provides a blockchain transaction reference, the backend doesn't ask the browser:
“How much were you supposed to pay?”
It already knows.
The architecture becomes:
User
↓
Authenticated Checkout
↓
Server-side Crypto Quote
↓
Persistent Payment Intent
↓
External Wallet Payment
↓
Trusted Blockchain Verifier
↓
Verified Payment
↓
Active Subscription
This changes the trust model considerably.
Bitcoin became our first real test
For Bitcoin, we built a small verification service around Electrum.
The service runs separately from the application and doesn't need to sign transactions.
Its job is much narrower:
inspect a transaction and report what actually happened on the blockchain.
While testing against Electrum 4.8.1, we discovered an important implementation detail.
We initially expected:
gettransaction
to give us a conveniently decoded transaction.
Instead, the real Electrum CLI returned the serialized transaction.
So the verifier had to evolve.
The flow became:
TXID
↓
gettransaction
↓
raw transaction
↓
deserialize
↓
outputs
↓
address + value_sats
Confirmations are obtained separately through:
get_tx_status
This is one reason I like developing infrastructure in the open.
The repository doesn't just show the final design.
It also shows where assumptions met reality.
Satoshis instead of guessing units
Another useful result of decoding the transaction is that Electrum exposes output values explicitly as satoshis.
Conceptually:
{
"address": "bc1q...",
"value_sats": 7212
}
That lets the verifier perform the critical comparison using integers:
paid satoshis >= expected satoshis
instead of relying on floating-point BTC arithmetic or guessing units.
For payment verification, small details like this matter.
A transaction isn't automatically a payment
Finding a transaction containing the expected address and amount still isn't enough.
We also need confirmation policy.
A transaction with:
confirmations: 0
may exist in the mempool, but the trusted payment layer can require a minimum number of confirmations before granting access.
Only after verification succeeds can Zorgax move toward:
PENDING
↓
VERIFIED
↓
ACTIVE
where ACTIVE refers to the subscription access, not simply the existence of a transaction.
Preventing one transaction from becoming many subscriptions
There is another less visible problem: replay.
Suppose someone takes one valid Bitcoin transaction and submits its TXID multiple times.
Without protection, the same economic event could potentially be used to activate several subscriptions.
So the payment-intent architecture also tracks consumed payment references and introduces uniqueness constraints around them.
A verified transaction should represent one settlement event, not an unlimited activation token.
Payment intents expire too
Crypto prices change continuously.
For that reason, the current checkout architecture uses short-lived quotes.
A Payment Intent currently has a 15-minute lifetime.
If it expires before settlement, it shouldn't remain a permanent promise to accept the original crypto amount.
The user can simply request a new quote and create a new intent.
What Zorgax never needs
The interesting result is what this architecture does not require.
Zorgax doesn't need the user's:
seed phrase
private key
wallet password
spend key
The user can pay from an external wallet.
The blockchain verifier observes the result.
The application decides whether that external event satisfies an internally stored Payment Intent.
That's a very different model from embedding a cryptocurrency wallet directly inside an AI application.
Beyond Bitcoin
Bitcoin is currently serving as our clearest implementation example, but the architecture is intended to be chain-independent.
Conceptually:
Payment Intent
↓
Verification Layer
/ | | \
BTC ETH XMR TARI
↓
Electrum
Each blockchain can have a different verifier behind the same general boundary.
This is especially important for Monero.
Because of Monero's privacy properties, its verification model cannot simply copy the assumptions used for transparent Bitcoin transactions.
The common abstraction should stay the same while chain-specific verification remains isolated.
Connecting this to the MyZubster Marketplace
The same idea extends beyond Zorgax subscriptions.
MyZubster's Marketplace is experimenting with a broader economic layer involving:
BTC, ETH, XMR, TARI, MYZ, barter and free exchanges.
The underlying principle remains:
The platform can coordinate economic activity without needing custody of users' private keys.
Zorgax monetization gives us a concrete environment in which to test that principle.
What is actually finished?
It's important not to confuse architecture with production readiness.
We now have several important building blocks: subscription plans, server-side crypto quoting, trusted verification boundaries, the BTC/Electrum verifier, persistent Payment Intents, expiry and replay protections, and the connection between verified payments and subscription activation.
But the complete system still needs production configuration, live end-to-end deployment testing and further operational hardening.
The other chains also need their own production-grade verification paths.
So this isn't a “payments are finished” announcement.
It's a development update.
The architecture we're moving toward
The final flow is becoming increasingly simple to describe:
Choose Plan
↓
Create Payment Intent
↓
Pay From External Wallet
↓
Verify Blockchain Transaction
↓
Match Transaction to Intent
↓
Activate Subscription
And underneath that flow is one rule that we don't want to compromise:
Verify the payment without owning the money.
For me, that's becoming one of the more interesting parts of building Zorgax.
Not simply teaching an AI assistant how to answer questions, but connecting software, identity, economic events and permissions while keeping the trust boundaries explicit.
The system is still evolving.
And, as with the rest of MyZubster, we're building it in the open.
Project links
MyZubster core:
github.com/MyZubster-Ecosystem/myzubster
Zorgax trusted payment verification — PR #814:
PR #814
Bitcoin/Electrum verifier — PR #815:
PR #815
Electrum 4.8.1 hardening — PR #817:
PR #817
Persistent Payment Intents — PR #818:
PR #818
MyZubster Marketplace:
github.com/MyZubster-Ecosystem/MyZubster-Marketplace