For AI agents: markdown of this page — /docs-content-en/entities/crm-payments/update.md documentation index — /llms.txt
Update a CRM payment
PATCH /v1/crm-payments/:id
Changes a CRM payment's payment system or its "paid" mark: sets the mark or clears it.
Fields are passed flat at the JSON root, without a fields wrapper.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Parameterid (path) |
Typenumber | Requiredyes | DescriptionPayment ID. List of an item's payments: GET /v1/crm-payments |
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
Fieldpaid |
Typeboolean | Requiredno | Descriptiontrue sets the "paid" mark, false clears it |
FieldpaySystemId |
Typenumber | Requiredno | DescriptionID of an existing payment system. List: GET /v1/pay-systems. The value 0 is rejected, as is the ID of a nonexistent system |
Pass at least one of the two fields. The payment amount is the sum of its line items and cannot be set directly.
Examples
curl — personal key
curl -X PATCH "https://vibecode.bitrix24.com/v1/crm-payments/565" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "paySystemId": 3 }'
curl — OAuth application
curl -X PATCH "https://vibecode.bitrix24.com/v1/crm-payments/565" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "paySystemId": 3 }'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/crm-payments/565', {
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ paySystemId: 3 }),
})
const { data } = await res.json()
console.log('Payment system:', data.paySystemName)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/crm-payments/565', {
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ paySystemId: 3 }),
})
const { data } = await res.json()
Response fields
Returns the payment after the change.
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | Descriptiontrue on success |
Fielddata.id |
Typenumber | DescriptionPayment ID |
Fielddata.accountNumber |
Typestring | DescriptionPayment number: the linked order number and the payment's sequence number separated by / |
Fielddata.paid |
Typestring | DescriptionPaid mark: Y for paid, N for not paid |
Fielddata.datePaid |
Typestring | null | DescriptionTime of the latest "paid" mark, ISO 8601 with a time zone offset. null if the payment was never marked |
Fielddata.empPaidId |
Typenumber | null | DescriptionID of the employee who last marked the payment. List: GET /v1/users |
Fielddata.paySystemId |
Typenumber | DescriptionPayment system ID. List: GET /v1/pay-systems |
Fielddata.sum |
Typenumber | DescriptionPayment amount |
Fielddata.currency |
Typestring | DescriptionCurrency code. List: GET /v1/currencies |
Fielddata.paySystemName |
Typestring | DescriptionPayment system name |
Fieldmeta.readbackUnavailable |
Typeboolean | DescriptionReturned only with the value true when the change was applied but the payment could not be read back. In that case data contains only id. Do not repeat the request; fetch the payment by this id |
Response example
{
"success": true,
"data": {
"id": 565,
"accountNumber": "1029/2",
"paid": "N",
"datePaid": null,
"empPaidId": null,
"paySystemId": 3,
"sum": 0,
"currency": "USD",
"paySystemName": "Bank transfer (Contacts)"
}
}
Error response example
400 — paid is not a boolean:
{
"success": false,
"error": {
"code": "INVALID_PARAMS",
"message": "paid must be a boolean."
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP400 | CodeMISSING_REQUIRED_FIELDS |
DescriptionThe body is missing, is not an object, or is an empty object {} |
| HTTP400 | CodeREADONLY_FIELD |
DescriptionThe body contains a field other than paid and paySystemId |
| HTTP400 | CodeINVALID_PARAMS |
Descriptionpaid is not a boolean, for example the string "Y", or paySystemId is negative or not an integer |
| HTTP400 | CodeINVALID_ID |
Descriptionid is not a positive integer |
| HTTP404 | CodeENTITY_NOT_FOUND |
DescriptionNo payment with this id exists |
| HTTP422 | CodeBITRIX_ERROR |
DescriptionNo payment system with this paySystemId exists, including 0. Message: Payment system has not been found |
| HTTP422 | CodeBITRIX_ERROR |
DescriptionBitrix24 rejected the request; the reason is in error.message |
| HTTP422 | CodeBITRIX_NO_EFFECT |
DescriptionBitrix24 did not confirm the change |
| HTTP403 | CodeBITRIX_ACCESS_DENIED |
DescriptionThe key's user has no access to the CRM item or payment in Bitrix24 |
| HTTP403 | CodeWRITE_BLOCKED_READONLY_KEY |
DescriptionThe key is not allowed to write |
| HTTP403 | CodeSCOPE_DENIED |
DescriptionThe API key does not have the crm scope |
| HTTP401 | CodeTOKEN_MISSING |
DescriptionThe API key has no configured tokens |
| HTTP401 | CodeMISSING_API_KEY |
DescriptionX-Api-Key is missing |
Full list of common API errors: Errors.
Known specifics
paid has different types in the request and the response. In the request body paid is a boolean, true or false; in the response it is the string Y or N.
paid behaves like the pay and unpay endpoints. paid: true sets the mark, like POST /v1/crm-payments/:id/pay, and paid: false clears it, like POST /v1/crm-payments/:id/unpay. Repeating paid: true on a payment that is already marked paid does not change datePaid. The mark does not transfer money, but it can trigger automation rules, an email or an online receipt.