How users add funds to their OFFER-HUB balance — crypto deposits and AirTM top-ups.
Note
This is the public API/SDK guide for integrators. For internal implementation detail (Orchestrator state machine, signer roles), see docs/guides/deposits.md in the repo.
Before users can create orders or fund escrow, they need balance in their account. OFFER-HUB supports two deposit methods depending on your payment provider configuration.
Payment Providers
Provider
Method
Speed
Currencies
crypto (default)
Stellar USDC transfer
~5 seconds
USDC
airtm
AirTM top-up
1-24 hours
USD, local currencies
Set your provider in environment:
env
PAYMENT_PROVIDER=crypto # or "airtm"
Crypto Deposits (Default)
When PAYMENT_PROVIDER=crypto, users deposit by sending USDC to their Stellar address.
{
"data": {
"provider": "crypto",
"method": "stellar_address",
"address": "GCV24WNJYXPG3QFNP6ZQMLVEMHQX5S6J2OWKGVF5U3XC6HF4QQHG7WMD",
"asset": {
"code": "USDC",
"issuer": "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5"
},
"network": "testnet",
"instructions": "Send USDC to this Stellar address. Deposits are detected automatically within seconds."
}
}
Step 2: User Sends USDC
The user sends USDC from any Stellar wallet:
Lobstr — Mobile wallet
StellarTerm — Web wallet
Exchange — Coinbase, Binance, etc. (if they support Stellar USDC)
Step 3: Automatic Detection
OFFER-HUB monitors the blockchain for incoming transactions. When USDC arrives:
Transaction detected — Horizon streaming catches the payment
Balance updated — Off-chain balance incremented
Event emitted — balance.credited pushed over the SSE event stream
User notified — UI can update in real-time
Note
Deposits are typically credited within 5-10 seconds of the Stellar transaction being confirmed.
Deposit Flow Diagram
Mermaid
Rendering diagram…
AirTM Deposits
With AirTM credentials configured, users can fund their accounts through AirTM's payment network. AirTM is not selected through PAYMENT_PROVIDER — that variable must stay crypto.
For the complete server-side flow — user linking, the create request, confirmationUri, statuses, and webhook delivery — see the AirTM Provider Guide.
Choose payment method (bank, mobile money, crypto, etc.)
Complete the payment
Step 3: Provider Confirmation (Inbound Webhook)
AirTM notifies your Orchestrator's inbound webhook receiver (POST /api/v1/webhooks/airtm) when payment completes. This is a provider-to-Orchestrator callback — you don't register anything, and your app isn't called.
The Orchestrator then:
Verifies the AirTM webhook signature (Svix headers + AIRTM_WEBHOOK_SECRET)
Credits the user's balance
Emits balance.credited on the SSE stream, which your app can listen to
Warning
AirTM deposits can take 1-24 hours depending on the user's payment method. Set user expectations accordingly.
Using the SDK
Crypto Deposits
typescript
import { OfferHubSDK } from '@offerhub/sdk';
const sdk = new OfferHubSDK({
apiUrl: 'http://localhost:4000',
apiKey: 'ohk_live_your_api_key'
});
// Get deposit address
const deposit = await sdk.wallet.getDepositAddress('usr_abc123');
// Display to user
console.log(`Send USDC to: ${deposit.address}`);
console.log(`Network: ${deposit.network}`);
// Listen for deposit
sdk.events.on('balance.credited', (event) => {
if (event.userId === 'usr_abc123') {
console.log(`Deposit received: ${event.amount}`);
// Update UI, notify user
}
});
AirTM Top-ups
typescript
// Create top-up request
const topup = await sdk.topups.create({
userId: 'usr_abc123',
amount: '100.00',
currency: 'USD'
});
// Redirect user to payment page
window.location.href = topup.airtm.paymentUrl;
// Or display in iframe/modal
// <iframe src={topup.airtm.paymentUrl} />
// Listen for completion
sdk.events.on('topup.succeeded', (event) => {
if (event.topupId === topup.id) {
console.log('Payment received!');
// Update UI
}
});
SSE is the only real-time event mechanism — there is no outbound webhook subscription API. See Events (SSE) for the full event catalog and connection details.