feat: add Stripe payment method support#145
Conversation
Adds the initial implementation for Stripe charge method (TOOLS-322): - src/protocol/methods/stripe/ — types (StripeChargeRequest, StripeCredentialPayload) and server-side ChargeMethod that verifies payments by creating a Stripe PaymentIntent with an SPT - src/client/stripe/ — StripeProvider implementing PaymentProvider with a user-provided createToken callback - src/server/ — StripeBuilder, StripeConfig, stripe() builder fn, Mpp::create_stripe(), Mpp::stripe_charge() - tests/integration_stripe.rs — e2e tests against a mock Stripe API (full 402 flow, challenge format, requires_action rejection) - Cargo.toml — stripe and integration-stripe feature flags Co-Authored-By: grandizzy <38490174+grandizzy@users.noreply.github.com>
Tempo Lint ResultsSummaryFound 687 issue(s) across 42 file(s)
Issues by Rule Type
|
- Add spec-required methodDetails (networkId, paymentMethodTypes) to challenges - Add StripeChargeOptions (description, external_id, expires, metadata) - Add ChargeChallenger impl so MppCharge extractor works with Stripe - Parse Stripe error response bodies for better error messages - Add Stripe unit and integration tests Amp-Thread-ID: https://ampcode.com/threads/T-019d1969-811c-7725-aaa6-1e0116d5652c Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019d1969-811c-7725-aaa6-1e0116d5652c Co-authored-by: Amp <amp@ampcode.com>
- Replace StripeChargeRequest with StripeMethodDetails (correct wire
shape: networkId/paymentMethodTypes/metadata nested under methodDetails)
- stripe_charge() now emits methodDetails with networkId and
paymentMethodTypes from config (fixes challenge schema bug)
- Add stripe_charge_with_options() + StripeChargeOptions
- Server verify() propagates metadata: analytics keys (mpp_version,
mpp_is_mpp, mpp_intent, mpp_challenge_id, mpp_server_id,
mpp_client_id) + user metadata from methodDetails
- Callback returns CreateTokenResult { spt, external_id } instead of
plain String (per-payment externalId support)
- Provider extracts metadata from methodDetails.metadata and passes
challenge JSON to callback
- Remove CreateTokenFn trait alias; use plain generic F: Fn(...)
- Provider reads networkId from methodDetails (not top-level)
Co-Authored-By: grandizzy <38490174+grandizzy@users.noreply.github.com>
Co-Authored-By: grandizzy <38490174+grandizzy@users.noreply.github.com>
…tocol::intents Amp-Thread-ID: https://ampcode.com/threads/T-019d1969-811c-7725-aaa6-1e0116d5652c Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019d1969-811c-7725-aaa6-1e0116d5652c Co-authored-by: Amp <amp@ampcode.com>
- tests/integration_stripe_live.rs: tests against real Stripe test-mode API using test_helpers/shared_payment/granted_tokens endpoint. Skipped when STRIPE_SECRET_KEY is not set. - CI runs live tests only when STRIPE_SECRET_KEY secret exists - Tests: happy path (real SPT + PaymentIntent), invalid SPT rejection, expired challenge rejection Co-Authored-By: grandizzy <38490174+grandizzy@users.noreply.github.com>
…e warning - create_test_spt now retries without seller_details when Stripe returns 'Received unknown parameter' (matches mppx fallback) - Suppress dead_code warning on ResultExt trait Co-Authored-By: grandizzy <38490174+grandizzy@users.noreply.github.com>
Remove integration-stripe-live feature flag. Live tests now live in integration_stripe.rs and skip at runtime when STRIPE_SECRET_KEY is not set (matching mppx pattern). CI passes STRIPE_SECRET_KEY as env var to the test step. Revert #[allow(dead_code)] on ResultExt — pre-existing, not ours. Co-Authored-By: grandizzy <38490174+grandizzy@users.noreply.github.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019d1f49-ad9f-74a8-9268-37d860491bb8 Co-authored-by: Amp <amp@ampcode.com>
|
a nicer split would be in tempo / stripe crates but don't think it worth at this stage |
brendanjryan
left a comment
There was a problem hiding this comment.
code-wise this LGTM!
In a follow up PR could we add a small example which shows how to use this with client/server?
here is what we are doing on the python side: tempoxyz/pympp#97
| - uses: taiki-e/install-action@cargo-hack | ||
| - run: cargo test --features tempo,server,client,axum,middleware,tower,utils | ||
| - name: Tests | ||
| run: cargo test --features tempo,stripe,server,client,axum,middleware,tower,utils,integration-stripe |
| fn build_analytics(credential: &PaymentCredential) -> HashMap<String, String> { | ||
| let challenge = &credential.challenge; | ||
| let mut meta = HashMap::new(); | ||
| meta.insert("mpp_version".into(), "1".into()); |
* docs: add Stripe example (server + client) Pay-per-fortune example demonstrating the full SPT flow: - Axum server with /api/create-spt proxy and /api/fortune gated endpoint - Headless CLI client using pm_card_visa test card - Mirrors the pympp examples/stripe/ structure Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> Amp-Thread-ID: https://ampcode.com/threads/T-019d20a8-7850-76dc-a346-432e5d2f4f5f * chore: add changelog --------- Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-Authored-By: grandizzy <38490174+grandizzy@users.noreply.github.com>
Summary
Adds Stripe charge method support to mpp-rs via Shared Payment Tokens (SPTs), matching the mppx TS SDK wire format.
Changes
src/protocol/methods/stripe/—StripeMethodDetails(networkId/paymentMethodTypes/metadata under methodDetails),StripeCredentialPayload,CreateTokenResult, serverChargeMethodwith analytics metadata propagationsrc/client/stripe/—StripeProviderwithcreate_tokencallback receiving full challenge context, returningCreateTokenResult { spt, external_id }src/server/—stripe()builder,Mpp::create_stripe(),stripe_charge()/stripe_charge_with_options()tests/integration_stripe.rs— e2e tests with mock Stripe API (challenge schema, callback params, metadata, error paths)tests/integration_stripe_live.rs— live tests against Stripe test-mode API (real SPT creation + PaymentIntent verification), skipped whenSTRIPE_SECRET_KEYnot setSTRIPE_SECRET_KEYsecret is availableTesting
Co-Authored-By: grandizzy 38490174+grandizzy@users.noreply.github.com
Prompted by: georgen