You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C# .NET WPF应用中集成POS设备实现刷卡支付?

Square Terminal API 集成WPF POS刷卡支付方案

Great to hear you've already got the Checkout API up and running in your WPF app! Adding Square Terminal support for card-present payments is a smart move—let’s walk through a practical, tailored integration plan based on the Square Terminal API docs you’re already referencing.

Core Integration Approach

Square Terminal API offers two primary deployment modes, and both work with WPF—pick the one that fits your use case:

  • Cloud Mode: Ideal if you need to manage payments across multiple locations or sync data remotely. All requests go through Square’s cloud servers.
  • Local Mode: Best for on-premise WPF apps where the terminal and your app are on the same local network. This reduces latency since communication happens directly between your app and the terminal (no cloud roundtrip).

For most WPF desktop POS scenarios, Local Mode is the smoother choice because it cuts down on payment processing delays and works even if internet is spotty temporarily.

Step-by-Step Integration for WPF

1. Pre-Requisites First

  • Ensure your Square Terminal device is connected to the same local network as your WPF app.
  • In the Square Developer Dashboard, enable Terminal API permissions for your app, and grab your:
    • Access Token (sandbox first, then production)
    • Location ID
  • Pair your Terminal device with your app via the Square Dashboard or using the Local API pairing code.

2. Add Square .NET SDK to Your WPF Project

Install the official Square SDK via NuGet—this handles all API communication so you don’t have to build HTTP calls from scratch:

Install-Package Square.Sdk

3. Initialize the Square Client

In your WPF app, initialize the client (use Local Mode if you’re going that route):

using Square;
using Square.Models;
using Square.Exceptions;

// Initialize client for Local Mode (sandbox example)
var squareClient = new SquareClient.Builder()
    .Environment(Square.Environment.Sandbox)
    .AccessToken("YOUR_SANDBOX_ACCESS_TOKEN")
    .Build();

// For Local Mode, you'll also need to point to the terminal's local IP (optional for auto-discovery)
// squareClient.SetBaseUrl("http://{TERMINAL_LOCAL_IP}:8000/v2");

4. Send a Payment Request to the Terminal

Build and send a checkout request to the terminal—make sure to run this on a background thread to avoid freezing your WPF UI:

private async void ProcessCardPayment()
{
    try
    {
        // Generate a unique idempotency key to prevent duplicate requests
        var idempotencyKey = Guid.NewGuid().ToString();

        // Build the payment amount (10.00 USD, amount is in cents)
        var amountMoney = new Money.Builder()
            .Amount(1000)
            .Currency("USD")
            .Build();

        // Build the terminal checkout request
        var checkoutRequest = new TerminalCheckout.Builder()
            .AmountMoney(amountMoney)
            .DeviceId("YOUR_TERMINAL_DEVICE_ID") // Get this via ListTerminalDevices API
            .Build();

        var requestBody = new CreateTerminalCheckoutRequest.Builder()
            .IdempotencyKey(idempotencyKey)
            .Checkout(checkoutRequest)
            .Build();

        // Send the request to Square
        var response = await squareClient.TerminalApi.CreateTerminalCheckoutAsync(requestBody);

        // Update UI on the main thread
        Dispatcher.Invoke(() =>
        {
            if (response.TerminalCheckout.Status == "PENDING")
            {
                PaymentStatusText.Text = "Please complete payment on the terminal";
            }
        });

        // Poll for payment status (or use webhooks for real-time updates)
        await PollPaymentStatus(response.TerminalCheckout.Id);
    }
    catch (ApiException ex)
    {
        Dispatcher.Invoke(() =>
        {
            PaymentStatusText.Text = $"Error: {ex.Message}";
        });
    }
}

5. Handle Payment Status Updates

You can either poll the Terminal API for checkout status changes or set up webhooks to get real-time notifications when the payment completes. For WPF, polling is simpler to implement initially:

private async Task PollPaymentStatus(string checkoutId)
{
    while (true)
    {
        await Task.Delay(2000); // Check every 2 seconds

        var response = await squareClient.TerminalApi.GetTerminalCheckoutAsync(checkoutId);
        var checkout = response.TerminalCheckout;

        Dispatcher.Invoke(() =>
        {
            switch (checkout.Status)
            {
                case "COMPLETED":
                    PaymentStatusText.Text = $"Payment Successful! ID: {checkout.PaymentId}";
                    return;
                case "CANCELED":
                    PaymentStatusText.Text = "Payment was canceled";
                    return;
                case "FAILED":
                    PaymentStatusText.Text = $"Payment Failed: {checkout.ErrorMessage}";
                    return;
            }
        });
    }
}

Key Tips for WPF-Specific Integration

  • UI Thread Safety: Always use Dispatcher.Invoke() when updating UI elements from background API calls—WPF doesn’t allow cross-thread UI updates.
  • Testing: Use Square’s sandbox environment with test cards (e.g., 4111 1111 1111 1111 with any expiration date and CVV) to avoid real charges during development.
  • Offline Resilience: If using Local Mode, the terminal will store payment requests temporarily if the network drops, then sync once connectivity returns.
  • PCI Compliance: Square Terminal handles all card data, so you don’t have to worry about PCI DSS compliance for card processing—just make sure your app doesn’t store any sensitive card info.

内容的提问来源于stack exchange,提问作者Jaimin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 17:06:50