QBitFlow Documentation
Complete guide to integrating cryptocurrency payments with QBitFlow
Welcome to QBitFlow
QBitFlow is a comprehensive cryptocurrency payment processing platform that enables businesses and developers to accept crypto payments with ease. Whether you need one-time payments, recurring subscriptions, or pay-as-you-go billing, QBitFlow provides the tools you need.
Why Choose QBitFlow?
Lightning Fast
Process cryptocurrency payments in seconds with our optimized infrastructure and smart contract technology.
Secure & Reliable
Built on blockchain technology with military-grade encryption. Your funds and data are always protected.
Multi-Currency Support
Accept payments in multiple cryptocurrencies including ETH, SOL, USDC, USDT, and more.
Developer Friendly
Comprehensive SDKs for Python, Go, JavaScript/TypeScript, and Java. RESTful API for direct integration.
Flexible Billing
Support for one-time payments, recurring subscriptions, and pay-as-you-go models.
Non-Custodial
Funds go directly to your wallet. We never hold your money, ensuring maximum security.
Smart Contract Automation
Automated billing through smart contracts. Transparent, trustless, and verifiable on-chain.
Built for Scale
From startups to enterprises, QBitFlow scales with your business needs.
Key Features
💡 Quick Start: New to QBitFlow? Check out our guide to accept your first payment in under 10 minutes!
Getting Started
Follow these steps to integrate QBitFlow into your application and start accepting cryptocurrency payments.
Create Account
Set up your QBitFlow merchant account
Add Wallets
Connect your crypto wallets to receive payments
Create Products
Define what you're selling
Test Your Payment Flow
Preview and test your payment page
You're All Set!
Start accepting crypto payments
Quick Start Guide
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
🎉 Congratulations! You've successfully created your first payment session. Share the checkout link with your customer, and they can complete the payment in their preferred cryptocurrency.
Next Steps
📚 Learn About Organization Structure
Understand how roles, permissions, and user management work in QBitFlow.
🔔 Set Up Webhooks
Learn how to receive real-time notifications when payments are completed.
🔄 Create Subscriptions
Set up recurring billing with flexible subscription plans.
⚙️ Explore Advanced Features
Discover pay-as-you-go billing, customer management, and more.
Organization Structure & Roles
Understanding how organizations, users, and roles work in QBitFlow is essential for effective team collaboration and payment management.
Organization Hierarchy
Organization
Every user belongs to an organization. When you sign up, an organization is automatically created with you as the owner. An organization can have multiple members with different roles and permissions.
User Roles
QBitFlow has three distinct user roles, each with different permissions and capabilities:
Owner
The owner has complete control over the organization and all its resources.
Permissions:
- Full access to all organization resources
- Manage organization settings and billing
- Add, remove, and manage all users
- Access organization-level wallets and revenue
- Transfer ownership to another user
Admin
Admins have nearly the same privileges as the owner and operate at the organization level.
Permissions:
- Access organization-level wallets and shared revenue
- Create and manage products
- Manage customers and view all transactions
- Generate and manage API keys
- Cannot transfer ownership or delete the organization
User
Users operate independently within the organization with their own wallets and revenue streams.
Permissions:
- Receive payments to their own wallet (separate from organization)
- Create products and manage their own inventory
- View only their own transactions and customers
- Subject to organization fee (if configured)
- Cannot access organization-level resources
Organization-Level vs User-Level
Organization-Level (Owner & Admins)
Revenue Sharing
All payments go to shared organization wallets. Revenue is pooled and accessible by owners and admins.
Use Case
Best for businesses where the organization handles all billing and revenue management.
Example
A SaaS company where all subscriptions are managed centrally by the business.
User-Level (Users)
Independent Revenue
Payments go directly to user's individual wallet. Each user manages their own revenue.
Use Case
Perfect for marketplaces where individual sellers or service providers need to receive payments.
Example
An online marketplace where each vendor receives payments for their own products.
Organization Fees for Users
Revenue Sharing Model
Organizations can configure a fee percentage that is automatically deducted from user-level payments. This allows marketplace owners to generate revenue while enabling individual users to accept payments.
Example:
If a marketplace sets a 5% organization fee:
- •Customer pays $100 for a product from User A
- •QBitFlow receives the 1.5% fees ($1.50)
- •Organization receives 5% as the platform fee (5% of (100 - 1.5) = $4.925)
- •User A receives $93.575 in their wallet
API Keys and Permissions
Using API Keys
When making API requests, the API key determines the scope and permissions:
Organization-Level API Key (Owner/Admin)
Payments and subscriptions created with this key will be credited to the organization's shared wallets. Use this when the organization is receiving the payment.
User-Level API Key
Payments created with this key will be credited to that specific user's wallet (minus any organization fee). Use this when a specific user within your organization is receiving the payment.
💡 Choosing the Right Structure: If you're running a traditional business where all revenue goes to the company, use organization-level permissions (Owner/Admin). If you're building a marketplace where individual users need to receive payments, add them as Users with user-level permissions.
Session Checkouts
Session checkouts are the foundation of accepting payments in QBitFlow. Learn how to create and manage checkout sessions for your customers.
What is a Session Checkout?
Payment Session
A session checkout is a payment session initialized with a unique link that you share with your customer. When a customer wants to make a payment (one-time, subscription, or pay-as-you-go), you create a new session checkout and provide them with the link. The customer then visits this link to complete the payment in their preferred cryptocurrency.
Creating Session Checkouts
You can create session checkouts for different types of payments:
1. One-Time Payment Session
# Create a payment from an existing productresponse = client.one_time_payments.create_session(product_id=1,customer_uuid="customer-uuid", # optionalwebhook_url="https://your-domain.com/webhook",)# Or create a custom paymentresponse = client.one_time_payments.create_session(product_name="Custom Product",description="Product description",price=99.99, # USDcustomer_uuid="customer-uuid",webhook_url="https://your-domain.com/webhook",)print(response.uuid) # Session UUIDprint(response.link) # Payment link for customer
2. Subscription Session
response = client.subscriptions.create_session(product_id=1,frequency=Duration(value=1, unit="months"), # Bill monthlytrial_period=Duration(value=7, unit="days"), # 7-day trial (optional)min_periods=3, # Minimum billing periods (optional)webhook_url="https://your-domain.com/webhook",customer_uuid="customer-uuid",)print(response.link) # Send to customer
3. Pay-As-You-Go Session
response = client.pay_as_you_go.create_session(product_id=1,frequency=Duration(value=1, unit="months"), # Bill monthlyfree_credits=100, # Initial free credits (optional)webhook_url="https://your-domain.com/webhook",customer_uuid="customer-uuid",)print(response.link)
URL Placeholders
When creating session checkouts, you can use placeholders in your success and cancel URLs. These placeholders are automatically replaced by QBitFlow when redirecting the customer:
{{UUID}}Replaced with the session UUID. Use this to identify the payment/subscription in your success handler.
{{TRANSACTION_TYPE}}Replaced with the transaction type (e.g., "payment", "createSubscription", "createPAYGSubscription").
Example URL:
https://yoursite.com/success?uuid={{UUID}}&type={{TRANSACTION_TYPE}}Becomes: https://yoursite.com/success?uuid=01997c89-d0e9-7c9a-9886-fe7709919695&type=payment
Customer UUID (Optional)
When creating a session checkout, you can optionally provide a customerUUID:
✅ With Customer UUID
If you provide a customer UUID (matching an existing customer in your QBitFlow account), the payment will be automatically associated with that customer. The customer won't need to fill in their information again.
📝 Without Customer UUID
If you don't provide a customer UUID, the customer will be asked to fill in their information (name, email, etc.) during the checkout process. A new customer record will be created automatically if they don't already exist.
Session Expiration
Time Limit
Session checkout links expire after a certain period (typically 24 hours). After expiration, the link will no longer be valid, and you'll need to create a new session for the customer. The expiration timestamp is included in the session creation response.
Retrieving Session Details
session = client.one_time_payments.get_session("session-uuid")print(session.product_name, session.price)
💡 Best Practice: Always include both a webhook URL and a success URL when creating sessions. Webhooks provide reliable server-to-server notifications, while success URLs give your customers immediate feedback. Learn more in the section.
Monitoring Transactions
QBitFlow provides three ways to monitor transaction status: webhooks, success URLs, and WebSocket connections. Choose the method that best fits your use case.
Overview
Webhooks
Server-to-server notifications. Most reliable method for production use.
Success URLs
Redirect customers after payment. Great for immediate user feedback.
WebSocket
Real-time status updates. Use when immediate feedback is critical.
Method 1: Webhooks (Recommended)
Reliable Server-to-Server Notifications
Webhooks are the most reliable way to receive payment notifications. When a transaction is processed, QBitFlow sends a POST request to your webhook URL with the transaction details. This happens regardless of whether the customer closes their browser or loses internet connection.
Setting Up Webhook Handler
from fastapi import FastAPIfrom qbitflow import QBitFlowfrom qbitflow.dto.transaction.session import SessionWebhookResponsefrom qbitflow.dto.transaction.status import TransactionStatusValueapp = FastAPI()client = QBitFlow(api_key="your_api_key")@app.post("/webhook")def handle_webhook(request: Request,x_webhook_signature_256: Annotated[str, Header()],x_webhook_timestamp: Annotated[str, Header()]):"""Handle webhook events from QBitFlow."""# Read raw request body for signature verificationbody = await request.body()# Verify the authenticity of the webhook requestif not qbitflow_client.webhooks.verify(payload=body,signature=x_webhook_signature_256,timestamp=x_webhook_timestamp):print("❌ Invalid webhook signature")raise HTTPException(status_code=401, detail="Invalid webhook signature")# Parse payload after verificationtry:event = SessionWebhookResponse.model_validate_json(body)except ValidationError as e:print(f"❌ Failed to parse webhook payload: {e}")raise HTTPException(status_code=401, detail="Invalid webhook payload")# Extract event detailssession_uuid = event.uuidtransaction_status = event.status.statustransaction_type = event.status.typesession = event.sessionprint(f"Session UUID: {session_uuid}")print(f"Transaction Type: {transaction_type.value}")print(f"Transaction Status: {transaction_status.value}")print(f"Product: {session.product_name}")print(f"Price: {session.price} USD")print(f"Customer UUID: {session.customer_uuid}")# Handle different transaction statuses# ... your business logic here ...print("=" * 60)# Always return 200 OK to acknowledge receiptreturn {"status": "received","session_uuid": session_uuid,"transaction_status": transaction_status.value}
⚠️ Important: Always return a 200 status code to acknowledge webhook receipt. If QBitFlow doesn't receive a 200 response, it will retry the webhook delivery multiple times.
Method 2: Success & Cancel URLs
Redirect-Based Monitoring
Success and cancel URLs provide immediate feedback to your customers by redirecting them back to your site after they complete or cancel a payment. While not as reliable as webhooks (customers might close their browser), they're excellent for providing instant user feedback.
Creating Session with URLs
response = client.one_time_payments.create_session(product_id=1,success_url=f"{MY_URL}/success?uuid={{{{UUID}}}}&transactionType={{{{TRANSACTION_TYPE}}}}",cancel_url=f"{MY_URL}/cancel",customer_uuid="customer-uuid",)print(f"✓ Payment session created with redirects!")print(f" - Session UUID: {response.uuid}")print(f" - Payment Link: {response.link}")
Handling Success Redirect
@app.get("/success")async def handle_success(uuid: str, transactionType: TransactionType):"""Handle success redirect from QBitFlow payment page.This endpoint is called when a customer completes a paymentand is redirected back to your application.Args:uuid: The session or transaction UUIDtransactionType: The type of transaction (payment, subscription, etc.)Returns:Success page data or redirect"""print("=" * 60)print("✅ Success redirect received")print("=" * 60)print(f"UUID: {uuid}")print(f"Transaction Type: {transactionType.value}")try:# Fetch the current transaction statustransaction_status = qbitflow_client.transaction_status.get(transaction_uuid=uuid,transaction_type=transactionType)print(f"Current Status: {transaction_status.status.value}")# Handle different statuses# ... your business logic here ...except Exception as e:print(f"❌ Error fetching transaction status: {e}")raise HTTPException(status_code=500,detail=f"Error processing success redirect: {str(e)}")
Method 3: WebSocket (Real-Time)
Real-Time Status Updates
WebSocket connections provide real-time transaction status updates. This is useful when you need immediate feedback, but it's generally not recommended as the primary monitoring method since it requires maintaining an active connection. Use WebSockets for UI updates while relying on webhooks for business logic.
# Note: WebSocket support varies by SDK# Check your SDK documentation for WebSocket implementation# Most applications should use webhooks instead# WebSockets are best for real-time UI updates
⚠️ Note: WebSockets are best used for real-time UI updates (like progress bars or status indicators). For reliable transaction processing, always implement webhook handlers as your primary monitoring method.
Best Practices
Use Webhooks as Primary Method
Always implement webhook handlers for production. They're the most reliable way to receive payment notifications, working even if customers close their browser.
✅ Combine Webhooks with Success URLs
Use webhooks for reliable server-side processing and success URLs for immediate customer feedback. This combination provides the best user experience.
🔒 Always Return 200 for Webhooks
Your webhook endpoint must return HTTP 200 to acknowledge receipt. If QBitFlow doesn't receive a 200 response, it will retry delivery.
🔍 Verify Transaction Status
In success URL handlers, always verify the transaction status by querying the API. Don't trust the redirect alone for critical business logic.
🎨 Use WebSockets for UI Only
WebSockets are perfect for real-time UI updates (progress bars, status badges), but rely on webhooks for actual payment processing logic.
Managing Subscriptions
QBitFlow supports two types of subscription models: fixed recurring subscriptions and pay-as-you-go (PAYG) subscriptions. Both leverage smart contracts for automated, trustless billing.
Subscription Types
Fixed Recurring Subscriptions
Traditional subscription model with fixed amounts charged at regular intervals (weekly, monthly, yearly).
Pay-As-You-Go (PAYG)
Usage-based billing where customers are charged based on consumption, with billing cycles to collect the fees.
Creating Subscriptions
Step-by-Step Process
- 1
- 2
- 3
- 4
- 5
Creating a Fixed Subscription
response = client.subscriptions.create_session(product_id=1,frequency=Duration(value=1, unit="months"), # Bill monthlytrial_period=Duration(value=7, unit="days"), # 7-day trial (optional)min_periods=3, # Minimum billing periods (optional)webhook_url="https://your-domain.com/webhook",customer_uuid="customer-uuid",)print(response.link) # Send to customer
Creating a Pay-As-You-Go Subscription
response = client.pay_as_you_go.create_session(product_id=1,frequency=Duration(value=1, unit="months"), # Bill monthlyfree_credits=100, # Initial free credits (optional)webhook_url="https://your-domain.com/webhook",customer_uuid="customer-uuid",)print(response.link)
Monitoring Subscriptions
Regular Status Polling
Unlike one-time payments that complete immediately, subscriptions are long-lived. You should fetch the subscription status regularly (e.g., once per day using a cron job) to monitor billing cycles, detect status changes, and take appropriate actions.
subscription = client.subscriptions.get("subscription-uuid")print(subscription.status, subscription.next_billing_date)# Handle different statuses# ... your business logic here ...
Customer Self-Service Management
Public Management Page
QBitFlow provides a public subscription management page that customers can access without logging in. Customers can view their subscription details and perform actions like canceling, increasing allowance, or updating the max amount. All actions require wallet signature verification for security.
Management Page URL:
https://qbitflow.app/user/<ref-id>/manage?uuid=<subscription-uuid>Share this link with your customers so they can manage their subscriptions themselves. This reduces support overhead and empowers customers.
Available Customer Actions
Cancel Subscription
Customers can cancel their subscription at any time. Requires wallet signature to verify ownership.
Increase Allowance
If the subscription shows "low_on_funds" status, customers can increase their allowance to ensure future billings succeed.
Update Max Amount
If crypto prices drop and the max amount is reached, customers can update it to resume billing.
💡 Automation Tip: Set up a daily cron job to fetch all active subscriptions and check their status. When a status changes (e.g., from "active" to "past_due"), take appropriate action like sending notifications or revoking access. See the section for details on all possible states.
Transaction Statuses
Understanding transaction statuses is crucial for properly handling payments and subscriptions in your application.
Status Values
Transactions go through various states during their lifecycle. Here are all possible transaction statuses:
created
The transaction has been created and acknowledged by the backend. It's being prepared to be sent to the blockchain.
waitingConfirmation
The transaction has been sent to the blockchain and is waiting for confirmations. This is a normal state during blockchain processing.
pending
The transaction is pending additional processing or actions. Continue monitoring until status changes.
completed
The transaction has been successfully completed and confirmed on the blockchain. This is a final, successful state.
failed
The transaction has failed. This could be due to insufficient funds, network issues, or other errors. This is a final state.
expired
The transaction couldn't be processed within the time limit and has expired. A new transaction needs to be created.
cancelled
An error occurred and the transaction was cancelled. It was not processed successfully.
Transaction Types
Transaction statuses apply to different types of transactions:
paymentOne-time payment transaction
createSubscriptionCreating a new subscription
cancelSubscriptionCancelling an existing subscription
executeSubscriptionExecuting a subscription billing cycle
createPAYGSubscriptionCreating a pay-as-you-go subscription
cancelPAYGSubscriptionCancelling a PAYG subscription
increaseAllowanceIncreasing subscription allowance
updateMaxAmountUpdating subscription max amount
Checking Transaction Status
# Check status of a one-time paymentstatus = client.transaction_status.get(transaction_uuid="transaction-uuid",transaction_type=TransactionType.ONE_TIME_PAYMENT)print(f"Type: {status.type.value}")print(f"Status: {status.status.value}")# Handle different statuses# ... your business logic here ...
💡 Best Practice: In your webhook and success URL handlers, always check the transaction status and handle each state appropriately. Final states (completed, failed, expired, cancelled) won't change, but in-progress states (created, waitingConfirmation, pending) may transition to final states.
Subscription Statuses
Subscriptions have their own set of statuses that indicate the health and state of recurring billing. Understanding these statuses helps you provide the best service to your customers.
Status Overview
active
The subscription is active and functioning normally. Billing cycles are executing successfully, and the customer has sufficient allowance.
Action Required:
None - continue providing service
past_due
The last billing cycle failed. QBitFlow will automatically retry the billing. After a grace period, if billing still fails, the subscription will be cancelled.
Action Required:
Monitor the subscription. Notify the customer that billing failed and will be retried. If it transitions back to "active", billing succeeded.
low_on_funds
The last billing cycle succeeded, but the customer's allowance is running low. The next billing cycle might fail if they don't increase their allowance.
Action Required:
Send a reminder email to the customer asking them to increase their allowance via the subscription management page.
pending
The max amount limit has been reached for this billing cycle. This typically happens when cryptocurrency prices drop significantly. The customer must update their max amount before billing can proceed.
Action Required:
Send urgent notification to customer. They must update the max amount via the subscription management page. After grace period, subscription will be cancelled if not updated.
cancelled
The subscription has been cancelled either by the customer or automatically due to billing failures after the grace period. This is a final state.
Action Required:
Revoke access to the service. Archive subscription data. If customer wants to resume, they need to create a new subscription.
trial
The subscription is in its trial period. No billing occurs during this time. When trial ends, it automatically transitions to "trial_expired".
Action Required:
Provide full service access. Optionally remind customer when trial is ending.
trial_expired
The trial period has ended but the customer hasn't upgraded. They can upgrade via the subscription management page. After grace period, will be cancelled.
Action Required:
Send email prompting customer to upgrade. Provide link to subscription management page. Consider reducing service access.
Status Transitions
Normal Flow
Warning States
Billing Issues
Max Amount Issues
Trial Expiration
Recommended Monitoring Strategy
- 1.
Daily Status Check
Set up a cron job that runs once daily to fetch all active subscriptions and check their status.
- 2.
Status Change Detection
Compare current status with previous status. If changed, trigger appropriate actions.
- 3.
Automated Notifications
Send emails when status becomes "low_on_funds", "pending", or "trial_expired". Include link to management page.
- 4.
Access Control
Grant/revoke service access based on status. "active" and "trial" = full access. "cancelled" = no access.
- 5.
Grace Period Handling
For "past_due" and "pending" states, consider maintaining limited access during grace period while notifying customer.
💡 Pro Tip: Don't wait for webhooks to check subscription status. Subscription billing happens on a schedule, and you should poll status regularly (daily is recommended). This ensures you catch status changes even if a webhook is missed.
Allowances, Max Amount & Pricing
Understanding how allowances, max amounts, and pricing work in QBitFlow is essential for managing subscriptions effectively.
What is an Allowance?
Authorized Amount, Not Escrow
An allowance is the amount a customer authorizes QBitFlow smart contracts to pull from their wallet for subscription billing. This is NOT an escrow - the customer keeps their funds in their wallet. They simply authorize the smart contract to pull up to this amount over time.
How Allowances Work
When creating a subscription, the customer selects how many billing periods they want to authorize (e.g., 3 months, 6 months, 12 months)
The required allowance is calculated automatically: price × periods × (1 + buffer)
The customer signs one transaction to approve this allowance
On each billing cycle, the smart contract automatically pulls the exact amount due
The allowance decreases with each billing but funds remain in customer's wallet until billed
Allowance Safety
Allowances are Safe and Controlled
The allowance cannot be pulled at once. Smart contracts enforce:
- ✓Billing frequency (can't bill more often than agreed)
- ✓Exact amount per billing cycle (can't exceed agreed price)
- ✓Customer can cancel anytime to stop future billings
- ✓All rules are enforced on-chain and verifiable
Example Allowance Calculation
* Includes buffer for price fluctuations
MaxSpending, MaxAmount & Num Periods Explained
Understanding these three concepts is crucial for properly managing subscriptions and controlling costs.
MaxSpending (PAYG Subscriptions)
Definition: A limit in USD set by the user defining the maximum amount they're willing to spend on a pay-as-you-go (PAYG) subscription.
Purpose:
- •Helps control spending on usage-based services
- •Prevents unexpected charges from high usage
- •Gives users peace of mind with predictable costs
Example:
If you set MaxSpending to $500 for an API service PAYG subscription, you won't be charged more than $500 total, regardless of your actual usage. Once the limit is reached, the service may be paused until you increase the limit or the next billing cycle.
MaxAmount (All Subscriptions)
Definition: Used to handle price fluctuations in cryptocurrency values, ensuring individual payments don't exceed a reasonable threshold.
For Regular Subscriptions:
- •Set as a percentage of subscription price at creation time
- •Accommodates reasonable price changes in crypto markets
- •Can be updated later if needed
For PAYG Subscriptions:
- •Set as a percentage of MaxSpending amount
- •Ensures individual payments don't exceed a threshold relative to overall spending limit
- •Protects against sudden crypto price drops
Example:
For a $100/month subscription, MaxAmount might be set to 120 USDC (20% buffer). If the price of USDC drops and would require 130 USDC (equivalent to $100 at the time of payment), the transaction will be blocked until the user updates MaxAmount, protecting them from excessive charges.
USDC is designed to be stable and closely match the USD value, so the amount of USDC needed for a $100 subscription should remain consistent. However, for other tokens/native currencies like ETH or SOL, their prices can fluctuate significantly. This means the number of tokens required to cover the USD subscription price may vary over time. MaxAmount acts as a safeguard to prevent unintended or unexpectedly large charges if the token price drops.
Num Periods (Subscription Creation)
Definition: Used when creating subscriptions to automatically compute and set the allowance based on the subscription price and number of periods specified.
Purpose:
- •Streamlines subscription setup by pre-calculating allowance
- •Defines how many billing cycles the customer authorizes upfront
- •Reduces friction - users don't manually calculate required allowance
How It Works:
Allowance = Price × NumPeriods × (1 + Buffer)
If subscription is $99.99/month and user selects 6 periods, the system automatically calculates the required allowance (≈ $620 with buffer) and prompts the user to approve it.
Comparison: When to Use What
| Concept | Used For | Purpose | Who Sets It |
|---|---|---|---|
| MaxSpending | PAYG Subscriptions | Control total spending | User/Customer |
| MaxAmount | All Subscriptions | Handle crypto price volatility | System (with buffer) |
| Num Periods | Subscription Creation | Calculate initial allowance | User/Customer |
What is Max Amount?
Protection Against Price Volatility
The max amount is a safety limit on how much cryptocurrency can be charged per billing cycle. Since subscription prices are in USD but paid in crypto, if the crypto price drops significantly, more tokens would be needed. The max amount prevents unexpectedly large charges.
Why Max Amount Exists
Problem: Crypto Price Volatility
A $100 subscription might normally cost 100 USDC. But if USDC depegs to $0.90, it would need 111 USDC. Without a limit, customers could be charged unexpectedly high amounts.
Solution: Max Amount Cap
The max amount is set when creating the subscription (e.g., 120 USDC). The smart contract will never pull more than this per billing cycle, even if prices fluctuate.
What Happens When Max Amount is Reached?
- 1.
Subscription Status Changes
The subscription status changes to
pending - 2.
Customer Must Update
Customer must visit the subscription management page and increase the max amount
- 3.
Grace Period
Customer has a grace period to update. If not updated in time, subscription is cancelled
- 4.
Your Action
Send urgent notification to customer with link to management page
Pricing in USD
Stable Pricing for Merchants
All product prices in QBitFlow are set in USD. When a customer pays, QBitFlow automatically converts the USD price to the customer's selected cryptocurrency at the current exchange rate. This gives you predictable revenue while customers can pay in their preferred crypto.
How Price Conversion Works
You Set USD Price
Create a product with price: $99.99
Customer Selects Cryptocurrency
Customer chooses to pay in ETH, USDC, SOL, etc.
Automatic Conversion
QBitFlow fetches current exchange rate and calculates equivalent amount in selected crypto
Customer Pays
Customer pays the converted amount in their chosen cryptocurrency
Best Practices
📧 Notify on Low Allowance
When subscription status is "low_on_funds", send a friendly reminder email to customer with link to increase their allowance.
🚨 Alert on Max Amount Issues
When status is "pending" (max amount reached), send urgent notification. This requires immediate customer action to avoid cancellation.
📊 Monitor Crypto Prices
If you notice significant crypto price drops, consider proactively notifying customers about potential max amount issues before they occur.
💡 Key Takeaway: Allowances keep funds in the customer's wallet while enabling automated billing. Max amounts protect customers from price volatility. USD pricing gives you predictable revenue. These three features work together to create a secure, user-friendly subscription experience.
Network Fees & Gasless Transactions
Understanding who pays network fees for different transaction types and how QBitFlow's gasless transaction model works.
Gasless Transaction Model
Seamless User Experience
When payments are made in tokens, QBitFlow implements a gasless transaction model where users don't pay network fees directly. QBitFlow covers these fees on behalf of users for a seamless experience.
How It Works
Users Don't Need Native Currency
Users don't need to hold the native cryptocurrency of the blockchain (like ETH for Ethereum or SOL for Solana).
QBitFlow Pays Gas Fees Upfront
QBitFlow pays gas fees with the native currency and is refunded in tokens as part of the transaction process.
Fees Paid Only on Success
Fees are paid by the user only when a transaction is successfully executed. Failed transactions don't cost the user anything.
Why Some Actions Require Gas
QBitFlow uses smart contracts, and each important action is performed on-chain. Even if funds aren’t moved (for example, creating a subscription), the action still updates contract state and therefore requires a network fee. Doing these critical updates on-chain ensures security, auditability, and transparency.
Our smart contracts are optimized to minimize network fees. QBitFlow follows an off-chain-first policy to reduce costs, performing as much computation and validation off-chain as possible. However, actions that impact security or user funds must be finalized on-chain and will require gas.
Network Fees by Transaction Type
Here's a comprehensive breakdown of who pays network fees for each transaction type in QBitFlow:
One-Time Payment
ONE_TIME_PAYMENTFor one-time payments, the user pays the network fees to process the transaction on the blockchain. When paying with tokens, this is handled seamlessly via QBitFlow's gasless model. When paying in the chain's native currency (e.g., ETH, SOL), the user pays gas directly; the gasless model does not apply.
Create Subscription
CREATE_SUBSCRIPTIONWhen creating a new subscription, the user pays the network fees required to set up the allowance and initialize the subscription smart contract. Although no funds move at this step, it updates on-chain state for security and transparency.
Cancel Subscription
CANCEL_SUBSCRIPTIONWhen canceling a subscription, QBitFlow covers the network fees. The user doesn't pay anything to cancel. The cancellation is recorded on-chain to ensure transparent and final state updates.
No network fees for user
Execute Subscription Payment
EXECUTE_SUBSCRIPTION_PAYMENTWhen a subscription billing cycle is executed, the user pays the network fees. This is part of the automated recurring payment process and is finalized on-chain for accuracy and security.
Create PAYG Subscription
CREATE_PAYG_SUBSCRIPTIONCreating a pay-as-you-go subscription requires the user to pay network fees for setting up the smart contract and allowance. This establishes on-chain parameters even before any payment occurs.
Cancel PAYG Subscription
CANCEL_PAYG_SUBSCRIPTIONCanceling a PAYG subscription is free for users. QBitFlow covers all network fees, and the cancellation is recorded on-chain for transparent enforcement.
No network fees for user
Increase Allowance
INCREASE_ALLOWANCEWhen increasing the allowance for a subscription, the user pays the network fees. This updates the smart contract state on-chain and is necessary for secure spending limits.
Update Max Amount
UPDATE_MAX_AMOUNTUpdating the max amount for a subscription requires the user to pay network fees. This modifies the subscription parameters on-chain to guarantee transparent enforcement.
Quick Reference Table
| Transaction Type | Code | Who Pays |
|---|---|---|
| One-Time Payment | payment | User |
| Create Subscription | createSubscription | User |
| Cancel Subscription | cancelSubscription | QBitFlow |
| Execute Subscription | executeSubscription | User |
| Create PAYG Subscription | createPAYGSubscription | User |
| Cancel PAYG Subscription | cancelPAYGSubscription | QBitFlow |
| Increase Allowance | increaseAllowance | User |
| Update Max Amount | updateMaxAmount | User |
💡 Key Takeaway: Gasless Transactions
With QBitFlow's gasless transaction model, users can pay with tokens without needing to hold native blockchain currency for gas fees. QBitFlow handles the complexity behind the scenes, making crypto payments as simple as traditional online payments. Users only pay when transactions succeed, and cancellations are always free. Critical actions that affect contract state are recorded on-chain for security and transparency, while non-critical work is optimized off-chain to minimize fees.
Benefits of the Gasless Model
Lower Barrier to Entry
Users don't need technical knowledge about blockchain gas fees or managing multiple cryptocurrencies.
Simplified User Experience
One transaction, one currency — users pay in their chosen token without worrying about gas.
No Failed Transactions Costs
If a transaction fails, users don't pay anything — they only pay when transactions succeed.
Free Cancellations
Users can cancel subscriptions without any cost, removing barriers to trying your service.
Test Mode: Try Before You Go Live
Before accepting real payments, you can test the entire QBitFlow payment flow for free using test networks. No real money involved—just safe, risk-free experimentation.
What is Test Mode?
Test mode lets you run through the complete payment process—creating products, generating links, and processing transactions—using fake cryptocurrency on test networks. It's like a sandbox where you can experiment without any financial risk.
Mainnet vs. Testnet
Mainnet (Live)
- 💰Real cryptocurrency & real money
- ✅Actual payments from customers
- 🔒Funds go directly to your wallets
Testnet (Test)
- 🎮Fake cryptocurrency with zero value
- 🧪Test the full payment flow safely
- 🆓Get free test tokens from faucets
How to Use Test Mode
Key Terms Explained
Test Network (Testnet)
A separate blockchain environment that works exactly like the real network, but uses fake cryptocurrency with zero real value. Perfect for testing.
Faucet
A free service that gives you test tokens. Think of it as a free dispenser— you paste your wallet address and claim free test crypto instantly.
Test Tokens
Fake cryptocurrency used on test networks. They have zero real value and are only useful for testing. You can't sell or trade them.
Mainnet
The real blockchain network where actual cryptocurrency transactions happen. This is where real money changes hands.
Why Test Mode Matters
- ✓Zero Risk: No real money involved—experiment freely
- ✓Full Experience: Test the complete payment flow end-to-end
- ✓Confidence: Know exactly how your customers will experience payments
- ✓Integration Testing: Verify your setup before going live
Ready to Go Live?
Once you're confident with test mode, switch to Mainnet in your dashboard settings. Your products and wallets will be ready to accept real payments immediately.
💡 Pro Tip: Keep your test products separate from live products so you can continue testing without affecting real transactions.
Test Your Integration
Learn how to test your QBitFlow integration safely using test networks before going live with real transactions.
⚡ Important: Always Test First!
Never skip testing. Use test networks and test API keys to ensure everything works correctly before processing real funds. This guide will walk you through the complete testing process.
Step-by-Step Testing Guide
- 1
- 2
- 3
- 4
- 5
- 6
Going Live: Production Checklist
Ready for Production
Once you've thoroughly tested your integration, follow these steps to go live with real transactions.
Create production wallets for each currency you want to support. These will receive real payments.
⚠️ Security First:
- •Use hardware wallets or secure multi-sig setups
- •Never share private keys or seed phrases
- •Enable all available security features
- •Backup your wallet securely
Add your production wallet addresses to the QBitFlow dashboard in Live mode.
Steps:
- 1.Switch dashboard to "Live Mode"
- 2.Navigate to Settings → Wallets
- 3.Add wallet for each supported currency
One Wallet Per Currency
You only need one wallet per native currency. Token wallets are automatically handled and initialized from your main wallet when needed.
Create a production API key and update your integration to use it.
Steps:
- 1.Go to Settings → API Keys in Live Mode
- 2.Click "Generate New Live API Key"
- 3.Copy the key and store it securely
- 4.Update your environment variables with the live key
- 5.Deploy your application with the new key
Never Commit API Keys
Always use environment variables for API keys. Never commit them to version control or expose them in client-side code.
Ensure your production webhook endpoints are accessible and working correctly.
Checklist:
- Webhook URL is publicly accessible (HTTPS)
- Signature verification is implemented
- Error handling is in place
- Webhook logs are being monitored
You're now ready to accept real cryptocurrency payments!
🎉 You're Live!
Your integration is now processing real transactions. Monitor your dashboard and logs closely during the first few transactions.
- •Monitor the first few transactions closely
- •Verify funds are being received correctly
- •Check webhook notifications are working
- •Keep test mode available for debugging
💡 Pro Tip: Keep your test environment active even after going live. Use it for testing new features, debugging issues, and training new team members without risking real funds.
Adding New Currencies
Supporting additional currencies is simple and requires no code changes:
- 1.Create a wallet for the new currency you want to support
- 2.Copy the wallet's public address
- 3.Go to QBitFlow dashboard → Wallets (in Test or Live mode)
- 4.Add the new wallet for the desired currency
- 5.Users can now pay in this new currency!
✨ That's It!
For native currencies, add the wallet directly. For tokens, they're automatically handled from your main wallet and initialized when needed. No code changes required!
Best Practices & Advanced Topics
Follow these best practices to build robust, production-ready integrations with QBitFlow.
Security Best Practices
Protect Your API Keys
Never expose API keys in client-side code or public repositories. Store them as environment variables and restrict access to authorized personnel only.
Validate Webhook Signatures
Always verify webhook signatures before processing. This prevents malicious actors from sending fake payment notifications to your server.
Environment Variables Example
import osfrom qbitflow import QBitFlow# Load API key from environment variableAPI_KEY = os.getenv('QBITFLOW_API_KEY')if not API_KEY:raise ValueError("QBITFLOW_API_KEY environment variable not set")client = QBitFlow(api_key=API_KEY)
Error Handling
Always implement proper error handling to gracefully handle API failures, network issues, and validation errors.
from qbitflow import QBitFlowfrom qbitflow.exceptions import (QBitFlowError,AuthenticationError,NotFoundException,ValidationError,RateLimitError,NetworkError,APIError)client = QBitFlow(api_key="your_api_key")try:payment = client.one_time_payments.get("non-existent-uuid")except AuthenticationError:print("Invalid API key or authentication failed")except NotFoundException as e:print(f"Payment not found: {e.message}")except ValidationError as e:print(f"Validation error: {e.message}")except RateLimitError as e:print(f"Rate limit exceeded: {e.message}")if e.response and 'retry_after' in e.response:print(f"Retry after {e.response['retry_after']} seconds")except NetworkError as e:print(f"Network error: {e.message}")except APIError as e:print(f"API error: {e.message} (status: {e.status_code})")except QBitFlowError as e:print(f"SDK error: {e.message}")
Database Integration
Store Critical Information
Always store payment and subscription information in your database. Don't rely solely on QBitFlow's API for historical data. Store customer UUIDs, transaction UUIDs, subscription statuses, and relevant metadata.
Recommended Database Schema
-- Customers tableCREATE TABLE customers (id SERIAL PRIMARY KEY,qbitflow_uuid VARCHAR(255) UNIQUE NOT NULL,email VARCHAR(255) NOT NULL,name VARCHAR(255),created_at TIMESTAMP DEFAULT NOW()-- ...);-- Payments tableCREATE TABLE payments (id SERIAL PRIMARY KEY,customer_id INTEGER REFERENCES customers(id),qbitflow_payment_uuid VARCHAR(255) UNIQUE NOT NULL,product_name VARCHAR(255) NOT NULL,amount DECIMAL(10, 2) NOT NULL,currency VARCHAR(10) NOT NULL,transaction_hash VARCHAR(255),created_at TIMESTAMP DEFAULT NOW(),completed_at TIMESTAMP-- ...);-- Subscriptions tableCREATE TABLE subscriptions (id SERIAL PRIMARY KEY,customer_id INTEGER REFERENCES customers(id),qbitflow_subscription_uuid VARCHAR(255) UNIQUE NOT NULL,product_name VARCHAR(255) NOT NULL,price DECIMAL(10, 2) NOT NULL,frequency VARCHAR(50) NOT NULL,status VARCHAR(50) NOT NULL,next_billing_date TIMESTAMP,last_billing_date TIMESTAMP,created_at TIMESTAMP DEFAULT NOW(),cancelled_at TIMESTAMP-- ...);
Notification Strategy
Keep Customers Informed
Set up automated notifications to keep customers informed about their payments and subscriptions. This reduces support requests and improves customer satisfaction.
✅ Payment Successful
Send confirmation email with transaction details, receipt, and access instructions.
🔄 Subscription Created
Welcome email with subscription details, billing schedule, and management link.
⚠️ Low Allowance Warning
Remind customer to increase allowance before next billing cycle.
🚨 Max Amount Reached
Urgent notification requiring immediate action to update max amount.
❌ Payment Failed
Inform customer of failed payment and provide troubleshooting steps.
Performance Optimization
Use Pagination
When fetching lists of payments or subscriptions, always use pagination to avoid loading too much data at once. This improves performance and reduces API costs.
Cache Session Data
Session checkout details don't change frequently. Cache them for a short period to reduce API calls when customers refresh the checkout page.
Production Checklist
Webhook endpoint is live and accessible
Test with ngrok or similar tool during development
Success and cancel URLs are configured
Provide good user experience after payment
Error handling is comprehensive
Handle all exception types gracefully
Database schema is set up
Store payments, subscriptions, and customer data
Notification system is configured
Email customers about important events
Cron job for subscription monitoring
Daily checks for subscription status changes
API keys are secured
Stored as environment variables, not in code
Testing in sandbox environment
Test all flows before going live
Monitoring & Analytics
Track Key Metrics
Monitor important metrics to understand your payment performance and customer behavior. Track conversion rates, failed payment rates, subscription churn, and revenue trends.
🎉 You're Ready! Follow these best practices, and you'll have a robust, production-ready QBitFlow integration. If you have questions, reach out to our support team at support@qbitflow.app or visit our documentation site.