Stripe payment method for one-time charges and recurring subscriptions.
The client creates a Shared Payment Granted Token (SPT) via Stripe, includes
it in the credential payload, and the server creates a PaymentIntent with
confirm: true to charge it immediately.
Configuration
Pass Stripe-specific config via :method_config in MPP.Plug opts:
plug MPP.Plug,
secret_key: "hmac-secret",
realm: "api.example.com",
method: MPP.Methods.Stripe,
amount: "5000",
currency: "usd",
method_config: %{
"stripe_secret_key" => "sk_test_...",
"network_id" => "profile_1Mqx...",
"payment_method_types" => ["card"]
}Config Keys
"stripe_secret_key"— (required) Stripe secret key for PaymentIntent creation"network_id"— (required) Stripe Business Network profile ID"payment_method_types"— (optional) accepted payment methods, defaults to["card"]"connect"— (optional) server-side Stripe Connect settlement policy (see below)"realm"— (optional, injected by Plug) server realm for analytics metadata
Stripe Connect settlement
Pass a "connect" map in method_config to route the resulting PaymentIntent
to a connected account (destination charge, direct charge, or application-fee
split). Connect settlement is a server-only credential — it is merged into
the charge at verify time and is never serialized into the public 402
challenge, matching the mppx reference (src/stripe/server/Charge.ts, where
connect is documented as "Not included in MPP challenges").
method_config: %{
"stripe_secret_key" => "sk_test_...",
"network_id" => "profile_1Mqx...",
"connect" => %{
# Destination charge: platform is merchant of record, funds routed on.
"transfer_data" => %{"destination" => "acct_seller", "amount" => 4000},
"application_fee_amount" => 500,
"on_behalf_of" => "acct_seller",
"transfer_group" => "order_42",
# Direct charge: run the PaymentIntent on the connected account itself.
"stripe_account" => "acct_seller"
}
}Wire mapping applied to the PaymentIntent (form-encoded), per the mppx reference:
"application_fee_amount"(integer) →application_fee_amount"on_behalf_of"(string) →on_behalf_of"transfer_data"%{"destination" => ..., "amount" => ...}→transfer_data[destination]/transfer_data[amount]"transfer_group"(string) →transfer_group"stripe_account"(string) →Stripe-Accountrequest header
Settlement is validated against the charge amount before the PaymentIntent is created: account ids must be non-empty, fee/transfer amounts must be non-negative integers not exceeding the payment amount.
Credential Payload
Charge credentials contain:
"spt"— (required) Stripe Shared Payment Granted Token (e.g.,"spt_1N4...")"externalId"— (optional) caller-provided correlation ID, echoed in receipt
Subscription credentials contain a required "paymentMethod" and an
optional existing "customer". Subscription activation follows the
constrained Stripe Billing profile in draft-stripe-subscription-00.
API Functions
| Function | Arity | Description | Param Kinds |
|---|---|---|---|
challenge_method_details | 1 | Return Stripe-specific fields (networkId, paymentMethodTypes) for the 402 challenge. | charge: value |
verify | 2 | Verify a Stripe SPT credential by creating a PaymentIntent with confirm: true. | payload: value, charge: value |
validate_config! | 1 | Validate Stripe method_config at init time. Raises on missing stripe_secret_key or network_id. | config: value |
credential_types | 0 | Return the Stripe charge payload types. Stripe uses SPT tokens, not typed hash payloads. | - |
method_name | 0 | Return the payment method identifier for Stripe. | - |
Summary
Functions
Return Stripe-specific fields (networkId, paymentMethodTypes) for the 402 challenge.
Return the Stripe charge payload types. Stripe uses SPT tokens, not typed hash payloads.
Return the payment method identifier for Stripe.
Validate Stripe method_config at init time. Raises on missing stripe_secret_key or network_id.
Verify a Stripe SPT credential by creating a PaymentIntent with confirm: true.
Functions
@spec challenge_method_details(MPP.Method.intent()) :: map() | nil
@spec challenge_method_details(MPP.Intents.Charge.t() | MPP.Intents.Subscription.t()) :: map() | nil
Return Stripe-specific fields (networkId, paymentMethodTypes) for the 402 challenge.
Parameters
charge- Charge struct with method_details containingnetwork_idand optionallypayment_method_types(value)
Returns
Map with networkId and paymentMethodTypes keys, or nil if no network_id configured (map_or_nil)
# descripex:contract
%{
params: %{
charge: %{
description: "Charge struct with method_details containing `network_id` and optionally `payment_method_types`",
kind: :value
}
},
returns: %{
type: :map_or_nil,
description: "Map with `networkId` and `paymentMethodTypes` keys, or `nil` if no `network_id` configured"
}
}
Return the Stripe charge payload types. Stripe uses SPT tokens, not typed hash payloads.
# descripex:contract
%{}
@spec method_name() :: String.t()
Return the payment method identifier for Stripe.
# descripex:contract
%{}
Validate Stripe method_config at init time. Raises on missing stripe_secret_key or network_id.
Parameters
config- method_config map to validate (value)
Returns
:ok on success, raises ArgumentError on missing keys (atom)
# descripex:contract
%{
params: %{
config: %{description: "method_config map to validate", kind: :value}
},
returns: %{
type: :atom,
description: "`:ok` on success, raises `ArgumentError` on missing keys"
}
}
@spec verify(map(), MPP.Intents.Charge.t() | MPP.Intents.Subscription.t()) :: {:ok, MPP.Receipt.t()} | {:error, MPP.Errors.t()}
Verify a Stripe SPT credential by creating a PaymentIntent with confirm: true.
Parameters
payload- Credential payload map containing"spt"(Stripe Shared Payment Granted Token) (value)charge- Charge intent struct with amount, currency, and method_details (includingstripe_secret_key) (value)
Returns
{:ok, receipt} on success, {:error, error} on failure (tagged_tuple)
Errors
:invalid_payload:verification_failed
# descripex:contract
%{
params: %{
payload: %{
description: "Credential payload map containing `\"spt\"` (Stripe Shared Payment Granted Token)",
kind: :value
},
charge: %{
description: "Charge intent struct with amount, currency, and method_details (including `stripe_secret_key`)",
kind: :value
}
},
errors: [:invalid_payload, :verification_failed],
returns: %{
type: :tagged_tuple,
description: "`{:ok, receipt}` on success, `{:error, error}` on failure"
}
}