openapi: 3.0.0
info:
  version: 1.0.0
  title: Shift72 Shopping API
servers:
  - url: https://{siteUrl}
    variables:
      siteUrl:
        default: vod.shift72.com
        description: Url to your Shift72 site
paths:
  /services/shopping/v1/purchase_options/{slug}:
    get:
      operationId: getPurchaseOptionsV1
      summary: Get Purchase Options
      description: |
        Returns the available purchase options for an item. For example, an item
        could be rented directly, or accessed via a pass, subscription, or bundle.

        This API is specific to the user making the request. 

        If no auth token is provided, only public purchase options will be returned.

        With an auth token it will take into account a user's plans for Plan Based
        Pricing, whether they already own the item, etc.

        The purchase options returned are payment-provider specific too. By default
        the API will use the default payment provider, but an API consumer can list
        the payment methods it specifically supports or is interested in (e.g.
        `?providers=vista_loyalty,apple`). 
        This filters out incompatible options (e.g. subscriptions are not supported with loyalty points or IAPs)


        This API can also provide a pricing preview when a promo code is being used (e.g. `?promo=RENT25`). 

        Prices will reflect any applicable discounts and will include the original price, amount off, and metadata describing whether the promo code applies to each option.

        A UI may want to disable or hide those options once the user enters the promo code, or show an error if the promocode doesn't apply to any options.

        ### Contract

        1. The options provided will be location-specific, based on the IP
           geolocation of the requester.
        2. The options will be user-specific if an auth token is provided. This
           might take into account plan-based pricing / availability.
        3. The `options` array will only include purchasable options. If an 
           offering is unavailable it will not be returned. In future, the API might 
           return an `unavailable_options` array as well, if this information is 
           useful.
        4. The options returned are indicative and not a guaranteed quote. 
           Pricing, availability, promo limits, or expiry conditions may change before a shopping session is created..
        5. The API will return purchase options for related items — e.g. bundles and
           plans that would give access to this content too. Callers should inspect the `slug` on each purchase option to determine the item being purchased.
      security: []
      parameters:
        - name: slug
          in: path
          description: The slug to get the purchase options for.
          example: /film/123
          required: true
          schema:
            type: string
        - name: providers
          description: |
            a comma-separated list of payment providers to find purchase options
            for. If not provided, the default provider for the site will be used.
            Payment providers that the backend doesn't support or are not configured
            will be ignored.
          example: stripe_elements,vista_loyalty
          required: false
          in: query
          schema:
            type: string
      responses:
        '200':
          description: |
            The ways that this content may be purchased.

            This may return an empty options array if there are no ways to purchase the item.
          content:
            application/json:
              schema:
                type: object
                properties:
                  options:
                    type: array
                    items:
                      $ref: '#/components/schemas/PurchaseOption'
              examples:
                A TVOD rental using the default payment provider:
                  value:
                    options:
                      - type: purchase
                        slug: /film/2858
                        provider: stripe_elements
                        price:
                          value: '9.99'
                          currency: NZD
                          tax_inclusive: true
                          formatted: $9.99
                        quality: hd
                        ownership: rent
                        id: /film/2858|hd-rent-stripe-elements-purchase
                Rent and Buy Options:
                  value:
                    options:
                      - type: purchase
                        slug: /film/2858
                        provider: stripe_elements
                        price:
                          value: '9.99'
                          currency: NZD
                          tax_inclusive: true
                          formatted: $9.99
                        quality: hd
                        ownership: rent
                        id: /film/2858|hd-rent-stripe-elements-purchase
                      - type: purchase
                        slug: /film/2858
                        provider: stripe_elements
                        price:
                          value: '20.99'
                          currency: NZD
                          tax_inclusive: true
                          formatted: $20.99
                        quality: hd
                        ownership: buy
                        id: /film/2858|hd-buy-stripe-elements-purchase
                TVOD - SVOD Hybrid:
                  value:
                    options:
                      - type: purchase
                        slug: /film/2858
                        provider: stripe_elements
                        price:
                          value: '9.99'
                          currency: NZD
                          tax_inclusive: true
                          formatted: $9.99
                        quality: hd
                        ownership: rent
                        id: /film/2858|hd-rent-stripe-elements-purchase
                      - type: subscription
                        slug: /plan/123
                        provider: stripe_elements
                        price:
                          value: '5.99'
                          currency: NZD
                          tax_inclusive: true
                          formatted: $5.99
                          period:
                            interval: month
                            interval_count: 1
                        period:
                          interval: month
                          interval_count: 1
                        id: /plan/123|stripe-elements-subscription
                No purchase options:
                  summary: No way to purchase this item
                  value:
                    options: []
components:
  securitySchemes:
    AuthToken:
      type: apiKey
      in: header
      name: X-Auth-Token
      description: A user auth token or API key.
    AdminAuthToken:
      type: apiKey
      in: header
      name: X-Auth-Token
      description: A user with the admin role
    ApiKey:
      type: apiKey
      in: header
      name: X-Auth-Token
      description: An API key. This may need specific permissions, documented in the endpoint
  schemas:
    PurchaseOptionSubscriptionPeriod:
      type: object
      description: The frequency for for a subscription renewal
      properties:
        interval:
          type: string
          description: The unit used (month, year)
          enum:
            - day
            - week
            - month
            - year
          example: year
        interval_count:
          type: integer
          description: The number of units (e.g. 3 months)
          example: 1
    PurchaseOptionPrice:
      type: object
      properties:
        value:
          type: string
          description: Decimal monetary value as a string to preserve precision (e.g. "7.99")
          pattern: ^\d+(\.\d+)?$
          example: '7.99'
        formatted:
          type: string
          description: A formatted representation of this currency value. (e.g. "$7.99" or "7.99€")
          example: $7.99
        currency:
          type: string
          example: NZD
        sku:
          description: The SKU to use when doing an IAP purchase. This may be provider specific. The presence of this field implies the purchase option is an IAP.
          type: string
          example: com.example.12345
        tax_inclusive:
          type: boolean
          default: true
          description: Whether this price is tax inclusive. This may be omitted if it's not a total price (e.g. amount off for a discount)
        period:
          description: Present for recurring prices (e.g. subscriptions)
          allOf:
            - $ref: '#/components/schemas/PurchaseOptionSubscriptionPeriod'
    PurchaseOption:
      type: object
      description: Represents a way a user should be able to buy something
      properties:
        type:
          type: string
          enum:
            - purchase
            - subscription
            - loyalty
            - free
            - promo_only
          description: |
            Type of purchase option, and the sort of payment flow that might be needed:

            - purchase: One-off payment
            - subscription: Recurring payment
            - loyalty: Uses loyalty credits, fairly provider specific
            - free: No payment required
            - promo_only: Only available via 100% discount code
        slug:
          type: string
          description: |
            The Shift72 identifier for the item being purchased. This could be a film, TV season, a plan, a bundle, etc.

            Usually, requesting purchase options for a particular slug would return
            purchase options matching that, but it could also return other suggestions
            -- e.g. for bundles or plans that grant access to the content too.
          example: /film/123
        id:
          type: string
          description: A human-readable ID that should be stable across calls, to assist with selection UIs. Do not attempt to parse this string as the format is not guaranteed.
          example: /film/123|hd-rent-stripe-purchase
        provider:
          type: string
          description: The payment provider this purchase option is intended to be used with.
          example: stripe_elements
        quality:
          type: string
          description: For video content purchases, is this an HD or SD purchase. Not present for plans.
          enum:
            - hd
            - sd
        ownership:
          type: string
          description: For video content purchases, is this a rental or a longer term ownership (buy / EST). Not present for plans.
          enum:
            - rent
            - buy
        price:
          description: The price the user will pay for this. This taken into account any discounts and plan based pricing. Will be absent if there is no monetary price to pay.
          allOf:
            - $ref: '#/components/schemas/PurchaseOptionPrice'
        original_price:
          description: If a discount was applied, this is the base price.
          allOf:
            - $ref: '#/components/schemas/PurchaseOptionPrice'
        period:
          description: Present for subscriptions. This should match the period on the price.
          allOf:
            - $ref: '#/components/schemas/PurchaseOptionPrice'
        discount:
          type: object
          description: Information about the discount
          properties:
            eligible:
              type: boolean
              description: Whether the promo-code can be applied to this purchase option.
            type:
              type: string
              description: The kind of discount. Percentage or a fixed value off
              enum:
                - percentage
                - value
            amount_off:
              description: How much the price was discounted by (positive value)
              allOf:
                - $ref: '#/components/schemas/PurchaseOptionPrice'
