{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/growsurf-com/json-schema/growsurf-com-record-transaction-request-schema.json",
  "title": "RecordTransactionRequest",
  "description": "To record a Stripe, Chargebee or Recurly payment, supply `paymentProvider`, `testMode`, and the provider's payment `transactionId`. For Stripe, use a Charge ID (`ch_...`) or PaymentIntent ID (`pi_...`); both identify the same captured payment. The integration must be enabled in that mode. `grossAmount`, `currency`, and any supplied `paidAt` must match the provider payment. Other payment identifiers and tax or net-amount overrides are not accepted for provider payments. GrowSurf reads those payment details from the connected account. The provider customer must match the participant's email or stored provider identity. Webhook, API, and manual submissions for the same provider payment are treated as duplicates. Omit `paymentProvider` and `testMode` to record a sale using your own transaction details.",
  "x-generated": "2026-11-10",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/growsurf-com-openapi.json#/components/schemas/RecordTransactionRequest",
  "type": "object",
  "required": [
    "currency",
    "grossAmount"
  ],
  "properties": {
    "paymentProvider": {
      "description": "Connected payment provider. Requires `transactionId` and an explicit `testMode`.",
      "type": "string",
      "enum": [
        "stripe",
        "chargebee",
        "recurly"
      ]
    },
    "testMode": {
      "description": "`true` for the provider's test account or `false` for its live account. Required when `paymentProvider` is supplied; otherwise omit this field.",
      "type": "boolean"
    },
    "currency": {
      "description": "3-letter ISO 4217 currency code for the sale. Must match the program currency.",
      "type": "string",
      "minLength": 3,
      "maxLength": 3,
      "pattern": "^[A-Za-z]{3}$"
    },
    "grossAmount": {
      "description": "Total sale amount in the currency's minor unit. Must be a positive integer.",
      "type": "integer",
      "minimum": 1
    },
    "netAmount": {
      "description": "Net-of-tax sale amount in the currency's minor unit. Used as the commissionable base when supplied.",
      "type": "integer",
      "minimum": 0
    },
    "taxAmount": {
      "description": "Tax collected in the currency's minor unit. Used to derive the commissionable base when `netAmount` is absent.",
      "type": "integer",
      "minimum": 0
    },
    "amountCashNet": {
      "description": "Explicit post-tax cash amount in the currency's minor unit. Overrides derived net amounts.",
      "type": "integer",
      "minimum": 0
    },
    "amountPaid": {
      "description": "Amount actually paid in the currency's minor unit, when reported by your payment processor.",
      "type": "integer",
      "minimum": 0
    },
    "paidAt": {
      "description": "When the payment was captured or settled, as a Unix timestamp in milliseconds.",
      "type": "integer",
      "format": "int64"
    },
    "externalId": {
      "description": "Primary transaction identifier from your billing system. Used to detect duplicate submissions.",
      "type": "string",
      "maxLength": 500
    },
    "transactionId": {
      "description": "Transaction identifier to store for this sale. Used to detect duplicate submissions.",
      "type": "string",
      "maxLength": 500
    },
    "customerId": {
      "description": "Customer record identifier, such as a payment-provider customer ID.",
      "type": "string",
      "maxLength": 500
    },
    "orderId": {
      "description": "Order identifier. Used to detect duplicate submissions when supplied.",
      "type": "string",
      "maxLength": 500
    },
    "paymentId": {
      "description": "Payment identifier. Used to detect duplicate submissions when supplied.",
      "type": "string",
      "maxLength": 500
    },
    "invoiceId": {
      "description": "Invoice identifier. Used to detect duplicate submissions when supplied.",
      "type": "string",
      "maxLength": 500
    },
    "subscriptionId": {
      "description": "Subscription identifier for recurring payments.",
      "type": "string",
      "maxLength": 500
    },
    "paymentIntentId": {
      "description": "Payment intent identifier. Used to detect duplicate submissions when supplied.",
      "type": "string",
      "maxLength": 500
    },
    "chargeId": {
      "description": "Charge identifier. Used to detect duplicate submissions when supplied.",
      "type": "string",
      "maxLength": 500
    },
    "description": {
      "description": "Freeform sale description shown in dashboard context and reports.",
      "type": "string",
      "maxLength": 500
    },
    "invoiceTotal": {
      "description": "Invoice total including tax, in the currency's minor unit.",
      "type": "integer",
      "minimum": 0
    },
    "invoiceTotalExcludingTax": {
      "description": "Invoice total excluding tax, in the currency's minor unit.",
      "type": "integer",
      "minimum": 0
    },
    "invoiceSubtotalExcludingTax": {
      "description": "Invoice subtotal excluding tax, in the currency's minor unit.",
      "type": "integer",
      "minimum": 0
    },
    "totalTaxAmount": {
      "description": "Aggregate tax amount in the currency's minor unit.",
      "type": "integer",
      "minimum": 0
    },
    "totalTaxAmounts": {
      "description": "Detailed tax breakdown objects from your payment processor.",
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": true
      }
    },
    "totalTaxes": {
      "description": "Alternate detailed tax breakdown objects from your payment processor.",
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": true
      }
    }
  }
}