openapi: 3.1.0
info:
  title: CoinPay Merchant API
  version: 1.0.0
  description: Server-to-server API for secure hosted payment orchestration.
servers:
  - url: https://pay.mapto.com/api/v1
security:
  - bearerAuth: []
paths:
  /payment-sessions:
    post:
      summary: Create a hosted payment session
      parameters:
        - in: header
          name: Idempotency-Key
          required: true
          schema: { type: string, minLength: 8, maxLength: 100 }
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePaymentSession'
      responses:
        '201':
          description: Payment session created
        '401':
          description: Invalid API key
        '422':
          description: Destination wallet is not allowlisted
  /payment-sessions/{id}:
    get:
      summary: Retrieve a payment session
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
      responses:
        '200': { description: Current payment state }
        '404': { description: Payment not found for this merchant }
  /payment-links:
    post:
      summary: Create a shareable payment link
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [title, amount]
              properties:
                title: { type: string }
                amount: { type: string, pattern: '^\\d+(\\.\\d{1,2})?$' }
                currency: { type: string, default: USD }
                customer_reference: { type: string }
      responses:
        '201': { description: Payment link created }
webhooks:
  paymentStatus:
    post:
      summary: Signed payment status callback sent to the merchant
      parameters:
        - in: header
          name: CoinPay-Signature
          required: true
          schema: { type: string, example: 't=1723200000,v1=hex_hmac' }
        - in: header
          name: CoinPay-Event
          required: true
          schema: { type: string, example: payment.succeeded }
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/WebhookEvent' }
      responses:
        '200': { description: Acknowledge within five seconds }
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
  schemas:
    CreatePaymentSession:
      type: object
      required: [merchant_order_id, amount]
      properties:
        merchant_order_id: { type: string, maxLength: 100 }
        customer_reference: { type: string, maxLength: 100 }
        amount: { type: string, example: '250.00' }
        currency: { type: string, default: USD }
        crypto_asset: { type: string, default: USDT }
        destination_wallet:
          type: string
          description: Optional; if sent, must equal the merchant allowlisted wallet.
    WebhookEvent:
      type: object
      required: [id, type, created_at, data]
      properties:
        id: { type: string }
        type: { type: string, enum: [payment.succeeded, payment.failed, payment.cancelled, payment.expired] }
        created_at: { type: string, format: date-time }
        data:
          type: object
          properties:
            payment:
              type: object
              properties:
                id: { type: string }
                merchant_order_id: { type: string }
                customer_reference: { type: string }
                amount: { type: string }
                currency: { type: string }
                status: { type: string }
