DEV Community

Daniel Ioni
Daniel Ioni

Posted on

Building Zorgax Monetization: From Non-Custodial Bitcoin Verification to Persistent Payment Intents

Building Zorgax Monetization: From Non-Custodial Bitcoin Verification to Persistent Payment Intents

Over the last few development cycles, Zorgax has been moving from an AI assistant experiment toward something that can eventually sustain itself economically.

That creates an interesting engineering problem:

How do you monetize an application with cryptocurrency without turning the application itself into a custodial wallet?

Our answer is increasingly based on one principle:

The application coordinates payments and verifies economic events. It does not need to own the user's private keys.

This post is an update on how that architecture is evolving inside MyZubster.

The Zorgax plans

The current monetization foundation defines three levels:

Zorgax Free
Zorgax Pro — €9.90 monthly equivalent
Zorgax Developer — €29.90 monthly equivalent

Paid plans are designed to support settlement through multiple crypto assets, currently including:

BTC, ETH, XMR and TARI.

But defining prices is the easy part.

The difficult part is proving that a payment actually happened before granting access.

Never trust “I paid”

A browser should never be able to tell the backend:

{
"plan": "developer",
"amount": "29.90",
"paid": true
}

and receive premium access.

Likewise, even a transaction ID supplied by a user isn't enough by itself.

The backend needs its own source of truth.

Our architecture is therefore evolving toward:

Authenticated User
|
v
Checkout
|
v
Server-side Quote
|
v
Persistent Payment Intent
|
v
External Crypto Payment
|
v
Trusted Chain Verifier
|
v
Payment Verification
|
v
Subscription ACTIVE

The important change is the Persistent Payment Intent.

Making payment intents persistent

Previously, Zorgax could create checkout information, but the next step was to make that information durable and tied to the authenticated user.

A payment intent now records server-side information such as:

intentId
owner
plan
asset
destination
quoted crypto amount
EUR price
quote timestamp
expiration
settlement status

The browser doesn't get to redefine those values during payment verification.

When verification happens, the backend retrieves the original payment intent and asks the appropriate trusted verifier to validate the transaction against it.

Conceptually:

verifySettlement({
asset: intent.asset,
paymentReference,
destination: intent.destination,
cryptoAmount: intent.quote.cryptoAmount
});

Notice what's missing.

The client isn't supplying the destination or expected amount.

Those values already belong to the payment intent.

Payment intents also expire

Crypto prices move.

A quote shouldn't remain valid forever.

Zorgax therefore currently gives checkout intents a limited lifetime of 15 minutes.

The lifecycle can look like:

QUOTED
|
v
PENDING
|
+----> EXPIRED
|
v
VERIFIED
|
v
CONSUMED

A stale checkout cannot simply be reused indefinitely.

Bitcoin: testing against real Electrum behavior

Another important lesson came from the BTC verifier.

Our first implementation expected Electrum's gettransaction command to return a decoded transaction object.

Testing against Electrum 4.8.1 showed something different.

It returned the serialized Bitcoin transaction.

So the verifier architecture was corrected to explicitly perform:

gettransaction
|
v
serialized transaction
|
v
deserialize
|
v
outputs[].address
outputs[].value_sats

Confirmation status is retrieved separately:

get_tx_status
|
v
confirmations

That distinction matters.

Stop guessing BTC units

The decoded Electrum output gives us something especially useful:

{
"address": "",
"value_sats": 7212
}

value_sats means we can reason about Bitcoin payments using integer satoshis.

No guessing whether a number represents BTC or satoshis.

No floating-point comparison for the critical verification decision.

Internally, the verifier can use integer arithmetic:

paidSats >= expectedSats

For payment infrastructure, explicit units are much safer than heuristics.

Confirmations are part of verification

Finding the correct destination and amount doesn't necessarily mean a payment should immediately activate a subscription.

The chain verifier also reports confirmations.

For example:

{
"confirmations": 0
}

A payment policy requiring at least one confirmation should therefore keep access inactive.

The trusted verification layer is responsible for enforcing that policy.

Preventing transaction replay

Another problem is payment-reference reuse.

One blockchain transaction shouldn't activate multiple independent subscriptions.

The persistent payment-intent model therefore introduces replay protection around settlement references.

Once a payment has been successfully consumed, the same reference shouldn't simply be reusable for another activation.

This sounds obvious, but it is an important property to enforce at the persistence layer rather than relying only on application logic.

From VERIFIED to ACTIVE

The new architecture connects a successful trusted verification with the existing Zorgax subscription lifecycle.

Conceptually:

Payment Intent
|
v
Trusted verification
|
v
VERIFIED payment
|
v
recordVerifiedPayment()
|
v
ACTIVE subscription
|
v
Zorgax Pro / Developer access

This is the bridge between blockchain settlement and application authorization.

Still non-custodial

None of this requires Zorgax to sign a Bitcoin transaction.

The verifier does not need to expose:

seed phrases
private keys
wallet passwords
spend keys

Signing stays outside the application.

That's an architectural boundary we're deliberately trying to preserve as the system grows.

For Bitcoin, we're also exploring progressively stronger operational isolation, including watch-only infrastructure and reducing privileges around the verifier process.

And this isn't only about Bitcoin

Bitcoin is currently giving us a useful reference implementation.

The broader architecture is multichain:

            Payment Intent
                  |
      +-----------+-----------+
      |           |           |
     BTC         ETH         TARI
      |           |           |
  verifier     verifier     verifier
      |
   Electrum

           + XMR
             |
      privacy-aware
      verification
Enter fullscreen mode Exit fullscreen mode

Monero requires a different verification strategy because its privacy model makes public-explorer-style verification inappropriate for this use case.

That is exactly why we want a common verification interface, rather than embedding chain-specific assumptions throughout the Zorgax application.

The Marketplace connection

This work also connects with the broader MyZubster Marketplace experiment.

The Marketplace is being designed around several possible economic interaction modes:

BTC
ETH
XMR
TARI
MYZ
barter
free exchange

The same principle applies there:

Economic coordination doesn't require custody of users' private keys.

Zorgax monetization is becoming one practical test of that idea.

What isn't finished yet

This is important.

The existence of a verifier, persistent payment intents and subscription lifecycle does not mean the payment system should already be described as production-ready.

We still need live end-to-end deployment testing, production provider configuration, further concurrency/replay hardening, operational isolation of verification services, and equivalent trusted verification paths for the other supported chains.

Open source development makes this evolution visible.

Instead of presenting a finished black box, we can show where assumptions failed, how the architecture changed, and why.

Recent development

The Bitcoin/Electrum verifier was introduced and subsequently hardened after testing against the actual Electrum 4.8.1 CLI behavior.

The latest work adds the persistent payment-intent layer connecting checkout data with trusted verification and subscription activation.

Relevant work:

BTC/Electrum verifier

MyZubster PR #815

Trusted payment verification

MyZubster PR #814

Electrum 4.8.1 hardening

MyZubster PR #817

Persistent payment intents + trusted activation

MyZubster PR #818

MyZubster Marketplace

MyZubster Marketplace repository

MyZubster core

MyZubster core repository

The bigger lesson

The interesting part of crypto payments isn't generating an address.

It's building a trustworthy boundary between an external economic event and an internal application permission.

For Zorgax, we're trying to make that boundary:

non-custodial, auditable, replay-resistant, server-authoritative and chain-independent.

There is still work ahead.

But we're getting closer to a complete path:

quote

payment intent

blockchain settlement

independent verification

subscription

access

And we're building that path in the open.

Per DEV.to, metterei come cover una grafica 1000×420 con:

ZORGAX MONETIZATION
Checkout → Payment Intent → BTC → Electrum → Verification → ACTIVE

Non-custodial • No private keys • Open source

Top comments (0)