openapi: 3.0.3
info:
  title: Onside Purchase Validation API
  version: 1.0.0
  description: API definitions for Onside Purchase Validation endpoints.

servers:
  - url: https://onside.io
    description: Production server
  - url: https://onside.dev
    description: Staging server

paths:
  /merchant-api/v1/purchases/in-app/history/{order_id}:
    get:
      tags:
        - Merchant API
      summary: Retrieve transaction details by Order ID
      parameters:
        - name: order_id
          in: path
          description: The unique identifier of the order.
          required: true
          schema:
            type: string
            format: uuid
      security:
        - bearerAuth: []
      responses:
        '200':
          description: Successfully retrieved transaction history (Signed JWS).
          content:
            application/jose:
              schema:
                type: string
                description: Compact JWS string. Payload matches TransactionHistory schema.
        '401':
          description: Unauthorized (Invalid or missing JWT)
        '403':
          description: Forbidden (Valid JWT but not allowed)
        '404':
          description: Order not found

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  schemas:
    TransactionHistory:
      type: object
      properties:
        transactions:
          type: array
          items:
            $ref: '#/components/schemas/InAppPurchase'
      required:
        - transactions
      example:
        transactions:
          - app_account_token: "user-uuid-1234"
            bundle_id: "com.example.app"
            currency: "USD"
            expires_at: null
            order_id: "3e46c75a-7e04-4530-979a-e275f3a7c50c"
            original_order_id: "3e46c75a-7e04-4530-979a-e275f3a7c50c"
            original_purchase_date: "2023-10-26T10:00:00Z"
            price: 999
            product_id: "premium_subscription_monthly"
            product_slug: "premium-monthly"
            product_type: "SUBSCRIPTION"
            purchase_date: "2023-10-26T10:00:00Z"
            quantity: 1
            revocation_date: null
            revocation_reason: null
            fetched_at: "2023-10-26T10:05:00Z"
            subscription_id: "sub-group-xyz"
            transaction_reason: "PURCHASE"
            user_country: "US"
          - app_account_token: "user-uuid-1234"
            bundle_id: "com.example.app"
            currency: "USD"
            expires_at: "2023-11-26T10:00:00Z"
            order_id: "4f57d86b-8f15-5641-080b-f386g4b8d61d"
            original_order_id: "3e46c75a-7e04-4530-979a-e275f3a7c50c"
            original_purchase_date: "2023-10-26T10:00:00Z"
            price: 999
            product_id: "premium_subscription_monthly"
            product_slug: "premium-monthly"
            product_type: "SUBSCRIPTION"
            purchase_date: "2023-11-26T10:00:00Z"
            quantity: 1
            revocation_date: null
            revocation_reason: null
            fetched_at: "2023-11-26T10:05:00Z"
            subscription_id: "sub-group-xyz"
            transaction_reason: "RENEWAL"
            user_country: "US"
          - app_account_token: "user-uuid-1234"
            bundle_id: "com.example.app"
            currency: "EUR"
            expires_at: null
            order_id: "5a68e97c-9g26-6752-191c-g497h5c9e72e"
            original_order_id: "5a68e97c-9g26-6752-191c-g497h5c9e72e"
            original_purchase_date: "2023-09-01T12:00:00Z"
            price: 499
            product_id: "remove_ads"
            product_slug: "remove-ads"
            product_type: "NON_CONSUMABLE"
            purchase_date: "2023-09-01T12:00:00Z"
            quantity: 1
            revocation_date: "2023-09-02T10:00:00Z"
            revocation_reason: "Refund"
            fetched_at: "2023-11-26T10:05:00Z"
            subscription_id: null
            transaction_reason: "PURCHASE"
            user_country: "DE"

    InAppPurchase:
      type: object
      properties:
        app_account_token:
          type: string
          nullable: true
          description: The user account ID.
        bundle_id:
          type: string
          description: The bundle ID.
        currency:
          type: string
          description: The currency code (ISO 4217).
        expires_at:
          type: string
          format: date-time
          nullable: true
          description: The subscription expiration date. None if not a subscription.
        order_id:
          type: string
          format: uuid
          description: The transaction ID.
        original_order_id:
          type: string
          format: uuid
          description: The original transaction ID.
        original_purchase_date:
          type: string
          format: date-time
          description: The original purchase date.
        price:
          type: integer
          format: int64
          description: The price in the smallest currency unit.
        product_id:
          type: string
          description: The product ID.
        product_slug:
          type: string
          nullable: true
          description: The product slug.
        product_type:
          $ref: '#/components/schemas/InAppProductType'
        purchase_date:
          type: string
          format: date-time
          description: The purchase or renewal date.
        quantity:
          type: integer
          minimum: 1
          description: The quantity.
        revocation_date:
          type: string
          format: date-time
          nullable: true
          description: The revocation date. None if not revoked.
        revocation_reason:
          $ref: '#/components/schemas/RevocationReason'
          nullable: true
        fetched_at:
          type: string
          format: date-time
          description: The time of the data fetch.
        subscription_id:
          type: string
          nullable: true
          description: The subscription group ID. None if not a subscription.
        transaction_reason:
          $ref: '#/components/schemas/TransactionReason'
        user_country:
          type: string
          minLength: 2
          maxLength: 2
          description: The user country (ISO 3166-1 alpha-2).
      required:
        - bundle_id
        - currency
        - order_id
        - original_order_id
        - original_purchase_date
        - price
        - product_id
        - product_type
        - purchase_date
        - quantity
        - fetched_at
        - transaction_reason
        - user_country

    InAppProductType:
      type: string
      enum:
        - NON_CONSUMABLE
        - CONSUMABLE
        - SUBSCRIPTION
      description: The type of in-app product.

    TransactionReason:
      type: string
      enum:
        - PURCHASE
        - RENEWAL
        - REFUND
        - CHARGEBACK
      description: The reason for the transaction.

    RevocationReason:
      type: string
      enum:
        - Refund
      description: Transaction revocation reason.
