If your app holds its own crypto keys (i.e. it is a wallet), you can let buyers pay for tickets with a single tap — no QR codes, no copy-pasting an address. You supply one closure; the SDK calls it with the exact payment details, your wallet signs and submits the transfer, and the SDK confirms the payment on-chain.
Pass onWalletPayment to the tickets screen or modifier:
.zuuppaTickets(
isPresented: $showTickets,
eventId: "your-event-uuid",
onWalletPayment: { request in
// Send EXACTLY request.amountBaseUnits of the token
// to request.depositAddress on request.chain ("solana").
//
// request.tokenMint == nil -> native SOL
// request.tokenMint != nil -> SPL token at that mint
let signature = try await myWallet.sendTransfer(
to: request.depositAddress,
amountBaseUnits: request.amountBaseUnits,
mint: request.tokenMint
)
return signature // display-only; return nil if unavailable
}
)As soon as the buyer taps Pay with app wallet, the SDK shows a processing screen and, in the background:
ZuuppaCryptoPaymentRequest.request.amountBaseUnits to request.depositAddress. No memo or reference is required — the backend matches the payment purely by the unique deposit address.public struct ZuuppaCryptoPaymentRequest: Sendable, Equatable {
public let orderID: String // Zuuppa order id (your records/logging)
public let chain: String // currently always "solana"
public let token: String // display symbol, e.g. "SOL" / "USDC"
public let tokenMint: String? // SPL mint base58; nil = native SOL
public let decimals: Int // token decimals
public let amountBaseUnits: String // EXACT amount, integer string, base units
public let depositAddress: String // where to send the funds
}| Parameter | Type | Description |
|---|---|---|
orderID | String | The Zuuppa order id, for your own records and logging. Not sent on-chain. |
chain | String | The chain to pay on. Currently always "solana". |
token | String | Display symbol only (e.g. "SOL", "USDC"). |
tokenMint | String? | Base58 SPL mint address, or nil for native SOL. |
decimals | Int | Token decimals, for interpreting amountBaseUnits. |
amountBaseUnits | String | The exact amount to send, as an integer string in the token's base units. |
depositAddress | String | The unique per-order destination address. Send the funds here. |
public typealias ZuuppaWalletPaymentHandler =
@Sendable (ZuuppaCryptoPaymentRequest) async throws -> String?nil if a signature isn’t available.@Sendable and async. Do your signing and network submission inside it and simply return once the transfer is broadcast — you don’t need to wait for on-chain confirmation, the SDK polls for that.