Accept payments
Receiving-address convention, integration options, and how to track inbound payments with SDP.
SDP does not ship a hosted checkout primitive. To accept payments today, you publish a Solana address you control and detect inbound transfers via the SDP transfer list. This page explains the pattern; the two pages that follow cover verification and indexing in detail.
Receiving-address convention
The receiving address is a custody wallet you control. Two scopings to choose between:
- One wallet per order (recommended for accept flows) — provision a fresh custody wallet (or sub-account) per order or per customer and use the destination address itself as the correlation key. The inbound transfer's
destinationfield maps 1:1 to your order row, so you do not depend on memo or reference fields that SDP does not surface for inbound payments. - One wallet per merchant scope — for marketplaces, one custody wallet per seller; for treasury operations, one per ledger account. Reasonable when correlation isn't required (treasury, settlement) or when you accept a single fixed-amount payment per merchant.
The address you publish is the on-chain address of the custody wallet (you can fetch it from GET /v1/wallets/{walletId}). You publish that address; senders use it as the destination of a normal SPL token transfer. SDP indexes the inbound transfer and exposes it in GET /v1/payments/transfers with direction=inbound.
Correlation caveats. For customer-initiated inbound transfers, SDP today does not populate Transfer.memo (Solana memo-program instructions aren't extracted into the record) and does not expose a reference field on the inbound record. The reliable on-record correlation key is the inbound transfer's destination — hence the per-order receiving-address recommendation. If you need memo- or reference-based correlation (e.g., for a Solana Pay URL that carries an order pubkey), read the on-chain transaction directly via Solana RPC using the transfer's signature.
Integration options
There are two ways customers can land a payment on the address you control:
- Direct address share — you display the address (and the expected token + amount) in your UI. The customer's wallet sends a transfer. This works with any Solana wallet and any client; SDP picks the transfer up purely from the on-chain side. Best for B2B settlement, treasury operations, and crypto-native flows.
- Solana Pay request — for consumer checkout, you give the customer a Solana Pay URL or QR code with the destination, amount, and a per-order
referencepubkey. The customer's wallet builds the transfer and attaches thereferenceaccount on-chain, so you can match the transfer back to the order by reading the transaction directly via Solana RPC (thereferencewon't be on the SDPTransferrecord — neither will any memo the wallet sets, since SDP doesn't extract memo-program instructions for inbound transfers). SDP does not ship a hosted Solana Pay endpoint today. ThePreparetransfer endpoint accepts areferenceAddressfield as a roadmap hook, but does not yet attach it on-chain or echo it on the inbound transfer record (see Indexing and reconciliation → Solana Pay reference accounts). For SDP-side correlation today, use per-order destination addresses (covered above); use the on-chain transaction (via RPC) when you need to read memo orreference.
What SDP gives you today
- Indexed inbound transfers —
GET /v1/payments/transfers?direction=inboundreturns all received transfers across your custody wallets, with filters for token, status, wallet, and date range. See Indexing and reconciliation. - Per-transfer status reads —
GET /v1/payments/transfers/{id}for a single payment's lifecycle. See Verifying a payment. - Wallet balances —
GET /v1/payments/wallets/{walletId}/balancesfor the current per-token balance on a receiving wallet. See Wallet balances. - Address-based correlation — the inbound transfer's
destinationis the on-record correlation key for accept flows. Pair with per-order receiving addresses (see above) to map inbound transfers to orders without depending on memo.Transfer.memois populated only for SDP-initiated transfers (outbound or internal); for customer-initiated inbound transfers the field is omitted from the response (it's optional in the schema, not nullable). Read the on-chain transaction via Solana RPC if you need memo or Solana Pay reference correlation.
What SDP does not give you yet
- No checkout session / payment intent object — you do not pre-register an expected payment with the API. Inbound transfers are recognized after the fact by matching the on-record
destination(token and amount are available for additional sanity checks). Memo and Solana Pay reference aren't on the transfer record for customer-initiated inbound transfers — see the correlation caveats above; read those from the on-chain transaction via Solana RPC if you need them. - No webhooks on settlement — status changes are observed by polling
GET /v1/payments/transfers/{id}or by re-listing with date filters. See the polling cadence guidance. - No hosted Solana Pay URL endpoint — if you want to ship a Solana Pay URL or QR, build it client-side from the destination address, token mint, amount, and reference pubkey.
Worked example: a marketplace checkout
A minimum-viable accept flow built on the per-order-address pattern:
- At checkout, provision (or claim from a warm pool) a fresh custody wallet for the order and stage an
ordersrow with that wallet's on-chain address, the expected amount, and the token. - Display the per-order custody-wallet address, the token, and the amount to the customer. Build a Solana Pay URL from those fields if you want a QR code; no SDP-specific endpoint required.
- The customer's wallet submits the transfer.
- Your reconciliation worker (see Indexing and reconciliation) periodically lists recent inbound transfers — without a
wallet/walletAddressfilter (the wallet-scoped path's signature-history branch ignores thefrom/towindow; see Indexing → Query parameters) — and matches each transfer'sdestinationto an open order in yourorderstable. - When a match lands, mark the order paid and ship the goods. Use the transfer's
signature(UNIQUE on the transfer record once present) to dedup if the worker is re-run.
This is intentionally low-level — there is no SDP-provided session object. Treat the orders table as your checkout state machine and SDP as the settlement and status backend.
Next steps
- Verifying a payment — status semantics and how to know when a payment is safe to act on.
- Indexing and reconciliation — listing inbound transfers, deduping, and building a delta-poll worker.