openapi: 3.0.3
info:
  title: 'TransVoucher API'
  description: 'TransVoucher API allows you to create and manage cryptocurrency payment intents for your customers. Accept fiat payments and receive cryptocurrency settlements.'
  version: 1.0.0
  contact:
    name: 'TransVoucher Support'
    url: 'https://transvoucher.com'
    email: support@transvoucher.com
  termsOfService: 'https://transvoucher.com/terms-of-service'
servers:
  -
    url: 'https://api.transvoucher.com/v1.0'
    description: 'Production server'
  -
    url: 'https://sandbox-api.transvoucher.com/v1.0'
    description: 'Sandbox server'
security:
  -
    ApiKeyAuth: {  }
    ApiSecretAuth: {  }
paths:
  /:
    get:
      summary: 'API Status'
      description: 'Check if the API is active and get basic information'
      operationId: getApiStatus
      security: {  }
      responses:
        200:
          description: 'API is active'
          content:
            application/json:
              schema:
                type: object
                properties:
                  message: { type: string, example: 'TransVoucher Production API 1.0' }
                  status: { type: string, example: active }
                  environment: { type: string, example: production }
  /payment/create:
    post:
      summary: 'Create Payment Intent'
      description: 'Create a new payment intent/link for a customer to complete payment'
      operationId: createPayment
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePaymentRequest'
      responses:
        201:
          description: 'Payment intent created successfully'
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean, example: true }
                  data: { $ref: '#/components/schemas/Payment' }
        400:
          $ref: '#/components/responses/BadRequest'
        401:
          $ref: '#/components/responses/Unauthorized'
        422:
          $ref: '#/components/responses/ValidationError'
        500:
          $ref: '#/components/responses/InternalError'
          description: Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean, example: true }
                  data: { $ref: '#/components/schemas/Payment' }
  '/payment/status/{referenceId}':
    get:
      summary: 'Get Payment Status'
      description: 'Retrieve the current status of a payment by transaction ID'
      operationId: getPaymentStatus
      parameters:
        -
          name: referenceId
          in: path
          schema:
            type: string
            example: 01234567-89ab-cdef-0123-456789abcdef
          description: 'The transaction ID'
          required: true
      responses:
        200:
          description: 'Payment status retrieved successfully'
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean, example: true }
                  data: { $ref: '#/components/schemas/PaymentStatus' }
        401:
          $ref: '#/components/responses/Unauthorized'
        404:
          $ref: '#/components/responses/NotFound'
          description: Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean, example: true }
                  data: { $ref: '#/components/schemas/PaymentStatus' }
  /payment/list:
    get:
      summary: 'List Payments'
      description: 'Retrieve a paginated list of payments with optional filtering'
      operationId: listPayments
      parameters:
        -
          name: to_date
          in: query
          schema:
            type: string
            format: date
          description: 'Filter payments to this date (YYYY-MM-DD)'
      responses:
        200:
          description: 'Payments retrieved successfully'
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean, example: true }
                  data: { $ref: '#/components/schemas/PaymentList' }
        400:
          $ref: '#/components/responses/BadRequest'
        401:
          $ref: '#/components/responses/Unauthorized'
        422:
          $ref: '#/components/responses/ValidationError'
          description: Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean, example: true }
                  data: { $ref: '#/components/schemas/PaymentList' }
  '/payment-link/status/{paymentLinkId}':
    get:
      summary: 'Get Payment Link Status'
      description: 'Retrieve the status of a payment link by its ID'
      operationId: getPaymentLinkStatus
      parameters:
        -
          name: paymentLinkId
          in: path
          schema:
            type: string
            example: 01234567-89ab-cdef-0123-456789abcdef
          description: 'The payment link ID'
          required: true
      responses:
        200:
          description: 'Payment link status retrieved successfully'
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean, example: true }
                  data: { $ref: '#/components/schemas/PaymentLinkStatus' }
        401:
          $ref: '#/components/responses/Unauthorized'
        404:
          $ref: '#/components/responses/NotFound'
          description: Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean, example: true }
                  data: { $ref: '#/components/schemas/PaymentLinkStatus' }
  /currencies:
    get:
      summary: 'Get Active Currencies'
      description: 'Retrieve all active processing currencies'
      operationId: getCurrencies
      security: {  }
      responses:
        200:
          description: 'Currencies retrieved successfully'
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean, example: true }
                  data: { type: array, items: { $ref: '#/components/schemas/Currency' } }
  /networks:
    get:
      summary: 'Get Active Networks'
      description: 'Retrieve all active settlement networks (blockchain networks)'
      operationId: getNetworks
      security: {  }
      responses:
        200:
          description: 'Networks retrieved successfully'
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean, example: true }
                  data: { type: array, items: { $ref: '#/components/schemas/Network' } }
  /commodities:
    get:
      summary: 'Get Active Commodities'
      description: 'Retrieve all active settlement commodities (cryptocurrencies)'
      operationId: getCommodities
      security: {  }
      responses:
        200:
          description: 'Commodities retrieved successfully'
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean, example: true }
                  data: { type: array, items: { $ref: '#/components/schemas/Commodity' } }
  '/conversion-rate/{network}/{commodity}/{fiatCurrency}/{paymentMethod}':
    get:
      summary: 'Get Conversion Rate'
      description: 'Get the current conversion rate for a network, commodity, and fiat currency pair'
      operationId: getConversionRate
      security: {  }
      parameters:
        -
          name: network
          in: path
          schema:
            type: string
            example: POL
          description: 'Network short_code (use /networks endpoint to see available values)'
          required: true
        -
          name: commodity
          in: path
          schema:
            type: string
            example: USDT
          description: 'Commodity short_code (use /commodities endpoint to see available values)'
          required: true
        -
          name: fiatCurrency
          in: path
          schema:
            type: string
            example: USD
          description: 'Fiat currency code (use /currencies endpoint to see available values)'
          required: true
        -
          name: paymentMethod
          in: path
          schema:
            type: string
            default: card
            example: card
          description: 'Payment method (e.g., card, bank_transfer)'
          required: true
      responses:
        200:
          description: 'Conversion rate retrieved successfully'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: { type: object, properties: { rate: { type: string, description: 'The conversion rate', example: '1.05' } } }
        400:
          $ref: '#/components/responses/BadRequest'
          description: Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: { type: object, properties: { rate: { type: string, description: 'The conversion rate', example: '1.05' } } }
  /payment/webhook:
    post:
      summary: 'Receive Payment Webhooks (Your Server)'
      description: 'This endpoint represents YOUR webhook endpoint that will receive payment events from TransVoucher. You must configure this URL in your merchant dashboard. All webhook requests include X-Webhook-Signature header for verification using HMAC SHA256 with your endpoint secret.'
      operationId: receiveWebhook
      security: {  }
      parameters:
        -
          name: X-Webhook-Signature
          in: header
          schema:
            type: string
            example: sha256=1234567890abcdef...
          description: 'HMAC SHA256 signature of the request body (format: sha256=<hex>). Verify this using your endpoint secret.'
          required: true
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEvent'
      responses:
        200:
          description: 'Webhook received and processed successfully'
        400:
          description: 'Invalid webhook or signature verification failed'
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: 'Your API key from the TransVoucher dashboard'
    ApiSecretAuth:
      type: apiKey
      in: header
      name: X-API-Secret
      description: 'Your API secret from the TransVoucher dashboard'
  schemas:
    CreatePaymentRequest:
      type: object
      required:
        - title
      properties:
        amount:
          type: number
          format: double
          minimum: 0.01
          description: 'Payment amount in fiat currency. Required unless is_price_dynamic is true. When is_price_dynamic is true, customers can enter their own amount during checkout.'
          example: 100.5
        currency:
          type: string
          description: 'Fiat currency code (default: USD)'
          example: USD
        title:
          type: string
          maxLength: 255
          description: 'Payment title/description'
          example: 'Order #12345'
        description:
          type: string
          maxLength: 1000
          description: 'Additional payment description'
          example: 'Purchase of premium subscription'
        redirect_url:
          type: string
          format: uri
          description: 'URL to redirect to after payment (deprecated, use success_url and cancel_url)'
          example: 'https://example.com/payment/complete'
        success_url:
          type: string
          format: uri
          description: 'URL to redirect to after successful payment'
          example: 'https://example.com/payment/success'
        cancel_url:
          type: string
          format: uri
          description: 'URL to redirect to if payment is cancelled'
          example: 'https://example.com/payment/cancel'
        metadata:
          type: object
          description: 'Custom metadata to attach to the payment (returned in webhooks)'
          example:
            order_id: '12345'
            customer_id: cust_abc123
        customer_details:
          type: object
          description: 'Customer information'
          properties:
            email:
              type: string
              format: email
              example: customer@example.com
            phone:
              type: string
              example: '+1234567890'
            full_name:
              type: string
              example: 'John Doe'
            first_name:
              type: string
              minLength: 2
              maxLength: 255
              example: John
            middle_name:
              type: string
              maxLength: 255
              example: Michael
            last_name:
              type: string
              minLength: 2
              maxLength: 255
              example: Doe
            date_of_birth:
              type: string
              format: date
              example: '1990-01-15'
            country_of_residence:
              type: string
              description: 'ISO 3166-1 alpha-2 country code'
              example: US
            state_of_residence:
              type: string
              description: 'US state code (for US residents)'
              example: CA
            card_country_code:
              type: string
              description: 'ISO 3166-1 alpha-2 country code for card billing address'
              example: US
            card_state_code:
              type: string
              description: 'US state code for card billing address'
              example: CA
            card_city:
              type: string
              example: 'San Francisco'
            card_post_code:
              type: string
              example: '94102'
            card_street:
              type: string
              example: '123 Main St'
        theme:
          type: string
          enum:
            - dark
            - light
          description: 'UI theme for payment page'
          example: light
        lang:
          type: string
          enum:
            - en
            - es
            - fr
            - de
            - it
            - pt
            - ru
            - zh
            - ja
            - ko
            - tr
            - ka
          description: 'Language code for payment page'
          example: en
        default_payment_method:
          type: string
          enum:
            - card
            - apple-pay
            - google-pay
          description: 'Default payment method to pre-select or force'
          example: card
        payment_method_forced:
          type: boolean
          description: 'If true, only the default_payment_method will be available. If false, user can choose other methods'
          example: false
        expires_at:
          type: string
          format: date-time
          description: 'When the payment link expires'
          example: '2024-12-31T23:59:59Z'
        custom_fields:
          type: object
          description: 'Custom fields to collect from customer'
          example:
            company_name: 'Acme Corp'
        multiple_use:
          type: boolean
          description: 'Whether the payment link can be used multiple times'
          example: false
        cancel_on_first_fail:
          type: boolean
          description: 'Cancel payment link after first failed attempt'
          example: false
        is_price_dynamic:
          type: boolean
          description: 'Whether the customer can enter their own amount'
          example: false
    Payment:
      type: object
      properties:
        id:
          type: string
          description: 'Payment link ID'
          example: 01234567-89ab-cdef-0123-456789abcdef
        payment_link_id:
          type: string
          description: 'Payment link ID (same as id)'
          example: 01234567-89ab-cdef-0123-456789abcdef
        reference_id:
          type: string
          description: 'Payment session reference ID'
          example: 01234567-89ab-cdef-0123-456789abcdef
        transaction_id:
          type: string
          nullable: true
          description: 'Transaction ID (only present after payment is initiated)'
          example: 01234567-89ab-cdef-0123-456789abcdef
        payment_url:
          type: string
          format: uri
          description: 'URL where customer can complete payment'
          example: 'https://transvoucher.com/pay/abc123'
        title:
          type: string
          description: 'Payment title'
          example: 'Order #12345'
        description:
          type: string
          nullable: true
          description: 'Payment description'
          example: 'Purchase of premium subscription'
        flow_type:
          type: string
          description: 'Payment flow type'
          example: nft
        amount:
          type: number
          format: double
          nullable: true
          description: 'Payment amount'
          example: 100.5
        fiat_base_amount:
          type: number
          format: double
          nullable: true
          description: 'Base fiat amount before fees'
          example: 100.5
        fiat_total_amount:
          type: number
          format: double
          nullable: true
          description: 'Total fiat amount including fees'
          example: 105
        currency:
          type: string
          nullable: true
          description: 'Fiat currency code'
          example: USD
        fiat_currency:
          type: string
          nullable: true
          description: 'Fiat currency code (same as currency)'
          example: USD
        commodity:
          type: string
          nullable: true
          description: 'Cryptocurrency commodity'
          example: USDT
        commodity_amount:
          type: number
          format: double
          nullable: true
          description: 'Amount of cryptocurrency'
          example: 100
        network:
          type: string
          nullable: true
          description: 'Blockchain network (e.g., POL for Polygon, BSC, ETH)'
          example: POL
        settled_amount:
          type: number
          format: double
          nullable: true
          description: 'Amount settled to merchant wallets'
          example: 100
        blockchain_tx_hash:
          type: string
          nullable: true
          description: 'Blockchain transaction hash'
          example: '0x1234567890abcdef'
        status:
          type: string
          enum:
            - pending
            - attempting
            - processing
            - completed
            - failed
            - expired
            - cancelled
          description: 'Payment status'
          example: pending
        fail_reason:
          type: string
          nullable: true
          description: 'Reason for payment failure'
          example: null
        expires_at:
          type: string
          format: date-time
          nullable: true
          description: 'When the payment link expires'
          example: '2024-12-31T23:59:59Z'
        created_at:
          type: string
          format: date-time
          description: 'When the payment was created'
          example: '2024-01-15T10:30:00Z'
        updated_at:
          type: string
          format: date-time
          description: 'When the payment was last updated'
          example: '2024-01-15T10:35:00Z'
        paid_at:
          type: string
          format: date-time
          nullable: true
          description: 'When the payment was completed'
          example: null
        custom_fields:
          type: object
          nullable: true
          description: 'Custom fields'
        customer_commission_percentage:
          type: number
          format: double
          nullable: true
          description: 'Customer commission percentage'
        multiple_use:
          type: boolean
          nullable: true
          description: 'Whether payment link can be used multiple times'
        customer_details:
          type: object
          nullable: true
          description: 'Customer information'
        metadata:
          type: object
          nullable: true
          description: 'Custom metadata'
        payment_method:
          type: object
          nullable: true
          description: 'Payment method details'
          properties:
            type:
              type: string
              nullable: true
              enum:
                - card
                - apple_pay
                - google_pay
              description: 'Payment method type'
            card_id:
              type: string
              nullable: true
              description: 'Card identifier (only for card payments)'
            brand:
              type: string
              nullable: true
              enum:
                - VISA
                - MASTERCARD
                - AMEX
                - JCB
                - DISCOVER
              description: 'Card brand (only for card payments)'
            processor:
              type: string
              nullable: true
              enum:
                - safecharge
                - ap_safecharge
                - gp_safecharge
                - worldpay
              description: 'Payment processor'
    PaymentStatus:
      type: object
      properties:
        transaction_id:
          type: string
          description: 'Transaction ID'
          example: 01234567-89ab-cdef-0123-456789abcdef
        reference_id:
          type: string
          nullable: true
          description: 'Payment session reference ID'
          example: 01234567-89ab-cdef-0123-456789abcdef
        fiat_base_amount:
          type: number
          format: double
          description: 'Base fiat amount'
          example: 100.5
        fiat_total_amount:
          type: number
          format: double
          description: 'Total fiat amount including fees'
          example: 105
        fiat_currency:
          type: string
          description: 'Fiat currency code'
          example: USD
        commodity:
          type: string
          description: 'Cryptocurrency commodity'
          example: USDT
        commodity_amount:
          type: number
          format: double
          nullable: true
          description: 'Amount of cryptocurrency'
          example: 100
        network:
          type: string
          nullable: true
          description: 'Blockchain network (e.g., POL for Polygon, BSC, ETH)'
          example: POL
        settled_amount:
          type: number
          format: double
          description: 'Amount settled to merchant'
          example: 100
        blockchain_tx_hash:
          type: string
          nullable: true
          description: 'Blockchain transaction hash'
          example: '0x1234567890abcdef'
        status:
          type: string
          enum:
            - pending
            - attempting
            - processing
            - completed
            - failed
            - expired
            - cancelled
          description: 'Payment status'
          example: completed
        fail_reason:
          type: string
          nullable: true
          description: 'Reason for failure if status is failed'
          example: null
        created_at:
          type: string
          format: date-time
          description: 'Transaction creation timestamp'
          example: '2024-01-15T10:30:00Z'
        updated_at:
          type: string
          format: date-time
          description: 'Transaction last update timestamp'
          example: '2024-01-15T10:35:00Z'
        paid_at:
          type: string
          format: date-time
          nullable: true
          description: 'Payment completion timestamp'
          example: '2024-01-15T10:35:00Z'
        payment_details:
          type: object
          deprecated: true
          description: 'Payment details (deprecated, use payment_method instead)'
          properties:
            notice:
              type: string
              example: '"payment_details" is deprecated and will be dropped soon'
            payment_method:
              type: object
        payment_method:
          type: object
          nullable: true
          description: 'Payment method information'
          properties:
            type:
              type: string
              nullable: true
              enum:
                - card
                - apple_pay
                - google_pay
              description: 'Payment method type'
            card_id:
              type: string
              nullable: true
              description: 'Card identifier (only for card payments)'
            brand:
              type: string
              nullable: true
              enum:
                - VISA
                - MASTERCARD
                - AMEX
                - JCB
                - DISCOVER
              description: 'Card brand (only for card payments)'
            processor:
              type: string
              nullable: true
              enum:
                - safecharge
                - ap_safecharge
                - gp_safecharge
                - worldpay
              description: 'Payment processor'
    PaymentLinkStatus:
      type: object
      oneOf:
        -
          type: object
          description: 'Payment link without transaction'
          properties:
            id:
              type: string
              description: 'Payment link ID'
            transaction_id:
              type: 'null'
            reference_id:
              type: string
              nullable: true
            status:
              type: string
              enum:
                - pending
                - failed
                - cancelled
                - expired
        -
          allOf:
            -
              type: object
              properties:
                id:
                  type: string
                  description: 'Payment link ID'
            -
              $ref: '#/components/schemas/PaymentStatus'
    PaymentList:
      type: object
      properties:
        payments:
          type: array
          items:
            allOf:
              -
                $ref: '#/components/schemas/PaymentStatus'
              -
                type: object
                properties:
                  id: { type: string, description: 'Payment ID' }
                  title: { type: string, nullable: true, description: 'Payment title' }
                  description: { type: string, nullable: true, description: 'Payment description' }
        has_more:
          type: boolean
          description: 'Whether there are more results available'
          example: true
        next_page_token:
          type: string
          nullable: true
          description: 'Token for fetching next page'
          example: eyJsYXN0X2lkIjoxMjM0NX0=
        count:
          type: integer
          description: 'Number of payments in this response'
          example: 10
    Currency:
      type: object
      properties:
        short_code:
          type: string
          description: 'Currency code'
          example: USD
        name:
          type: string
          description: 'Currency name'
          example: 'US Dollar'
        symbol:
          type: string
          description: 'Currency symbol'
          example: $
        current_usd_value:
          type: string
          nullable: true
          description: 'Current USD exchange rate'
          example: '1.00'
        processed_via_currency_code:
          type: string
          nullable: true
          description: 'Currency code this is processed via'
          example: null
    Network:
      type: object
      properties:
        short_code:
          type: string
          description: 'Network short code'
          example: POL
        identifier:
          type: string
          description: 'Network identifier'
          example: polygon
        name:
          type: string
          description: 'Network name'
          example: Polygon
        token_standard:
          type: string
          nullable: true
          description: 'Token standard (e.g., ERC-20, BEP-20)'
          example: ERC-20
        chain_id:
          type: integer
          nullable: true
          description: 'Blockchain chain ID'
          example: 137
        explorer_url:
          type: string
          nullable: true
          description: 'Block explorer URL'
          example: 'https://polygonscan.com'
        icon_url:
          type: string
          nullable: true
          description: 'Full URL to network icon image'
          example: 'https://transvoucher.com/storage/networks/POL.webp'
        is_testnet:
          type: boolean
          description: 'Whether this is a testnet or mainnet'
          example: false
    Commodity:
      type: object
      properties:
        short_code:
          type: string
          description: 'Commodity short code'
          example: USDT
        name:
          type: string
          description: 'Commodity name'
          example: 'Tether USD'
        icon_url:
          type: string
          nullable: true
          description: 'Full URL to commodity icon image'
          example: 'https://transvoucher.com/storage/commodities/USDT.webp'
        current_usd_value:
          type: string
          nullable: true
          description: 'Current USD value of the commodity'
          example: '1.00'
        contract_address:
          type: string
          nullable: true
          description: 'Smart contract address on the blockchain'
          example: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F'
        decimals:
          type: integer
          nullable: true
          description: 'Number of decimal places for the commodity'
          example: 6
        network_short_code:
          type: string
          nullable: true
          description: 'Network short code this commodity operates on'
          example: POL
    WebhookEvent:
      type: object
      description: 'Webhook event sent to your endpoint'
      properties:
        event:
          type: string
          enum:
            - payment_intent.created
            - payment_intent.attempting
            - payment_intent.processing
            - payment_intent.succeeded
            - payment_intent.failed
            - payment_intent.cancelled
            - payment_intent.expired
            - system.health_check
          description: 'Event type'
        timestamp:
          type: string
          format: date-time
          description: 'Webhook event timestamp'
        data:
          oneOf:
            -
              $ref: '#/components/schemas/WebhookEventData'
            -
              $ref: '#/components/schemas/HealthCheckEventData'
    HealthCheckEventData:
      type: object
      description: 'Health check event data payload'
      properties:
        message:
          type: string
          description: 'Health check message'
          example: 'This is a health check from TransVoucher.'
        sales_channel_id:
          type: integer
          description: 'Sales channel ID'
          example: 12345
    WebhookEventData:
      type: object
      description: 'Webhook event data payload'
      properties:
        payment_link_id:
          type: string
          nullable: true
          description: 'Payment link ID'
        transaction:
          type: object
          description: 'Transaction details'
          properties:
            id:
              type: string
              description: 'Transaction ID'
            reference_id:
              type: string
              description: 'Payment session reference ID'
            fiat_base_amount:
              type: string
              description: 'Base fiat amount'
            fiat_total_amount:
              type: string
              description: 'Total fiat amount including fees'
            fiat_currency:
              type: string
              description: 'Fiat currency code'
            commodity_amount:
              type: string
              description: 'Amount of cryptocurrency'
            commodity:
              type: string
              description: 'Cryptocurrency commodity'
            network:
              type: string
              description: 'Blockchain network (e.g., POL for Polygon)'
            status:
              type: string
              enum:
                - pending
                - attempting
                - processing
                - completed
                - failed
                - expired
                - cancelled
              description: 'Transaction status'
            created_at:
              type: string
              format: date-time
              description: 'Transaction creation timestamp'
            updated_at:
              type: string
              format: date-time
              description: 'Transaction last update timestamp'
            paid_at:
              type: string
              format: date-time
              nullable: true
              description: 'Payment completion timestamp'
        blockchain_tx_hash:
          type: string
          nullable: true
          description: 'Blockchain transaction hash'
        settled_amount:
          type: number
          format: double
          nullable: true
          description: 'Amount settled to merchant wallets'
        fail_reason:
          type: string
          nullable: true
          description: 'Reason for payment failure (only present in failed events)'
        sales_channel:
          type: object
          description: 'Sales channel information'
          properties:
            id:
              type: integer
              description: 'Sales channel ID'
            name:
              type: string
              description: 'Sales channel name'
            type:
              type: string
              description: 'Sales channel type'
        merchant:
          type: object
          description: 'Merchant information'
          properties:
            id:
              type: integer
              description: 'Merchant ID'
            company_name:
              type: string
              description: 'Merchant company name'
        customer_details:
          type: object
          nullable: true
          description: 'Customer information (all fields optional)'
          properties:
            email:
              type: string
              nullable: true
            phone:
              type: string
              nullable: true
            first_name:
              type: string
              nullable: true
            middle_name:
              type: string
              nullable: true
            last_name:
              type: string
              nullable: true
            date_of_birth:
              type: string
              format: date
              nullable: true
            country_of_residence:
              type: string
              nullable: true
              description: 'ISO alpha-2 country code'
            state_of_residence:
              type: string
              nullable: true
              description: 'US state code (alpha-2 uppercase)'
            card_country_code:
              type: string
              nullable: true
              description: 'ISO alpha-2 country code'
            card_state_code:
              type: string
              nullable: true
              description: 'US state code (alpha-2 uppercase)'
            card_city:
              type: string
              nullable: true
            card_post_code:
              type: string
              nullable: true
            card_street:
              type: string
              nullable: true
            lang:
              type: string
              nullable: true
              enum:
                - en
                - es
                - fr
                - de
                - it
                - pt
                - ru
                - zh
                - ja
                - ko
                - tr
              description: 'Language for payment page'
        metadata:
          type: object
          nullable: true
          description: 'Custom metadata including payment_link_title, payment_link_description, and your custom fields'
        payment_method:
          type: object
          nullable: true
          description: 'Payment method information'
          properties:
            type:
              type: string
              nullable: true
              enum:
                - card
                - apple_pay
                - google_pay
            brand:
              type: string
              nullable: true
              enum:
                - VISA
                - MASTERCARD
                - AMEX
                - JCB
                - DISCOVER
            processor:
              type: string
              nullable: true
              enum:
                - safecharge
                - ap_safecharge
                - gp_safecharge
                - worldpay
            card_id:
              type: string
              nullable: true
              description: 'Card identifier (only for card payments)'
    Error:
      type: object
      properties:
        error:
          type: boolean
          example: true
        message:
          type: string
          description: 'Error message'
          example: 'Invalid request'
        errors:
          type: object
          description: 'Validation errors (only for 422 responses)'
          additionalProperties:
            type: array
            items:
              type: string
  responses:
    Unauthorized:
      description: 'Authentication failed'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: true
            message: 'Invalid API credentials'
    BadRequest:
      description: 'Bad request'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: true
            message: 'Invalid request parameters'
    NotFound:
      description: 'Resource not found'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: true
            message: 'Transaction not found'
    ValidationError:
      description: 'Validation error'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: true
            message: 'Validation failed'
            errors:
              amount:
                - 'The amount field is required.'
              title:
                - 'The title field is required.'
    InternalError:
      description: 'Internal server error'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: true
            message: 'An internal error occurred'
tags:
  -
    name: Payments
    description: 'Payment operations'
  -
    name: Metadata
    description: 'Metadata endpoints'
