Overview
Try the live demo!
- Onboard: Authentication
- Integrate: Recipe
- Test: Recipe
This overview is written for the merchant — the resource server (seller) that integrates the facilitator into its paywall. You never sign the buyer's transfer or interact with the blockchain; the facilitator does the on-chain work. Your job is three calls:
GET /supportedonce at startup, to learn the fee-payer address and which(scheme, network)pairs you can charge on.POST /verifywhen a buyer presents a payment, to check it's good before you do any work.POST /settleto broadcast the payment on-chain and get a transaction signature back.
A buyer hits your protected resource, you reply 402 Payment Required with your paymentRequirements, the buyer signs a transfer and sends it back in an PAYMENT-SIGNATURE header. You pass that header into a paymentPayload, then call /verify and /settle with the same (paymentPayload, paymentRequirements) pair.
sequenceDiagram
participant B as Buyer
participant M as Merchant
participant F as Facilitator
participant S as Solana<br/>(blockchain)
Note over M,F: At startup
M->>F: GET /supported
F-->>M: kinds + feePayer address
Note over B,S: Per payment
B->>M: GET /protected-resource
M-->>B: 402 PAYMENT-REQUIRED + accepts[]
B->>B: Select paymentDetails<br/>from accepts[]
B->>B: Create Payment Payload<br/>Sign transaction<br/>(facilitator set as fee-payer)
B->>M: GET /protected-resource<br/>PAYMENT-SIGNATURE: paymentPayload
M->>F: POST /verify<br/>(paymentPayload, paymentRequirements)
F->>F: Screen buyer + merchant
F->>F: Verify paymentPayload against<br/>paymentRequirements
F->>S: Simulate transaction
S-->>F: ok
F-->>M: Verification Response<br/>isValid true
M->>M: Perform work to fulfill request
M->>F: POST /settle<br/>(same payload + requirements)
F->>F: Re-verify + deduplicate settlements
F->>S: Submit payment<br/>co-sign as fee-payer + broadcast
S-->>F: Transaction signature
F->>S: Wait for blockchain confirmation
S-->>F: Confirmed
F-->>M: success: true with transaction hash
M-->>B: 200 OK + protected resource<br/>PAYMENT-RESPONSE paymentResponse
Conventions for all three endpoints:
- Send
Content-Type: application/jsonon the twoPOSTs. - A protocol-level rejection (bad payment, sanctioned address, duplicate) is HTTP 200 with
{ "isValid": false, ... }or{ "success": false, ... }. Only a structurally malformed request body is HTTP 400. Don't treat a 200 as success — read the body. - Pass an
x-request-idheader to correlate logs; if you omit it the facilitator generates one and echoes it back on the response.
For background on the solana:… network identifier and the fee-payer address, see CAIP-2 and use the table below:
| Network | CAIP-2 Identifier | Figment Fee Payer |
|---|---|---|
| Solana Mainnet | solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp | 93syNmtT1tTd5ZtPwHqzGf6CM7fKhMmArpv4AM4FtyNX |
| Solana Devnet | solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 | 2bogRi1wDCdT8ECp8aMrZhF4jX23vxZDUxJjaGkcasKg |
