# Create a Payment Link

Creates a new Payment Link for a merchant. The link generates a shareable URL that directs payers to a Plexo-hosted checkout page.

**Endpoint**: `POST /v1/payment-links`

**Authentication**: Required (Basic Auth or Bearer Token)

***

## Request body

```json
{
  "merchantId": 12345,
  "type": "regular",
  "amount": {
    "currency": "UYU",
    "total": 1500.00
  },
  "settings": {
    "amountMode": "fixed",
    "paymentMethods": ["VISA", "MASTERCARD"],
    "installments": { "*": [1, 3, 6] },
    "callbackUrl": "https://example.com/webhook",
    "skipPreCheckout": false
  },
  "validUntil": "2025-08-01T00:00:00Z",
  "displayName": "Invoice #1042",
  "description": "Payment for consulting services",
  "items": [
    {
      "referenceId": "SKU-001",
      "name": "Consulting — July 2025",
      "description": "Monthly consulting fee",
      "quantity": 1,
      "price": 1500.00,
      "discount": 0,
      "tax": { "amount": 330.00, "currency": "UYU" },
      "metadata": { "sku": "CONS-001" }
    }
  ]
}
```

### Fields

| Field               | Type                                                      | Required    | Description                                                                                                     |
| ------------------- | --------------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------- |
| `merchantId`        | integer                                                   | Yes         | ID of the merchant that will receive the payment. Must belong to your client.                                   |
| `type`              | string                                                    | Yes         | Link type: `regular`, `one-time`, or `quick-pay`.                                                               |
| `amount`            | [PaymentAmountDto](#paymentamountdto-object)              | Conditional | Payment amount object. Required when `settings.amountMode` is `fixed`.                                          |
| `settings`          | [SettingsObject](#settings-object)                        | Yes         | Configuration for payment behavior and constraints.                                                             |
| `validFrom`         | datetime                                                  | No          | Start of the link's validity window (ISO 8601). If omitted, the link is valid immediately.                      |
| `validUntil`        | datetime                                                  | No          | End of the link's validity window (ISO 8601). If omitted, the link does not expire automatically.               |
| `displayName`       | string                                                    | No          | Short title displayed to the payer on the checkout page.                                                        |
| `description`       | string                                                    | No          | Longer description displayed to the payer on the checkout page.                                                 |
| `items`             | array of [PaymentRequestItem](#paymentrequestitem-object) | No          | Line items describing the payment. Shown to the payer on the pre-checkout page.                                 |
| `splitDestinations` | array of [SplitDestination](#splitdestination-object)     | No          | Split payment destinations. Can be used with any link type to distribute the payment across multiple merchants. |

### PaymentAmountDto object

| Field      | Type    | Required | Description                                                |
| ---------- | ------- | -------- | ---------------------------------------------------------- |
| `currency` | string  | Yes      | ISO 4217 currency code (e.g. `UYU`, `USD`).                |
| `total`    | decimal | Yes      | Total payment amount. Must be greater than 0.              |
| `details`  | object  | No       | Additional amount details (e.g. tax, shipping breakdowns). |

### Settings object

| Field                | Type                                           | Required | Description                                                                                                                           |
| -------------------- | ---------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `amountMode`         | string                                         | Yes      | Amount mode: `fixed` (exact amount) or `flexible` (payer enters amount).                                                              |
| `paymentMethodTypes` | array of string                                | No       | Accepted payment method types (e.g. `["card"]`).                                                                                      |
| `paymentMethods`     | array of string                                | No       | Allowed payment method identifiers (e.g. `["VISA", "MASTERCARD"]`). If omitted, all merchant-configured methods are available.        |
| `installments`       | object                                         | No       | Map of payment method to allowed installment counts. Use `"*"` as a wildcard key for defaults (e.g. `{"VISA": [1, 3, 6], "*": [1]}`). |
| `callbackUrl`        | string                                         | No       | Per-link callback URL override for payment notifications.                                                                             |
| `flexibleAmount`     | [FlexibleAmountObject](#flexibleamount-object) | No       | Constraints for flexible-amount links. Only used when `amountMode` is `flexible`.                                                     |
| `skipPreCheckout`    | boolean                                        | No       | When `true`, the hosted payment page skips the pre-checkout landing and redirects the payer directly to checkout. Default: `false`.   |

### FlexibleAmount object

| Field               | Type            | Required | Description                                        |
| ------------------- | --------------- | -------- | -------------------------------------------------- |
| `minAmount`         | decimal         | No       | Minimum amount the payer can enter.                |
| `maxAmount`         | decimal         | No       | Maximum amount the payer can enter.                |
| `suggestedAmount`   | decimal         | No       | Pre-filled suggested amount shown to the payer.    |
| `allowedCurrencies` | array of string | No       | ISO 4217 currency codes the payer can choose from. |

### PaymentRequestItem object

| Field         | Type    | Required | Description                                              |
| ------------- | ------- | -------- | -------------------------------------------------------- |
| `referenceId` | string  | No       | Merchant-defined reference for the item (e.g., SKU).     |
| `name`        | string  | Yes      | Item display name shown to the payer.                    |
| `description` | string  | No       | Additional item description.                             |
| `quantity`    | integer | Yes      | Quantity of this item. Must be >= 1.                     |
| `price`       | decimal | Yes      | Unit price for this item.                                |
| `discount`    | decimal | No       | Discount applied to this item.                           |
| `tax`         | object  | No       | Tax amount: `{ "amount": decimal, "currency": string }`. |
| `metadata`    | object  | No       | Key-value metadata for this item.                        |

### SplitDestination object

Each object defines one destination leg of a split payment. Can be used with any link type.

| Field                   | Type                                       | Required | Description                                                 |
| ----------------------- | ------------------------------------------ | -------- | ----------------------------------------------------------- |
| `destinationMerchantId` | integer                                    | No       | Merchant ID of the split destination.                       |
| `subMerchantReference`  | string                                     | No       | External reference for the sub-merchant.                    |
| `amountRule`            | [SplitAmountRule](#splitamountrule-object) | Yes      | Rule for allocating the payment amount to this destination. |
| `vatRule`               | [SplitAmountRule](#splitamountrule-object) | No       | Rule for allocating VAT to this destination.                |
| `routingMetadata`       | object                                     | No       | Key-value metadata for processor routing.                   |

### SplitAmountRule object

| Field   | Type    | Required    | Description                                                                                      |
| ------- | ------- | ----------- | ------------------------------------------------------------------------------------------------ |
| `type`  | string  | Yes         | Rule type: `percentage`, `fixed`, or `residual`.                                                 |
| `value` | decimal | Conditional | Numeric value. For `percentage`: 0–100. For `fixed`: amount greater than 0. Null for `residual`. |

***

## Response

### Success (201 Created)

Returns the created [PaymentLinkDto](#paymentlinkdto-fields).

```json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "externalId": "pl_xK9mQ2vR",
  "shareUrl": "https://links.plexo.com.uy/pl_xK9mQ2vR",
  "qrCodeUrl": "https://api.plexo.com.uy/v1/public/payment-links/pl_xK9mQ2vR/qr.svg",
  "merchantId": 12345,
  "type": "regular",
  "amount": {
    "currency": "UYU",
    "total": 1500.00,
    "details": null
  },
  "settings": {
    "amountMode": "fixed",
    "paymentMethodTypes": null,
    "paymentMethods": ["VISA", "MASTERCARD"],
    "installments": { "*": [1, 3, 6] },
    "callbackUrl": "https://example.com/webhook",
    "flexibleAmount": null,
    "skipPreCheckout": false
  },
  "validFrom": null,
  "validUntil": "2025-08-01T00:00:00Z",
  "displayName": "Invoice #1042",
  "description": "Payment for consulting services",
  "items": [
    {
      "referenceId": "SKU-001",
      "name": "Consulting — July 2025",
      "description": "Monthly consulting fee",
      "quantity": 1,
      "price": 1500.00,
      "discount": 0,
      "tax": { "amount": 330.00, "currency": "UYU" },
      "metadata": { "sku": "CONS-001" }
    }
  ],
  "status": "active",
  "createdAt": "2025-07-01T14:30:00Z",
  "updatedAt": null,
  "splitDestinations": null
}
```

### PaymentLinkDto fields

| Field               | Type             | Description                                                                             |
| ------------------- | ---------------- | --------------------------------------------------------------------------------------- |
| `id`                | GUID             | Unique internal identifier for the Payment Link.                                        |
| `externalId`        | string           | Public-facing identifier used in the shareable URL.                                     |
| `shareUrl`          | string           | Canonical hosted checkout URL to share with payers.                                     |
| `qrCodeUrl`         | string           | Public QR SVG URL for the canonical hosted checkout URL.                                |
| `merchantId`        | integer          | ID of the merchant receiving payments.                                                  |
| `type`              | string           | Link type: `regular`, `one-time`, or `quick-pay`.                                       |
| `amount`            | object or null   | Payment amount object (`currency`, `total`, `details`). Null for flexible-amount links. |
| `settings`          | object           | Configuration for payment behavior (amount mode, methods, installments, callbacks).     |
| `validFrom`         | datetime or null | Start of validity window.                                                               |
| `validUntil`        | datetime or null | End of validity window.                                                                 |
| `displayName`       | string or null   | Short title shown to payers.                                                            |
| `description`       | string or null   | Description shown to payers.                                                            |
| `status`            | string           | Current status: `active`, `expired`, `completed`, or `deleted`.                         |
| `createdAt`         | datetime         | Creation timestamp (ISO 8601).                                                          |
| `updatedAt`         | datetime or null | Last modification timestamp.                                                            |
| `items`             | array or null    | Line items for the payment. Null when no items are configured.                          |
| `splitDestinations` | array or null    | Split destination legs (populated when split destinations are configured).              |

### Error (400 Bad Request)

```json
{
  "code": "request-validation-errors",
  "message": "One or more validation errors occurred.",
  "type": "invalid-request-error",
  "status": 400,
  "traceId": "0HMVG9K3R5T4J:00000001",
  "params": {
    "amount.currency": ["Currency is required when amountMode is 'fixed'."],
    "amount.total": ["Total is required when amountMode is 'fixed'."]
  }
}
```

### Error (403 Forbidden)

Returned when the authenticated client does not have access to the specified merchant.

***

## Response codes

| Code  | Description                                               |
| ----- | --------------------------------------------------------- |
| `201` | Payment Link created successfully.                        |
| `400` | Validation error in the request body.                     |
| `401` | Authentication required or credentials invalid.           |
| `403` | Authenticated client does not own the specified merchant. |

***

## Example

```bash
curl -X POST "https://api.plexo.com.uy/v1/payment-links" \
  -u "YOUR_USERNAME:YOUR_PASSWORD" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": 12345,
    "type": "one-time",
    "amount": {
      "currency": "UYU",
      "total": 1500.00
    },
    "settings": {
      "amountMode": "fixed",
      "paymentMethods": ["VISA", "MASTERCARD"],
      "installments": { "VISA": [1, 3, 6], "MASTERCARD": [1, 3] }
    },
    "displayName": "Invoice #1042",
    "description": "Payment for consulting services",
    "validUntil": "2025-08-01T00:00:00Z"
  }'
```

### Split Payment Link example

```bash
curl -X POST "https://api.plexo.com.uy/v1/payment-links" \
  -u "YOUR_USERNAME:YOUR_PASSWORD" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": 12345,
    "type": "regular",
    "amount": {
      "currency": "UYU",
      "total": 10000.00
    },
    "settings": {
      "amountMode": "fixed",
      "paymentMethods": ["VISA", "MASTERCARD"],
      "installments": { "*": [1, 3] }
    },
    "displayName": "Platform purchase",
    "splitDestinations": [
      {
        "destinationMerchantId": 67890,
        "amountRule": { "type": "percentage", "value": 85 }
      },
      {
        "destinationMerchantId": 12345,
        "amountRule": { "type": "residual" }
      }
    ]
  }'
```

{% hint style="info" %}
The `externalId` in the response is the public identifier used to share the Payment Link with payers. Build the shareable URL using this value.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://plexo.gitbook.io/rest-api/api-reference/payment-links/create.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
