Skip to main content
SEMANTIC KERNEL INTEGRATION

Semantic Kernel payment integration.

Add USDC payments to any Microsoft Semantic Kernel agent. Drop-in plugin for .NET, Python, and Java.

SHORT ANSWER

Blockchain0x provides a drop-in Blockchain0xPaymentPlugin for Microsoft Semantic Kernel. Install Blockchain0x.SemanticKernel (.NET) or blockchain0x-semantic-kernel (Python), register the plugin on your kernel, set FunctionChoiceBehavior to Auto, and your ChatCompletionAgent can request and refund USDC payments. Payments settle on Base; webhooks confirm.

WHY SEMANTIC KERNEL

The only enterprise-grade .NET agent framework.

If your stack is Microsoft-shaped (Azure, .NET, SQL Server, Teams, Copilot Studio), Semantic Kernel is almost certainly the right agent framework. It is built by Microsoft, it integrates with Azure OpenAI, AKS, and Entra, and it has first-class support across .NET, Python, and Java in a way no other framework matches. Blockchain0x's payment plugin slots into the standard SK plugin model - it looks and feels like any plugin you would write internally.

The integration is a thin wrapper over the same HTTP API every other Blockchain0x integration uses. What the plugin gives you is idiomatic .NET (or Python, or Java) ergonomics: KernelFunction-decorated methods with proper async semantics, parameter validation via attributes, and exception handling that maps to Semantic Kernel's standard error pipeline. You can call the API by hand if you prefer; the plugin saves the boilerplate.

INSTALLATION

One package install. Four environment variables.

We ship a NuGet package for .NET, a PyPI package for Python, and a Maven artifact for Java. Pick the one that matches your stack; all three expose the same plugin shape and webhook helpers.

INSTALL - .NET
dotnet add package Blockchain0x.SemanticKernel
INSTALL - PYTHON
pip install blockchain0x-semantic-kernel
ENVIRONMENT VARIABLES
BLOCKCHAIN0X_API_KEY=sk_live_...
BLOCKCHAIN0X_AGENT_ID=agt_abc123
BLOCKCHAIN0X_SIGNING_SECRET=whsec_...
OPENAI_API_KEY=sk-...

BLOCKCHAIN0X_API_KEY and BLOCKCHAIN0X_AGENT_ID come from the agent's settings page in the Blockchain0x dashboard. BLOCKCHAIN0X_SIGNING_SECRET is needed only in the process that handles webhooks. OPENAI_API_KEY (or AZURE_OPENAI_* for Azure-hosted models) is your LLM provider key.

FULL AGENT EXAMPLES

ChatCompletionAgent with the payment plugin, in .NET and Python.

Both languages register the plugin on the kernel, instantiate a ChatCompletionAgent, and iterate the streaming response. The plugin function name (Payments.RequestPayment) is the same across runtimes; only the surrounding ceremony differs.

.NET (Program.cs)
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Blockchain0x.SemanticKernel;

// Build the kernel and register the Blockchain0x plugin
var builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion("gpt-4o", openAiApiKey);
builder.Plugins.AddFromType<Blockchain0xPaymentPlugin>("Payments");
var kernel = builder.Build();

// Create a ChatCompletionAgent that can use the payment plugin
var agent = new ChatCompletionAgent
{
    Name = "ResearchBot",
    Instructions = """
        You produce paid research reports. Before doing any research,
        call Payments.RequestPayment with the dollar amount, then hand
        the hosted_url to the client. End your turn after the request.
        """,
    Kernel = kernel,
    Arguments = new(new OpenAIPromptExecutionSettings
    {
        FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(),
    }),
};

await foreach (var response in agent.InvokeAsync(
    "Write me a Q4 LLM market analysis. Charge me $5 USDC for it."))
{
    Console.WriteLine(response.Content);
}
PYTHON (agent.py)
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
from semantic_kernel.agents import ChatCompletionAgent
from blockchain0x.semantic_kernel import Blockchain0xPaymentPlugin

kernel = Kernel()
kernel.add_service(OpenAIChatCompletion(ai_model_id="gpt-4o"))
kernel.add_plugin(Blockchain0xPaymentPlugin(), plugin_name="Payments")

agent = ChatCompletionAgent(
    kernel=kernel,
    name="ResearchBot",
    instructions=(
        "You produce paid research reports. Before research, call "
        "Payments.RequestPayment with the amount, hand the hosted URL "
        "to the client, end your turn."
    ),
)

async for message in agent.invoke(
    "Write me a Q4 LLM market analysis. Charge $5 USDC."
):
    print(message.content)

When the agent runs with the example user message, the LLM identifies the dollar amount, calls Payments.RequestPayment, gets back a hosted_url, surfaces it as part of its response, and ends the turn. The actual research happens in a follow-up invocation triggered by the webhook handler.

WEBHOOK HANDLING

ASP.NET Core minimal API for receiving payment events.

The webhook URL receives a signed POST when the chain confirms payment. Verify the signature, parse the typed WebhookEvent, and trigger your resume logic. .NET example below; equivalent FastAPI handler in Python is in the starter repo.

WEBHOOK.CS
using Microsoft.AspNetCore.Builder;
using Blockchain0x.SemanticKernel;

var app = WebApplication.CreateBuilder(args).Build();
var signingSecret = Environment.GetEnvironmentVariable("BLOCKCHAIN0X_SIGNING_SECRET")!;

app.MapPost("/webhooks/payment", async (HttpRequest req) =>
{
    using var reader = new StreamReader(req.Body);
    var body = await reader.ReadToEndAsync();
    var signature = req.Headers["X-Blockchain0x-Signature"].ToString();

    if (!WebhookVerifier.Verify(body, signature, signingSecret))
        return Results.Unauthorized();

    var evt = WebhookEvent.Parse(body);
    if (evt.Type == "payment.confirmed")
    {
        await ResumeResearchAsync(evt.Data.PaymentRequestId);
    }
    return Results.Ok();
});

app.Run();

WebhookVerifier.Verify uses HMAC-SHA256 in constant time. Read the raw body via StreamReader so the signature stays intact; do not deserialize then re-serialize. Production deployments typically run the webhook as a separate ASP.NET Core service from the agent process, with both sharing a database (SQL Server / PostgreSQL) indexed by payment_request_id to coordinate the resume.

STARTER REPOSITORY

Working examples in .NET, Python, and Java.

A complete Semantic Kernel repository at the GitHub link below. Includes single-agent and AgentGroupChat examples in .NET 8 and Python 3.10+, a Java reference implementation, the ASP.NET Core webhook handler, a SQL Server / PostgreSQL state store, and an Azure Bicep template for one-click deployment to Azure App Service.

github.com/blockchain0x/agent-wallet-semantic-kernel

Repository structure: dotnet/ (Program.cs + WebhookApi.cs + AgentGroupChat sample), python/ (agent.py + webhook.py via FastAPI), java/ (Java reference), azure/ (Bicep deployment template), README walking through Azure OpenAI + Azure SQL configuration.

COMMON PITFALLS

Five Semantic Kernel-specific traps to avoid.

Semantic Kernel's plugin model is clean but has cross-language and behavior-default gotchas. Knowing them up front saves time.

PITFALL 1

FunctionChoiceBehavior must be Auto

Semantic Kernel agents only invoke plugin functions when FunctionChoiceBehavior is set to Auto on the prompt-execution settings. The default behavior is None, meaning the LLM never calls your payment function regardless of how clearly the user requests it. If your agent ignores the payment plugin entirely, this is the first thing to check.

PITFALL 2

.NET vs Python plugin naming

In .NET, plugins are registered via Plugins.AddFromType<T>() and the type's [KernelFunction] attributes define the function names. In Python, plugins are registered via kernel.add_plugin() and the @kernel_function decorator defines names. The Blockchain0x plugin exposes RequestPayment and RefundPayment in both languages, but the casing/style follows the host language's conventions. If your prompt says 'request_payment' in a .NET project, the function-call resolution fails silently.

PITFALL 3

Async streaming vs full-response invocation

ChatCompletionAgent.InvokeAsync (.NET) and .invoke() (Python) return streaming responses. If you await the full result instead of iterating, you can miss tool-call deltas. The example above iterates with await foreach (.NET) and async for (Python); use those patterns rather than .ToListAsync().Result or similar.

PITFALL 4

Plugin scope across agents

If you have multiple ChatCompletionAgents in your application, you must register the Blockchain0xPaymentPlugin on each agent's kernel that needs it. The plugin is not global. Agents that should not be able to request payment (e.g. a reviewer agent) should be given a separate kernel without the plugin registered, or use ChatCompletionAgent's per-agent FunctionChoiceBehavior to restrict allowed functions.

PITFALL 5

Webhook host process separation

In .NET, your Semantic Kernel agent often runs as a background service or a long-running console app, while the webhook handler is an ASP.NET Core minimal API. The two need to share state about pending payments - the recommended pattern is a SQL Server or PostgreSQL table indexed by payment_request_id, written by the agent on payment-request creation and read by the webhook handler to dispatch the resume. The starter repo includes a working two-service setup.

FREQUENTLY ASKED

Three Semantic Kernel-specific questions.

Does this work with Semantic Kernel Agent Framework (the multi-agent extension)?

Yes. The Agent Framework adds AgentGroupChat and OrchestrationAgent on top of single ChatCompletionAgent runs. The Blockchain0xPaymentPlugin works in any agent that has access to the kernel where it is registered. For multi-agent orchestrations, the recommended pattern is to register the plugin only on the agent responsible for billing (e.g. a dedicated BillingAgent) and let other agents handle work after payment confirms. The starter repo has both single-agent and AgentGroupChat examples.

Can I use this from F#, VB.NET, or Java versions of Semantic Kernel?

F# and VB.NET work because they are .NET languages and consume the same Blockchain0x.SemanticKernel NuGet package. Java Semantic Kernel is a separate runtime; we ship com.blockchain0x:semantic-kernel as a Maven artifact for Java users. The class names mirror the .NET package (Blockchain0xPaymentPlugin, WebhookVerifier). The Java variant has feature parity for plugin registration and webhook verification; the example code is in the starter repo's java/ subdirectory.

How does this work with Microsoft 365 Copilot extensions?

Microsoft 365 Copilot extensions can use Semantic Kernel under the hood when deployed via Azure. The Blockchain0x plugin can be registered just like any other SK plugin in the M365 extension's kernel configuration. For Copilot-specific UX (paying through a Teams chat interface), you typically want a custom UI that surfaces the hosted_url; we have not yet shipped first-class Copilot Studio templates, but the underlying integration works. Talk to us if you are building one - we will help work through the surface details.

Add billing to your SK agent.

Five minutes from package install to your first paid SK invocation. Pro at $9/agent/month.