SSeev PlusDocs
Stellar Anchor

SEP-24: Interactive Deposit & Withdrawal

Use the anchor-hosted interactive UI for deposit and withdrawal flows via SEP-24.

SEP-24 provides an interactive, anchor-hosted UI for deposits and withdrawals. Unlike SEP-6 (where the wallet handles all UX), SEP-24 opens a popup or webview where the anchor collects KYC and payment details directly from the user.

SeevCash supports both SEP-6 (programmatic) and SEP-24 (interactive). Choose SEP-6 for API-driven integrations and SEP-24 for simple wallet integrations that want the anchor to handle the UI.

When to use SEP-24 vs SEP-6

SEP-6SEP-24
UIWallet handles all UIAnchor provides popup/webview
KYCWallet submits KYC via SEP-12 APIAnchor collects in hosted form
Best forAPI integrations, automated systemsSimple wallets, MoneyGram flows
ComplexityMore code, full controlLess code, less control

Endpoints

MethodPathAuthDescription
GET/sep24/infoNoService info and supported assets
POST/sep24/transactions/deposit/interactiveJWTStart interactive deposit
POST/sep24/transactions/withdraw/interactiveJWTStart interactive withdrawal
GET/sep24/transactionJWTGet transaction status
GET/sep24/transactionsJWTList transaction history

Flow overview

Wallet                    Anchor                     User
  │                         │                         │
  │  POST /deposit/interactive                        │
  │────────────────────────►│                         │
  │  { url, id }            │                         │
  │◄────────────────────────│                         │
  │                         │                         │
  │  Open URL in popup      │                         │
  │─────────────────────────────────────────────────►│
  │                         │                         │
  │                         │  User fills KYC form    │
  │                         │◄────────────────────────│
  │                         │  User enters MoMo info  │
  │                         │◄────────────────────────│
  │                         │                         │
  │  Poll GET /transaction  │                         │
  │────────────────────────►│                         │
  │  { status: completed }  │                         │
  │◄────────────────────────│                         │

Interactive deposit (GHS → USDC)

Step 1: Start the interactive flow

curl -X POST "https://<your-anchor-domain>/sep24/transactions/deposit/interactive" \
  -H "Authorization: Bearer <sep10_jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "asset_code": "USDC",
    "account": "GA2E5D24D2LCGVA3SVVKDP64OTN2M2NLUWRDYINB352HW35ABZ66MPVR"
  }'
import { Wallet, Keypair } from '@stellar/typescript-wallet-sdk';

const wallet = Wallet.TestNet();
const anchor = wallet.anchor({ homeDomain: '<your-anchor-domain>' });
const accountKp = Keypair.fromSecret('SCZANGBA5YHTNYVVV3C7CAZMCLXPJLNS2YFGXDNASLFTGBPFMRKCY6ML');

// Authenticate
const sep10 = await anchor.sep10();
const authToken = await sep10.authenticate({ accountKp });

// Start interactive deposit via SEP-24
const sep24 = anchor.sep24();
const { url, id } = await sep24.deposit({
  authToken,
  params: {
    asset_code: 'USDC',
    account: accountKp.publicKey,
  },
});

// Open url in popup/webview for user to complete
console.log("Interactive URL:", url);
console.log("Transaction ID:", id);

Response:

{
  "type": "interactive_customer_info_needed",
  "url": "https://<your-anchor-domain>/sep24/interactive?token=abc123&transaction_id=txn-456",
  "id": "txn-456"
}

Step 2: Open the URL

The wallet opens the returned url in a popup, iframe, or webview. The user completes:

  1. KYC information (name, phone, ID)
  2. Mobile money details (phone number, provider)
  3. Amount confirmation

Step 3: Poll for completion

curl -X GET "https://<your-anchor-domain>/sep24/transaction?id=txn-456" \
  -H "Authorization: Bearer <sep10_jwt>"
import { Wallet, Keypair } from '@stellar/typescript-wallet-sdk';

const wallet = Wallet.TestNet();
const anchor = wallet.anchor({ homeDomain: '<your-anchor-domain>' });
const accountKp = Keypair.fromSecret('SCZANGBA5YHTNYVVV3C7CAZMCLXPJLNS2YFGXDNASLFTGBPFMRKCY6ML');

const sep10 = await anchor.sep10();
const authToken = await sep10.authenticate({ accountKp });

const sep24 = anchor.sep24();
const { transaction } = await sep24.getTransactionBy({
  authToken,
  id: 'txn-456',
});
console.log('Status:', transaction.status);

Response (in progress):

{
  "transaction": {
    "id": "txn-456",
    "kind": "deposit",
    "status": "pending_user_transfer_start",
    "more_info_url": "https://<your-anchor-domain>/sep24/transaction/more_info?id=txn-456"
  }
}

Response (completed):

{
  "transaction": {
    "id": "txn-456",
    "kind": "deposit",
    "status": "completed",
    "amount_in": "100.00",
    "amount_out": "6.50",
    "stellar_transaction_id": "abc123def...",
    "completed_at": "2026-08-05T01:00:00Z"
  }
}

Interactive withdrawal (USDC → GHS)

Step 1: Start the interactive flow

curl -X POST "https://<your-anchor-domain>/sep24/transactions/withdraw/interactive" \
  -H "Authorization: Bearer <sep10_jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "asset_code": "USDC",
    "account": "GA2E5D24D2LCGVA3SVVKDP64OTN2M2NLUWRDYINB352HW35ABZ66MPVR"
  }'
import { Wallet, Keypair } from '@stellar/typescript-wallet-sdk';

const wallet = Wallet.TestNet();
const anchor = wallet.anchor({ homeDomain: '<your-anchor-domain>' });
const accountKp = Keypair.fromSecret('SCZANGBA5YHTNYVVV3C7CAZMCLXPJLNS2YFGXDNASLFTGBPFMRKCY6ML');

// Authenticate
const sep10 = await anchor.sep10();
const authToken = await sep10.authenticate({ accountKp });

// Start interactive withdrawal via SEP-24
const sep24 = anchor.sep24();
const { url, id } = await sep24.withdraw({
  authToken,
  params: {
    asset_code: 'USDC',
    account: accountKp.publicKey,
  },
});

// Open url in popup/webview for user to complete
console.log("Interactive URL:", url);
console.log("Transaction ID:", id);

Response:

{
  "type": "interactive_customer_info_needed",
  "url": "https://<your-anchor-domain>/sep24/interactive?token=def789&transaction_id=txn-789",
  "id": "txn-789"
}

Step 2: User completes the form

In the interactive UI, the user:

  1. Enters the amount of USDC to withdraw
  2. Provides mobile money payout details
  3. Confirms the exchange rate

Step 3: Send USDC

After the interactive form is complete, the transaction status changes to pending_user_transfer_start. The wallet must send USDC to the anchor:

import { Wallet, Keypair } from '@stellar/typescript-wallet-sdk';
import {
  Asset,
  TransactionBuilder,
  Networks,
  Horizon,
  Operation,
  Memo,
} from '@stellar/stellar-sdk';

const wallet = Wallet.TestNet();
const anchor = wallet.anchor({ homeDomain: '<your-anchor-domain>' });
const accountKp = Keypair.fromSecret('SCZANGBA5YHTNYVVV3C7CAZMCLXPJLNS2YFGXDNASLFTGBPFMRKCY6ML');

const sep10 = await anchor.sep10();
const authToken = await sep10.authenticate({ accountKp });

// Get transaction details for withdraw_anchor_account and memo
const sep24 = anchor.sep24();
const { transaction } = await sep24.getTransactionBy({ authToken, id: 'txn-789' });

const server = new Horizon.Server('https://horizon-testnet.stellar.org');
const account = await server.loadAccount(accountKp.publicKey);
const tx = new TransactionBuilder(account, {
  fee: '100',
  networkPassphrase: Networks.TESTNET,
})
  .addOperation(Operation.payment({
    destination: transaction.withdraw_anchor_account,
    asset: new Asset('USDC', 'GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5'),
    amount: transaction.amount_in,
  }))
  .addMemo(Memo.text(transaction.withdraw_memo))
  .setTimeout(300)
  .build();

tx.sign(accountKp);
await server.submitTransaction(tx);

Step 4: Poll for completion

The anchor detects the incoming USDC payment, converts to GHS, and pays out via Mobile Money.

curl -X GET "https://<your-anchor-domain>/sep24/transaction?id=txn-789" \
  -H "Authorization: Bearer <sep10_jwt>"
import { Wallet, Keypair } from '@stellar/typescript-wallet-sdk';

const wallet = Wallet.TestNet();
const anchor = wallet.anchor({ homeDomain: '<your-anchor-domain>' });
const accountKp = Keypair.fromSecret('SCZANGBA5YHTNYVVV3C7CAZMCLXPJLNS2YFGXDNASLFTGBPFMRKCY6ML');

const sep10 = await anchor.sep10();
const authToken = await sep10.authenticate({ accountKp });

const sep24 = anchor.sep24();
const { transaction } = await sep24.getTransactionBy({
  authToken,
  id: 'txn-789',
});
console.log('Status:', transaction.status);
// terminal statuses: completed, error, expired, refunded
{
  "transaction": {
    "id": "txn-789",
    "kind": "withdrawal",
    "status": "completed",
    "amount_in": "50.00",
    "amount_out": "665.00",
    "stellar_transaction_id": "xyz789...",
    "external_transaction_id": "PROV-456",
    "completed_at": "2026-08-05T01:05:00Z"
  }
}

TypeScript integration

import { Wallet, Keypair } from '@stellar/typescript-wallet-sdk';

const wallet = Wallet.TestNet();
const ANCHOR_HOME_DOMAIN = '<your-anchor-domain>';
const anchor = wallet.anchor({ homeDomain: ANCHOR_HOME_DOMAIN });
const accountKp = Keypair.fromSecret('SCZANGBA5YHTNYVVV3C7CAZMCLXPJLNS2YFGXDNASLFTGBPFMRKCY6ML');

// 1. Authenticate (SEP-10)
const sep10 = await anchor.sep10();
const authToken = await sep10.authenticate({ accountKp });

// 2. Start interactive deposit (SEP-24)
const sep24 = anchor.sep24();
const { url, id } = await sep24.deposit({
  authToken,
  params: {
    asset_code: 'USDC',
    account: accountKp.publicKey,
  },
});

// 3. Open the URL in a popup/webview
window.open(url, '_blank', 'width=450,height=700');

// 4. Poll for status using the watcher
const watcher = sep24.watcher();
const { stop } = watcher.watchOneTransaction({
  authToken,
  assetCode: 'USDC',
  id,
  onMessage: (txn) => console.log('Status:', txn.status),
  onSuccess: (txn) => {
    console.log('Deposit complete! Stellar TX:', txn.stellar_transaction_id);
    stop();
  },
  onError: (err) => {
    console.error('Error:', err);
    stop();
  },
});

SEP-6 vs SEP-24 comparison

FeatureSEP-6 (Programmatic)SEP-24 (Interactive)
KYC collectionWallet → SEP-12 APIAnchor's hosted form
Payment detailsWallet shows instructionsAnchor's hosted form
Mobile money triggerAnchor auto-collects (auto mode)Anchor handles in form
Integration effortMore codeLess code (just open URL)
User experience controlWallet controls UXAnchor controls UX
MoneyGram support

On this page