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

# Receiving Payments

> Receiving payments from UMA addresses

This guide explains how to enable your customers to receive UMA payments. When an external sender initiates a payment to your customer's UMA address, the Grid API requests the counterparty fields you defined in your platform configuration. You can review the counterparty and transaction details for risk before approving the payment.

<Note>
  Before you begin, make sure you:

  * Configure UMA, supported currencies, and required counterparty fields in <a href="/global-p2p/getting-started/platform-configuration">Platform Configuration</a>
  * Create customers and capture any provider-required user fields in <a href="/global-p2p/onboarding/configuring-customers">Creating Customers</a>
  * Set up and verify webhooks in <a href="/global-p2p/platform-tools/webhooks">Webhooks</a>
</Note>

## Receive webhook for initiated payment

When someone initiates a payment to one of your users' UMA addresses, you'll receive a webhook call with a pending transaction:

```json theme={null}
{
  "id": "Webhook:019542f5-b3e7-1d02-0000-000000000007",
  "type": "INCOMING_PAYMENT.PENDING",
  "timestamp": "2023-08-15T14:32:00Z",
  "data": {
    "id": "Transaction:019542f5-b3e7-1d02-0000-000000000005",
    "status": "PENDING",
    "type": "INCOMING",
    "source": {
      "sourceType": "UMA_ADDRESS",
      "umaAddress": "$mary.sender@thelessgoodbank.com"
    },
    "receivedAmount": {
      "amount": 50000,
      "currency": {
        "code": "USD",
        "name": "United States Dollar",
        "symbol": "$",
        "decimals": 2
      }
    },
    "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
    "platformCustomerId": "9f84e0c2a72c4fa",
    "description": "Payment for services",
    "counterpartyInformation": {
      "FULL_NAME": "Mary Sender",
      "BIRTH_DATE": "1985-06-15"
    },
    "reconciliationInstructions": {
      "reference": "REF-123456789"
    },
    "requestedReceiverCustomerInfoFields": [
      { "name": "COUNTRY_OF_RESIDENCE", "mandatory": true },
      { "name": "FULL_NAME", "mandatory": true },
      { "name": "NATIONALITY", "mandatory": false }
    ]
  }
}
```

The `counterpartyInformation` object contains PII about the sender, provided by their FI, based on your configured `requiredCounterpartyFields`. If present, `requestedReceiverCustomerInfoFields` lists information needed about your customer to proceed. Provide those fields when approving.

You can approve or reject the payment synchronously (recommended) or asynchronously:

### Option 1: Synchronous (recommended)

To approve the payment synchronously, respond with a `200 OK` status:

* If the `requestedReceiverCustomerInfoFields` array was present in the webhook request and contained mandatory fields, your `200 OK` response **must** include a JSON body containing a `receiverCustomerInfo` object. This object should contain the key-value pairs for the information fields that were requested.
* If `requestedReceiverCustomerInfoFields` was not present, was empty, or contained only non-mandatory fields for which you have no information, your `200 OK` response can have an empty body.

Example `200 OK` response body when information was requested and provided:

```json theme={null}
{
  "receiverCustomerInfo": {
    "COUNTRY_OF_RESIDENCE": "US",
    "FULL_NAME": "John Receiver"
  }
}
```

To reject the payment, respond with a 403 Forbidden status and a JSON body with the following fields:

```json theme={null}
{
  "code": "payment_rejected",
  "message": "Payment rejected due to compliance policy",
  "details": {
    "reason": "failed_counterparty_check",
    "rejectionReason": "User is in a restricted jurisdiction"
  }
}
```

### Option 2: Asynchronous Processing

If your platform's architecture requires asynchronous processing before approving or rejecting the payment, you can:

1. Return a `202 Accepted` response to acknowledge receipt of the webhook
2. Process the payment asynchronously
3. Call either the `/transactions/{transactionId}/approve` or `/transactions/{transactionId}/reject` endpoint *within 5 seconds*

Example of approving asynchronously:

```bash theme={null}
curl -X POST "https://api.lightspark.com/grid/2025-10-13/transactions/Transaction:019542f5-b3e7-1d02-0000-000000000005/approve" \
  -H "Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "receiverCustomerInfo": {
      "COUNTRY_OF_RESIDENCE": "US",
      "FULL_NAME": "John Receiver"
    }
  }'
```

Example of rejecting asynchronously:

```bash theme={null}
curl -X POST "https://api.lightspark.com/grid/2025-10-13/transactions/Transaction:019542f5-b3e7-1d02-0000-000000000005/reject" \
  -H "Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "RESTRICTED_JURISDICTION"
  }'
```

<Warning>
  If you choose the asynchronous path, you must call the approve/reject endpoint within 5 seconds, or the payment will be automatically rejected.
</Warning>

## Receive completion notification and credit

When the payment completes, you'll receive another webhook notifying you of the completion. The envelope `id` is distinct from the `INCOMING_PAYMENT.PENDING` delivery above — use it for idempotent deduplication.

```json theme={null}
{
  "id": "Webhook:019542f5-b3e7-1d02-0000-000000000008",
  "type": "INCOMING_PAYMENT.COMPLETED",
  "timestamp": "2023-08-15T14:32:00Z",
  "data": {
    "id": "Transaction:019542f5-b3e7-1d02-0000-000000000005",
    "status": "COMPLETED",
    "type": "INCOMING",
    "source": {
      "sourceType": "UMA_ADDRESS",
      "umaAddress": "$mary.sender@thelessgoodbank.com"
    },
    "receivedAmount": {
      "amount": 50000,
      "currency": {
        "code": "USD",
        "name": "United States Dollar",
        "symbol": "$",
        "decimals": 2
      }
    },
    "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
    "platformCustomerId": "9f84e0c2a72c4fa",
    "settledAt": "2023-08-15T14:30:00Z",
    "createdAt": "2023-08-15T14:25:18Z",
    "description": "Payment for services",
    "counterpartyInformation": {
      "FULL_NAME": "Mary Sender",
      "BIRTH_DATE": "1985-06-15"
    },
    "reconciliationInstructions": {
      "reference": "REF-123456789"
    }
  }
}
```

On completion, the received funds are immediately credited to the account associated with the UMA customer. By default, funds
land in the customer's primary internal account. However, you can also set an external account as the default UMA deposit account
for the customer, which will cause incoming UMA payments to be deposited into that external account instead. This is useful for
customers who prefer to receive UMA payments into a specific bank account directly, for example.

To set an external account as the default UMA deposit account for a customer, you can set the `defaultUmaDepositAccount` flag to true when creating the external account.

```bash theme={null}
curl -X POST "https://api.lightspark.com/grid/2025-10-13/customers/external-accounts" \
  -H "Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
    "currency": "USD",
    "accountInfo": {
      "accountType": "US_ACCOUNT",
      "accountNumber": "9876543210",
      "routingNumber": "123456789",
      "accountCategory": "CHECKING",
      "bankName": "Chase Bank"
    },
    "defaultUmaDepositAccount": true
  }'
```

## Test the inbound flow

Use the <a href="/global-p2p/platform-tools/uma-test-wallet">UMA Test Wallet</a> to send a regtest payment to your customer's UMA address.
