post_donations_org_checkout_session
Calls POST /api/donations/org-checkout-session as the signed-in person · REST reference
Create a Stripe Checkout session for a gift made on behalf of the caller's organization
Same body and same 201 shape as the public /create-checkout-session, with one difference that is a security property rather than a convenience - the organization credited is taken from the CALLER'S OWN first membership (req.user.organizations[0].orgId) and the request body is never consulted for it, so a member of one organization cannot attribute a gift to another. The org id rides payment_intent_data.metadata.org_id, because Stripe Checkout does not copy session metadata onto the PaymentIntent and the webhook is where the donation is written. A caller who belongs to no organization gets 400, since there would be nothing to attribute the gift to. A caller whose organization is a SERVICE PROVIDER gets 403 before any Checkout session exists - service providers are paid for their work and never donate. As with the public route, nothing is persisted here. amount is in DOLLARS, not cents.
Arguments
| Argument | Type | Description | |
|---|---|---|---|
bodyJSON | object | required | The request body, as a JSON object. Its fields are listed below. |
Fields of body
| Field | Type | Description | |
|---|---|---|---|
amount | number | required | Gift amount in DOLLARS, not cents. Must be greater than zero. |
anonymity | "NAMED" | "ANONYMOUS" | "FULLY_ANONYMOUS" | ||
coverProcessingFees | boolean | ||
donorInfo | object | Required unless anonymity is FULLY_ANONYMOUS. | |
donorInfo.address | string | ||
donorInfo.city | string | ||
donorInfo.email | string (email) | ||
donorInfo.name | string | ||
donorInfo.phone | string | ||
donorInfo.zipCode | string | ||
recurring | boolean | ||
recurringInterval | "DAILY" | "WEEKLY" | "MONTHLY" | "ANNUAL" | ||
recurringRule | string | An RRULE string, the advanced alternative to recurringInterval. |
Example call
A client sends this over the MCP session; Claude and other agents build it for you. The values are placeholders — the shape is real.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "post_donations_org_checkout_session",
"arguments": {
"body": {
"amount": 1,
"anonymity": "NAMED",
"coverProcessingFees": false,
"donorInfo": {
"address": "string",
"city": "string",
"email": "name@example.org",
"name": "string",
"phone": "string",
"zipCode": "string"
},
"recurring": false,
"recurringInterval": "DAILY",
"recurringRule": "string"
}
}
}
}Result
On success (HTTP 201) the tool returns one text item holding the API's JSON, pretty-printed.
Checkout session created. Redirect the browser to url.
{
"sessionId": "string",
"url": "https://example.org"
}Fields
| Field | Type | Description |
|---|---|---|
sessionId | string | |
url | string (uri) |
When it fails
A failed call returns isError: true with the API's message as text. A change the person declines, or lets time out, also comes back this way and nothing changes.
400The request was malformed or failed a guard.
403The caller's organization is a SERVICE PROVIDER, which never donates; or a donor-realm credential was presented at a platform endpoint (
authenticateanswers 403 rather than 401 because the identity is established, just in the wrong realm).
What the model is shown
This is the tool exactly as the server lists it in tools/list. The description starts with the REST call it makes.
{
"name": "post_donations_org_checkout_session",
"description": "POST /api/donations/org-checkout-session — Same body and same 201 shape as the public /create-checkout-session, with one difference that is a security property rather than a convenience - the organization credited is taken from the CALLER'S OWN first membership (req.user.organizations[0].orgId) and the request body is never consulted for it, so a member of one organization cannot attribute a gift to another. The org id rides payment_intent_data.metadata.org_id, because Stripe Checkout does not copy session metadata onto the PaymentIntent and the webhook is where the donation is written. A caller who belongs to no organization gets 400, since there would be nothing to attribute the gift to. A caller whose organization is a SERVICE PROVIDER gets 403 before any Checkout session exists - service providers are paid for their work and never donate. As with the public route, nothing is persisted here. `amount` is in DOLLARS, not cents.\n\nThis changes data. The person is asked to confirm it before it runs, and nothing happens if they decline.",
"inputSchema": {
"type": "object",
"properties": {
"body": {
"type": "string",
"description": "The JSON request body: { amount*: number (Gift amount in DOLLARS, not cents.); anonymity: one of \"NAMED\" | \"ANONYMOUS\" | \"FULLY_ANONYMOUS\"; coverProcessingFees: boolean; donorInfo: { address: string; city: string; email: string; name: string; phone: string; zipCode: string } (Required unless anonymity is FULLY_ANONYMOUS.); recurring: boolean; recurringInterval: one of \"DAILY\" | \"WEEKLY\" | \"MONTHLY\" | \"ANNUAL\"; recurringRule: string (An RRULE string, the advanced alternative to recurringInterval.) }"
}
},
"required": [
"body"
]
},
"annotations": {
"readOnlyHint": false,
"destructiveHint": true,
"idempotentHint": false,
"openWorldHint": false
}
}