# Create Payment Request

### Overview

Payment requests are the core of Unter's payment system. When you create a payment request, you're asking someone to pay a specific amount of a cryptocurrency token to a designated wallet address. Each payment request gets a unique payment URL that you can share with your customers.

### Endpoint

```
POST /api/payment-requests
```

**Required Permission:** `create_payments`

### Request Body

#### Required Fields

| Field               | Type    | Description                                                          | Example                                        |
| ------------------- | ------- | -------------------------------------------------------------------- | ---------------------------------------------- |
| `amount`            | string  | The amount to request in the token's smallest unit (wei-like format) | `"1000000"` (1 USDC with 6 decimals)           |
| `token_id`          | integer | The ID of the token to receive                                       | `1`                                            |
| `chain_id`          | integer | The ID of the blockchain network                                     | `1`                                            |
| `recipient_address` | string  | The wallet address to receive the payment                            | `"0x742C4B8C2515Ad1D8e1C71e8e24c8D5F9A1a8B5A"` |

#### Optional Fields

| Field          | Type              | Description                                                         | Example                                          |
| -------------- | ----------------- | ------------------------------------------------------------------- | ------------------------------------------------ |
| `external_id`  | string            | Your internal reference ID for this payment request (max 255 chars) | `"order_12345"`                                  |
| `description`  | string            | Description of what this payment is for (max 1000 chars)            | `"Payment for premium subscription"`             |
| `redirect_url` | string            | URL to redirect to after successful payment (max 500 chars)         | `"https://yourapp.com/payment/success"`          |
| `cancel_url`   | string            | URL to redirect to if payment is cancelled (max 500 chars)          | `"https://yourapp.com/payment/cancel"`           |
| `expires_at`   | string (ISO 8601) | When this payment request expires (max 30 days from now)            | `"2024-12-31T23:59:59Z"`                         |
| `metadata`     | object            | Additional key-value data for the payment request                   | `{"customer_id": "12345", "product": "premium"}` |

### Understanding Amounts

Cryptocurrency amounts are handled in their smallest unit (similar to how cents relate to dollars):

* **USDC (6 decimals)**: `"1000000"` = $1.00 USDC
* **ETH (18 decimals)**: `"1000000000000000000"` = 1.0 ETH
* **USDT (6 decimals)**: `"500000"` = $0.50 USDT

The amount must be a string containing only digits, with no decimal points or commas.

### Address Validation

Recipient addresses are validated based on the blockchain type:

#### Ethereum-compatible chains (EVM)

* Must be 42 characters long
* Must start with `0x`
* Example: `0x742C4B8C2515Ad1D8e1C71e8e24c8D5F9A1a8B5A`

#### Solana

* Must use Base58 encoding
* Example: `9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM`

### Automatic Behavior

When you create a payment request, several things happen automatically:

1. **Unique identifiers are generated:**
   * `public_id`: A UUID for internal tracking
   * `shortcode`: An 8-character code for the payment URL (e.g., `A4B2C8XZ`)
2. **Default expiration is set:**
   * If you don't specify `expires_at`, it defaults to 24 hours from creation
3. **Payment URL is created:**
   * Format: `https://unter.tech/pay/{shortcode}`
   * This is where customers go to complete payment

### Example Requests

#### Minimal Request

```bash
curl -X POST https://api.unter.tech/api/payment-requests \
  -H "X-API-Key: unter_YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "2500000",
    "token_id": 1,
    "chain_id": 1,
    "recipient_address": "0x742C4B8C2515Ad1D8e1C71e8e24c8D5F9A1a8B5A"
  }'
```

#### Full Request with All Options

```bash
curl -X POST https://api.unter.tech/api/payment-requests \
  -H "X-API-Key: unter_YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "5000000",
    "token_id": 1,
    "chain_id": 1,
    "recipient_address": "0x742C4B8C2515Ad1D8e1C71e8e24c8D5F9A1a8B5A",
    "external_id": "invoice_789",
    "description": "Pro Plan Subscription - Monthly",
    "redirect_url": "https://myapp.com/success?order=789",
    "cancel_url": "https://myapp.com/cancelled?order=789",
    "expires_at": "2024-08-15T18:00:00Z",
    "metadata": {
      "customer_id": "cust_abc123",
      "plan": "pro",
      "billing_cycle": "monthly"
    }
  }'
```

### Success Response (201 Created)

```json
{
  "data": {
    "public_id": "550e8400-e29b-41d4-a716-446655440000",
    "shortcode": "A4B2C8XZ",
    "amount": {
      "raw": "5000000",
      "formatted": "5.00",
      "decimals": 6
    },
    "token": {
      "id": 1,
      "symbol": "USDC",
      "name": "USD Coin",
      "decimals": 6
    },
    "chain": {
      "id": 1,
      "slug": "ethereum",
      "name": "Ethereum"
    },
    "recipient_address": "0x742C4B8C2515Ad1D8e1C71e8e24c8D5F9A1a8B5A",
    "status": "active",
    "description": "Pro Plan Subscription - Monthly",
    "external_id": "invoice_789",
    "payment_url": "https://pay.unter.tech/pay/A4B2C8XZ",
    "redirect_url": "https://myapp.com/success?order=789",
    "cancel_url": "https://myapp.com/cancelled?order=789",
    "paid_amount": {
      "raw": "0",
      "formatted": "0.00",
      "decimals": 6
    },
    "remaining_amount": {
      "raw": "5000000",
      "formatted": "5.00",
      "decimals": 6
    },
    "payment_attempts": 0,
    "expires_at": "2024-08-15T18:00:00.000Z",
    "created_at": "2024-08-14T12:30:00.000Z",
    "completed_at": null,
    "metadata": {
      "customer_id": "cust_abc123",
      "plan": "pro",
      "billing_cycle": "monthly"
    },
    "payments": []
  }
}
```

### Code Examples

#### JavaScript (Node.js)

```javascript
const axios = require('axios');

const apiKey = process.env.UNTER_API_KEY;

const client = axios.create({
  baseURL: 'https://api.unter.tech/api',
  headers: {
    'X-API-Key': apiKey,
    'Content-Type': 'application/json'
  }
});

async function createPaymentRequest(data) {
  try {
    const response = await client.post('/payment-requests', {
      amount: "1000000", // $1.00 USDC
      token_id: 1,
      chain_id: 1,
      recipient_address: "0x742C4B8C2515Ad1D8e1C71e8e24c8D5F9A1a8B5A",
      external_id: "order_123",
      description: "Monthly subscription",
      redirect_url: "https://myapp.com/success",
      expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
    });

    console.log('Payment request created:', response.data.data.payment_url);
    return response.data.data;
  } catch (error) {
    if (error.response?.status === 422) {
      console.error('Validation errors:', error.response.data.errors);
    } else {
      console.error('Error:', error.response?.data || error.message);
    }
    throw error;
  }
}
```

### Payment Request Lifecycle

1. **Active**: Payment request is created and ready to receive payments
2. **Completed**: Full amount has been received
3. **Expired**: Past the expiration date without full payment
4. **Cancelled**: Manually cancelled via API

### Best Practices

1. **Always set reasonable expiration times**
2. **Use external\_id for tracking**
   * Link payment requests to your internal order/invoice system
3. **Handle webhook notifications**
   * Set up webhooks to get notified of payment status changes
4. **Validate token/chain combinations**
   * Use the chains and tokens endpoints to get valid combinations
   * Not all tokens are available as receiving token on all chains

### Getting Available Tokens and Chains

Before creating payment requests, you need to know which tokens and chains are supported. Use these **public endpoints** (no authentication required):

#### List All Supported Chains

```bash
GET /api/public/chains?include_tokens=true
```

#### List Tokens for a Specific Chain

```bash
GET /api/public/chains/{chain_id}/tokens
```
