PaymentIntent enrichment
Validate a canonical invoice and return enhanced commercial fields for your own Stripe PaymentIntent request.
On this page
Endpoint
POST /api/v1/stripe/payment-intent-enrichmentThe JSON body contains required invoice: CanonicalInvoice and optional options. A successful response is 200 with object: stripe.payment_intent_enrichment, api_version: v1, and the prepared Stripe fields in data. Read x-carden-request-id from the response header.
Canonical invoice fields
| Field | Type | Meaning |
|---|---|---|
invoiceNumber | string | Authoritative invoice identifier. |
purchaseOrderReference | string or null | Real source PO reference, if available. |
status | enum | draft, open, partially_paid, paid, void, uncollectible, or unknown. |
currency | string | Three-letter currency code. |
subtotalAmountMinor | nonnegative safe integer | Invoice subtotal before tax, shipping, and discounts. |
taxAmountMinor / shippingAmountMinor / discountAmountMinor | nonnegative safe integers | Invoice-level component totals, even when a component is zero. |
totalAmountMinor / balanceAmountMinor | nonnegative safe integers | Full invoice total and remaining balance. |
issuedAt / dueAt / voidedAt | ISO datetime or null | Source timestamps; retain null when absent. |
lineItems | array | Canonical lines in the shape below; enrichment supports 1–200 lines. |
All canonical properties are required, including nullable fields. Send null for an absent nullable fact, not an invented value. Objects use a strict schema; unsupported properties are rejected.
| Line field | Type / rule |
|---|---|
sequence | Unique nonnegative safe integer; output is ordered by sequence. |
productName | Nonempty product name; up to 1,024 characters for the Stripe transformer. |
description | String or null; preserve source description. |
productCode / commodityCode | String or null in the canonical model. Stripe enrichment requires productCode; commodityCode is optional. Transformer limit: 12 characters each. |
quantity | Decimal string in the canonical model; this transformer requires a positive safe integer string, such as "2". |
unitOfMeasure | String or null in the canonical model; required for enrichment, up to 12 characters. |
unitAmountMinor | Nonnegative safe integer unit price. |
subtotalAmountMinor / taxAmountMinor / discountAmountMinor / totalAmountMinor | Nonnegative safe integer line amounts that reconcile to the source invoice. |
Options
| Option | Behavior |
|---|---|
orderReference | Override with a real reference. Otherwise use purchaseOrderReference, then invoiceNumber. |
customerReference | Optional string or null; a real customer reference for payment_details. |
taxRepresentation | transaction (default) or line_item; selects where tax appears in the Stripe fields. |
discountRepresentation | transaction (default) or line_item; selects where discounts appear. |
shipping.fromPostalCode / shipping.toPostalCode | Optional strings or null; factual origin/destination postal codes, up to 10 characters. |
The adapter validates arithmetic and representation rather than repairing invoice facts. Line-item tax must reconcile to invoice tax when using line_item; the same applies to discounts. Avoid sending a second copy of the same tax or discount at another Stripe representation level.
Example request
This synthetic invoice totals USD 113.00: two USD 50.00 items, USD 8.00 tax, and USD 5.00 shipping. Example identifiers are not templates for missing merchant facts.
{
"invoice": {
"invoiceNumber": "INV-1042",
"purchaseOrderReference": "PO-2081",
"status": "open",
"currency": "USD",
"subtotalAmountMinor": 10000,
"taxAmountMinor": 800,
"shippingAmountMinor": 500,
"discountAmountMinor": 0,
"totalAmountMinor": 11300,
"balanceAmountMinor": 11300,
"issuedAt": null,
"dueAt": null,
"voidedAt": null,
"lineItems": [
{
"sequence": 1,
"productName": "Industrial filter",
"description": null,
"productCode": "FILTER-01",
"commodityCode": null,
"quantity": "2",
"unitOfMeasure": "each",
"unitAmountMinor": 5000,
"subtotalAmountMinor": 10000,
"taxAmountMinor": 800,
"discountAmountMinor": 0,
"totalAmountMinor": 10800
}
]
},
"options": {
"taxRepresentation": "line_item",
"discountRepresentation": "line_item"
}
}Example response
{
"object": "stripe.payment_intent_enrichment",
"api_version": "v1",
"data": {
"payment_details": {
"order_reference": "PO-2081"
},
"amount_details": {
"enforce_arithmetic_validation": true,
"line_items": [
{
"product_name": "Industrial filter",
"product_code": "FILTER-01",
"unit_cost": 5000,
"quantity": 2,
"unit_of_measure": "each",
"tax": {
"total_tax_amount": 800
}
}
],
"shipping": {
"amount": 500
}
}
}
}Merge only data into your supported Stripe PaymentIntent request. Retain responsibility for amount, currency, customer, payment method, confirmation, and Stripe idempotency. Confirm your account and Stripe API version accept these fields.
Validation and follow-up
- 400: invalid JSON or a body that does not match the strict v1 input contract.
- 422: a structurally valid invoice cannot produce valid Stripe enrichment; inspect field paths and issue codes.
- 401/403: fix Carden credentials, scopes, or context.
- 5xx/transport error: retain the request context and retry preparation under a bounded policy; preparation retries do not execute a payment.
Preserve the request ID as enrichmentRequestId when reporting the actual payment. Preparation success alone should never be recorded as a successful payment.