Het is januari 1997. De (Internet Engineering Task Force) heeft net vrijgegeven officieel te definiëren De specificatie is geschreven door webpioniers - het - het - het en , de architecten die vormden hoe het internet communiceert. IETF De RFC 2068 HTTP/1.1 door Roy Fielding door Jim Gettys Jeffrey Mogul Henrik Frostyk van Tim Berners-Lee IETF De RFC 2068 door Roy Fielding door Jim Gettys Jeffrey Mogul Henrik Frostyk van Tim Berners-Lee De specificatie introduceert : 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. persistent connections Er is ook Een 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. chunked transfer encoding Maar Een nieuwe statuscode: RFC 2068 quietly introduces something intriguing 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 ( In 2015, in het jaar 2022, Ondanks de fintech revolutie, de opkomst van online betalingen en een hele economie gebaseerd op internettransacties, had niemand bedacht wat ermee te doen. HTTP/2 HTTP/3 Status Code 402 still sits there with the exact same note: 'reserved for future use.' Until now. Vorige maand ( mei 2025 ) vrijgelaten Een open source protocol dat zijn eerste echte baan: het mogelijk maken van native Betalingen binnen HTTP verzoeken. Coinbase x402 HTTP 402 onchain Vandaag de dag moeten agenten (machine-to-machine) betalingen over het web met verminderde (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. M2M HITL Het voorstelt een geautomatiseerde betalingsstroom in de keten die natief wordt geïmplementeerd binnen het HTTP-protocol. . x402 making them as seamless as any other web request Maar hoe ziet dat er in de praktijk uit? Architectuur en componenten van x402 x402 Het is gebouwd rond vier kerncomponenten: x402 De a fungeert 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. client De handhaaft 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. resource server Blockchain-logica wordt toegepast in de component: 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. facilitator Het is de uiteindelijke afwikkelingslaag, waardoor betalingen onveranderlijk en transparant zijn; het maakt programmerbaar geld mogelijk via slimme contracten en stable-coins, . blockchain 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. Elke component heeft een enkele, goed gedefinieerde verantwoordelijkheid. . separation of concerns Resource servers focus purely on business logic, facilitators handle payment complexity, and clients manage user interaction Het systeem bereikt Componenten interageren alleen via gestandaardiseerde HTTP- en REST-interfaces. . 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. loose coupling 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 De facilitator brengt de Door alle blockchain-complexiteit in één gespecialiseerde service te isoleren, voorkomt dit dat betalingslogica in zakelijke toepassingen wordt gelekt en houden zorgen goed gescheiden. single responsibility principle Last but not least volgt deze architectuur High-level componenten zijn afhankelijk van abstracties in plaats van concrete implementaties. servers en clients zijn afhankelijk van HTTP-interfaces, niet specifieke blockchain-API's. dependency inversion Betalingsstroom Wanneer een AI-agent of gebruiker een -enabled API, hier is de vierstapsstroom die plaatsvindt: x402 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. Stromen, geen account aanmaken OAuth Just 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. De 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 met en gedetailleerde betalingsinstructies. Als de betaling in de header, het controleert de betaling met een facilitator service voordat het toestaan van de aanvraag om door te gaan. HTTP 402 X-PAYMENT 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); } } } U voegt gewoon het betalingsfilter toe aan uw mid-ware stack en bepaalt welke eindpunten betaling vereisen. The beauty of this approach is that it requires minimal changes to existing applications. Reactie PaymentRequirements Wanneer een client een beschermd eindpunt bereikt zonder betaling, bouwt de server een gedetailleerd betalingsvereisteobject op. ), het ontvangende portefeuilleadres, blockchain-netwerk en een vervaltijd om replay-aanvallen te voorkomen. USDC 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 de wordt als volgt beschreven: PaymentRequirements 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. : A timestamp after which this payment requirement becomes invalid. This prevents old payment requests from being reused and adds security against replay attacks. expiry 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 de Een standaard, die een gestructureerde, menselijk leesbare weergave van de betalingsgegevens creëert voor het hashen en ondertekenen ervan. EIP-712 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. De interface definieert het contract dat elke facilitatorclient moet implementeren: FacilitatorClient 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. Een voorbeeld dat de volledige stroom laat zien. Spring Boot Eerst creëer je een De annotatie: @PaymentRequired @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface PaymentRequired { String price(); String currency() default "USDC"; String network() default "base-sepolia"; } Vervolgens wijzigen de om te scannen voor deze annotaties bij de start: PaymentFilter @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 annotatie behandelt de prijsconfiguratie declaratief, terwijl de 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. kosten 0,001 USDC en kost 0,01 USDC, waarbij alle betalingen transparant worden verwerkt op de HTTP-laag. @PaymentRequired PaymentFilter /weather /premium-forecast Veiligheids- en productieoverwegingen 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: . x402 putting AI agents in charge of money creates new attack vectors Terwijl handtekeningen en nonce management omgaan met replay-aanvallen, wat gebeurt er als een agent wordt gecompromitteerd? Een gecompromitteerde agent kan fondsen sneller leegmaken dan een menselijke oplichter. EIP-712 AI agents don't follow human spending habits De facilitatorcomponent wordt een ander hoogwaardig doelwit omdat het handtekeningen controleert en nonces beheert. . blockchain settlements are final Sinds 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? x402 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 aan 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. x402 De veiligheids- en operationele uitdagingen zijn reëel, maar ze zijn technische problemen met mogelijke oplossingen. Na bijna drie decennia, Uiteindelijk zou het kunnen doen waarvoor het was ontworpen: het betalen voor dingen op het internet zo eenvoudig maken als het aanvragen ervan. HTTP 402 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 Reppel van Ronnie Caspers door Kevin Leffew Danny Orgel Coinbase . bedankt van Erik Reppel en van Yuga Cohler Voor het beoordelen Mijn bijdragen to x402 van Erik Reppel van Yuga Cohler Mijn bijdragen 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