Skip to content

feat: add Stripe payment handler for Google Pay token processing#57

Open
paiking1 wants to merge 2 commits intoUniversal-Commerce-Protocol:mainfrom
paiking1:feat/stripe-payment-handler
Open

feat: add Stripe payment handler for Google Pay token processing#57
paiking1 wants to merge 2 commits intoUniversal-Commerce-Protocol:mainfrom
paiking1:feat/stripe-payment-handler

Conversation

@paiking1
Copy link

@paiking1 paiking1 commented Mar 9, 2026

Hey Google!

My name is Gal, I'm an ex-Googler myself, currently working at Sellersnap and we're very excited for the UCP launch, and we're currently in the waitlist.

Sellersnap is a company that provides repricing services for E-Commerce, so we're looking forward to allow our seller's items appear in Gemini. Let me know if it's possible for us to join the Beta asap, because we already have the core necessary logic implemented!

Below I'm sharing a PR to add Stripe support, because we've already implemented it in our codebase for UCP integration. Let me know what you think.

Thanks!

Summary

  • Adds a Stripe PSP handler (payment_handlers/stripe_handler.py) that processes Google Pay credential tokens through Stripe PaymentIntent.create
  • Routes google_pay handler in _process_payment to Stripe when STRIPE_SECRET_KEY is set, falls back to existing mock behavior otherwise
  • Updates discovery_profile.json with Stripe tokenization gateway parameters
  • Adds stripe>=7.0.0 as optional dependency
  • Includes 15 unit + integration tests with full error handling coverage

This is the "last mile" that every merchant implementing UCP with a real PSP needs — the sample currently accepts Google Pay tokens without contacting a PSP. This PR shows the complete credential.token → stripe.PaymentIntent.create() flow.

Zero breaking changes: without STRIPE_SECRET_KEY, the server behaves exactly as before.

How to use

# Install stripe
uv sync --extra stripe

# Run with Stripe test mode
STRIPE_SECRET_KEY=sk_test_... uv run server.py \
   --products_db_path=/tmp/ucp_test/products.db \
   --transactions_db_path=/tmp/ucp_test/transactions.db \
   --port=8182

# Verify directly (creates real PaymentIntent in Stripe test dashboard)
STRIPE_SECRET_KEY=sk_test_... uv run python3 -c "
from payment_handlers.stripe_handler import StripePaymentHandler
handler = StripePaymentHandler()
print('PaymentIntent:', handler.process_token('tok_visa', 3500, 'USD'))
"

Tests

# Unit tests (no Stripe key needed) — 13 pass
uv run pytest payment_handlers/test_stripe_handler.py -v

# All tests including live Stripe API — 15 pass
STRIPE_SECRET_KEY=sk_test_... uv run pytest payment_handlers/test_stripe_handler.py -v

Test plan

  • 13 unit tests pass without Stripe key (mocked)
  • 2 live integration tests pass with sk_test_* key
  • Real PaymentIntent created in Stripe test dashboard (pi_3T92T6KCyqI7L8TF0fm9FvWn)
  • Server starts and /.well-known/ucp shows Stripe tokenization config
  • simple_happy_path_client.py still works (steps 0–6, backward compatible)
  • Without STRIPE_SECRET_KEY, google_pay tokens accepted as before (mock fallback)

🤖 Generated with Claude Code

paiking1 added 2 commits March 9, 2026 14:00
Adds a real PSP integration showing how to process Google Pay payment
tokens through Stripe. Currently all payment handlers in the sample
accept tokens without contacting a PSP — this shows the actual
"last mile" every merchant needs.

Changes:
- New payment_handlers/stripe_handler.py with full Stripe error handling
- Updated _process_payment to route google_pay to Stripe when configured
- Updated discovery_profile.json with Stripe tokenization parameters
- Added stripe as optional dependency
- Added "Using Stripe as PSP" section to README

Zero breaking changes: without STRIPE_SECRET_KEY, behavior is unchanged.
15 tests covering:
- Configuration gating (is_configured, missing env var)
- Successful PaymentIntent creation with mocked Stripe
- Error handling for all Stripe exception types:
  CardError (402), InvalidRequestError (400), RateLimitError (429),
  APIConnectionError (503), generic StripeError (500)
- Non-success statuses: requires_action (3DS), unexpected status
- Currency normalization (USD -> usd)
- Lazy import with clear error when stripe package missing
- Live integration tests (skipped without STRIPE_SECRET_KEY):
  tok_visa succeeds, tok_chargeDeclined fails

Run unit tests (no Stripe key needed):
  uv run pytest payment_handlers/test_stripe_handler.py -v

Run all tests including live Stripe API:
  STRIPE_SECRET_KEY=sk_test_... uv run pytest payment_handlers/test_stripe_handler.py -v
@google-cla
Copy link

google-cla bot commented Mar 9, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@paiking1 paiking1 force-pushed the feat/stripe-payment-handler branch 2 times, most recently from 504779a to 2bf9988 Compare March 9, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant