{
  "openapi": "3.2.0",
  "info": {
    "title": "Receipt Service API",
    "description": "The Receipt Service generates and delivers branded payment receipts.\n\n## Key Concepts\n\n### Two Receipt Types\n- **Invoice-Based**: Payment applied to one or more invoices\n- **Payment-Only**: Standalone payment (e.g., one-time service fee) with no invoices\n\n### Receipt Generation\n- Branded with merchant configuration using Liquid templates\n- Delivered via email through OSI Push Notification Service\n- MVP: HTML rendering on-demand (PDF generation and S3 storage are post-MVP)\n\n## Error Handling\n\nAll API responses use HTTP status 200. Success and failure are expressed in the NPS response envelope.\n- `responseCode` **A100** indicates success; the payload is in the `object` field when present.\n- `responseCode` values **E4xx** (and **E500**) indicate errors; `responseMessage` carries details.\n- **E422** (**VALIDATION_ERROR**) is returned for standard request validation failures.\n\nAdditional application error codes include **E400_VALIDATION** (request validation failure, for example malformed `entityId`), **E403_ACCESS** (caller lacks permission for the requested resource), and **E403_TENANT** (entity ID is outside the caller's hierarchy).\n\n**Exception to HTTP 200 convention:** Requests with a syntactically invalid `entityId` (non-numeric or negative) receive HTTP 400 with a minimal JSON body (`responseCode: \"E400_VALIDATION\"`) before reaching the application layer. This is enforced by the tenant isolation interceptor and does not use the standard NPS envelope.\n\n**Null field omission:** Success and error responses use `@JsonInclude(NON_NULL)`. Fields with null values (including `object` on void successes and `responseDetails` when absent) are omitted from the JSON response rather than serialized as explicit `null`.\n\n## Authentication Note\n\nOpenAPI security schemes in this specification reference OAuth2 for documentation tooling compatibility.\nIn deployed environments, all service-to-service authentication uses S2S JWT (signed JWTs from the hierarchy key tree).\n",
    "version": "1.0.0",
    "contact": {
      "name": "NPS Platform Team"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://www.nps.com/license"
    }
  },
  "servers": [
    {
      "url": "https://api.nelnetpay.com/receipts",
      "description": "Production server"
    },
    {
      "url": "https://api.uat.nelnetpay.com/receipts",
      "description": "Staging server"
    }
  ],
  "tags": [
    {
      "name": "Receipts",
      "summary": "Payment receipts",
      "description": "Generate and manage payment receipts"
    },
    {
      "name": "Configuration",
      "description": "Per-merchant receipt configuration stored locally by the Receipt Service"
    },
    {
      "name": "Templates",
      "description": "Liquid template management for receipt and email rendering.\nMerchants can use built-in system templates (standard, detailed, compact) or upload\ncustom Liquid templates. Templates control the layout and content of rendered receipts\nand notification emails.\n"
    }
  ],
  "paths": {
    "/": {
      "get": {
        "tags": [
          "Receipts"
        ],
        "summary": "List Receipts",
        "description": "List all receipts for the authenticated merchant",
        "operationId": "listReceipts",
        "parameters": [
          {
            "$ref": "#/components/parameters/EntityIdQuery"
          },
          {
            "$ref": "#/components/parameters/PersonIdFilter"
          },
          {
            "$ref": "#/components/parameters/ReceiptStatusFilter"
          },
          {
            "$ref": "#/components/parameters/CreatedAtFromFilter"
          },
          {
            "$ref": "#/components/parameters/CreatedAtToFilter"
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/PageSizeParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWrappedReceiptList"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      },
      "post": {
        "tags": [
          "Receipts"
        ],
        "summary": "Create Receipt",
        "description": "Create a new receipt for a payment.\n\n**Called by:**\n- Invoice Service after payment application\n- Payment Widget for payment-only flows\n\n**Invoice-Based Receipt:**\nInclude `invoices` array with invoice details.\n\n**Payment-Only Receipt:**\nOmit `invoices` array or pass empty array.\n",
        "operationId": "createReceipt",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateReceiptRequest"
              },
              "examples": {
                "invoiceBased": {
                  "summary": "Invoice-based receipt",
                  "value": {
                    "personId": "550e8400-e29b-41d4-a716-446655440012",
                    "payment": {
                      "paymentId": "pay_abc123",
                      "transactionId": "txn_xyz789",
                      "amount": 250,
                      "paymentMethod": "CARD",
                      "lastFour": "4242",
                      "processedAt": "2026-01-20T10:30:00Z"
                    },
                    "invoices": [
                      {
                        "invoiceId": "550e8400-e29b-41d4-a716-446655440060",
                        "invoiceNumber": "INV-2026-00001",
                        "amountApplied": 250
                      }
                    ],
                    "sendOptions": {
                      "send": true
                    }
                  }
                },
                "paymentOnly": {
                  "summary": "Payment-only receipt",
                  "value": {
                    "person": {
                      "name": "John Doe",
                      "email": "john.doe@example.com"
                    },
                    "payment": {
                      "paymentId": "pay_def456",
                      "transactionId": "txn_abc123",
                      "amount": 50,
                      "paymentMethod": "CARD",
                      "lastFour": "1234",
                      "processedAt": "2026-01-20T11:00:00Z"
                    },
                    "description": "Processing fee",
                    "sendOptions": {
                      "send": true
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Receipt created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWrappedReceipt"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      }
    },
    "/{receiptId}": {
      "get": {
        "tags": [
          "Receipts"
        ],
        "summary": "Get Receipt Details",
        "description": "Retrieve details of a specific receipt",
        "operationId": "getReceipt",
        "parameters": [
          {
            "$ref": "#/components/parameters/EntityIdQuery"
          },
          {
            "$ref": "#/components/parameters/ReceiptId"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWrappedReceipt"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      }
    },
    "/{receiptId}/html": {
      "get": {
        "tags": [
          "Receipts"
        ],
        "summary": "Get Receipt HTML",
        "description": "Generate and return the receipt as HTML for browser viewing.\n\nHTML is generated on-demand using the merchant's active Liquid receipt template\nwith branding (logo, colors, merchant name) applied. If no custom template is\nconfigured, the built-in system template is used.\n",
        "operationId": "getReceiptHtml",
        "parameters": [
          {
            "$ref": "#/components/parameters/EntityIdQuery"
          },
          {
            "$ref": "#/components/parameters/ReceiptId"
          }
        ],
        "responses": {
          "200": {
            "description": "HTML document",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      }
    },
    "/{receiptId}/resend": {
      "post": {
        "tags": [
          "Receipts"
        ],
        "summary": "Resend Receipt",
        "description": "Resend a receipt notification to the original recipient, optionally with updated delivery options.\n\n**Delivery channels:** Only `EMAIL` is supported today. The `channels` array accepts at most one value.\n",
        "operationId": "resendReceipt",
        "parameters": [
          {
            "$ref": "#/components/parameters/ReceiptId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "entityId"
                ],
                "properties": {
                  "entityId": {
                    "type": "integer",
                    "format": "int64",
                    "description": "Merchant/tenant identifier for tenant isolation"
                  },
                  "emailAddresses": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "email"
                    }
                  },
                  "channels": {
                    "type": "array",
                    "description": "Delivery channels for this resend. Accepts at most one value (matches server validation).\nOnly EMAIL is currently supported.\n",
                    "maxItems": 1,
                    "items": {
                      "type": "string",
                      "enum": [
                        "EMAIL"
                      ],
                      "description": "Delivery channel; only EMAIL is supported currently"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Receipt resent successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWrappedReceipt"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      }
    },
    "/{receiptId}/pdf": {
      "get": {
        "x-todo": "PDF download implementation is planned but not yet available.",
        "tags": [
          "Receipts"
        ],
        "summary": "Get Receipt PDF (Post-MVP)",
        "description": "**Post-MVP.** Download the receipt as a PDF document.\nPDF generation and S3 storage are not included in the MVP release.\n",
        "operationId": "getReceiptPdf",
        "parameters": [
          {
            "$ref": "#/components/parameters/EntityIdQuery"
          },
          {
            "$ref": "#/components/parameters/ReceiptId"
          }
        ],
        "responses": {
          "200": {
            "description": "PDF document",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                },
                "example": "attachment; filename=\"RCP-2026-00001.pdf\""
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      }
    },
    "/{receiptId}/deliveries": {
      "post": {
        "tags": [
          "Receipts"
        ],
        "summary": "Create Receipt Delivery",
        "description": "Send or resend a receipt to the original recipient or additional email addresses",
        "operationId": "createReceiptDelivery",
        "parameters": [
          {
            "$ref": "#/components/parameters/ReceiptId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "entityId"
                ],
                "properties": {
                  "entityId": {
                    "type": "integer",
                    "format": "int64",
                    "description": "Merchant/tenant identifier for tenant isolation"
                  },
                  "additionalEmails": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "email"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Delivery created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWrappedReceiptDelivery"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      }
    },
    "/config": {
      "get": {
        "tags": [
          "Configuration"
        ],
        "summary": "Get Receipt Configuration",
        "description": "Retrieve the per-merchant receipt configuration stored locally by the Receipt Service.\n\nIncludes branding, template, receipt number format, send defaults,\nand push notification settings.\n",
        "operationId": "getReceiptConfig",
        "parameters": [
          {
            "$ref": "#/components/parameters/EntityIdQuery"
          }
        ],
        "responses": {
          "200": {
            "description": "Configuration retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWrappedReceiptConfig"
                },
                "example": {
                  "responseCode": "A100",
                  "responseMessage": "Approved",
                  "object": {
                    "id": "550e8400-e29b-41d4-a716-446655440099",
                    "entityId": 6393980735,
                    "enabled": true,
                    "defaultCurrency": "USD",
                    "branding": {
                      "logoUrl": "https://cdn.example.com/logo.png",
                      "primaryColor": "#003366",
                      "merchantName": "Acme Services"
                    },
                    "receiptNumberFormat": "RCP-{YEAR}{MONTH}-{SEQ}",
                    "receiptNumberPrefix": "RCP",
                    "minDigits": 6,
                    "autoSendOnPayment": true,
                    "defaultSendChannels": [
                      "EMAIL"
                    ],
                    "createdAt": "2026-01-15T10:00:00Z",
                    "updatedAt": "2026-02-20T14:30:00Z"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      },
      "put": {
        "tags": [
          "Configuration"
        ],
        "summary": "Upsert Receipt Configuration",
        "description": "Create or update the per-merchant receipt configuration.\n",
        "operationId": "upsertReceiptConfig",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpsertReceiptConfigRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuration saved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWrappedReceiptConfig"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      }
    },
    "/templates": {
      "get": {
        "tags": [
          "Templates"
        ],
        "summary": "List Templates",
        "description": "List available templates for the authenticated merchant.\nReturns both built-in system templates and merchant-uploaded custom templates.\n",
        "operationId": "listTemplates",
        "parameters": [
          {
            "$ref": "#/components/parameters/EntityIdQuery"
          },
          {
            "name": "type",
            "in": "query",
            "description": "Filter by template type",
            "schema": {
              "$ref": "#/components/schemas/ReceiptTemplateType"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by template status",
            "schema": {
              "$ref": "#/components/schemas/TemplateStatus"
            }
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/PageSizeParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Templates retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWrappedTemplateList"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      },
      "post": {
        "tags": [
          "Templates"
        ],
        "summary": "Create Template",
        "description": "Upload a new custom Liquid template for receipt or email rendering.\nThe template is created in DRAFT status and must be activated before use.\nLiquid syntax is validated on creation.\n",
        "operationId": "createTemplate",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTemplateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Template created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWrappedTemplateResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      }
    },
    "/templates/{templateId}": {
      "get": {
        "tags": [
          "Templates"
        ],
        "summary": "Get Template",
        "description": "Retrieve a single template by ID, including its full Liquid content.",
        "operationId": "getTemplate",
        "parameters": [
          {
            "$ref": "#/components/parameters/EntityIdQuery"
          },
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "responses": {
          "200": {
            "description": "Template retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWrappedTemplateResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      },
      "put": {
        "tags": [
          "Templates"
        ],
        "summary": "Update Template",
        "description": "Update a custom template. System templates cannot be modified.\nLiquid syntax is re-validated on update. Increments the template version.\n",
        "operationId": "updateTemplate",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTemplateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Template updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWrappedTemplateResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Templates"
        ],
        "summary": "Delete Template",
        "description": "Delete a custom template. System templates cannot be deleted.\nIf the template is set as the active template in the merchant's configuration,\nthe response uses responseCode E409 in the NPS error envelope.\n",
        "operationId": "deleteTemplate",
        "parameters": [
          {
            "$ref": "#/components/parameters/EntityIdQuery"
          },
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "responses": {
          "200": {
            "description": "Template deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWrappedTemplateDelete"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      }
    },
    "/templates/validate": {
      "post": {
        "tags": [
          "Templates"
        ],
        "summary": "Validate Template",
        "description": "Validate Liquid template syntax without persisting.\nReturns validation results including any syntax errors and\nunrecognized variable references.\n",
        "operationId": "validateTemplate",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ValidateTemplateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validation completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NpsWrappedValidateTemplateResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      }
    },
    "/templates/{templateId}/preview": {
      "post": {
        "tags": [
          "Templates"
        ],
        "summary": "Preview Template",
        "description": "Render a template with sample data and return the resulting HTML.\nUseful for previewing how a template will look before activating it.\n",
        "operationId": "previewTemplate",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewTemplateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rendered HTML preview",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "OAuth2": {
        "type": "oauth2",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://auth.nps.com/oauth/authorize",
            "tokenUrl": "https://auth.nps.com/oauth/token",
            "scopes": {}
          }
        }
      }
    },
    "parameters": {
      "PageParam": {
        "name": "page",
        "in": "query",
        "description": "Page number (1-indexed)",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 1
        },
        "example": 1
      },
      "PageSizeParam": {
        "name": "pageSize",
        "in": "query",
        "description": "Number of items per page",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 200,
          "default": 50
        },
        "example": 50
      },
      "ReceiptId": {
        "name": "receiptId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "TemplateId": {
        "name": "templateId",
        "in": "path",
        "required": true,
        "description": "Template identifier",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "PersonIdFilter": {
        "name": "personId",
        "in": "query",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "ReceiptStatusFilter": {
        "name": "status",
        "in": "query",
        "schema": {
          "$ref": "#/components/schemas/ReceiptStatus"
        }
      },
      "CreatedAtFromFilter": {
        "name": "createdAtFrom",
        "in": "query",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "CreatedAtToFilter": {
        "name": "createdAtTo",
        "in": "query",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "EntityIdQuery": {
        "name": "entityId",
        "in": "query",
        "required": true,
        "schema": {
          "type": "integer",
          "format": "int64"
        },
        "description": "Merchant/tenant identifier for tenant isolation"
      }
    },
    "schemas": {
      "HealthResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "UP",
              "DOWN"
            ]
          },
          "components": {
            "type": "object",
            "properties": {
              "db": {
                "$ref": "#/components/schemas/HealthComponent"
              },
              "diskSpace": {
                "$ref": "#/components/schemas/HealthComponent"
              },
              "ping": {
                "$ref": "#/components/schemas/HealthComponent"
              },
              "ssl": {
                "$ref": "#/components/schemas/HealthComponent"
              }
            }
          }
        }
      },
      "HealthComponent": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "UP",
              "DOWN"
            ]
          },
          "details": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "NpsResponse": {
        "type": "object",
        "description": "Standard NPS success envelope. `object` holds the operation-specific payload.\n",
        "required": [
          "responseCode",
          "responseMessage",
          "responseDetails",
          "object"
        ],
        "properties": {
          "responseCode": {
            "type": "string",
            "example": "A100"
          },
          "responseMessage": {
            "type": "string",
            "example": "Approved"
          },
          "responseDetails": {
            "type": "null"
          },
          "object": {
            "type": "null",
            "description": "Business payload for this operation (null when no payload)"
          }
        }
      },
      "NpsWrappedReceipt": {
        "allOf": [
          {
            "$ref": "#/components/schemas/NpsResponse"
          },
          {
            "type": "object",
            "properties": {
              "object": {
                "$ref": "#/components/schemas/Receipt"
              }
            }
          }
        ]
      },
      "NpsWrappedReceiptList": {
        "allOf": [
          {
            "$ref": "#/components/schemas/NpsResponse"
          },
          {
            "type": "object",
            "properties": {
              "object": {
                "$ref": "#/components/schemas/ReceiptListResponse"
              }
            }
          }
        ]
      },
      "NpsWrappedReceiptConfig": {
        "allOf": [
          {
            "$ref": "#/components/schemas/NpsResponse"
          },
          {
            "type": "object",
            "properties": {
              "object": {
                "$ref": "#/components/schemas/ReceiptConfigResponse"
              }
            }
          }
        ]
      },
      "ReceiptDeliveryResult": {
        "type": "object",
        "properties": {
          "sentTo": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            }
          },
          "sentAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "NpsWrappedReceiptDelivery": {
        "allOf": [
          {
            "$ref": "#/components/schemas/NpsResponse"
          },
          {
            "type": "object",
            "properties": {
              "object": {
                "$ref": "#/components/schemas/ReceiptDeliveryResult"
              }
            }
          }
        ]
      },
      "NpsWrappedTemplateList": {
        "allOf": [
          {
            "$ref": "#/components/schemas/NpsResponse"
          },
          {
            "type": "object",
            "properties": {
              "object": {
                "$ref": "#/components/schemas/TemplateListResponse"
              }
            }
          }
        ]
      },
      "NpsWrappedTemplateResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/NpsResponse"
          },
          {
            "type": "object",
            "properties": {
              "object": {
                "$ref": "#/components/schemas/TemplateResponse"
              }
            }
          }
        ]
      },
      "NpsWrappedValidateTemplateResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/NpsResponse"
          },
          {
            "type": "object",
            "properties": {
              "object": {
                "$ref": "#/components/schemas/ValidateTemplateResponse"
              }
            }
          }
        ]
      },
      "TemplateDeleteResult": {
        "type": "object",
        "required": [
          "templateId",
          "deleted"
        ],
        "properties": {
          "templateId": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the deleted template"
          },
          "deleted": {
            "type": "boolean",
            "example": true
          }
        }
      },
      "NpsWrappedTemplateDelete": {
        "allOf": [
          {
            "$ref": "#/components/schemas/NpsResponse"
          },
          {
            "type": "object",
            "properties": {
              "object": {
                "$ref": "#/components/schemas/TemplateDeleteResult"
              }
            }
          }
        ]
      },
      "PnsEvent": {
        "type": "object",
        "required": [
          "eventType",
          "sourceApplicationName",
          "entityId",
          "createDateTime",
          "payload"
        ],
        "properties": {
          "eventType": {
            "type": "string",
            "description": "Human-readable event type"
          },
          "sourceApplicationName": {
            "type": "string",
            "const": "receipt-service"
          },
          "entityId": {
            "type": "integer",
            "format": "int64",
            "description": "Merchant/tenant identifier for tenant isolation"
          },
          "createDateTime": {
            "type": "string",
            "format": "date-time",
            "description": "When the event was created (ISO 8601)"
          },
          "payload": {
            "type": "object",
            "required": [
              "notificationMessageId"
            ],
            "properties": {
              "notificationMessageId": {
                "type": "string",
                "format": "uuid",
                "description": "Unique message identifier (idempotency key)"
              },
              "status": {
                "type": "string",
                "description": "Status context for the event"
              },
              "additionalProperties": {
                "type": "object",
                "description": "Event-specific data (e.g. receiptId, channel)",
                "additionalProperties": true
              },
              "tags": {
                "type": "object",
                "description": "Arbitrary tags for routing or filtering",
                "additionalProperties": true
              }
            }
          }
        }
      },
      "Pagination": {
        "type": "object",
        "required": [
          "totalRecords",
          "currentPage",
          "totalPages"
        ],
        "properties": {
          "totalRecords": {
            "type": "integer",
            "description": "Total number of records across all pages",
            "example": 100
          },
          "currentPage": {
            "type": "integer",
            "description": "Current page number (1-indexed)",
            "example": 1
          },
          "totalPages": {
            "type": "integer",
            "description": "Total number of pages",
            "example": 10
          },
          "nextPage": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Next page number, null if on last page",
            "example": 2
          },
          "prevPage": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Previous page number, null if on first page",
            "example": null
          }
        }
      },
      "ReceiptStatus": {
        "type": "string",
        "enum": [
          "CREATED",
          "SENT",
          "FAILED"
        ]
      },
      "PaymentMethodType": {
        "type": "string",
        "enum": [
          "CARD",
          "ACH",
          "APPLE_PAY",
          "PAYPAL"
        ],
        "description": "Type of payment method for receipt display (includes PAYPAL for tracking)\n"
      },
      "Receipt": {
        "type": "object",
        "required": [
          "id",
          "receiptNumber",
          "entityId",
          "status",
          "payment",
          "version",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "receiptNumber": {
            "type": "string",
            "description": "Sequential receipt number"
          },
          "entityId": {
            "type": "integer",
            "format": "int64",
            "description": "Merchant/tenant identifier for tenant isolation"
          },
          "personId": {
            "type": "string",
            "format": "uuid",
            "description": "Person ID if linked to Profile Service"
          },
          "personName": {
            "type": "string",
            "description": "Snapshot of person name"
          },
          "personEmail": {
            "type": "string",
            "format": "email",
            "description": "Snapshot of person email"
          },
          "status": {
            "$ref": "#/components/schemas/ReceiptStatus"
          },
          "payment": {
            "$ref": "#/components/schemas/ReceiptPayment"
          },
          "invoices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceiptInvoice"
            }
          },
          "sendAttempts": {
            "type": "array",
            "description": "History of send/resend attempts for this receipt.",
            "items": {
              "type": "object",
              "properties": {
                "attemptedAt": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Timestamp of the send attempt"
                },
                "channel": {
                  "type": "string",
                  "enum": [
                    "EMAIL"
                  ],
                  "description": "Delivery channel used"
                },
                "status": {
                  "type": "string",
                  "description": "Result status of the attempt"
                },
                "emailAddresses": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Email addresses the receipt was sent to"
                }
              }
            }
          },
          "description": {
            "type": "string",
            "description": "Description for payment-only receipts"
          },
          "pdfUrl": {
            "type": "string",
            "format": "uri",
            "x-status": "planned",
            "description": "Not yet implemented. Planned for future release.\nPost-MVP. URL to download PDF (signed, time-limited).\nNot populated in MVP; receipts are rendered as HTML on-demand.\n"
          },
          "consolidatedTags": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ConsolidatedTagsObject"
              },
              {
                "description": "Consolidated tags carried from the invoice/payment that generated this receipt.\nImmutable snapshot for reporting and analytics.\n",
                "readOnly": true
              }
            ]
          },
          "sentAt": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer",
            "format": "int64",
            "description": "Version number for optimistic locking"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ReceiptPayment": {
        "type": "object",
        "required": [
          "paymentId",
          "amount",
          "paymentMethod",
          "processedAt"
        ],
        "properties": {
          "paymentId": {
            "type": "string"
          },
          "transactionId": {
            "type": "string"
          },
          "amount": {
            "type": "number",
            "format": "decimal",
            "description": "Amount in dollars"
          },
          "paymentMethod": {
            "$ref": "#/components/schemas/PaymentMethodType"
          },
          "lastFour": {
            "type": "string"
          },
          "processedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ReceiptInvoice": {
        "type": "object",
        "required": [
          "invoiceId",
          "invoiceNumber",
          "amountApplied"
        ],
        "properties": {
          "invoiceId": {
            "type": "string",
            "format": "uuid"
          },
          "invoiceNumber": {
            "type": "string",
            "description": "Snapshot of invoice number"
          },
          "amountApplied": {
            "type": "number",
            "format": "decimal",
            "description": "Amount applied to this invoice in dollars"
          }
        }
      },
      "CreateReceiptRequest": {
        "type": "object",
        "required": [
          "entityId",
          "payment"
        ],
        "properties": {
          "entityId": {
            "type": "integer",
            "format": "int64",
            "description": "Merchant/tenant identifier for tenant isolation"
          },
          "personId": {
            "type": "string",
            "format": "uuid",
            "description": "Link to existing Person in Profile Service"
          },
          "person": {
            "type": "object",
            "description": "Ad-hoc person info (for payment-only when no personId)",
            "properties": {
              "name": {
                "type": "string"
              },
              "email": {
                "type": "string",
                "format": "email"
              }
            }
          },
          "payment": {
            "$ref": "#/components/schemas/ReceiptPayment"
          },
          "invoices": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "invoiceId",
                "invoiceNumber",
                "amountApplied"
              ],
              "properties": {
                "invoiceId": {
                  "type": "string",
                  "format": "uuid"
                },
                "invoiceNumber": {
                  "type": "string"
                },
                "amountApplied": {
                  "type": "number",
                  "format": "decimal",
                  "description": "Amount applied to this invoice in dollars"
                }
              }
            }
          },
          "description": {
            "type": "string",
            "description": "Description for payment-only receipts"
          },
          "sendOptions": {
            "type": "object",
            "properties": {
              "send": {
                "type": "boolean",
                "default": true
              },
              "additionalEmails": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "email"
                }
              }
            }
          }
        }
      },
      "ReceiptListResponse": {
        "type": "object",
        "required": [
          "results",
          "pagination"
        ],
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Receipt"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "ConsolidatedTagsObject": {
        "type": "object",
        "description": "Immutable consolidated tags with source prefixes, carried from the invoice/payment.\nMerges tags from all upstream sources (Profile, Billing, etc.) into a single snapshot.\n\nTag keys must follow the `source.entity.namespace.key` format (four dot-separated segments). Keys with fewer segments are silently dropped during consolidation.\n\n**Format:** `source.entity.namespace.key = value`\n**Example prefixes:**\n- `profile.billableEntity.*` - Tags from BillableEntity\n- `profile.account.*` - Tags from Account\n- `billing.rate.*` - Tags from Rate\n- `billing.subscription.*` - Tags from Subscription\n- `billing.charge.*` - Tags from Charge\n\nThese tags are frozen and are never modified after receipt generation.\n",
        "additionalProperties": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                "type": "string",
                "maxLength": 256
              }
            }
          }
        },
        "example": {
          "profile": {
            "billableEntity": {
              "service": {
                "program": "standard"
              }
            }
          },
          "billing": {
            "charge": {
              "event": {
                "date": "2026-01-15"
              }
            }
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "responseCode",
          "responseMessage",
          "responseDetails",
          "object"
        ],
        "description": "NPS API error envelope.\n**Null field omission:** With `@JsonInclude(NON_NULL)`, null-valued fields (including `object` and `responseDetails` when absent) are omitted rather than serialized as explicit `null`.\n",
        "properties": {
          "responseCode": {
            "type": "string",
            "description": "NPS error code (not HTTP status as string). Includes E422 (VALIDATION_ERROR) for request validation failures,\nplus **E400_VALIDATION**, **E403_ACCESS**, and **E403_TENANT** as described in the API introduction.\n",
            "enum": [
              "E400",
              "E400_VALIDATION",
              "E401",
              "E403",
              "E403_ACCESS",
              "E403_TENANT",
              "E404",
              "E409",
              "E422",
              "E500"
            ],
            "example": "E400"
          },
          "responseMessage": {
            "type": "string",
            "description": "Human-readable error summary",
            "example": "Invalid request parameters"
          },
          "responseDetails": {
            "type": [
              "array",
              "null"
            ],
            "description": "Structured error details (field errors, codes, etc.)",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "object": {
            "type": "null",
            "description": "Omitted when null in actual JSON responses (see null field omission note on this schema)."
          }
        },
        "example": {
          "responseCode": "E400",
          "responseMessage": "Invalid request parameters",
          "responseDetails": []
        }
      },
      "UpsertReceiptConfigRequest": {
        "type": "object",
        "required": [
          "entityId",
          "enabled",
          "defaultCurrency"
        ],
        "properties": {
          "entityId": {
            "type": "integer",
            "format": "int64",
            "description": "Merchant/tenant identifier for tenant isolation"
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether receipt generation is enabled for this merchant"
          },
          "defaultCurrency": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3,
            "description": "ISO 4217 currency code",
            "default": "USD",
            "example": "USD"
          },
          "branding": {
            "type": "object",
            "properties": {
              "logoUrl": {
                "type": "string",
                "format": "uri",
                "description": "Merchant logo URL displayed on receipts"
              },
              "primaryColor": {
                "type": "string",
                "pattern": "^#[0-9A-Fa-f]{6}$",
                "description": "Primary brand color hex code",
                "example": "#003366"
              },
              "merchantName": {
                "type": "string",
                "description": "Merchant display name on receipts"
              },
              "receiptTemplateId": {
                "type": "string",
                "format": "uuid",
                "description": "Active template ID for receipt rendering. References a template\nfrom the /templates endpoint. If omitted, the system default\ntemplate (standard) is used.\n"
              },
              "emailTemplateId": {
                "type": "string",
                "format": "uuid",
                "description": "Active template ID for receipt notification emails. References\na template from the /templates endpoint. If omitted, the system\ndefault email template is used.\n"
              }
            }
          },
          "receiptNumberFormat": {
            "type": "string",
            "description": "Receipt number format with placeholders:\n{YEAR} - 4-digit year, {MONTH} - 2-digit month,\n{SEQ} - sequential number, {PREFIX} - merchant prefix\n",
            "example": "RCP-{YEAR}{MONTH}-{SEQ}"
          },
          "receiptNumberPrefix": {
            "type": "string",
            "maxLength": 10,
            "description": "Merchant-specific prefix for receipt numbers",
            "example": "RCP"
          },
          "minDigits": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "description": "Minimum digits for the sequential number (zero-padded)"
          },
          "autoSendOnPayment": {
            "type": "boolean",
            "description": "Automatically send receipt after successful payment"
          },
          "defaultSendChannels": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "EMAIL",
                "SMS"
              ]
            },
            "description": "Default channels for sending receipts"
          }
        }
      },
      "ReceiptConfigResponse": {
        "type": "object",
        "required": [
          "defaultCurrency"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "entityId": {
            "type": "integer",
            "format": "int64",
            "description": "Merchant/tenant identifier for tenant isolation"
          },
          "enabled": {
            "type": "boolean"
          },
          "defaultCurrency": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3,
            "description": "ISO 4217 currency code",
            "default": "USD",
            "example": "USD"
          },
          "branding": {
            "type": "object",
            "properties": {
              "logoUrl": {
                "type": "string",
                "format": "uri"
              },
              "primaryColor": {
                "type": "string"
              },
              "merchantName": {
                "type": "string"
              },
              "receiptTemplateId": {
                "type": "string",
                "format": "uuid",
                "description": "Active template for receipt rendering"
              },
              "emailTemplateId": {
                "type": "string",
                "format": "uuid",
                "description": "Active template for receipt notification emails"
              }
            }
          },
          "receiptNumberFormat": {
            "type": "string"
          },
          "receiptNumberPrefix": {
            "type": "string"
          },
          "minDigits": {
            "type": "integer"
          },
          "autoSendOnPayment": {
            "type": "boolean"
          },
          "defaultSendChannels": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "EMAIL",
                "SMS"
              ]
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ReceiptTemplateType": {
        "type": "string",
        "enum": [
          "RECEIPT",
          "RECEIPT_EMAIL"
        ],
        "description": "RECEIPT - Template for the rendered receipt document (HTML).\nRECEIPT_EMAIL - Template for the receipt notification email body.\n"
      },
      "TemplateStatus": {
        "type": "string",
        "enum": [
          "DRAFT",
          "ACTIVE",
          "ARCHIVED"
        ]
      },
      "CreateTemplateRequest": {
        "type": "object",
        "required": [
          "entityId",
          "name",
          "type",
          "content"
        ],
        "properties": {
          "entityId": {
            "type": "integer",
            "format": "int64",
            "description": "Merchant/tenant identifier for tenant isolation"
          },
          "name": {
            "type": "string",
            "maxLength": 255,
            "description": "Human-readable template name",
            "example": "Custom branded receipt"
          },
          "type": {
            "$ref": "#/components/schemas/ReceiptTemplateType"
          },
          "content": {
            "type": "string",
            "maxLength": 65536,
            "description": "Liquid template markup"
          },
          "description": {
            "type": "string",
            "maxLength": 1000,
            "description": "Optional description of the template's purpose"
          }
        }
      },
      "UpdateTemplateRequest": {
        "type": "object",
        "required": [
          "entityId"
        ],
        "properties": {
          "entityId": {
            "type": "integer",
            "format": "int64",
            "description": "Merchant/tenant identifier for tenant isolation"
          },
          "name": {
            "type": "string",
            "maxLength": 255
          },
          "content": {
            "type": "string",
            "maxLength": 65536,
            "description": "Liquid template markup"
          },
          "status": {
            "$ref": "#/components/schemas/TemplateStatus"
          },
          "description": {
            "type": "string",
            "maxLength": 1000
          }
        }
      },
      "ValidateTemplateRequest": {
        "type": "object",
        "required": [
          "entityId",
          "content",
          "type"
        ],
        "properties": {
          "entityId": {
            "type": "integer",
            "format": "int64",
            "description": "Merchant/tenant identifier for tenant isolation"
          },
          "content": {
            "type": "string",
            "maxLength": 65536,
            "description": "Liquid template markup to validate"
          },
          "type": {
            "$ref": "#/components/schemas/ReceiptTemplateType"
          }
        }
      },
      "ValidateTemplateResponse": {
        "type": "object",
        "required": [
          "valid"
        ],
        "properties": {
          "valid": {
            "type": "boolean",
            "description": "Whether the template syntax is valid"
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateValidationError"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Non-fatal issues detected during validation (e.g. unrecognized root-level template variables)"
          }
        }
      },
      "TemplateValidationError": {
        "type": "object",
        "properties": {
          "line": {
            "type": "integer",
            "description": "Line number where the error occurred"
          },
          "column": {
            "type": "integer",
            "description": "Column number where the error occurred"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error description"
          },
          "severity": {
            "type": "string",
            "enum": [
              "ERROR",
              "WARNING"
            ]
          }
        }
      },
      "PreviewTemplateRequest": {
        "type": "object",
        "required": [
          "entityId"
        ],
        "properties": {
          "entityId": {
            "type": "integer",
            "format": "int64",
            "description": "Merchant/tenant identifier for tenant isolation"
          },
          "sampleData": {
            "type": "object",
            "additionalProperties": true,
            "description": "Key-value data to populate the template variables.\nIf omitted, the service generates representative sample data\nbased on the template type.\n"
          }
        }
      },
      "TemplateResponse": {
        "type": "object",
        "required": [
          "id",
          "entityId",
          "name",
          "type",
          "engineType",
          "content",
          "version",
          "status",
          "isSystem",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "entityId": {
            "type": "integer",
            "format": "int64",
            "description": "Merchant/tenant identifier for tenant isolation"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "$ref": "#/components/schemas/ReceiptTemplateType"
          },
          "engineType": {
            "type": "string",
            "enum": [
              "LIQUID"
            ],
            "description": "Template engine used for rendering"
          },
          "content": {
            "type": "string",
            "description": "Full Liquid template markup"
          },
          "version": {
            "type": "integer",
            "minimum": 1,
            "description": "Auto-incremented on each update"
          },
          "status": {
            "$ref": "#/components/schemas/TemplateStatus"
          },
          "isSystem": {
            "type": "boolean",
            "description": "True for built-in system templates, false for merchant-uploaded"
          },
          "description": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdBy": {
            "type": "string",
            "description": "User or system identifier that created the template"
          }
        }
      },
      "TemplateSummary": {
        "type": "object",
        "required": [
          "id",
          "name",
          "type",
          "engineType",
          "version",
          "status",
          "isSystem",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "$ref": "#/components/schemas/ReceiptTemplateType"
          },
          "engineType": {
            "type": "string",
            "enum": [
              "LIQUID"
            ]
          },
          "version": {
            "type": "integer"
          },
          "status": {
            "$ref": "#/components/schemas/TemplateStatus"
          },
          "isSystem": {
            "type": "boolean"
          },
          "description": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TemplateListResponse": {
        "type": "object",
        "required": [
          "results",
          "pagination"
        ],
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateSummary"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      }
    }
  },
  "webhooks": {
    "receiptCreated": {
      "post": {
        "summary": "Receipt Created",
        "description": "Fired when a receipt is successfully generated.",
        "operationId": "webhookReceiptCreated",
        "tags": [
          "Receipts"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PnsEvent"
              },
              "example": {
                "eventType": "receipt.created",
                "sourceApplicationName": "receipt-service",
                "entityId": 1350714789,
                "createDateTime": "2026-01-15T14:32:00.000Z",
                "payload": {
                  "notificationMessageId": "a1b2c3d4-5678-9012-abcd-ef0123456789",
                  "status": "Created",
                  "additionalProperties": {
                    "receiptId": "550e8400-e29b-41d4-a716-446655440001",
                    "receiptNumber": "RCP-2026-00001",
                    "paymentId": "pay_001",
                    "amount": "450.00"
                  },
                  "tags": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook processed"
          }
        }
      }
    },
    "receiptSent": {
      "post": {
        "summary": "Receipt Sent",
        "description": "Fired when a receipt is delivered via configured channel.",
        "operationId": "webhookReceiptSent",
        "tags": [
          "Receipts"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PnsEvent"
              },
              "example": {
                "eventType": "receipt.sent",
                "sourceApplicationName": "receipt-service",
                "entityId": 1350714789,
                "createDateTime": "2026-01-15T14:33:00.000Z",
                "payload": {
                  "notificationMessageId": "b2c3d4e5-6789-0123-bcde-f01234567890",
                  "status": "Sent",
                  "additionalProperties": {
                    "receiptId": "550e8400-e29b-41d4-a716-446655440001",
                    "channel": "EMAIL",
                    "recipient": "contact@example.com"
                  },
                  "tags": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook processed"
          }
        }
      }
    },
    "receiptSendFailed": {
      "post": {
        "summary": "Receipt Send Failed",
        "description": "Fired when receipt delivery fails.",
        "operationId": "webhookReceiptSendFailed",
        "tags": [
          "Receipts"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PnsEvent"
              },
              "example": {
                "eventType": "receipt.send_failed",
                "sourceApplicationName": "receipt-service",
                "entityId": 1350714789,
                "createDateTime": "2026-01-15T14:33:05.000Z",
                "payload": {
                  "notificationMessageId": "c3d4e5f6-7890-1234-cdef-012345678901",
                  "status": "Send Failed",
                  "additionalProperties": {
                    "receiptId": "550e8400-e29b-41d4-a716-446655440001",
                    "channel": "EMAIL",
                    "failureReason": "Invalid email address"
                  },
                  "tags": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook processed"
          }
        }
      }
    },
    "templateCreated": {
      "post": {
        "x-todo": "Template lifecycle webhook events are planned for future implementation.",
        "summary": "Template Created",
        "description": "Fired when a new custom Liquid template is created.",
        "operationId": "webhookTemplateCreated",
        "tags": [
          "Templates"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PnsEvent"
              },
              "example": {
                "eventType": "receipt.template.created",
                "sourceApplicationName": "receipt-service",
                "entityId": 1350714789,
                "createDateTime": "2026-03-01T10:00:00.000Z",
                "payload": {
                  "notificationMessageId": "d1e2f3a4-5678-9012-abcd-ef0123456789",
                  "status": "Created",
                  "additionalProperties": {
                    "templateId": "550e8400-e29b-41d4-a716-446655440020",
                    "templateName": "Custom branded receipt",
                    "templateType": "RECEIPT"
                  },
                  "tags": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook processed"
          }
        }
      }
    },
    "templateUpdated": {
      "post": {
        "x-todo": "Template lifecycle webhook events are planned for future implementation.",
        "summary": "Template Updated",
        "description": "Fired when a custom template is updated.",
        "operationId": "webhookTemplateUpdated",
        "tags": [
          "Templates"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PnsEvent"
              },
              "example": {
                "eventType": "receipt.template.updated",
                "sourceApplicationName": "receipt-service",
                "entityId": 1350714789,
                "createDateTime": "2026-03-01T11:00:00.000Z",
                "payload": {
                  "notificationMessageId": "e2f3a4b5-6789-0123-bcde-f01234567890",
                  "status": "Updated",
                  "additionalProperties": {
                    "templateId": "550e8400-e29b-41d4-a716-446655440020",
                    "version": 2
                  },
                  "tags": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook processed"
          }
        }
      }
    },
    "templateActivated": {
      "post": {
        "x-todo": "Template lifecycle webhook events are planned for future implementation.",
        "summary": "Template Activated",
        "description": "Fired when a template status changes to ACTIVE.",
        "operationId": "webhookTemplateActivated",
        "tags": [
          "Templates"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PnsEvent"
              },
              "example": {
                "eventType": "receipt.template.activated",
                "sourceApplicationName": "receipt-service",
                "entityId": 1350714789,
                "createDateTime": "2026-03-01T12:00:00.000Z",
                "payload": {
                  "notificationMessageId": "f3a4b5c6-7890-1234-cdef-012345678901",
                  "status": "Activated",
                  "additionalProperties": {
                    "templateId": "550e8400-e29b-41d4-a716-446655440020",
                    "templateType": "RECEIPT"
                  },
                  "tags": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook processed"
          }
        }
      }
    },
    "templateArchived": {
      "post": {
        "x-todo": "Template lifecycle webhook events are planned for future implementation.",
        "summary": "Template Archived",
        "description": "Fired when a template status changes to ARCHIVED.",
        "operationId": "webhookTemplateArchived",
        "tags": [
          "Templates"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PnsEvent"
              },
              "example": {
                "eventType": "receipt.template.archived",
                "sourceApplicationName": "receipt-service",
                "entityId": 1350714789,
                "createDateTime": "2026-03-02T09:00:00.000Z",
                "payload": {
                  "notificationMessageId": "a4b5c6d7-8901-2345-defa-123456789012",
                  "status": "Archived",
                  "additionalProperties": {
                    "templateId": "550e8400-e29b-41d4-a716-446655440020"
                  },
                  "tags": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook processed"
          }
        }
      }
    },
    "templateDeleted": {
      "post": {
        "x-todo": "Template lifecycle webhook events are planned for future implementation.",
        "summary": "Template Deleted",
        "description": "Fired when a custom template is permanently deleted.",
        "operationId": "webhookTemplateDeleted",
        "tags": [
          "Templates"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PnsEvent"
              },
              "example": {
                "eventType": "receipt.template.deleted",
                "sourceApplicationName": "receipt-service",
                "entityId": 1350714789,
                "createDateTime": "2026-03-03T08:00:00.000Z",
                "payload": {
                  "notificationMessageId": "b5c6d7e8-9012-3456-efab-234567890123",
                  "status": "Deleted",
                  "additionalProperties": {
                    "templateId": "550e8400-e29b-41d4-a716-446655440020"
                  },
                  "tags": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook processed"
          }
        }
      }
    }
  }
}