> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fossapay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sign a Customer Wallet Transaction

> Validate, simulate, sign, and broadcast a Solana transaction with a customer wallet

The customer and active Solana wallet must belong to the merchant resolved from the API key. The customer wallet must be both a required signer and the fee payer. A successful `202` response means the transaction was submitted, not finalized.

## Path parameter

<ParamField path="customerId" type="string" required>
  FossaPay UUID of the individual customer whose wallet will sign and fund the transaction.
</ParamField>

## Headers

<ParamField header="x-api-key" type="string" required>
  Active production API key belonging to the customer's merchant.
</ParamField>

<ParamField header="X-Idempotency-Key" type="string" required>
  Unique key for this logical signing request, up to 255 characters. Retain it with the exact serialized transaction.
</ParamField>

## Request body

<ParamField body="serializedTransaction" type="string" required>
  Base64-encoded serialized Solana `VersionedTransaction`, up to 4,096 characters. The selected customer wallet must be the fee payer and a required signer. Other required signers must sign before serialization.
</ParamField>

```bash theme={null}
curl --request POST \
  --url https://api-production.fossapay.com/api/v1/wallets/crypto/customer/11111111-1111-4111-8111-111111111111/transactions/sign-and-broadcast \
  --header "x-api-key: $FOSSAPAY_API_KEY" \
  --header "X-Idempotency-Key: $IDEMPOTENCY_KEY" \
  --header 'Content-Type: application/json' \
  --data "{\"serializedTransaction\":\"$SERIALIZED_TRANSACTION\"}"
```

## Response

<ResponseExample>
  ```json Submitted theme={null}
  {
    "status": "success",
    "statusCode": 202,
    "message": "Solana transaction signed and submitted successfully",
    "data": {
      "requestId": "07836944-c8fd-444b-b080-776077fc70c9",
      "walletType": "customer",
      "customerId": "11111111-1111-4111-8111-111111111111",
      "walletId": "61237ceb-bde6-4052-9294-38470806f672",
      "walletAddress": "8aQ3Y97fxiX26Pe2ckc3keoQEz5MtWBCVk4pEx96Sqeb",
      "network": "solana",
      "cluster": "mainnet-beta",
      "feePayer": "8aQ3Y97fxiX26Pe2ckc3keoQEz5MtWBCVk4pEx96Sqeb",
      "status": "submitted",
      "providerTransactionId": "8f9e6478-6ba7-462d-b53a-ec09d9f3a8c9",
      "transactionHash": "3cQYpNzFfDm6BkLwgGz4JPQCYGmS7SxTpKRtvBPWVPSLDjpGJBrUojwt7FA97Cn4vdHXgyxL4G2LQ1HsBYVkKb9U",
      "explorerLink": "https://explorer.solana.com/tx/3cQYpNzFfDm6BkLwgGz4JPQCYGmS7SxTpKRtvBPWVPSLDjpGJBrUojwt7FA97Cn4vdHXgyxL4G2LQ1HsBYVkKb9U",
      "simulation": {
        "unitsConsumed": 21192,
        "logs": ["Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr success"]
      }
    }
  }
  ```
</ResponseExample>

## Important behavior

* FossaPay verifies customer ownership before accessing the wallet.
* FossaPay simulates before signing and broadcasting.
* The selected customer wallet pays the Solana network fee.
* Requests are limited to 10 per minute.
* Repeating the identical submitted request with the same idempotency key returns the stored result.
* A failed or expired transaction must be rebuilt with a fresh blockhash and submitted with a new key.
* Finality is reconciled through Solana RPC; this flow does not emit a merchant webhook.

See [Solana Transaction Signing](/guides/solana-transaction-signing) for transaction construction, statuses, retries, and security controls.


## OpenAPI

````yaml POST /api/v1/wallets/crypto/customer/{customerId}/transactions/sign-and-broadcast
openapi: 3.1.0
info:
  title: FossaPay API
  description: >-
    FossaPay API for checkout wallets, master-wallet payouts, customer
    management, NGN wallets, crypto wallets, transfers, fees, banks, and
    webhooks.
  license:
    name: MIT
  version: 1.0.0
servers:
  - url: https://api-production.fossapay.com
    description: Production server
security:
  - ApiKeyAuth: []
paths:
  /api/v1/wallets/crypto/customer/{customerId}/transactions/sign-and-broadcast:
    post:
      tags:
        - Crypto Wallets
      summary: Sign and broadcast with a customer Solana wallet
      description: >-
        Verifies that the customer belongs to the authenticated merchant,
        validates and simulates a serialized Solana versioned transaction, then
        signs and broadcasts it with the customer's active wallet. The selected
        wallet must be a required signer and the fee payer. A 202 response
        represents submission, not on-chain finality.
      operationId: CryptoWalletsController_signAndBroadcastCustomerTransaction
      parameters:
        - name: customerId
          in: path
          required: true
          description: FossaPay customer UUID owned by the authenticated merchant.
          schema:
            type: string
            format: uuid
        - name: X-Idempotency-Key
          in: header
          required: true
          description: >-
            Unique merchant-scoped key for this exact signing request. Maximum
            255 characters.
          schema:
            type: string
            minLength: 1
            maxLength: 255
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SolanaSigningRequest'
      responses:
        '202':
          description: Transaction simulated, signed, and submitted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SolanaSigningResponse'
        '400':
          description: >-
            Malformed or unsupported transaction, wrong fee payer, missing
            co-signer, or invalid idempotency header
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '404':
          description: Customer or active customer Solana wallet not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '409':
          description: Idempotency key conflict or request already processing
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '422':
          description: Solana transaction simulation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '429':
          description: Signing rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
components:
  schemas:
    SolanaSigningRequest:
      type: object
      required:
        - serializedTransaction
      properties:
        serializedTransaction:
          type: string
          minLength: 1
          maxLength: 4096
          description: >-
            Base64-encoded serialized Solana VersionedTransaction. The selected
            FossaPay wallet must be a required signer and the fee payer; all
            other required signers must already have signed.
          example: >-
            AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAB...
      additionalProperties: false
    SolanaSigningResponse:
      type: object
      required:
        - status
        - statusCode
        - message
        - data
      properties:
        status:
          type: string
          const: success
        statusCode:
          type: integer
          const: 202
        message:
          type: string
        data:
          $ref: '#/components/schemas/SolanaSigningSubmission'
      additionalProperties: true
    ApiError:
      type: object
      properties:
        status:
          oneOf:
            - type: string
            - type: boolean
        statusCode:
          type: integer
        message:
          type: string
        error:
          type: string
        code:
          type: string
        errors:
          type: object
          additionalProperties: true
      additionalProperties: true
    SolanaSigningSubmission:
      type: object
      required:
        - requestId
        - walletType
        - walletId
        - walletAddress
        - network
        - cluster
        - feePayer
        - status
        - providerTransactionId
        - transactionHash
        - explorerLink
        - simulation
      properties:
        requestId:
          type: string
          format: uuid
        walletType:
          type: string
          enum:
            - master
            - customer
        customerId:
          type:
            - string
            - 'null'
          format: uuid
        walletId:
          type: string
          format: uuid
        walletAddress:
          type: string
        network:
          type: string
          const: solana
        cluster:
          type: string
          const: mainnet-beta
        feePayer:
          type: string
        status:
          type: string
          const: submitted
        providerTransactionId:
          type: string
        transactionHash:
          type: string
        recentBlockhash:
          type: string
        explorerLink:
          type: string
          format: uri
        simulation:
          $ref: '#/components/schemas/SolanaSigningSimulation'
      additionalProperties: true
    SolanaSigningSimulation:
      type: object
      properties:
        unitsConsumed:
          type:
            - integer
            - 'null'
        logs:
          type: array
          items:
            type: string
      additionalProperties: true
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````