openapi: '3.1.0'
info:
  title: Apt Commerce API
  version: '1.0.0'
  description: |
    Modern payment processing API supporting cards, ACH, and stablecoin payments.
    All requests and responses use JSON. Authentication via Bearer token.
  contact:
    name: Apt Commerce Developer Support
    url: https://github.com/aptcommerce/api-spec
servers:
  - url: https://api.aptcommerce.com/v1
    description: Production
  - url: https://sandbox.aptcommerce.com/v1
    description: Sandbox

security:
  - BearerAuth: []

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: 'Use sk_live_ or sk_test_ prefixed keys'

  schemas:
    Address:
      type: object
      description: International address object. Use the country field (ISO 3166-1 alpha-2) to indicate format.
      properties:
        line1:
          type: string
          description: Street address, P.O. box, or company name
          example: '123 Main St'
        line2:
          type: string
          description: Apartment, suite, unit, or building
          example: 'Suite 100'
        line3:
          type: string
          description: Additional address line (used in GB, JP, BR, IN, and others requiring 3+ lines)
        city:
          type: string
          description: City, town, village, or locality
          example: 'Austin'
        state:
          type: string
          description: State, province, region, county, or prefecture
          example: 'TX'
        postal_code:
          type: string
          description: ZIP or postal code (format varies by country)
          example: '78701'
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code
          example: 'US'
        district:
          type: string
          description: District, sub-locality, or ward (used in JP, IN, BR, KR, TH)
        sorting_code:
          type: string
          description: CEDEX or sorting code (used in FR, BE)

    Transaction:
      type: object
      properties:
        id:
          type: string
          example: txn_1a2b3c4d
        object:
          type: string
          enum: [transaction]
        amount:
          type: integer
          description: Amount in cents
          example: 9900
        currency:
          type: string
          example: usd
        status:
          type: string
          enum: [pending, completed, failed, refunded, voided]
        payment_method:
          type: string
          enum: [card, ach, stablecoin]
        customer:
          type: string
          example: cust_abc123
        description:
          type: string
        billing_address:
          $ref: '#/components/schemas/Address'
        shipping_address:
          $ref: '#/components/schemas/Address'
        created_at:
          type: string
          format: date-time
        metadata:
          type: object
        links:
          type: object
          properties:
            self:
              type: string
            customer:
              type: string
            refund:
              type: string

    Customer:
      type: object
      properties:
        id:
          type: string
          example: cust_abc123
        object:
          type: string
          enum: [customer]
        name:
          type: string
        email:
          type: string
          format: email
        phone:
          type: string
        created_at:
          type: string
          format: date-time
        metadata:
          type: object

    ListEnvelope:
      type: object
      properties:
        object:
          type: string
          enum: [list]
        data:
          type: array
          items: {}
        has_more:
          type: boolean
        next_cursor:
          type: string
        total_count:
          type: integer

    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            type:
              type: string
            code:
              type: string
            message:
              type: string
            status:
              type: integer

paths:
  /transactions:
    post:
      summary: Create a transaction
      operationId: createTransaction
      tags: [Transactions]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [amount, currency, payment_method]
              properties:
                amount:
                  type: integer
                currency:
                  type: string
                payment_method:
                  type: string
                customer:
                  type: string
                description:
                  type: string
                capture:
                  type: boolean
                  default: true
                billing_address:
                  $ref: '#/components/schemas/Address'
                shipping_address:
                  $ref: '#/components/schemas/Address'
                metadata:
                  type: object
      responses:
        '201':
          description: Transaction created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transaction'
    get:
      summary: List transactions
      operationId: listTransactions
      tags: [Transactions]
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 25
      responses:
        '200':
          description: List of transactions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListEnvelope'

  /transactions/{id}:
    get:
      summary: Retrieve a transaction
      operationId: getTransaction
      tags: [Transactions]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Transaction details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transaction'

  /transactions/{id}/refund:
    post:
      summary: Refund a transaction
      operationId: refundTransaction
      tags: [Transactions]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                amount:
                  type: integer
                  description: Partial refund amount in cents. Omit for full refund.
      responses:
        '200':
          description: Refund processed

  /transactions/{id}/capture:
    post:
      summary: Capture an authorized transaction
      operationId: captureTransaction
      tags: [Transactions]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Transaction captured

  /transactions/{id}/void:
    post:
      summary: Void an unsettled transaction
      operationId: voidTransaction
      tags: [Transactions]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Transaction voided

  /customers:
    get:
      summary: List customers
      operationId: listCustomers
      tags: [Customers]
      responses:
        '200':
          description: List of customers
    post:
      summary: Create a customer
      operationId: createCustomer
      tags: [Customers]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name, email]
              properties:
                name:
                  type: string
                email:
                  type: string
                phone:
                  type: string
                metadata:
                  type: object
      responses:
        '201':
          description: Customer created

  /customers/{id}:
    get:
      summary: Retrieve a customer
      operationId: getCustomer
      tags: [Customers]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Customer details
    patch:
      summary: Update a customer
      operationId: updateCustomer
      tags: [Customers]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Customer updated
    delete:
      summary: Delete a customer
      operationId: deleteCustomer
      tags: [Customers]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '204':
          description: Customer deleted

  /invoices:
    post:
      summary: Create an invoice
      operationId: createInvoice
      tags: [Invoices]
      responses:
        '201':
          description: Invoice created

  /invoices/{id}:
    get:
      summary: Retrieve an invoice
      operationId: getInvoice
      tags: [Invoices]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Invoice details

  /invoices/{id}/send:
    post:
      summary: Send an invoice
      operationId: sendInvoice
      tags: [Invoices]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Invoice sent

  /payment-links:
    post:
      summary: Create a payment link
      operationId: createPaymentLink
      tags: [Payment Links]
      responses:
        '201':
          description: Payment link created
    get:
      summary: List payment links
      operationId: listPaymentLinks
      tags: [Payment Links]
      responses:
        '200':
          description: List of payment links

  /subscriptions:
    post:
      summary: Create a subscription
      operationId: createSubscription
      tags: [Subscriptions]
      responses:
        '201':
          description: Subscription created

  /subscriptions/{id}:
    get:
      summary: Retrieve a subscription
      operationId: getSubscription
      tags: [Subscriptions]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Subscription details

  /subscriptions/{id}/cancel:
    post:
      summary: Cancel a subscription
      operationId: cancelSubscription
      tags: [Subscriptions]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Subscription cancelled
