Gateman
Documentation/Use Stripe

Use Stripe

capability_id: stripe.use
display_name: Use Stripe
ui_capability_key: use_stripe
scope: stripe:use
endpoint:
  method: POST
  path: /stripe/request
operation: stripe.request
billable: true
environments:
  - production
  - staging
  - development

Purpose and authorization

stripe.use authorizes an authenticated, application-scoped relay for native Stripe API requests. The application must use Contract v1 and have the stripe:use scope.

Gateman selects the configured Stripe secret for the requested application environment, sends the authorized request to Stripe, returns the provider's status and response subject to this transport contract, and accounts for the admitted Gateman operation. Gateman does not return the selected Stripe credential to the application.

This is a native API relay, not a general payment-processing abstraction. It does not independently manage payment lifecycles, reconcile orders, track generic Stripe transactions, or confirm final payment status. Stripe API permissions remain authoritative; Gateman does not restrict the relay to a predefined set of payment business workflows beyond its request contract.

Implementation contract

The outer request is an authenticated Gateman request. Its JSON body contains the nested native Stripe request. The outer request is not itself sent to Stripe as the provider body.

POST /stripe/request
Content-Type: application/json
X-GM-App: app_...
X-GM-Ts: 1710000000
X-GM-Sig: <Contract-v1-signature>
X-GM-Idempotency-Key: optional-gateman-key

The request body is:

{
  "environment": "production",
  "method": "POST",
  "path": "/v1/payment_intents",
  "body": {
    "amount": 1000,
    "currency": "usd"
  },
  "headers": {
    "Idempotency-Key": "order-123"
  }
}

Request envelope

FieldRequiredContract
environmentYesString, trimmed and lowercased; must be production, staging, or development.
methodNoString; defaults to POST; supported values are GET, POST, and DELETE, case-insensitively.
pathYesString satisfying the native Stripe path rules below.
bodyNoString or array; defaults to an empty string.
headersNoObject/map of supported caller-provided Stripe headers; defaults to empty.

Unknown top-level envelope fields are ignored by the current validator. An integration should send only the documented fields. environment is required even when the selected Stripe request itself does not vary by environment.

Invalid JSON, a missing or unsupported environment, an unsupported method, an invalid path, an invalid body type or size, and invalid headers are rejected before the provider request. The route does not add a separate general JSON envelope-size limit to this capability.

Native Stripe request forwarding

Gateman uses the fixed provider origin https://api.stripe.com. The caller supplies a relative native Stripe path; it cannot select another host.

Supported native methods are GET, POST, and DELETE. PUT and PATCH are not supported. The path:

  • must begin with /v1/;
  • must be at most 2,048 bytes;
  • may include a query string;
  • must not contain spaces or other control characters, #, <, >, ", backslashes, .., or //; and
  • must not contain a scheme or host.

Gateman does not provide a general multipart or file-upload contract, a public streaming-response contract, arbitrary provider hosts, pagination, payment orchestration, or a universal Stripe SDK wrapper. The relay supports only Stripe operations representable through these allowed methods, paths, headers, and body transport rules. A reachable Stripe path is not a separate Gateman capability identifier.

Native body serialization

The nested body is converted into the body sent to Stripe:

  • A string is forwarded unchanged.
  • An array is serialized as URL-encoded parameters using RFC 3986 encoding.
  • Nested arrays and objects use PHP/Stripe-style bracket notation, such as items[0][price]=price_....
  • Boolean values serialize as 1 and 0.
  • Null array values are omitted by the URL-encoding serializer.
  • An omitted or JSON null body becomes an empty string.
  • Other scalar body types are invalid.
  • The serialized body must be no larger than 4 MiB (4,194,304 bytes).
  • When a non-empty body has no caller-supplied Content-Type, Gateman sends application/x-www-form-urlencoded.
  • A caller-supplied valid Content-Type is preserved.

This distinguishes three values: the outer JSON envelope, the nested Stripe body value, and the encoded content sent to Stripe. The nested body is not an arbitrary JSON payload forwarded unchanged. Stripe remains responsible for validating native Stripe parameters.

Native request headers

The caller may provide these nested headers entries:

  • Idempotency-Key: Stripe's native idempotency key for an eligible request.
  • Stripe-Account: Stripe Connect account selection, subject to Stripe's account and credential permissions.
  • Stripe-Version: a native Stripe API version for this request.
  • Content-Type: the content type for the serialized nested body.

Header names are matched case-insensitively. Values must be strings of no more than 512 bytes and must not contain carriage returns or line feeds. Gateman constructs the Stripe Authorization: Bearer ... header from the configured application-scoped secret; callers cannot override that credential through the nested headers. Gateman does not independently validate Connect authorization beyond its relay controls and does not transform every request to one pinned Stripe API version.

Environment and credential selection

Gateman environmentCredential selectedProvider execution
productionConfigured Stripe live secretReal Stripe API request using the configured live secret.
stagingConfigured Stripe test secretReal Stripe API request using the configured test secret.
developmentConfigured Stripe test secretReal Stripe API request using the configured test secret.

Staging and development are not local capture or simulation modes. A request in either environment reaches Stripe's real API endpoint and can create or modify Stripe test-mode resources. Gateman selects the configured credential; it does not independently guarantee that the effective Stripe mode matches an environment label.

Response contract and limits

For a response within the transport limit, Gateman preserves Stripe's original HTTP status and response body. It forwards only these provider response headers, when present:

  • Content-Type
  • Request-Id
  • Idempotency-Key
  • Stripe-Version
  • Retry-After

Gateman does not wrap every Stripe response in an ok JSON envelope. Stripe HTTP 4xx and 5xx responses remain native Stripe responses when their bodies are within the limit. The four official clients may expose or decode these responses differently; this relay does not promise universal compatibility with every Stripe SDK response transport.

Decoded response-body limit

The maximum decoded Stripe response body is 4 MiB (4,194,304 bytes). The limit is measured after HTTP content decompression and applies regardless of Stripe's HTTP status.

A body of exactly 4,194,304 bytes is accepted. A body exceeding the limit is rejected while it is being received, before complete response materialization; Gateman does not return a partial provider response. The caller receives:

HTTP/1.1 502 Bad Gateway
Content-Type: application/json; charset=utf-8
{
  "ok": false,
  "error": "stripe_response_too_large"
}

This is a Gateman-generated transport error, not a native Stripe error. The failure to return Stripe's body does not establish that Stripe did not execute the requested operation. It is therefore not a safe-to-retry signal by itself.

Retry-After

When Stripe supplies Retry-After, Gateman forwards the original value. It does not synthesize the header when Stripe omits it, reinterpret its value, or automatically retry the request. A Gateman-generated provider-concurrency rejection may independently return Retry-After; that is distinct from a Stripe-generated response header.

Idempotency and retry obligations

The two idempotency headers have different meanings.

X-GM-Idempotency-Key

This optional outer Gateman header is included in Contract v1 signing when supplied. For stripe.use, it does not cache a response, deduplicate relay invocations, or prevent another Stripe request. It must not be treated as a Stripe idempotency mechanism.

Native Stripe Idempotency-Key

This nested header is forwarded to Stripe and is interpreted according to Stripe's own idempotency contract. Use it where Stripe supports provider-side duplicate protection for the selected mutation. Gateman does not generate it, cache prior Stripe responses, or automatically retry Stripe requests.

The official PHP, Node.js, Python, and Go clients do not automatically retry Stripe requests. A repeated Gateman invocation can reach Stripe again and can consume another Gateman operation, even when Stripe returns a previously retained idempotent result.

After a timeout, transport failure, oversized response, or other missing or indeterminate provider response, the application must not assume that Stripe did not execute the request. Do not blindly retry a mutation. Use a stable Stripe-native idempotency key and the application's reconciliation policy when the selected Stripe operation supports it; idempotency does not make every Stripe request or every retry safe.

See Idempotency for shared Contract v1 mechanics.

Operation accounting and concurrency

The billable operation is stripe.request. One operation is reserved for one admitted Gateman relay invocation. Validation and provider-concurrency admission occur before reservation; credential lookup and Stripe execution follow reservation.

After reservation, a provider HTTP 4xx/5xx response, Stripe rate-limit response, transport failure, uncertain outcome, or oversized response consumes the already reserved operation. A call rejected before reservation does not consume one. Gateman does not replay a prior Stripe response.

Provider-bound concurrency admission can reject a request with HTTP 429 and an applicable Retry-After header. If the guard is unavailable, Gateman returns HTTP 503. These Gateman admission responses are distinct from Stripe's own rate limits. Application-level admission controls and the monthly operation allowance also apply. A monthly allowance rejection is HTTP 403; accounting unavailability is HTTP 503.

Operation usage is not Stripe processing fees, Stripe API rate limiting, or Stripe's native idempotency behavior. See Operation Accounting and Rate limits and concurrency.

Errors and uncertain outcomes

ConditionHTTP responseOperation consequence and handling
Contract v1 authentication failure401Rejected before capability execution; no operation. Follow the authentication and signature contract.
Missing stripe:use scope401Rejected before capability execution; no operation.
Invalid JSON400Rejected before reservation; no operation.
Invalid environment400Rejected before reservation; no operation.
Invalid method, path, body, or headers400Rejected before reservation; no operation.
Application admission rejection429Gateman admission failure; no operation for the rejected request.
Provider-concurrency rejection429, with Retry-After when applicableRejected before reservation; no operation.
Provider-concurrency guard unavailable503Rejected before reservation; no operation.
Monthly operation allowance exhausted403No new operation is reserved.
Operation accounting unavailable503No confirmed operation is reserved. Do not assume an external request occurred.
Stripe credential missing after reservation502Reserved operation is finalized as failed. No Stripe execution is established.
Native Stripe HTTP error within the limitStripe's native statusReserved operation is consumed; preserve and interpret Stripe's status/body.
Provider transport failure502Reserved operation is consumed; execution may be uncertain. Do not blindly retry mutations.
Decoded response exceeds 4 MiB502, stripe_response_too_largeReserved operation is consumed; Stripe execution is uncertain and no partial body is returned.
Unexpected Gateman failureShared Gateman error, normally 500Treat as an error and do not infer that Stripe did not execute an admitted request.

The exact shared authentication, response headers, and error envelope are defined by Errors and responses and Authentication.

Payment and webhook responsibility boundaries

stripe.use is an API relay. It does not independently:

  • confirm that a payment settled;
  • track arbitrary PaymentIntents or other Stripe resources;
  • reconcile orders or mark purchases completed;
  • manage browser payment-method collection;
  • maintain a generic subscription state machine; or
  • guarantee delivery of Stripe webhook events.

A successful Stripe API request is not necessarily a final successful payment. The application must interpret the selected Stripe resource's native status and event model.

Stripe webhook configuration is separate from this relay. Gateman has separate customer-facing routes for reading an eligible webhook secret (POST /stripe/webhook-secret, scope stripe:webhook:read) and creating or updating a Stripe endpoint for a customer's HTTPS callback (POST /stripe/webhook/setup, scope stripe:webhook:write). Gateman does not receive customer Stripe events through /stripe/request, and stripe.use does not automatically provision a webhook. The customer callback application receives, verifies, and processes its Stripe events; see Webhooks and event handling.

The internal platform-billing webhook is not part of this customer capability.

WordPress integration

The Gateman WordPress plugin provides higher-level Stripe payment behavior for supported commerce integrations, including WooCommerce, Easy Digital Downloads, and FluentCart. Those integrations add checkout and payment- completion behavior that must not be attributed to the generic stripe.use relay. WordPress integration documentation is separate from this capability reference.

Implementation outcome

An independently correct Use Stripe integration:

  • authenticates with Contract v1 and the stripe:use scope;
  • expresses the intended native Stripe operation through the allowed method, /v1/ path, body, and header contract;
  • selects the intended Gateman environment and configured provider secret;
  • represents native Stripe parameters using the actual form serializer;
  • forwards supported native headers, including an explicitly selected Stripe account or API version;
  • interprets Stripe's status and body without assuming a common ok envelope;
  • uses Stripe-native idempotency where repeat-execution safety matters;
  • distinguishes Gateman admission failures from provider responses;
  • does not interpret an oversized or indeterminate response as proof that Stripe did nothing; and
  • understands that each admitted invocation is one stripe.request operation, not a final payment-completion result.

Implementation instructions for agents

  • SHOULD use one of the official PHP, Node.js, Python, or Go Gateman clients where appropriate. A direct HTTP implementation MUST follow Contract v1.
  • The integration MUST use the stripe:use scope and target POST /stripe/request.
  • It MUST provide environment as production, staging, or development and MUST represent the native method, /v1/ path, body, and supported headers according to this contract.
  • It MUST NOT assume that an array body is sent as JSON; arrays are serialized as URL-encoded Stripe parameters with bracket notation.
  • It MUST use Stripe-native Idempotency-Key when provider-side idempotency is needed. It MUST NOT treat X-GM-Idempotency-Key as Stripe relay deduplication.
  • It MUST interpret native provider statuses and error bodies correctly and MUST distinguish Stripe-generated responses from Gateman-generated admission and transport errors.
  • It MUST handle HTTP 502 stripe_response_too_large as an uncertain provider-execution outcome and MUST NOT blindly retry a potentially executed mutation.
  • It MUST account for one stripe.request operation per admitted relay invocation, including provider errors, transport failures, and oversized responses.
  • It MUST NOT assume Gateman provides final payment-state reporting, a universal webhook receiver, or automatic webhook provisioning.
  • It MUST preserve the customer's explicitly selected Stripe API version and connected-account behavior where configured.
  • It MUST NOT alter Stripe credentials, webhook configuration, or payment workflow without authorization.

Reusable AGENTS.md block

<!-- gateman:begin capability=stripe.use -->
- Use authenticated Contract v1 with the `stripe:use` scope and target
  `POST /stripe/request`.
- Include `environment`: `production` uses the configured Stripe live secret;
  `staging` and `development` use the configured Stripe test secret and still
  call Stripe's real API.
- Use only `GET`, `POST`, or `DELETE` with a `/v1/` Stripe path. Gateman uses
  the fixed Stripe API origin and does not support arbitrary hosts, `PUT`,
  `PATCH`, or a general multipart/file-upload contract.
- Represent the native request body as a string or array in the envelope.
  Arrays become URL-encoded Stripe parameters with bracket notation; they are
  not sent as JSON. The serialized outbound Stripe request body is limited to
  4 MiB (4,194,304 bytes).
- Use only supported nested headers: `Idempotency-Key`, `Stripe-Account`,
  `Stripe-Version`, and `Content-Type`. Gateman supplies Stripe bearer
  authorization from the configured application credential.
- Use Stripe-native `Idempotency-Key` for provider-side duplicate protection
  where appropriate. Do not treat `X-GM-Idempotency-Key` as Stripe relay
  deduplication. Official clients do not automatically retry.
- Account for one `stripe.request` operation per admitted invocation, including
  provider errors, transport failures, and oversized responses.
- A decoded Stripe response body of exactly 4 MiB is accepted. A larger body
  returns HTTP 502 `stripe_response_too_large` without a partial body; this is
  an uncertain provider-execution outcome and is not a safe-to-retry signal.
- Preserve and interpret Stripe's native status and body. `Retry-After` is
  forwarded only when Stripe supplies it; Gateman does not synthesize it or
  retry automatically.
- Do not assume a successful relay means final payment completion. Webhook
  provisioning, event receipt, payment reconciliation, and WordPress checkout
  behavior are separate responsibilities.
- Full capability reference: https://docs.getgateman.com/capabilities/stripe.use/
<!-- gateman:end capability=stripe.use -->