# Stripe Payments handler for UCP Accept payments through UCP-compatible platforms using the Stripe unified payment handler. Use the `com.stripe.payments` handler to accept payments through [Universal Commerce Protocol](https://ucp.dev) (UCP) compatible platforms. This handler provides a unified interface for all Stripe payment methods through credential tokenization. In UCP terminology, *platform* refers to the agent or application acting on behalf of the consumer, *business* refers to the merchant or seller processing the payment. ## How it works The Stripe Payments handler enables credential acquisition and payment processing for UCP checkouts: 1. **Discovery**: The business advertises `com.stripe.payments` in its UCP profile at `/.well-known/ucp`, declaring supported instruments and their configuration. 2. **Credential collection**: The platform collects payment credentials from the consumer using the instrument’s configured credential provider. 3. **Tokenization**: The platform calls `/tokenize` with the raw credential. The handler returns an opaque, scoped token bound to the checkout and business. 4. **Completion**: The platform submits the token to the business’s checkout completion endpoint. The business declares which instruments are available and whether each requires tokenization. The handler mediates between the platform and the business for all payment operations. ## Supported instruments | Instrument type | Tokenization | Description | | --- | --- | --- | | `card` | Required | Visa, Mastercard, Amex, Discover. Platform collects card details via the credential provider, then tokenizes. | | `link` | Not required | Link wallet. Consumer authenticates via Link UI; platform receives a token directly. | | `google_pay` | Not required | Google Pay wallet. Consumer authenticates via Google Pay SDK; platform receives a token directly. | | `apple_pay` | Not required | Apple Pay wallet. Consumer authenticates via Apple Pay SDK; platform receives a token directly. | | `gift_card` | Not required | Business-issued gift card. Submit directly. | | `store_credit` | Not required | Business store credit balance. Submit directly. | The handler also accepts pre-existing tokens for instruments that don’t require tokenization. ## Discovery The business advertises `com.stripe.payments` in its UCP profile at `/.well-known/ucp`. The declaration includes all supported instruments, their constraints, and configuration the platform needs to render each payment method. ### Business profile example ```json { "ucp": { "version": "2026-04-08", "payment_handlers": { "com.stripe.payments": [ { "id": "stripe_payments", "version": "2026-06-25", "spec": "https://docs.stripe.com/agentic-commerce/ucp/stripe-payments-handler", "schema": "https://ucp.stripe.com/payments/2026-06-25/schema.json", "available_instruments": [ { "type": "card", "constraints": { "brands": ["visa", "mastercard", "amex", "discover"], "tokenization": "required" } }, { "type": "link" }, { "type": "google_pay", "config": { "gateway": "stripe", "gateway_merchant_id": "acct_1234567890" } }, { "type": "apple_pay", "config": { "merchant_identifier": "merchant.com.example.store", "supported_networks": ["visa", "mastercard", "amex", "discover"] } }, { "type": "gift_card" }, { "type": "store_credit" } ], "config": { "environment": "production", "merchant_id": "acct_1234567890", "publishable_key": "pk_live_abc123", "credential_provider": "https://stripe.com/credential-provider/v1/" } } ] } } } ``` ### Handler configuration fields **Required:** | Field | Type | Description | | --- | --- | --- | | `merchant_id` | string | The business’s Stripe account identifier (for example, `acct_xxx`) | | `environment` | string | `sandbox` or `production` | | `publishable_key` | string | Stripe publishable key for initializing the credential provider and authenticating tokenization calls | | `credential_provider` | string | URL of the secure credential collection surface for instruments requiring tokenization | ### Per-instrument configuration | Instrument | Config fields | Purpose | | --- | --- | --- | | `google_pay` | `gateway`, `gateway_merchant_id` | Platform initializes Google Pay SDK with these values | | `apple_pay` | `merchant_identifier`, `supported_networks` | Platform initializes Apple Pay with merchant identity and accepted networks | ## Tokenize credentials When an instrument declares `"tokenization": "required"`, the platform must call `/tokenize` before completing payment. The endpoint accepts raw credentials and returns an opaque, scoped token bound to the checkout and business. **Endpoint:** `POST https://ucp.stripe.com/handlers/payments/tokenize` **Authentication:** Bearer token using the `publishable_key` from handler config. ### Request ```json POST /tokenize Content-Type: application/json Authorization: Bearer pk_live_abc123 { "credential": { "type": "card", "card_number_type": "fpan", "number": "4242424242424242", "expiry_month": 12, "expiry_year": 2027, "cvc": "314" }, "binding": { "checkout_id": "chk_abc123", "identity": { "access_token": "acct_merchant_xyz" } }, "allowance": { "max_amount": 10000, "currency": "usd", "expires_at": "2027-01-15T14:35:00Z" } } ``` ### Response ```json { "token": "tok_1abc2def3ghi", "type": "stripe_payment_token", "expires_at": "2027-01-15T14:35:00Z" } ``` ### Request fields | Field | Type | Description | | --- | --- | --- | | `credential` | object | The raw credential to tokenize. Shape varies by instrument type. | | `credential.type` | string | Instrument type (`card`, `bank_account`) | | `binding.checkout_id` | string | The checkout session this token is scoped to | | `binding.identity.access_token` | string | Business’s Stripe-issued access token (from UCP discovery) | | `allowance.max_amount` | integer | Maximum charge amount in smallest currency unit | | `allowance.currency` | string | Three-letter ISO currency code | | `allowance.expires_at` | string | Token expiration (ISO 8601). Defaults to 1 hour if omitted. | ## Complete payment After acquiring a token (either from `/tokenize` or from a wallet or provider UI), the platform submits it in the checkout completion request. ```json POST /checkout-sessions/{checkout_id}/complete Content-Type: application/json UCP-Agent: profile="https://agent.example/profile" { "payment": { "instruments": [ { "id": "instr_1", "handler_id": "stripe_payments", "type": "card", "selected": true, "display": { "brand": "visa", "last_digits": "4242", "expiry_month": 12, "expiry_year": 2027 }, "credential": { "type": "stripe_payment_token", "token": "tok_1abc2def3ghi", "expires_at": "2027-01-15T14:35:00Z" } } ] } } ``` ### Payment instrument fields | Field | Type | Description | | --- | --- | --- | | `id` | string | Unique identifier for this instrument instance, assigned by the platform | | `handler_id` | string | Must match the handler’s `id` from the business’s profile (`stripe_payments`) | | `type` | string | Instrument type (for example, `card`, `link`, `google_pay`) | | `credential.type` | string | Token type discriminator. The business uses this to determine its internal processing path. | | `credential.token` | string | The opaque scoped token | | `credential.expires_at` | string | Token expiration timestamp (present for tokenized credentials) | ## Wallet flows For wallet instruments (`link`, `google_pay`, `apple_pay`), the platform renders the wallet provider’s UI using the configuration from discovery. The consumer authenticates within the wallet UI, and the platform receives a token directly. No `/tokenize` call is needed. ### Link 1. Platform reads `publishable_key` from the handler config 2. Platform initializes the Link UI with the publishable key 3. Consumer authenticates (passkey) and selects a saved payment method 4. Platform receives an opaque token 5. Platform submits the token in `/complete` ### Google Pay 1. Platform reads `gateway` and `gateway_merchant_id` from config 2. Platform initializes the Google Pay SDK 3. Consumer authenticates and selects a payment method 4. Platform receives a token 5. Platform submits the token in `/complete` ### Apple Pay 1. Platform reads `merchant_identifier` and `supported_networks` from config 2. Platform initializes the Apple Pay session 3. Consumer authenticates (biometric) and selects a payment method 4. Platform receives a token 5. Platform submits the token in `/complete` ## Consumer actions Some payment methods require consumer interaction after submission (3D Secure challenges, BNPL approval). The handler returns a redirect action: ```json { "status": "requires_action", "redirect_url": "https://ucp.stripe.com/payment-actions/session_456", "redirect_context": { "reason": "three_ds_challenge", "timeout_seconds": 300 } } ``` Platform flow: 1. Receive `status: "requires_action"` with `redirect_url` 2. Open the URL for the consumer (browser, webview, or iframe) 3. Consumer completes the interaction (3D Secure challenge, BNPL approval) 4. Platform re-submits `/complete` with the same checkout ID and instruments 5. Handler processes payment ## Charge the token The business uses the token from `credential.token` to create a Stripe PaymentIntent. The token is bound to the business’s account and can only be used once. ``` POST /v1/payment_intents Content-Type: application/x-www-form-urlencoded amount=10000& currency=usd& payment_method_data[type]=card& payment_method_data[card][token]=tok_1abc2def3ghi& confirm=true ``` ## Error handling | Failure | Error code | Severity | Retryable | | --- | --- | --- | --- | | Card declined | `payment_declined` | recoverable | Yes (different card) | | Insufficient funds | `payment_declined` | recoverable | Yes | | Token expired | `token_invalid` | recoverable | Yes (re-tokenize) | | Binding mismatch | `binding_invalid` | unrecoverable | No | | Rate limited | `rate_limited` | recoverable | Yes (after backoff) | | Fraud detected | `payment_declined` | unrecoverable | No | ## Security | Requirement | Description | | --- | --- | | TLS/HTTPS | All calls to handler endpoints must be encrypted | | PCI DSS | Stripe is PCI Level 1. Platform’s credential provider must be PCI compliant for card and bank instruments. | | Binding | All tokens are bound to checkout + business identity. Verified before processing. | | Token lifecycle | Tokens are scoped to a single checkout with a default TTL of 1 hour. Cannot be reused across checkouts. | | No detokenize | This is a processor-tokenizer handler. Token resolution happens internally. No credential is ever returned to external parties. | ## References | Resource | URL | | --- | --- | | Handler schema | `https://ucp.stripe.com/payments/2026-06-25/schema.json` | | UCP Payment Handler Guide | [ucp.dev/latest/specification/payment-handler-guide](https://ucp.dev/latest/specification/payment-handler-guide/) | | UCP Tokenization Guide | [ucp.dev/latest/specification/tokenization-guide](https://ucp.dev/latest/specification/tokenization-guide/) |