> ## Documentation Index
> Fetch the complete documentation index at: https://ifdocdemo.lumivescence.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Python, Go và Rust

> Thu phí agent cho các endpoint của bạn bằng Pay (x402 và MPP) và các SDK Python, Go và Rust của InFlow.

Thu phí agent cho các endpoint của bạn bằng Pay (x402 và MPP) và SDK Python, Go hoặc Rust của InFlow. Với Node.js, đọc [Nhận thanh toán từ agent](https://ifdocdemo.lumivescence.com/vi/sellers/protect-an-endpoint.md).

## Trước khi bắt đầu

| Mục | Chi tiết |
| - | - |
| Tài khoản | Một tài khoản Seller và một API key. Xem [Tạo tài khoản Seller](https://ifdocdemo.lumivescence.com/vi/sellers/create-a-seller-account.md). |
| Biến môi trường | `INFLOW_API_KEY`. Người bán dùng MPP cũng cần `MPP_SECRET_KEY`. Tạo giá trị này bằng `openssl rand -base64 32`. Giữ nguyên giá trị này qua các lần deploy. |
| Môi trường | Các ví dụ dùng sandbox. Dùng production khi bạn chuyển sang production. Giá trị này phải khớp với dashboard cấp key. |
| Runtime | Python 3.11, Go 1.26 hoặc Rust 1.93, hoặc phiên bản mới hơn. |

Tích hợp cả hai giao thức trong một dịch vụ, với logic định giá và logic xử lý đơn hàng dùng chung. Giữ mỗi request trên một luồng thu phí. Các tính năng khác nhau theo SDK. Xem [Tham khảo SDK](https://ifdocdemo.lumivescence.com/vi/reference/sdk-packages.md#khác-biệt-về-tính-năng).

## Bảo vệ endpoint

> [tab] Python
>
> Các ví dụ dùng FastAPI. Các client này cũng hoạt động với các framework bất đồng bộ khác.
>
> ### MPP
>
> ```bash theme={null}
> pip install 'inflowpay[mpp,fastapi]' uvicorn
> ```
>
> ```python theme={null}
> import os
> from contextlib import asynccontextmanager
>
> from fastapi import FastAPI, Request
> from mpp import Credential, Receipt
> from mpp.server.decorator import pay
> from starlette.responses import JSONResponse
>
> from inflowpay import ClientOptions
> from inflowpay.mpp.seller import Seller
>
>
> @asynccontextmanager
> async def application():
>     async with await Seller.create(
>         ClientOptions(environment="sandbox", api_key=os.environ["INFLOW_API_KEY"])
>     ) as seller:
>         app = FastAPI()
>
>         @app.get("/report")
>         @pay(
>             intent=seller,
>             method=seller.method,
>             request=seller.charge_request({"amount": "0.50", "currency": "USDC"}),
>             realm="api.example.com",
>             secret_key=os.environ["MPP_SECRET_KEY"],
>         )
>         async def report(
>             request: Request, credential: Credential, receipt: Receipt
>         ) -> JSONResponse:
>             return JSONResponse(
>                 {"report": "Paid content"},
>                 headers={"Payment-Receipt": receipt.to_payment_receipt()},
>             )
>
>         yield app
> ```
>
> ### x402
>
> ```bash theme={null}
> pip install 'inflowpay[x402,fastapi]' uvicorn
> ```
>
> ```python theme={null}
> import asyncio
> import os
>
> import uvicorn
> from fastapi import FastAPI
> from x402 import x402ResourceServer
> from x402.http.middleware.fastapi import payment_middleware
> from x402.http.types import RouteConfig
>
> from inflowpay import ClientOptions
> from inflowpay.x402.facilitator import Facilitator
> from inflowpay.x402.seller import Seller
>
>
> async def serve() -> None:
>     options = ClientOptions(environment="sandbox", api_key=os.environ["INFLOW_API_KEY"])
>     async with (
>         await Seller.create(options) as seller,
>         await Facilitator.create(options) as facilitator,
>     ):
>         resource_server = x402ResourceServer(facilitator)
>         for registration in await seller.scheme_registrations():
>             resource_server.register(registration["network"], registration["server"])
>
>         routes = {
>             "GET /report": RouteConfig(accepts=await seller.offers("$0.01")),
>         }
>         app = FastAPI()
>         app.middleware("http")(payment_middleware(routes, resource_server))
>
>         @app.get("/report")
>         async def report() -> dict[str, str]:
>             return {"report": "Your paid report"}
>
>         await uvicorn.Server(uvicorn.Config(app, host="127.0.0.1", port=8000)).serve()
>
>
> asyncio.run(serve())
> ```
>
> SDK Python không hỗ trợ endpoint thuê bao của người bán hoặc nhiều hơn một offer InFlow trên một endpoint.

> [tab] Go
>
> ```bash theme={null}
> go get github.com/inflowpayai/inflow-go@v0.3.2
> ```
>
> ### MPP
>
> `Protect` trả về một `http.Handler` chuẩn. Gắn handler này vào `ServeMux` của bạn.
>
> ```go theme={null}
> client, err := seller.New(inflow.Options{
>     Environment: inflow.Sandbox,
>     APIKey: os.Getenv("INFLOW_API_KEY"),
> })
> if err != nil {
>     return err
> }
> handler, err := client.Protect(seller.Route{
>     Realm: "api.example.com",
>     SecretKey: os.Getenv("MPP_SECRET_KEY"),
>     Offers: []seller.Offer{{Charge: &mpp.ChargeRequest{
>         Amount: "0.01",
>         Currency: "USDC",
>     }}},
> }, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
>     w.Write([]byte("paid response"))
> }))
> if err != nil {
>     return err
> }
> mux.Handle("/paid", handler)
> ```
>
> ### x402
>
> Người bán x402 dùng middleware `nethttp` của x402 upstream.
>
> ```go theme={null}
> import (
>     "context"
>     "errors"
>     "net/http"
>     "os"
>
>     inflow "github.com/inflowpayai/inflow-go"
>     "github.com/inflowpayai/inflow-go/x402/seller"
>     foundation "github.com/x402-foundation/x402/go/v2"
>     xhttp "github.com/x402-foundation/x402/go/v2/http"
>     "github.com/x402-foundation/x402/go/v2/http/nethttp"
> )
>
> func paidHandler(ctx context.Context, handler http.Handler) (http.Handler, error) {
>     options := inflow.Options{Environment: inflow.Sandbox, APIKey: os.Getenv("INFLOW_API_KEY")}
>     client, err := seller.New(options)
>     if err != nil { return nil, err }
>     facilitator, err := seller.NewFacilitator(options)
>     if err != nil { return nil, err }
>     route, err := client.Route(ctx, seller.RouteOptions{
>         AcceptsOptions: seller.AcceptsOptions{Price: seller.PriceSpec{Amount: "$0.01"}},
>     })
>     if err != nil { return nil, err }
>     if len(route.Accepts) == 0 { return nil, errors.New("no payment offers match this route") }
>     registrations, err := client.SchemeRegistrations(ctx, seller.RegistrationOptions{})
>     if err != nil { return nil, err }
>     server := xhttp.Newx402HTTPResourceServer(
>         xhttp.RoutesConfig{"GET /api/data": route},
>         foundation.WithFacilitatorClient(facilitator),
>     )
>     for _, registration := range registrations {
>         server.Register(registration.Network, registration.Server)
>     }
>     if err := server.Initialize(ctx); err != nil { return nil, err }
>     return nethttp.PaymentMiddlewareFromHTTPServer(
>         server, nethttp.WithSyncFacilitatorOnStart(false),
>     )(handler), nil
> }
> ```

> [tab] Rust
>
> ### MPP
>
> Thêm `inflow-mpp-seller`, `inflow-mpp` và `serde_json`. Tạo đối tượng người bán và một offer.
>
> ```rust theme={null}
> use inflow_mpp_seller::{
>     Authentication, CancellationToken, ChallengeOptions, ClientOptions,
>     Environment, Method, Offer, Seller, SellerOptions,
> };
> use serde_json::json;
>
> async fn configure() -> Result<Offer, Box<dyn std::error::Error>> {
>     let seller = Seller::new(
>         ClientOptions {
>             environment: Environment::Sandbox,
>             authentication: Authentication::ApiKey(std::env::var("INFLOW_API_KEY")?),
>             ..Default::default()
>         },
>         SellerOptions {
>             realm: "api.example.com".into(),
>             secret_key: std::env::var("MPP_SECRET_KEY")?,
>         },
>         &CancellationToken::new(),
>     ).await?;
>     Ok(seller.offer(
>         Method::Inflow,
>         json!({"amount": "0.10", "currency": "USDC"}),
>         ChallengeOptions {
>             description: Some("One search request".into()),
>             requires_auth: true,
>             ..Default::default()
>         },
>     )?)
> }
> ```
>
> Dùng offer này trong handler request của bạn. Request chưa thanh toán nhận một challenge `402`. Request đã thanh toán nhận một receipt.
>
> ```rust theme={null}
> use inflow_mpp_seller::{
>     CancellationToken, Error, Offer, decode_credential, render_challenge,
> };
>
> async fn payment_response(
>     offer: &Offer,
>     payment_authorization: Option<&str>,
>     body: &[u8],
>     cancellation: &CancellationToken,
> ) -> Result<(u16, &'static str, String, &'static str), Error> {
>     let Some(header) = payment_authorization else {
>         let challenge = offer.challenge(Some(body))?;
>         return Ok((402, "WWW-Authenticate", render_challenge(&challenge)?, ""));
>     };
>     let (_, encoded) = header.split_once(' ')
>         .filter(|(scheme, _)| scheme.eq_ignore_ascii_case("Payment"))
>         .ok_or_else(|| Error::new("INVALID_MPP_DATA", "expected Payment credential"))?;
>     let credential = decode_credential(encoded.trim())?;
>     let receipt = offer.accept(&credential, Some(body), cancellation).await?;
>     let header = inflow_mpp::encode(&serde_json::to_value(receipt)
>         .map_err(|_| Error::new("INVALID_MPP_DATA", "invalid receipt"))?)?;
>     // Run the paid operation only after accept returns a receipt.
>     Ok((200, "Payment-Receipt", header, "paid result"))
> }
> ```
>
> Handler này chạy trong mọi framework HTTP dùng Tokio runtime của ứng dụng bạn.
>
> ### x402 với Axum
>
> `inflow-x402-axum` thêm một lớp thanh toán vào một endpoint Axum.
>
> ```rust theme={null}
> use axum::{Router, routing::get};
> use inflow_x402_axum::payment_layer;
> use inflow_x402_seller::{Seller, OfferOptions, CancellationToken};
>
> async fn example(seller: Seller) -> Result<Router, Box<dyn std::error::Error>> {
>     let route = seller.route(&OfferOptions::new("$0.01"),
>         &CancellationToken::new()).await?;
>     let layer = payment_layer(seller.facilitator(), route,
>         "https://service.example/report")?;
>     let app = Router::new().route("/report",
>         get(|| async { "Your report" }).route_layer(layer));
>     Ok(app)
> }
> ```
>
> SDK Rust không hỗ trợ gói thuê bao của người bán. Lớp Axum từ chối các endpoint `upto` tự động, vì middleware upstream quyết toán toàn bộ số tiền đã ủy quyền.

Mỗi repository SDK có các ví dụ sandbox chạy được. Xem [Tham khảo SDK](https://ifdocdemo.lumivescence.com/vi/reference/sdk-packages.md#ví-dụ).

## Bước tiếp theo

> [card] [Kiểm thử thanh toán](https://ifdocdemo.lumivescence.com/vi/sellers/test-a-payment.md)
>
> Xác nhận challenge `402`. Sau đó thanh toán cho endpoint của bạn bằng CLI trong sandbox.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.