openapi: 3.0.1
info:
  title: Service Engine APIs for HTM voucher for sales Touchpoint
  description: Service Engine APIs for HTM vouchers. These are NOT the CRUD APIs to the data hub. These ARE the APIs for sales touchpoints.
  version: "1.0"
servers:
  - url: https://services.acc.api.htm.nl/abt/abtvouchersTouchpoint/1.0
paths:
  /issuedvouchers/{voucherCode}:
    get:
      summary: Get details of a voucher, that was issued for a specific touchpoint
      description:
        Get details of an issued voucher for a specific touchpoint. This means that only products that the calling touchpoint is allowed to see or sell
        (i.e. has active sellingPeriods for touchPointId of the calling touchpoint) are returned.
      parameters:
        - name: voucherCode
          in: path
          required: true
          description: The unique code of the issued voucher to retrieve.
          schema:
            type: string
            example: VOUCHER123
      tags:
        - Vouchers
      responses:
        "200":
          description: Successful retrieval of voucher instance
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/salesTouchpointIssuedVoucherResponse"
              examples:
                Voucher that grants a voucher-only product for free:
                  summary: Voucher that grants a voucher-only product for free
                  description: |-
                    Voucher that grants a product (that can only be acquired via a voucher) for free.
                    In this case, the voucher has an amountInclTax of 0. If the requiredProduct has a
                    non-zero sellingPrice (amountInclTax), the difference between sellingPrice and 
                    voucher amountInclTax represents the granted discount. If the requiredProduct has 
                    a sellingPrice of 0, no "discount" is shown; just the voucher's amountInclTax.
                  value:
                    {
                      "issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
                      "voucherCode": "HTM-A7J-128-PYT",
                      "fromInclusive": "2024-10-04T00:00:00.000",
                      "untilInclusive": "2024-11-04T00:00:00.000",
                      "voucherStatus": { "voucherStatusId": 2, "name": "issued" },
                      "product":
                        {
                          "productId": 263,
                          "productName": "Voucher Ooievaarspas-product AOW",
                          "productDescription": "Voucher voor AOW-ers in Den Haag met een Ooievaarspas, die ingewisseld kan worden voor het product \"Ooievaarspas voor AOW-ers in Den Haag\"",
                          "amountInclTax": 0,
                          "requiredProducts":
                            [
                              {
                                "productId": 982,
                                "productName": "Ooievaarspas voor AOW-ers in Den Haag",
                                "productDescription": "Vrij reizen bij HTM voor Haagse AOW-gerechtigden met een Ooievaarspas.",
                                "productCategory": 
                                  {
                                    "productCategoryId": 2,
                                    "isTravelProduct": true,
                                    "name": "Afgekocht reisrecht",
                                  },
                                "amountInclTax": 0,
                                "_links":
                                  {
                                    "get_details":
                                      {
                                        "href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/982",
                                        "method": "GET",
                                      },
                                  },
                              },
                            ]
                        },
                      "mandatoryCustomerDataItems":
                        [
                          {
                            "mandatoryCustomerDataItemId": 8,
                            "customerDataItem": "padBirthDate"
                          }
                        ]
                    }
                Voucher that grants a hybrid product for a reduced price:
                  summary: Voucher that grants a hybrid product for a reduced price
                  description: |-
                    Voucher that grants a hybrid product (that can be acquired via voucher or via ordinary order flow) 
                    for a reduced price. In this case, the voucher has an amountInclTax > 0, which dictates the (modified) 
                    total amount that needs to be paid for said product. If the requiredProduct has a 
                    non-zero sellingPrice (amountInclTax), the difference between sellingPrice and 
                    voucher amountInclTax represents the granted discount. If the requiredProduct has 
                    a sellingPrice of 0, no "discount" is shown; just the voucher's amountInclTax./
                    Specifically, in this example, the product "HTM 20% Korting" can be purchased for 1 euro instead of 5 euro.
                  value:
                    {
                      "issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
                      "voucherCode": "HTM-A7J-128-PYT",
                      "fromInclusive": "2024-10-04T00:00:00.000",
                      "untilInclusive": "2024-11-04T00:00:00.000",
                      "voucherStatus": { "voucherStatusId": 2, "name": "issued" },
                      "product":
                        {
                          "productId": 264,
                          "productName": "Kortingsvoucher HTM 20% Korting ",
                          "productDescription": "Voucher waarmee het product \"HTM 20% Korting\" voor een lagere prijs kan worden aangeschaft.",
                          "amountInclTax": 100,
                          "requiredProducts":
                            [
                              {
                                "productId": 984,
                                "productName": "HTM 20% Korting",
                                "productDescription": "Reis met 20% korting op je betaalpas bij HTM.",
                                "productCategory": 
                                  {
                                    "productCategoryId": 1,
                                    "isTravelProduct": true,
                                    "name": "Kortingsabonnement",
                                  },
                                "amountInclTax": 500,
                                "_links":
                                  {
                                    "get_details":
                                      {
                                        "href": "https://api.integratielaag.nl/abt/touchpoint/1.0/products/984",
                                        "method": "GET",
                                      },
                                  },
                              },
                            ]
                        },
                      "mandatoryCustomerDataItems": []
                    }
                Voucher that grants a discount for a whole order:
                  summary: Voucher that grants a discount for a whole order
                  description: |-
                    Voucher that grants a discount for a whole order. In this case, no requiredProduct is specified, and 
                    the voucher has an amountInclTax < 0. The (negative) amountInclTax dictates the value of the voucher, 
                    that is subtracted from the total order value as a discount (with a minimum order total of 0).
                  value:
                    {
                      "issuedVoucherId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
                      "voucherCode": "HTM-A7J-128-PYT",
                      "fromInclusive": "2024-10-04T00:00:00.000",
                      "untilInclusive": "2024-11-04T00:00:00.000",
                      "voucherStatus": { "voucherStatusId": 2, "name": "issued" },
                      "product":
                        {
                          "productId": 265,
                          "productName": "Voucher 10 euro korting",
                          "productDescription": "Voucher die 10 euro korting geeft op je gehele winkelmand.",
                          "amountInclTax": -1000,
                          "requiredProducts": []
                        },
                      "mandatoryCustomerDataItems": []
                    }
        "403":
          description: Forbidden
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/rfc9457"
              examples:
                Access denied due to insufficient permissions:
                  summary: Access denied due to insufficient permissions
                  value:
                    {
                      "type": "https://example.com/probs/forbidden",
                      "title": "Access denied",
                      "detail": "You do not have permission to access this resource.",
                      "instance": "/issuedvouchers",
                    }
        "400":
          description: Bad request
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/rfc9457"
              examples:
                Invalid voucher code:
                  summary: Invalid voucher code
                  value:
                    {
                      "type": "https://example.com/probs/bad-request",
                      "title": "Invalid voucher code",
                      "detail": "No valid voucher found for code VOUCHER123.",
                      "instance": "/issuedvouchers",
                    }
        "500":
          description: Internal server error
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/rfc9457"
              examples:
                Unexpected server error:
                  summary: Unexpected server error
                  value:
                    {
                      "type": "https://example.com/probs/internal-server-error",
                      "title": "Internal Server Error",
                      "detail": "An unexpected error occurred while processing your request.",
                      "instance": "/issuedvouchers",
                    }
components:
  securitySchemes:
    bearerToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
  schemas:
    salesTouchpointIssuedVoucherResponse:
      type: object
      required:
        - issuedVoucherId
        - voucherCode
        - fromInclusive
        - untilInclusive
        - voucherStatus
        - product
        - mandatoryCustomerDataItems
      properties:
        issuedVoucherId:
          type: string
          description: The unique (technical) identifier of the issued voucher instance.
          example: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90"
        voucherCode:
          type: string
          description: The voucher code that is shared with the customer and uniquely identifies this voucher.
          example: "HTM-A7J-128-PYT"
        fromInclusive:
          type: string
          format: date-time-offset
          description: |-
           The date and time the voucher becomes valid for redemption. This has nothing to do with 
           the allowed start date of a requiredProduct (for this, the existing order flow logic is applied).
          example: "2024-10-04T00:00:00.000+02:00"
        untilInclusive:
          type: string
          format: date-time-offset
          description: |-
           The date and time the voucher becomes invalid for redemption. This has nothing to do with 
           the maximum allowed start date of a requiredProduct (for this, the existing order flow logic is applied).
          example: "2024-11-04T00:00:00.000+01:00"
        voucherStatus:
          type: object
          required:
            - voucherStatusId
            - name
          description: |-
           The current status of the voucher. Can be any of the following:
            - 1 = new
            - 2 = issued
            - 3 = redeemed
            - 4 = revoked
            - 5 = expired
            - 6 = pendingRedemption
          properties:
            voucherStatusId:
              type: integer
              example: 2
            name:
              type: string
              example: "issued"
        product:
          type: object
          description: The "product" referencing the voucher definition that this voucher instance is based on
          required:
            - productId
            - productName
            - productDescription
            - amountInclTax
          properties:
            productId:
              type: integer
              example: 263
            productName:
              type: string
              example: Voucher Ooievaarspas-product AOW
            productDescription:
              type: string
              example: |-
               Voucher voor AOW-ers in Den Haag met een Ooievaarspas, die ingewisseld kan worden 
               voor het product "Ooievaarspas voor AOW-ers in Den Haag".
            amountInclTax:
              type: integer
              description: |- 
               When combined with a requiredProduct, the (positive or zero) amountInclTax dictates 
               the (modified) total amount that needs to be paid for said product. When the requiredProduct 
               has a sellingPrice > 0, the difference between sellingPrice and voucher amountInclTax
               represents the granted discount.
               When not combined with a required product, the (negative) amountInclTax dictates
               the value of the voucher, that is subtracted from the total order value as a discount 
               (with a minimum order total of 0).
              example: 0
            requiredProducts:
              type: array
              description: |-
               Currently, only one requiredProduct is supported and thus, this array can contain at 
               most one element.
              items:
                type: object
                required:
                  - productId                 
                properties:
                  productId:
                    type: integer
                    example: 892
                  productName:
                    type: string
                    example: "Ooievaarspas voor AOW-ers in Den Haag"
                  productDescription:
                    type: string
                    example: "Vrij reizen bij HTM voor Haagse AOW-gerechtigden met een Ooievaarspas."
                  productCategory:
                    type: object
                    required: 
                      - productCategoryId
                      - isTravelProduct
                      - name
                    properties:
                      productCategoryId:
                        type: integer
                        example: 2
                      isTravelProduct:
                        type: boolean
                        example: true
                      name:
                        type: string
                        example: "Afgekocht reisrecht"
                  amountInclTax:
                    type: integer
                    description: |-
                      Selling price of the product in cents (including tax, if applicable) that is 
                      currently active for the calling touchpoint. When 0, the product is free of charge.
                    example: 0
                  imageReference:
                    type: string
                    description: Can be a URL or a base64 encoded image
                    example: https://www.htm.nl/nog-onbekende-productafbeelding
                  _links:
                    type: object
                    properties:
                      get_details:
                        type: object
                        description: Link to get more details for the product that this voucher instance applies to
                        properties:
                          href:
                            type: string
                            example: https://api.integratielaag.nl/abt/touchpoint/1.0/products/982
                          method:
                            type: string
                            example: GET
        mandatoryCustomerDataItems:
          type: array
          description: |-
           List of mandatory customer data items that are required to redeem this voucher.\
           The values provided for these data items may be checked against allowed values as provided by the voucher issuer.
          items: 
            type: object
            required:
              - mandatoryCustomerDataItemId
              - customerDataItem
            properties:
              mandatoryCustomerDataItemId:
                type: integer
                example: 8
              customerDataItem:
                type: string
                example: padBirthdate

    unavailable:
      type: object
    rfc9457:
      type: object
      properties:
        type:
          type: string
          format: url
          example: https://example.com/probs/out-of-credit
        title:
          type: string
          example: You do not have enough credit.
        detail:
          type: string
          example: Your current balance is 30, but that costs 50.
        instance:
          type: string
          example: /account/12345/msgs/abc
        balance:
          type: string
          example: 30
        accounts:
          type: array
          items:
            type: string
            example:
              - /account/12345
              - /account/67890
