Het is januari 1997.
DeIETF(Internet Engineering Task Force) heeft net vrijgegevenDe RFC 2068officieel te definiërenHTTP/1.1De specificatie is geschreven door webpioniersdoor Roy Fielding- hetdoor Jim Gettys- hetJeffrey Mogul- hetHenrik Frostykenvan Tim Berners-Lee, de architecten die vormden hoe het internet communiceert.
IETFDe RFC 2068door Roy Fieldingdoor Jim GettysJeffrey MogulHenrik Frostykvan Tim Berners-LeeDe specificatie introduceertpersistent connections: voorheen vereiste elke enkele HTTP-verzoek een nieuwe TCP-verbinding. persistente verbindingen lossen dit op, waardoor meerdere HTTP-verzoeken via een enkele, langdurige TCP-verbinding kunnen stromen.
Er is ookchunked transfer encodingEen nieuwe manier voor webservers om inhoud te streamen zonder de volledige grootte van tevoren te kennen.Niet langer hoeft een server de totale grootte van dynamisch gegenereerde inhoud van tevoren te berekenen, het is nu vrij om gegevens incrementeel te leveren, omdat het wordt geproduceerd.
MaarRFC 2068 quietly introduces something intriguingEen nieuwe statuscode:
HTTP 402 Payment Required
This code is reserved for future use.
Dit laat zien hoe de oprichters van het World Wide Web voorspelden hoe geld uiteindelijk een groot deel van het internet zou worden.even if they had no clear path on how it would actually play out.
Vandaag, 2025, bijna drie decennia en meerdere HTTP-versies later (HTTP/2
In 2015,HTTP/3
in het jaar 2022,Status Code 402
still sits there with the exact same note: 'reserved for future use.'Ondanks de fintech revolutie, de opkomst van online betalingen en een hele economie gebaseerd op internettransacties, had niemand bedacht wat ermee te doen.
Until now.
Vorige maand ( mei 2025 )Coinbasevrijgelatenx402
Een open source protocol datHTTP 402
zijn eerste echte baan: het mogelijk maken van nativeonchainBetalingen binnen HTTP verzoeken.
Vandaag de dag moeten agentenM2M(machine-to-machine) betalingen over het web met verminderdeHITL(mens-in-the-loop) interventies, maar traditionele betalingsstromen werken niet goed in dit geval. ze vereisen meerdere menselijke interacties, omleidingen en handmatige stappen die gewoon niet werken wanneer een AI-agent een transactie autonoom moet maken.
x402
Het voorstelt een geautomatiseerde betalingsstroom in de keten die natief wordt geïmplementeerd binnen het HTTP-protocol.making them as seamless as any other web request.
Maar hoe ziet dat er in de praktijk uit?
Architectuur en componenten vanx402
x402
x402
Het is gebouwd rond vier kerncomponenten:
aclientfungeert als de initiator van betalingen, ontdekken wat nodig is voor toegang en het bouwen van de juiste betaalgewicht. Simpel gezegd, dit is wat de HTTP-aanvraag naar een betaalde bron maakt. Het kan een browser zijn die een verzoek doet voor premium-inhoud, een AI-agent die API-toegang koopt, of een mobiele app die functies ontgrendelt. De client behandelt de cryptografische handtekening met behulp van de privésleutel van de gebruiker en herroept verzoeken automatisch wanneer betaling vereist is.
Deresource serverhandhaaft betalingsbeleidsregels voor zijn eindpunten terwijl hij zich concentreert op zijn kernbedrijfslogica. Dit is de webserver of API die de gekochte inhoud of service host. Het onderhoudt eenvoudige prijstabellen die eindpunten naar kosten mappen, maar delegeert de betalingsverificatielogica aan de facilitator.
Blockchain-logica wordt toegepast in defacilitatorcomponent: het verifiëren van cryptografische handtekeningen, het voorkomen van replay-aanvallen via nonce-tracking en het beheren van de feitelijke on-chain-afwikkeling. het stelt zowel klanten als servers in staat om met on-chain-betalingen te werken zonder de details van de blockchain-implementatie te begrijpen.
Het isblockchainde uiteindelijke afwikkelingslaag, waardoor betalingen onveranderlijk en transparant zijn; het maakt programmerbaar geld mogelijk via slimme contracten en stable-coins,but its complexity is completely hidden from the application layer by the facilitator.
Client:
- Hoofdverantwoordelijkheid: Initiatie van de betaling
- Belangrijkste kenmerken:EIP-712 ondertekening, automatische retries, betaling ontdekking
- Wat het doet: Verzoeken doen, portefeuilles verwerken, retries met betaling
Resource Server:
- Primaire verantwoordelijkheid: betalingsuitvoering
- Belangrijkste functies: prijstabel, HTTP 402 responses, middleware-integratie
- Wat het doet: Stelt prijzen, controleert betalingen, levert inhoud
Facilitator:
- Primaire verantwoordelijkheid: betalingsverificatie
- Belangrijkste kenmerken: handtekeningverificatie, nonce tracking, gasabstractie
- Wat het doet: Controleert handtekeningen, praat met blockchain
Blockchain:
- Primaire verantwoordelijkheid: Betalingsregeling
- Belangrijkste kenmerken:USDC-overdrachten, slimme contracten, onveranderlijke records
- Wat het doet: Settles payments on chain
Principles
Deze architectuur demonstreert verschillende fundamentele principes van software engineering.separation of concernsElke component heeft een enkele, goed gedefinieerde verantwoordelijkheid.Resource servers focus purely on business logic, facilitators handle payment complexity, and clients manage user interaction.
Het systeem bereiktloose couplingComponenten interageren alleen via gestandaardiseerde HTTP- en REST-interfaces.A resource server doesn't need to understand how blockchain transactions work, and a client doesn't need to know the server's internal implementation. This isolation means you can swap out components (for example, use a different blockchain, change facilitator providers, or modify server logic) without affecting the rest of the system.
De facilitator brengt desingle responsibility principleDoor alle blockchain-complexiteit in één gespecialiseerde service te isoleren, voorkomt dit dat betalingslogica in zakelijke toepassingen wordt gelekt en houden zorgen goed gescheiden.
Last but not least volgt deze architectuurdependency inversionHigh-level componenten zijn afhankelijk van abstracties in plaats van concrete implementaties. servers en clients zijn afhankelijk van HTTP-interfaces, niet specifieke blockchain-API's.
Betalingsstroom
Wanneer een AI-agent of gebruiker eenx402
-enabled API, hier is de vierstapsstroom die plaatsvindt:
- Initiële verzoek: De client maakt een standaard HTTP-verzoek om toegang te krijgen tot een bepaalde bron
- Reactie op betaling vereist: Als er geen betaling is toegevoegd, reageert de server met HTTP 402 en bevat de betalingsgegevens
- Betalingsautorisatie: De klant maakt een cryptografisch ondertekende betaling en herstelt de aanvraag
- Verificatie en toegang : De server valideert de betaling, zendt deze naar de blockchain en verleent toegang
Wat dit krachtig maakt, is dat het allemaal gebeurt op het niveau van het HTTP-protocol.OAuth
Stromen, geen account aanmakenJust standard HTTP with extra headers:
- X-PAYMENT stroomt van client tot server en bevat de ondertekende betaalgewicht. Dit omvat de betalingsgegevens (bedrag, ontvanger, token) plus een cryptografische handtekening die bewijst dat de klant de betaling heeft gemachtigd.
- X-PAYMENT-RESPONSE stroomt van de server naar de client na een succesvolle betaling en bevat transactie ontvangst informatie, waardoor transparantie over wat er gebeurde op de keten.
Server-side implementatie
Betalingsarchitectuur Middleware
De kern server-side implementatie draait om een betalingsfilter (AKA middleware) die HTTP-verzoeken onderschept en betalingsvereisten handhaaft.Wanneer geïntegreerd in uw webserver, controleert deze middleware inkomende verzoeken tegen een prijstabel die eindpunten naar hun kosten mappt.
De mid-ware volgt een eenvoudige beslissingsboom: als een verzoek een beschermd eindpunt bereikt zonder betaling, reageert het metHTTP 402
en gedetailleerde betalingsinstructies. Als de betaling in deX-PAYMENT
header, het controleert de betaling met een facilitator service voordat het toestaan van de aanvraag om door te gaan.
Hier is de essentiële structuur van de Java-implementatie:
public class PaymentFilter implements Filter {
private final String payTo;
private final Map<String, BigInteger> priceTable; // path → amount
private final FacilitatorClient facilitator;
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
String path = req.getRequestURI();
String paymentHeader = req.getHeader("X-PAYMENT");
if (!priceTable.containsKey(path)) {
chain.doFilter(request, response); // Free endpoint
return;
}
if (paymentHeader == null) {
send402Response(resp, path); // Request payment
return;
}
// Verify payment, process request, then settle
VerificationResponse verification = facilitator.verify(paymentHeader, requirements);
if (verification.valid) {
chain.doFilter(request, response);
facilitator.settle(paymentHeader, requirements);
}
}
}
The beauty of this approach is that it requires minimal changes to existing applications.U voegt gewoon het betalingsfilter toe aan uw mid-ware stack en bepaalt welke eindpunten betaling vereisen.
PaymentRequirements
Reactie
Wanneer een client een beschermd eindpunt bereikt zonder betaling, bouwt de server een gedetailleerd betalingsvereisteobject op.USDC
), het ontvangende portefeuilleadres, blockchain-netwerk en een vervaltijd om replay-aanvallen te voorkomen.
private void send402Response(HttpServletResponse response, String path) throws IOException {
response.setStatus(HttpStatus.PAYMENT_REQUIRED);
response.setContentType("application/json");
PaymentRequirements requirements = PaymentRequirements.builder()
.paymentRequirement(List.of(
PaymentRequirement.builder()
.kind(new Kind("exact", "base-sepolia")) // Payment scheme + blockchain network
.receiver(payTo) // Wallet address to receive payment
.amount(priceTable.get(path)) // Cost for this specific endpoint
.asset("<USDC_TOKEN_CONTRACT>") // USDC token contract
.expiry(Instant.now().plus(Duration.ofMinutes(5))) // Payment window
.nonce(UUID.randomUUID().toString()) // One-time use identifier
.build()
))
.build();
response.getWriter().write(Json.MAPPER.writeValueAsString(requirements));
}
Elk veld in dePaymentRequirements
wordt als volgt beschreven:
- Type: Definieert het betalingsschema (nauwkeurig voor vaste bedragen) en het blockchain-netwerk (base-sepolia voor Base testnet).
- ontvanger: Het portemonnee adres waar de betaling moet worden verzonden.Dit is uw zakelijke portemonnee die de fondsen zal ontvangen.
- bedrag: De kosten voor toegang tot dit specifieke eindpunt, opgehaald uit uw prijstabel. Voor USDC wordt dit meestal uitgedrukt in wei (kleinste eenheid).
- asset: Het slimme contractadres van de token die wordt gebruikt voor betaling.Het voorbeeld toont USDC op Base Sepolia testnet.
expiry
: A timestamp after which this payment requirement becomes invalid. This prevents old payment requests from being reused and adds security against replay attacks.- Nonce: Een unieke identificatiecode (UUID) die ervoor zorgt dat elke betalingsvereiste slechts één keer kan worden vervuld, zelfs als dezelfde klant meerdere verzoeken naar hetzelfde eindpunt doet.
Client-side implementatie
Automatische betalingsbehandeling
Cliëntbibliotheken wikkelen standaard HTTP-clients om automatisch 402-reacties te verwerken.Wanneer een client een betalingsaanvraag ontvangt, (1) bouwt het een betaalgewicht, (2) ondertekent het met de privésleutel van de gebruiker en (3) herstelt het oorspronkelijke verzoek met de bijgevoegde betaling.
public HttpResponse<String> makeRequest(String url, String method) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.method(method, HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
// Handle 402 Payment Required
if (response.statusCode() == 402) {
PaymentRequirements requirements = Json.MAPPER.readValue(
response.body(), PaymentRequirements.class);
// Create payment payload matching the requirements
PaymentPayload payment = PaymentPayload.builder()
.receiver(requirements.getPaymentRequirement().get(0).getReceiver())
.amount(requirements.getPaymentRequirement().get(0).getAmount())
.asset(requirements.getPaymentRequirement().get(0).getAsset())
.nonce(requirements.getPaymentRequirement().get(0).getNonce())
.expiry(requirements.getPaymentRequirement().get(0).getExpiry())
.build();
// Sign using EIP-712 structured data signing
String signature = signer.sign(payment.toSigningMap());
// Retry with payment header
String paymentHeader = encodePaymentHeader(payment, signature);
HttpRequest paidRequest = HttpRequest.newBuilder()
.uri(URI.create(url))
.method(method, HttpRequest.BodyPublishers.noBody())
.header("X-PAYMENT", paymentHeader)
.build();
return httpClient.send(paidRequest, HttpResponse.BodyHandlers.ofString());
}
return response;
}
Het handtekeningsproces maakt gebruik van deEIP-712
Een standaard, die een gestructureerde, menselijk leesbare weergave van de betalingsgegevens creëert voor het hashen en ondertekenen ervan.
Verificatie van betalingsstromen
Facilitator voor integratie
De facilitator service is waar de blockchain complexiteit leeft, abstracten het weg van zowel cliënten als servers.Wanneer een server een betaling ontvangt, stuurt het de payload naar de facilitator voor verificatie.
public class HttpFacilitatorClient implements FacilitatorClient {
private final HttpClient http;
private final String baseUrl;
@Override
public VerificationResponse verify(String paymentHeader, PaymentRequirements requirements)
throws Exception {
// Construct verification request with payment and requirements
VerifyRequest body = VerifyRequest.builder()
.paymentHeader(paymentHeader) // The X-PAYMENT header from client
.requirements(requirements) // What the server expects
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + "/verify"))
.POST(HttpRequest.BodyPublishers.ofString(Json.MAPPER.writeValueAsString(body)))
.header("Content-Type", "application/json")
.build();
String json = http.send(request, HttpResponse.BodyHandlers.ofString()).body();
return Json.MAPPER.readValue(json, VerificationResponse.class);
}
@Override
public SettlementResponse settle(String paymentHeader, PaymentRequirements requirements)
throws Exception {
// Settlement happens after successful verification
SettleRequest body = SettleRequest.builder()
.paymentHeader(paymentHeader)
.requirements(requirements)
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + "/settle"))
.POST(HttpRequest.BodyPublishers.ofString(Json.MAPPER.writeValueAsString(body)))
.header("Content-Type", "application/json")
.build();
String json = http.send(request, HttpResponse.BodyHandlers.ofString()).body();
return Json.MAPPER.readValue(json, SettlementResponse.class);
}
}
De facilitator controleert verschillende dingen:
- Is the signature valid?
- Voldoet het bedrag aan de vereisten?
- Is deze betaling al eerder gebruikt?
- Is de betaling nog binnen het vervalvenster?
Als verificatie wordt doorgegeven, verwerkt de facilitator ook de afwikkeling door de transactie uit te zenden naar de blockchain van keuze.FacilitatorClient
De interface definieert het contract dat elke facilitatorclient moet implementeren:
public interface FacilitatorClient {
VerificationResponse verify(String paymentHeader, PaymentRequirements requirements);
SettlementResponse settle(String paymentHeader, PaymentRequirements requirements);
}
Uw applicatie moet een concrete implementatie van deze interface bieden.
Integratie voorbeeld
Nu we de afzonderlijke componenten (betalingsfilters, facilitatorintegratie en client handling) hebben gezien, laten we eens kijken hoe deze stukken samenkomen in een echte applicatie.Spring Boot
Een voorbeeld dat de volledige stroom laat zien.
Eerst creëer je een@PaymentRequired
De annotatie:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PaymentRequired {
String price();
String currency() default "USDC";
String network() default "base-sepolia";
}
Vervolgens wijzigen dePaymentFilter
om te scannen voor deze annotaties bij de start:
@Component
public class PaymentFilter implements Filter {
private final Map<String, BigInteger> priceTable;
private final String payTo;
private final FacilitatorClient facilitator;
public PaymentFilter(ApplicationContext context, String payTo, FacilitatorClient facilitator) {
this.payTo = payTo;
this.facilitator = facilitator;
this.priceTable = buildPriceTableFromAnnotations(context);
}
private Map<String, BigInteger> buildPriceTableFromAnnotations(ApplicationContext context) {
Map<String, BigInteger> prices = new HashMap<>();
// Scan all @RestController beans for @PaymentRequired annotations
Map<String, Object> controllers = context.getBeansWithAnnotation(RestController.class);
for (Object controller : controllers.values()) {
Method[] methods = controller.getClass().getMethods();
for (Method method : methods) {
PaymentRequired payment = method.getAnnotation(PaymentRequired.class);
if (payment != null) {
String path = extractPathFromMapping(method);
BigInteger amount = new BigInteger(payment.price().replace(".", ""));
prices.put(path, amount);
}
}
}
return prices;
}
}
Nu kunt u uw controllermethoden rechtstreeks annoteren:
@RestController
public class WeatherController {
@GetMapping("/weather")
@PaymentRequired(price = "0.001", currency = "USDC", network = "base-sepolia")
public WeatherData getWeather(@RequestParam String city) {
// Your existing business logic
return weatherService.getWeatherForCity(city);
}
@GetMapping("/premium-forecast")
@PaymentRequired(price = "0.01", currency = "USDC", network = "base-sepolia")
public ExtendedForecast getPremiumForecast(@RequestParam String city) {
return weatherService.getExtendedForecast(city);
}
}
@Configuration
public class PaymentConfig {
@Bean
public PaymentFilter paymentFilter(ApplicationContext context) {
return new PaymentFilter(
context,
"<WALLET_ADDRESS>", // Your wallet address
new HttpFacilitatorClient("<FACILITATOR_URL>")
);
}
@Bean
public FilterRegistrationBean<PaymentFilter> paymentFilterRegistration(PaymentFilter filter) {
FilterRegistrationBean<PaymentFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(filter);
registration.addUrlPatterns("/*");
registration.setOrder(1);
return registration;
}
}
De@PaymentRequired
annotatie behandelt de prijsconfiguratie declaratief, terwijl dePaymentFilter
Deze annotaties worden automatisch gedetecteerd bij het opstarten en de prijslijst wordt opgebouwd. Uw bestaande bedrijfslogica in de controllermethoden blijft volledig ongewijzigd. De configuratie verbindt alles door het betalingsfilter te registreren en verbinding te maken met een facilitatordienst./weather
kosten 0,001 USDC en/premium-forecast
kost 0,01 USDC, waarbij alle betalingen transparant worden verwerkt op de HTTP-laag.
Veiligheids- en productieoverwegingen
x402
is eenvoudig en elegant, het verbergt complexiteit. Dit is een pro en een con. Het maakt integratie gemakkelijk, maar het verbergt ook een belangrijk aspect:putting AI agents in charge of money creates new attack vectors.
TerwijlEIP-712
handtekeningen en nonce management omgaan met replay-aanvallen, wat gebeurt er als een agent wordt gecompromitteerd?AI agents don't follow human spending habitsEen gecompromitteerde agent kan fondsen sneller leegmaken dan een menselijke oplichter.
De facilitatorcomponent wordt een ander hoogwaardig doelwit omdat het handtekeningen controleert en nonces beheert.blockchain settlements are final.
Sindsx402
is gebaseerd op transacties in de keten, het erft de operationele risico's van blockchain transacties. Gaskosten fluctueren wild, soms waardoor micropayments economisch ongemakkelijk. Netwerk congestie transacties kan vertragen. Wat moet een AI-agent doen wanneer het real-time gegevens nodig heeft, maar de betaling zit vast in een mempool?
Een ander belangrijk aspect is regelgeving.Compliance varieert in verschillende jurisdicties met verschillende regels over geautomatiseerde betalingen, cryptocurrency-gebruik en gegevensbewaring.Een AI-agent die een groot aantal micro-transacties over de grenzen heen uitvoert, kan AML-waarschuwingen activeren of lokale voorschriften schenden zonder dat iemand het zich realiseert.
Wat is het volgende
Wat is er interessant aanx402
AI-agenten hebben autonome betalingsmogelijkheden nodig, stablecoins bieden een programmeerbare geldlaag en de blockchain-infrastructuur is volwassen genoeg om schaalbare toepassingen te verwerken.Deze stukken hebben zich niet eerder afgestemd.
x402
In plaats van het opnieuw uitvinden van betalingen vanaf nul, breidt het de bestaande HTTP-infrastructuur uit.In plaats van nieuwe integraties te vereisen, werkt het met standaardpatronen die we al begrijpen.
De veiligheids- en operationele uitdagingen zijn reëel, maar ze zijn technische problemen met mogelijke oplossingen.
Na bijna drie decennia,HTTP 402
Uiteindelijk zou het kunnen doen waarvoor het was ontworpen: het betalen voor dingen op het internet zo eenvoudig maken als het aanvragen ervan.
The foundation is set. Now it's time to build.
bedankt van Erik Reppel, van Ronnie Caspers, van Kevin Leffew, Danny Organ en het hele team Coinbase voor open sourcing van dit protocol.
van Erik Reppelvan Ronnie Caspersdoor Kevin LeffewDanny OrgelCoinbasebedankt van Erik Reppel en van Yuga Cohler Voor het beoordelen Mijn bijdragen to x402
.
Bronnen en verder lezen
- HTTP 402-betaling vereist - RFC 2068 - Original 1997 HTTP-specificatie
- x402 Protocolspecificatie - Officiële protocoldocumentatie
- x402 GitHub Repository - Open source implementatie van Coinbase
- x402 Java implementatie - De PR die de Java implementatie van het protocol introduceerde
- EIP-712: Ethereum Typed Structured Data Hashing en Signing - Signing standaard gebruikt in x402
- Base Network Documentation - Layer 2 blockchain platform gebruikt in voorbeelden
- USDC Documentatie - USD Coin stablecoin contract details
- Spring Boot Filter Documentatie - Java middleware implementatie
- Java HTTP Client API - Client-side HTTP beheer
- Machine-to-Machine (M2M) Communicatie Normen - Autonome systeemcommunicatie
- Autonome AI-agentarchitectuur - Onderzoek naar AI-agentontwerppatronen
- Google's Approach to Secure AI Agents - Google-voorstellen voor een veilig, door de mens geleid AI-agentkader