Skip to content

Update a payment link

Open .md

PUT/v2/api/store/{team_slug}/v2/payment_link/{hash_id}

v2Operation ID v2_public_payment_link_update

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_slugstringrequired

    Your team slug, shown as Team ID next to your API key in Profile.

    • Example your-team
  • hash_idstringrequired

    The payment link's hash id. Hash ids only: a unique key or a document number gives 404.

    • Example IirNDCwiaCVSKx

Request body

application/json, required.

  • allocated_transactionsarray of objects

    Changes to existing allocations.

    Fields of each item (3)
    • actionstringrequired
      • One of: "update", "delete"
    • idstringrequired

      The allocation id from allocated_transactions[].id.

    • totaldecimal pair

      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.

  • notestring

    A note on the link.

  • unallocated_transactionsarray of objects

    New allocations.

    Fields of each item (4)
    • actionstringrequired
      • Always "create"
    • totaldecimal pairrequired

      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).

    • invoice_idstringrequired

      An invoice of the same sales order.

    • transaction_idstringrequired

      A payment on the same sales order.

Response

200Successful response.

  • dataobjectrequired
    Child fields (7)
    • allocated_transactionsarray of objectsrequired

      One row per allocation.

      Fields of each item (6)
      • statestring
        • Always "existing"
      • idstring

        The allocation. Send it in allocated_transactions[].id to update or delete it.

      • The invoice it pays.

      • totaldecimal pair

        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.

      • The payment.

      • unallocated_amountdecimal pair

        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.

    • created_atstring (date-time)required
    • idstringrequired

      The payment link.

    • order_idstringrequired

      The sales order.

    • totaldecimal pairrequired

      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.

    • updated_atstring (date-time)required
    • notestring | null
  • statusintegerrequired
  • successbooleanrequired

Errors

  • 401The API key is missing or wrong (unauthenticated).

  • 403You 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.

  • 404Not 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.
  • 422The 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.