# Update a payment link

```http
PUT https://secure.yoprint.com/v2/api/store/{team_slug}/v2/payment_link/{hash_id}
```

- API version: v2
- Operation ID: `v2_public_payment_link_update`
- Section: Invoices and payments › [Payment links](https://developer.yoprint.com/reference/payment-links.md)
- Web page: https://developer.yoprint.com/reference/payment-links/v2-payment-link-update/
- Authentication: `Authorization: Bearer YOUR_API_KEY`

A payment link records how payments already received on a sales order are split across its invoices (the web app calls this a payment allocation). It is not a URL or payment page your customer opens to pay, and it moves no money.

Changes the note and the allocations in one call: `delete` and `update` act on existing allocations (by allocation `id`), `create` adds new ones (a payment and an invoice of the same order). Allocations you leave out stay as they are. Returns the link as Show one payment link does.

Amounts in allocations must use exactly 3 decimal places (`dp: 3`):
- Correct: `{ "value": 12500, "dp": 3 }` for 12.50.
- Wrong: `{ "value": 1250, "dp": 2 }` — the server always interprets `value` as thousandths (scale 3), which would mean 1.250, and validation requires `dp: 3`.

In answers, the link's own `total` uses 4 decimal places (`{ "value": 175000, "dp": 4 }` is 17.50): always read each pair's `dp`.

Amounts are capped, not refused: an allocation never exceeds what the invoice still owes or what the payment has left. A `create` row asking for more than the payment has left, or for an invoice with nothing left to pay, is skipped without an error. Read the response to see what was saved.

## Permission

Any member of the team. No sales order permission is checked.

## Business rules

- Payments and invoices must belong to the link's sales order; others are skipped.
- For `update`, `total.dp` must be 3 and `total.value` 0 or more (422 otherwise).
- Deletes run first, then updates, then creates, so you can move money from one invoice to another in one call.

## Side effects

- Changes how much each invoice shows as paid.
- Updates the order's customer's balance totals in the background.
- No money moves and nothing is sent to the customer. Open Admin Portal pages refresh, and so do Customer Portal pages the customer has open.

## Path parameters

- `team_slug` (string, required): Your team slug, shown as Team ID next to your API key in Profile. Example `your-team`.
- `hash_id` (string, required): The payment link's hash id. Hash ids only: a unique key or a document number gives 404. Example `IirNDCwiaCVSKx`.

## Request body

Content type `application/json`, required.

Fields:

- `allocated_transactions` (array of objects, optional): Changes to existing allocations.
  - Each item:
    - `action` (string, required): One of: `"update"`, `"delete"`.
    - `id` (string, required): The allocation id from `allocated_transactions[].id`.
    - `total` (decimal pair, optional): Required for `update`: the new allocated amount with `dp: 3` (for example `{ "value": 12500, "dp": 3 }` for 12.50). `value` is always read as thousandths. See https://developer.yoprint.com/concepts/money-and-quantities.md.
- `note` (string, optional): A note on the link.
- `unallocated_transactions` (array of objects, optional): New allocations.
  - Each item:
    - `action` (string, required): Always `"create"`.
    - `total` (decimal pair, required): The amount to allocate. Send it: the server doesn't require it, and a row without it adds a 0.000 allocation. `value` is always read as thousandths whatever `dp` says (for example send `{ "value": 12500, "dp": 3 }` for 12.50). See https://developer.yoprint.com/concepts/money-and-quantities.md.
    - `invoice_id` (string, required): An invoice of the same sales order.
    - `transaction_id` (string, required): A payment on the same sales order.

### Example request

```bash
curl -X PUT 'https://secure.yoprint.com/v2/api/store/your-team/v2/payment_link/IirNDCwiaCVSKx' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "allocated_transactions": [
      {
        "action": "update",
        "id": "SAo2jTR8BZUnyc",
        "total": {
          "dp": 3,
          "value": 12500
        }
      }
    ],
    "note": "Deposit split across two invoices",
    "unallocated_transactions": [
      {
        "action": "create",
        "invoice_id": "7ELS3Vmu6QfJxT",
        "total": {
          "dp": 3,
          "value": 5000
        },
        "transaction_id": "tUq7cR8dTLKFPm"
      }
    ]
  }'
```

## Response

`200` Successful response.

Fields:

- `data` (object, required)
  - `allocated_transactions` (array of objects, required): One row per allocation.
    - Each item:
      - `state` (string, optional): Always `"existing"`.
      - `id` (string, optional): The allocation. Send it in `allocated_transactions[].id` to update or delete it.
      - `invoice_id` (string, optional): The invoice it pays.
      - `total` (decimal pair, optional): The allocated amount (usually 3 decimal places; a finer stored amount comes back with a larger `dp`). A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
      - `transaction_id` (string, optional): The payment.
      - `unallocated_amount` (decimal pair, optional): What the payment still has to allocate (usually 3 decimal places; a finer stored amount comes back with a larger `dp`). A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
  - `created_at` (string (date-time), required)
  - `id` (string, required): The payment link.
  - `order_id` (string, required): The sales order.
  - `total` (decimal pair, required): The sum of its allocations. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 175000, "dp": 4 }` is 17.50). Kept at 4 decimal places; `{ "value": 0, "dp": 0 }` when the link has no allocations. Read `dp` every time. See https://developer.yoprint.com/concepts/money-and-quantities.md.
  - `updated_at` (string (date-time), required)
  - `note` (string | null, optional)
- `status` (integer, required)
- `success` (boolean, required)

Example response:

```json
{
  "data": {
    "allocated_transactions": [
      {
        "id": "SAo2jTR8BZUnyc",
        "invoice_id": "gtnwEWU4Npp9eC",
        "state": "existing",
        "total": {
          "dp": 3,
          "value": 12500
        },
        "transaction_id": "tUq7cR8dTLKFPm",
        "unallocated_amount": {
          "dp": 3,
          "value": 2500
        }
      },
      {
        "id": "8Ejv1L5Duc4hRZ",
        "invoice_id": "7ELS3Vmu6QfJxT",
        "state": "existing",
        "total": {
          "dp": 3,
          "value": 5000
        },
        "transaction_id": "tUq7cR8dTLKFPm",
        "unallocated_amount": {
          "dp": 3,
          "value": 2500
        }
      }
    ],
    "created_at": "2026-11-03T15:00:00+00:00",
    "id": "IirNDCwiaCVSKx",
    "note": "Deposit split across two invoices",
    "order_id": "ERwEdCKYNeQIHW",
    "total": {
      "dp": 4,
      "value": 175000
    },
    "updated_at": "2026-11-03T15:05:00+00:00"
  },
  "status": 200,
  "success": true
}
```

## Errors

- `401` The API key is missing or wrong (`unauthenticated`).
- `403` You are not allowed to do this. `api_access_not_in_plan`: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only `{"message": "Insufficient Permission"}`. Other refusals use the error envelope, with `unauthorized` or `user_is_not_authorized`.
- `404` Not found. `page_not_found`: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's. `code: null`, with a message that starts "No query results for": there is no record with that id.
  - When: The link isn't your team's. Fix: Check the id.
- `422` The request was refused and changed nothing. `validation_failed` lists what to fix in `error.fields`; other codes name a business rule, explained in `error.message`. A few checks answer with only `{"message": "..."}`. An operation that calls another service (a payment provider, a carrier, an accounting app) can answer `connect_timeout` ("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.
  - When: A row lacks `action`, an `id`, `invoice_id` or `transaction_id`, or an update `total` isn't 3 decimal places. Fix: Start from Get the starting point for editing a payment link and keep its shapes.
  - When: The order came from Shopify and was deleted there (`shopify_order_deleted_externally`). Fix: Only local cleanup is allowed on that order.

## Related

- [Get the starting point for editing a payment link](https://developer.yoprint.com/reference/payment-links/v2-payment-link-get-update-template.md): `GET /v2/api/store/{team_slug}/v2/payment_link/{hash_id}/get_update_template`
- [Show one payment link with allocations](https://developer.yoprint.com/reference/payment-links/v2-payment-link-show.md): `GET /v2/api/store/{team_slug}/v2/payment_link/{hash_id}`
- [Create a payment link for a sales order](https://developer.yoprint.com/reference/payment-links/v2-sales-order-payment-link-create.md): `POST /v2/api/store/{team_slug}/v2/sales_order/{hash_id}/payment_link`
