openapi: 3.0.3
info:
  title: PSP Gateway Invoice API
  version: 1.0.0
  description: |
    Invoice service surface for merchant invoice write flows. This service
    only accepts invoice account secrets and rejects transfer/query/webhook/proof
    traffic.
    A missing X-API-ID header returns 400 INVALID_REQUEST. A missing X-API-Key
    header or invalid credentials return 401 UNAUTHORIZED. A credential store
    failure returns 500 INTERNAL_ERROR before the request handler runs.
servers:
  - url: https://invoice-api.psp.example.com
    description: Example host; obtain the actual Invoice host from PSP
tags:
  - name: Invoice Payment Intents
  - name: Invoice Credit Cards
  - name: Invoice Tokenization
security:
  - AccountSecretEd25519: []
paths:
  /api/v1/payments/intents:
    post:
      tags: [Invoice Payment Intents]
      summary: Create a invoice payment intent
      description: |
        Requires a invoice account secret and `invoices:write` scope.

        Send the idempotency key in `X-Idempotency-Key` or `Idempotency-Key`;
        at least one is required. When both are sent they must be equal,
        otherwise the request is rejected with 400 INVALID_REQUEST. The Ed25519
        signature covers `X-Idempotency-Key` when it is sent, otherwise
        `Idempotency-Key`.

        Unlike other write operations, this one is not deduplicated by the
        idempotency key: the gateway keeps no response cache for it, and the
        key does not decide retries. The invoice service identifies a retry by
        `merchant_order_id` within the merchant account; reusing a
        `merchant_order_id` with a different request is rejected with
        409 CONFLICT.
      parameters:
        - $ref: '#/components/parameters/XIdempotencyKey'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateInvoicePaymentIntentRequest'
      responses:
        '500':
          $ref: '#/components/responses/AuthenticationDependencyFailure'
        '201':
          description: Payment intent created
          content:
            application/json:
              schema: { $ref: '#/components/schemas/InvoiceResponse' }
        '400':
          description: >
            Invalid request. When payin_payer_validation_mode is optional or required
            and payer_info.tax_id is present but not a valid market document, or when
            required mode is missing payer name/tax_id, the gateway returns INVALID_REQUEST.
        '503':
          description: Risk evaluation unavailable; no invoice or provider order is created. Retry the same merchant order and idempotency key after the prerequisite is restored.
        '401':
          $ref: '#/components/responses/WrongServiceOrCredential'
        '403':
          $ref: '#/components/responses/PermissionDenied'
  /api/v1/payments/intents/{invoice_number}/cancel:
    post:
      tags: [Invoice Payment Intents]
      summary: Cancel a invoice payment intent
      description: |
        Send the idempotency key in `X-Idempotency-Key` or `Idempotency-Key`;
        at least one is required. When both are sent they must be equal,
        otherwise the request is rejected with 400 INVALID_REQUEST. The Ed25519
        signature covers `X-Idempotency-Key` when it is sent, otherwise
        `Idempotency-Key`.
      parameters:
        - $ref: '#/components/parameters/InvoiceNumber'
        - $ref: '#/components/parameters/XIdempotencyKey'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason: { type: string, maxLength: 500 }
      responses:
        '500':
          $ref: '#/components/responses/AuthenticationDependencyFailure'
        '200':
          description: Payment intent canceled
          content:
            application/json:
              schema:
                type: object
                required: [status]
                properties:
                  status: { type: string, enum: [canceled] }
        '401':
          $ref: '#/components/responses/WrongServiceOrCredential'
  /api/v1/payments/intents/{invoice_number}/refund:
    post:
      tags: [Invoice Payment Intents]
      summary: Create a invoice refund
      description: |
        Send the idempotency key in `X-Idempotency-Key` or `Idempotency-Key`;
        at least one is required. When both are sent they must be equal,
        otherwise the request is rejected with 400 INVALID_REQUEST. The Ed25519
        signature covers `X-Idempotency-Key` when it is sent, otherwise
        `Idempotency-Key`.

        The same header key is also the refund's business idempotency key
        within the merchant: a retry with the same key returns the existing
        refund, and reusing the key for a different refund is rejected with
        409 CONFLICT.

        New requests evaluate the original account's published refund rules
        before creating the refund or freezing funds. A block returns
        403 RISK_REJECTED; risk dependency failure returns 503 SERVICE_UNAVAILABLE.
        The refund amount is evaluated against the original frozen method/rail;
        no new invoice or transfer limit reservation is created.
      parameters:
        - $ref: '#/components/parameters/InvoiceNumber'
        - $ref: '#/components/parameters/XIdempotencyKey'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/CreateInvoiceRefundRequest' }
      responses:
        '500':
          $ref: '#/components/responses/AuthenticationDependencyFailure'
        '201':
          description: Invoice refund created
          content:
            application/json:
              schema: { $ref: '#/components/schemas/InvoiceRefundResponse' }
        '403':
          description: RISK_REJECTED or RISK_REVIEW; no refund created
        '503':
          description: SERVICE_UNAVAILABLE; refund risk evaluation failed closed
        '401':
          $ref: '#/components/responses/WrongServiceOrCredential'
  /api/v1/cards/authorizations:
    post:
      tags: [Invoice Credit Cards]
      summary: Create a credit card authorization
      description: |
        Send the idempotency key in `X-Idempotency-Key` or `Idempotency-Key`;
        at least one is required. When both are sent they must be equal,
        otherwise the request is rejected with 400 INVALID_REQUEST. The Ed25519
        signature covers `X-Idempotency-Key` when it is sent, otherwise
        `Idempotency-Key`.

        This operation has two idempotency layers. The header key is covered
        by the signature and deduplicates the request at the gateway. The
        required JSON field `idempotency_key` in the request body is the
        business idempotency key: the card service uses it to recognize a
        retried authorization within the merchant account. The gateway does
        not check that the two values are equal. Send the same value in both
        places and keep it unchanged when retrying.
      parameters:
        - $ref: '#/components/parameters/XIdempotencyKey'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/CardAuthorizationRequest' }
      responses:
        '500':
          $ref: '#/components/responses/AuthenticationDependencyFailure'
        '201':
          description: Authorization created
          content:
            application/json:
              schema: { type: object, additionalProperties: true }
  /api/v1/cards/authorizations/{authorization_id}/complete-3ds:
    post:
      tags: [Invoice Credit Cards]
      summary: Complete 3DS for an authorization
      description: |
        Send the idempotency key in `X-Idempotency-Key` or `Idempotency-Key`;
        at least one is required. When both are sent they must be equal,
        otherwise the request is rejected with 400 INVALID_REQUEST. The Ed25519
        signature covers `X-Idempotency-Key` when it is sent, otherwise
        `Idempotency-Key`.

        The header key only signs and deduplicates the request; the request
        body has no `idempotency_key`. A replayed completion is rejected by the
        one-time `cres_nonce` with 409 CONFLICT.
      parameters:
        - $ref: '#/components/parameters/AuthorizationID'
        - $ref: '#/components/parameters/XIdempotencyKey'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [invoice_id, transaction_id, auth_value, eci, cres_nonce]
              properties:
                invoice_id: { type: string, format: uuid }
                transaction_id: { type: string }
                auth_value: { type: string }
                eci: { type: string }
                cres_nonce: { type: string }
      responses:
        '410':
          description: Authorization has expired (INVOICE_EXPIRED).
        '500':
          $ref: '#/components/responses/AuthenticationDependencyFailure'
        '200':
          description: Authorization updated
  /api/v1/cards/captures:
    post:
      tags: [Invoice Credit Cards]
      summary: Capture a credit card authorization
      description: |
        Send the idempotency key in `X-Idempotency-Key` or `Idempotency-Key`;
        at least one is required. When both are sent they must be equal,
        otherwise the request is rejected with 400 INVALID_REQUEST. The Ed25519
        signature covers `X-Idempotency-Key` when it is sent, otherwise
        `Idempotency-Key`.

        This operation has two idempotency layers. The header key is covered
        by the signature and deduplicates the request at the gateway. The
        required JSON field `idempotency_key` in the request body is the
        business idempotency key: the card service uses it to recognize a
        retried capture. The gateway does not check that the two values are
        equal. Send the same value in both places and keep it unchanged when
        retrying.
      parameters:
        - $ref: '#/components/parameters/XIdempotencyKey'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [invoice_id, capture_amount, idempotency_key]
              properties:
                invoice_id: { type: string, format: uuid }
                capture_amount: { type: integer, format: int64, minimum: 1 }
                idempotency_key: { type: string }
                reason: { type: string }
      responses:
        '410':
          description: Authorization has expired (INVOICE_EXPIRED).
        '500':
          $ref: '#/components/responses/AuthenticationDependencyFailure'
        '200':
          description: Capture completed
          content:
            application/json:
              schema:
                type: object
                properties:
                  invoice_id: { type: string, format: uuid }
                  captured_amount: { type: integer, format: int64 }
                  total_captured: { type: integer, format: int64 }
                  status: { type: string }
                  captured_at: { type: string, format: date-time, nullable: true }
  /api/v1/cards/refunds:
    post:
      tags: [Invoice Credit Cards]
      summary: Create a credit card refund
      description: |
        Send the idempotency key in `X-Idempotency-Key` or `Idempotency-Key`;
        at least one is required. When both are sent they must be equal,
        otherwise the request is rejected with 400 INVALID_REQUEST. The Ed25519
        signature covers `X-Idempotency-Key` when it is sent, otherwise
        `Idempotency-Key`.

        This operation has two idempotency layers. The header key is covered
        by the signature and deduplicates the request at the gateway. The
        required JSON field `idempotency_key` in the request body is the
        business idempotency key: within the merchant account, a retry with
        the same `idempotency_key` and the same refund returns the first
        refund, and reusing it for a different refund is rejected with
        409 DUPLICATE_IDEMPOTENCY_KEY. The gateway does not check that the two
        values are equal. Send the same value in both places and keep it
        unchanged when retrying.
      parameters:
        - $ref: '#/components/parameters/XIdempotencyKey'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/CardRefundRequest' }
      responses:
        '500':
          $ref: '#/components/responses/AuthenticationDependencyFailure'
        '201':
          description: Card refund created
          content:
            application/json:
              schema: { type: object, additionalProperties: true }
  /api/v1/tokenization/cards:
    post:
      tags: [Invoice Tokenization]
      summary: Tokenize a card
      description: |
        Send the idempotency key in `X-Idempotency-Key` or `Idempotency-Key`;
        at least one is required. When both are sent they must be equal,
        otherwise the request is rejected with 400 INVALID_REQUEST. The Ed25519
        signature covers `X-Idempotency-Key` when it is sent, otherwise
        `Idempotency-Key`.
      parameters:
        - $ref: '#/components/parameters/XIdempotencyKey'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/TokenizeCardRequest' }
      responses:
        '500':
          $ref: '#/components/responses/AuthenticationDependencyFailure'
        '201':
          description: Token created
          content:
            application/json:
              schema: { $ref: '#/components/schemas/TokenResponse' }
  /api/v1/tokenization/bank-accounts:
    post:
      tags: [Invoice Tokenization]
      summary: Tokenize a bank account
      description: |
        Send the idempotency key in `X-Idempotency-Key` or `Idempotency-Key`;
        at least one is required. When both are sent they must be equal,
        otherwise the request is rejected with 400 INVALID_REQUEST. The Ed25519
        signature covers `X-Idempotency-Key` when it is sent, otherwise
        `Idempotency-Key`.
      parameters:
        - $ref: '#/components/parameters/XIdempotencyKey'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/TokenizeBankAccountRequest' }
      responses:
        '500':
          $ref: '#/components/responses/AuthenticationDependencyFailure'
        '201':
          description: Token created
          content:
            application/json:
              schema: { $ref: '#/components/schemas/TokenResponse' }
  /api/v1/tokenization/tokens/{token_id}/detokenize:
    post:
      tags: [Invoice Tokenization]
      summary: Detokenize a token
      description: |
        Send the idempotency key in `X-Idempotency-Key` or `Idempotency-Key`;
        at least one is required. When both are sent they must be equal,
        otherwise the request is rejected with 400 INVALID_REQUEST. The Ed25519
        signature covers `X-Idempotency-Key` when it is sent, otherwise
        `Idempotency-Key`.
      parameters:
        - $ref: '#/components/parameters/TokenID'
        - $ref: '#/components/parameters/XIdempotencyKey'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '500':
          $ref: '#/components/responses/AuthenticationDependencyFailure'
        '200':
          description: Sensitive token data returned
  /api/v1/tokenization/tokens/{token_id}/extend:
    post:
      tags: [Invoice Tokenization]
      summary: Extend a token
      description: |
        Send the idempotency key in `X-Idempotency-Key` or `Idempotency-Key`;
        at least one is required. When both are sent they must be equal,
        otherwise the request is rejected with 400 INVALID_REQUEST. The Ed25519
        signature covers `X-Idempotency-Key` when it is sent, otherwise
        `Idempotency-Key`.
      parameters:
        - $ref: '#/components/parameters/TokenID'
        - $ref: '#/components/parameters/XIdempotencyKey'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                extension_days: { type: integer, minimum: 1, maximum: 365, default: 365 }
      responses:
        '500':
          $ref: '#/components/responses/AuthenticationDependencyFailure'
        '200':
          description: Token extended
  /api/v1/tokenization/tokens/{token_id}:
    delete:
      tags: [Invoice Tokenization]
      summary: Revoke a token
      description: |
        Send the idempotency key in `X-Idempotency-Key` or `Idempotency-Key`;
        at least one is required. When both are sent they must be equal,
        otherwise the request is rejected with 400 INVALID_REQUEST. The Ed25519
        signature covers `X-Idempotency-Key` when it is sent, otherwise
        `Idempotency-Key`.
      parameters:
        - $ref: '#/components/parameters/TokenID'
        - $ref: '#/components/parameters/XIdempotencyKey'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '500':
          $ref: '#/components/responses/AuthenticationDependencyFailure'
        '204':
          description: Token revoked
components:
  securitySchemes:
    AccountSecretEd25519:
      type: apiKey
      in: header
      name: X-API-ID
      description: |
        Account secret Ed25519 authentication using X-API-ID, X-API-Key,
        X-Timestamp, X-Signature, and, for non-idempotent requests, an
        idempotency key in X-Idempotency-Key or Idempotency-Key (see the
        XIdempotencyKey and IdempotencyKey parameters). PSP stores only the
        merchant-uploaded public key.
  parameters:
    XIdempotencyKey:
      name: X-Idempotency-Key
      in: header
      required: false
      description: |
        Idempotency key. Send it in this header or in Idempotency-Key; at least
        one of the two is required. When this header is sent, the Ed25519
        signature covers its value. If both headers are sent they must be
        equal, otherwise the request is rejected with 400 INVALID_REQUEST.
      schema:
        $ref: '#/components/schemas/IdempotencyKey'
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: |
        Idempotency key, alternative to X-Idempotency-Key; at least one of the
        two is required. The Ed25519 signature covers this header only when
        X-Idempotency-Key is not sent. If both headers are sent they must be
        equal, otherwise the request is rejected with 400 INVALID_REQUEST.
      schema:
        $ref: '#/components/schemas/IdempotencyKey'
    InvoiceNumber:
      name: invoice_number
      in: path
      required: true
      schema: { type: string }
    AuthorizationID:
      name: authorization_id
      in: path
      required: true
      schema: { type: string }
    TokenID:
      name: token_id
      in: path
      required: true
      schema: { type: string }
  schemas:
    IdempotencyKey:
      type: string
      minLength: 1
      description: |
        Merchant-chosen idempotency key, shared by both idempotency headers.
        Surrounding whitespace is ignored and a blank value counts as missing.
        The gateway uses it for two things only: the Ed25519 signature covers
        it, and it deduplicates requests within the merchant account and
        endpoint path (a retry with the same key and body gets the first
        response once the gateway has stored it, for example a success or 409
        response for 24 hours; the same key with a different body is rejected
        with 422 VALIDATION_ERROR). Whether an operation also uses it
        as its business idempotency key, or uses a request body field such as
        `idempotency_key` instead, is stated in the operation description.
    CreateInvoicePaymentIntentRequest:
      type: object
      required: [payment_method, rail_variant, amount, currency, merchant_order_id]
      properties:
        payment_method:
          type: string
          enum: [pix, spei, upi, credit_card, apple_pay, google_pay, cash_app, paypal, zelle, chime, venmo, emt, boleto]
        rail_variant:
          type: string
          description: Canonical rail variant paired with payment_method; cash_app accepts standard/ecashapp, paypal accepts standard/epaypal, and zelle/chime/venmo/emt use standard.
          example: standard
        amount:
          type: integer
          format: int64
          minimum: 1
        currency:
          type: string
          minLength: 3
          maxLength: 3
        instruction:
          type: object
          additionalProperties: true
        items:
          type: array
          maxItems: 20
          items: { $ref: '#/components/schemas/CheckoutItem' }
        payer_info:
          $ref: '#/components/schemas/PayerInfo'
        description:
          type: string
          maxLength: 500
        merchant_order_id:
          type: string
          maxLength: 100
        return_url:
          type: string
          format: uri
          maxLength: 500
          description: HTTPS return URL for provider-hosted checkout or 3DS completion.
        webhook_url:
          type: string
          format: uri
          maxLength: 500
        expires_in_minutes: { type: integer, minimum: 1, maximum: 1440 }
        allow_different_amount: { type: boolean }
        allow_multiple_payments: { type: boolean }
        metadata:
          type: object
          additionalProperties: true
    CheckoutItem:
      type: object
      required: [name, quantity, unit_amount]
      properties:
        name: { type: string, maxLength: 160 }
        description: { type: string, maxLength: 500 }
        sku: { type: string, maxLength: 80 }
        quantity: { type: integer, minimum: 1, maximum: 999999 }
        unit_amount: { type: integer, format: int64, minimum: 0 }
        currency: { type: string, minLength: 3, maxLength: 3 }
        image_url: { type: string, format: uri, maxLength: 2048 }
    InvoiceResponse:
      type: object
      required: [id, invoice_number, payment_method, amount, currency, status, created_at, updated_at]
      properties:
        id: { type: string, format: uuid }
        invoice_number: { type: string }
        payment_method: { type: string }
        classification: { type: object, additionalProperties: true }
        amount: { type: integer, format: int64 }
        currency: { type: string }
        paid_amount: { type: integer, format: int64 }
        refunded_amount: { type: integer, format: int64 }
        status: { type: string }
        state: { type: string }
        merchant_order_id: { type: string }
        payment_url: { type: string }
        psp_checkout_url: { type: string }
        provider_checkout_url: { type: string }
        payment_url_source: { type: string }
        instruction: { type: object, additionalProperties: true }
        expected_payer_info: { $ref: '#/components/schemas/PayerInfo' }
        payer_info: { $ref: '#/components/schemas/PayerInfo' }
        items:
          type: array
          items: { $ref: '#/components/schemas/CheckoutItem' }
        allow_different_amount: { type: boolean }
        allow_multiple_payments: { type: boolean }
        expires_at: { type: string, format: date-time }
        created_at: { type: string, format: date-time }
        updated_at: { type: string, format: date-time }
        metadata: { type: object, additionalProperties: true }
    CreateInvoiceRefundRequest:
      type: object
      required: [amount]
      properties:
        amount: { type: integer, format: int64, minimum: 1 }
        reason: { type: string, maxLength: 500 }
        metadata: { type: object, additionalProperties: true }
    InvoiceRefundResponse:
      type: object
      required: [id, invoice_number, refund_number, amount, currency, status]
      properties:
        id: { type: string, format: uuid }
        invoice_number: { type: string }
        refund_number: { type: string }
        original_intent_id: { type: string, format: uuid }
        amount: { type: integer, format: int64 }
        currency: { type: string }
        status: { type: string }
        reason: { type: string }
        created_at: { type: string, format: date-time }
        updated_at: { type: string, format: date-time }
    CardAuthorizationRequest:
      type: object
      required: [invoice_number, idempotency_key, channel_id, amount, currency, payer_info]
      description: Merchant and account IDs are derived from the authenticated account secret.
      properties:
        invoice_number: { type: string }
        idempotency_key: { type: string }
        channel_id: { type: string, format: uuid }
        amount: { type: integer, format: int64, minimum: 1 }
        currency: { type: string, minLength: 3, maxLength: 3 }
        card_token: { type: string }
        card_cvv: { type: string }
        card_info: { $ref: '#/components/schemas/CardInfo' }
        payer_info: { $ref: '#/components/schemas/CardPayerInfo' }
        description: { type: string }
        merchant_order_id: { type: string }
        require_3ds: { type: boolean }
        pre_auth: { type: boolean }
        metadata: { type: object, additionalProperties: true }
    CardInfo:
      type: object
      required: [card_number, cvv, expiry_month, expiry_year, cardholder_name]
      properties:
        card_number: { type: string }
        cvv: { type: string }
        expiry_month: { type: integer, minimum: 1, maximum: 12 }
        expiry_year: { type: integer }
        cardholder_name: { type: string }
    CardPayerInfo:
      type: object
      required: [name, email]
      properties:
        name: { type: string }
        email: { type: string, format: email }
        phone: { type: string }
    CardRefundRequest:
      type: object
      required: [invoice_id, idempotency_key, refund_amount]
      description: Merchant and account IDs are derived from the authenticated account secret.
      properties:
        invoice_id: { type: string, format: uuid }
        idempotency_key: { type: string }
        merchant_refund_id: { type: string }
        refund_amount: { type: integer, format: int64, minimum: 1 }
        reason: { type: string }
        notes: { type: string }
        metadata: { type: object, additionalProperties: true }
    TokenizeCardRequest:
      type: object
      required: [customer_id, card_number, expiry_month, expiry_year, cardholder_name]
      properties:
        customer_id: { type: string }
        card_number: { type: string, minLength: 16, maxLength: 16 }
        expiry_month: { type: string, minLength: 2, maxLength: 2 }
        expiry_year: { type: string, minLength: 4, maxLength: 4 }
        cardholder_name: { type: string }
        cvv: { type: string, minLength: 3, maxLength: 4 }
        scope: { type: string, enum: [single_use, multi_use, permanent] }
    TokenizeBankAccountRequest:
      type: object
      required: [customer_id, account_number, bank_code, account_holder_name]
      properties:
        customer_id: { type: string }
        account_number: { type: string }
        bank_code: { type: string }
        account_type: { type: string, enum: [checking, savings] }
        account_holder_name: { type: string }
        branch_code: { type: string }
        scope: { type: string, enum: [single_use, multi_use, permanent] }
    TokenResponse:
      type: object
      required: [token_id, customer_id, token_type, created_at, masked_info]
      properties:
        token_id: { type: string }
        customer_id: { type: string }
        token_type: { type: string, enum: [card, bank_account] }
        scope: { type: string }
        created_at: { type: string, format: date-time }
        expires_at: { type: string, format: date-time, nullable: true }
        masked_info: { type: object, additionalProperties: true }
    PayerInfo:
      type: object
      properties:
        name: { type: string, maxLength: 200 }
        tax_id:
          type: string
          maxLength: 50
          description: >
            付款人证件号。账户 payin_payer_validation_mode 为 optional 或 required
            且提交了本字段时，须符合账户市场格式：巴西 CPF（11 位数字含校验位）或 CNPJ
            （14 位，数字或字母数字，含官方校验位，例如 00.000.000/E08G-12）；墨西哥 RFC
            （12 或 13 位，日期段月份 01–12、日期 01–31）。格式错误返回 INVALID_REQUEST。
            required 档未提交亦返回 INVALID_REQUEST。
        email: { type: string, format: email, maxLength: 200 }
        phone: { type: string, maxLength: 50 }
        account: { type: string, maxLength: 200 }
  responses:
    AuthenticationDependencyFailure:
      description: Credential lookup failed (INTERNAL_ERROR). The request handler was not executed.
    WrongServiceOrCredential:
      description: The credential kind or host does not match the invoice service.
    PermissionDenied:
      description: The account secret lacks the required invoice scope.
