Stripe enrichment API
Validate an inline canonical invoice and return commercial fields for a merchant-owned Stripe PaymentIntent request.
On this page
Prepare inline Stripe fields
POST /api/v1/stripe/payment-intent-enrichmentThe strict JSON body contains required invoice: CanonicalInvoice and optional options. Success returns 200 with object: stripe.payment_intent_enrichment, api_version: v1, and prepared Stripe fields in data. Read x-carden-request-id for diagnostics.
This inline contract requires enrichment:write but no QuickBooks link or invoices:read. When QuickBooks is linked, POST /api/v1/stripe/payment-intent-enrichment/from-invoice accepts an exact stored-invoice selector and returns separate immutable preparation metadata.
Canonical invoice fields
| Field | Rule |
|---|---|
| invoiceNumber | Required authoritative invoice identifier. |
| purchaseOrderReference | Real source PO reference or null. |
| status | draft, open, partially_paid, paid, void, uncollectible, or unknown. |
| currency | Required three-letter currency code. |
| subtotalAmountMinor / taxAmountMinor / shippingAmountMinor / discountAmountMinor | Required nonnegative safe integers, including zero. |
| totalAmountMinor / balanceAmountMinor | Required nonnegative safe integers that reconcile to source economics. |
| issuedAt / dueAt / voidedAt | ISO datetime or null; retain null when absent. |
| lineItems | One to 200 canonical lines for the Stripe transformer. |
Every canonical property is required, including nullable fields. Send null for an absent nullable fact rather than inventing a value. Objects use strict schemas and unsupported properties are rejected.
| Line field | Type and adapter rule |
|---|---|
| sequence | Unique nonnegative safe integer; output follows source sequence. |
| productName / description | Nonempty name and factual description or null. |
| productCode / commodityCode | Canonical nullable strings. Stripe requires productCode; each transformer value is at most 12 characters and commodityCode is alphanumeric. |
| quantity | Canonical decimal string; this adapter currently requires a positive safe-integer string. |
| unitOfMeasure | Required 1–12 letters or numbers for Stripe enrichment. |
| unitAmountMinor / subtotalAmountMinor / taxAmountMinor / discountAmountMinor / totalAmountMinor | Nonnegative safe integers that reconcile to the source invoice. |
Choose factual representation options
| Option | Behavior |
|---|---|
| orderReference | Real override; otherwise purchaseOrderReference then invoiceNumber. |
| customerReference | Optional real customer reference or null. |
| taxRepresentation | transaction by default or line_item; controls where tax is represented. |
| discountRepresentation | transaction by default or line_item; controls where discounts are represented. |
| shipping.fromPostalCode / shipping.toPostalCode | Optional factual postal codes, up to 10 letters, numbers, or hyphens. |
The adapter validates arithmetic and representation rather than repairing invoice facts. Line-item tax and discounts must reconcile to invoice totals when selected, and the same amount must not be represented twice.
Example request
The synthetic invoice totals USD 113.00: two USD 50.00 items, USD 8.00 tax, and USD 5.00 shipping. Example identifiers are never 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 a supported Stripe PaymentIntent request. The merchant backend remains responsible for amount, currency, customer, payment method, confirmation, Stripe idempotency, and current account/API-version support.
Recheck Stripe's payment-line-item requirements for current geography, card product, merchant category, field, and program eligibility before production use.
Validation and follow-up
- 400 means invalid JSON or a body outside the strict v1 contract.
- 422 means the structured invoice cannot produce valid Stripe enrichment; inspect issue paths and codes.
- 401 or 403 requires correcting Carden authentication, scope, or context.
- A transport or 5xx failure permits a bounded preparation retry because preparation never executes a payment.
For inline preparation, preserve the response request ID as enrichmentRequestId when available. Source-backed preparation instead uses stable preparation.id. Reporting-only callers omit the field.