---
title: "Incoming payment webhook and approval mechanism"
method: POST
path: "incoming-payment"
tags: ["Webhooks"]
---

# Incoming payment webhook and approval mechanism

`POST incoming-payment` (webhook)

Webhook that is called when an incoming payment is received by a user's UMA address.
This endpoint should be implemented by clients of the UMAaas API.

### Authentication
The webhook includes a signature in the `X-UMAaas-Signature` header that allows you to verify that the webhook was sent by UMAaas.
To verify the signature:
1. Get the UMAaas public key provided to you during integration
2. Decode the base64 signature from the header
3. Create a SHA-256 hash of the request body
4. Verify the signature using the public key and the hash

If the signature verification succeeds, the webhook is authentic. If not, it should be rejected.

### Payment Approval Flow
When a transaction has `status: "PENDING"`, this webhook serves as an approval mechanism:

1. The client should check the `counterpartyInformation` against their requirements
2. To APPROVE the payment synchronously, return a 200 OK response
3. To REJECT the payment, return a 403 Forbidden response with an Error object
4. To request more information, return a 422 Unprocessable Entity with specific missing fields
5. To process the payment asynchronously, return a 202 Accepted response and then call the `/transactions/{transactionId}/approve` or `/transactions/{transactionId}/reject` endpoint within 5 seconds. Note that synchronous approval/rejection is preferred where possible.

The UMAaas system will proceed or cancel the payment based on your response.

For transactions with other statuses (COMPLETED, FAILED, REFUNDED), this webhook is purely informational.

## Payload

- IncomingPaymentWebhook
  - `timestamp` string, date-time, required — ISO8601 timestamp when the webhook was sent (can be used to prevent replay attacks)
  - `webhookId` string, required — Unique identifier for this webhook delivery (can be used for idempotency)
  - `type` 'INCOMING_PAYMENT' | 'OUTGOING_PAYMENT' | 'TEST' | 'BULK_UPLOAD' | 'INVITATION_CLAIMED', required — Type of webhook event, used by the receiver to identify which webhook is being received
  - `transaction` IncomingTransaction, required
    - `id` string, required — Unique identifier for the transaction
    - `status` 'CREATED' | 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'REJECTED' | 'FAILED' | 'REFUNDED' | 'EXPIRED', required — Status of a payment transaction
    - `type` 'INCOMING' | 'OUTGOING', required — Type of transaction (incoming payment or outgoing payment)
    - `senderUmaAddress` string, required — UMA address of the payment sender
    - `receiverUmaAddress` string, required — UMA address of the payment recipient
    - `userId` string, required — System ID of the user (sender for outgoing, recipient for incoming)
    - `platformUserId` string, required — Platform-specific ID of the user (sender for outgoing, recipient for incoming)
    - `settledAt` string, date-time — When the payment was or will be settled
    - `createdAt` string, date-time — When the transaction was created
    - `description` string — Optional memo or description for the payment
    - `counterpartyInformation` object — Additional information about the counterparty, if available
    - `receivedAmount` CurrencyAmount, required
      - `amount` integer, required — Amount in the smallest unit of the currency (e.g., cents for USD/EUR, satoshis for BTC)
      - `currency` Currency, required
        - `code` string — Three-letter currency code (ISO 4217) for fiat currencies. Some cryptocurrencies may use their own ticker symbols (e.g. "SAT" for satoshis, "USDC" for USDCoin, etc.)
        - `name` string — Full name of the currency
        - `symbol` string — Symbol of the currency
        - `decimals` integer — Number of decimal places for the currency
    - `reconciliationInstructions` ReconciliationInstructions
      - `reference` string, required — Unique reference code that must be included with the payment to match it with the correct incoming transaction
    - `rateDetails` IncomingRateDetails — Details about the rate and fees for an incoming transaction.
      - `umaaasMultiplier` number, double, required — The underlying multiplier from the mSATS to the receiving currency, including variable fees.
      - `umaaasFixedFee` integer, required — The fixed fee charged by the UMAaaS product to execute the quote in the smallest unit of the receiving currency (eg. cents).
      - `umaaasVariableFeeRate` number, double, required — The variable fee rate charged by the UMAaaS product to execute the quote as a percentage of the receiving currency amount.
      - `umaaasVariableFeeAmount` number, required — The variable fee amount charged by the UMAaaS product to execute the quote in the smallest unit of the receiving currency (eg. cents). This is the receiving amount times umaaasVariableFeeRate.
    - `failureReason` 'LNURLP_FAILED' | 'PAY_REQUEST_FAILED' | 'PAYMENT_APPROVAL_WEBHOOK_ERROR' | 'PAYMENT_APPROVAL_TIMED_OUT' | 'OFFRAMP_FAILED' | 'MISSING_MANDATORY_PAYEE_DATA' | 'QUOTE_EXPIRED' | 'QUOTE_EXECUTION_FAILED' — Reason for failure of an incoming transaction. This is used to provide more context on why a transaction failed. If the transaction is not in a failed state, this field is omitted.
  - `requestedReceiverUserInfoFields` CounterpartyFieldDefinition[] — Information required by the sender's VASP about the recipient. Platform must provide these in the 200 OK response if approving. Note that this only includes fields which UMAaaS does not already have from initial user registration.
    - `name` 'FULL_NAME' | 'BIRTH_DATE' | 'NATIONALITY' | 'PHONE_NUMBER' | 'EMAIL' | 'POSTAL_ADDRESS' | 'TAX_ID' | 'REGISTRATION_NUMBER' | 'USER_TYPE' | 'COUNTRY_OF_RESIDENCE' | 'ACCOUNT_IDENTIFIER' | 'FI_LEGAL_ENTITY_NAME' | 'FI_ADDRESS' | 'PURPOSE_OF_PAYMENT' | 'ULTIMATE_INSTITUTION_COUNTRY' | 'IDENTIFIER' | 'BUSINESS_TYPE', required — Name of a type of field containing info about a platform's user or counterparty user.
    - `mandatory` boolean, required — Whether the field is mandatory

## Acknowledgement `200`

Webhook received successfully. 
For PENDING transactions, this indicates approval to proceed with the payment.
If `requestedReceiverUserInfoFields` were present in the webhook request, the corresponding fields for the recipient must be included in this response in the `receiverUserInfo` object.

- IncomingPaymentWebhookResponse
  - `receiverUserInfo` object — Information about the recipient, provided by the platform if requested in the webhook via `requestedReceiverUserInfoFields` and the payment is approved.

## Other responses

- `202` — Webhook received and will be processed asynchronously. The synchronous 200 response should be preferred where possible. This asycnhronous path should only be used in cases where the platform's architecture requires async (but still very quick) processing before approving or rejecting the payment. The platform must call the `/transactions/{transactionId}/approve` or `/transactions/{transactionId}/reject` endpoint to approve or reject the payment within 5 seconds or the payment will be automatically rejected.
- `400` — Bad request
- `401` — Unauthorized - Signature validation failed
- `403` — Forbidden - Payment rejected by the client. Only applicable for PENDING transactions.
- `409` — Conflict - Webhook has already been processed (duplicate webhookId)
- `422` — Unprocessable Entity - Additional counterparty information required. Only applicable for PENDING transactions.

---

[API](https://skmtc.net/lightsparkdev/apis/uma-as-a-service-umaaas-api.md) · [All operations](https://skmtc.net/lightsparkdev/apis/uma-as-a-service-umaaas-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/lightsparkdev/uma-as-a-service-umaaas-api/versions/2e2b5ba6d69b/schema)
