# Cancel a multi-payment page Building with an AI agent? Start at https://docs.payme.io/agents.md - Sandbox: `POST https://sandbox.payme.io/api/cancel-template` - Production: `POST https://live.payme.io/api/cancel-template` ## Credentials - Request body field `seller_payme_id` (optional): The MPL of the seller that owns the page. Required unless you send `payme_client_key`. - Request body field `payme_client_key` (optional): Partners: your partner key, instead of `seller_payme_id`. You can send it in the `PayMe-Partner-Key` header instead. ## Overview Closes a [multi-payment page](/accepting-payments/checkout-and-in-person/multi-payment-page) so no more buyers can pay on its link. The page must still be open (`initial`); its status becomes `canceled`. Nothing is refunded: sales already paid through the page stay as they are. Send the page's ID in **`sale_payme_id`**. This call uses that name, unlike the other post-sale calls, which take `payme_sale_id`. ### Credentials Send `seller_payme_id` of the seller that owns the page. Partners can send `payme_client_key` (or the `PayMe-Partner-Key` header) instead. The page must belong to the seller or partner you name; otherwise the call returns HTTP 403, error `303`. This call works only on multi-payment pages (`template` sales); any other sale returns error `357`. There is no cancel call for an ordinary sale. ## Parameters This endpoint takes no path, query or header parameters. ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `seller_payme_id` | string | no | The MPL of the seller that owns the page. Required unless you send `payme_client_key`. | | `payme_client_key` | string | no | Partners: your partner key, instead of `seller_payme_id`. You can send it in the `PayMe-Partner-Key` header instead. | | `sale_payme_id` | string | yes | The multi-payment page's ID: the `payme_sale_id` that `generate-sale` returned for it. Note the field name. | | `language` | string | no | Language of error messages: `en`, or `he` (the default). `es`, `ru` and `ar` are accepted, but messages then come back mostly in English. Any other value returns error `51`. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payme_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/cancel-template' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payme_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/cancel-template", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payme_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/cancel-template", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payme_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "language": "en", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — The page is canceled. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0`: the page is canceled. | | `session` | string | PayMe's ID for this request. Quote it when you contact PayMe. | ```json { "status_code": 0, "session": "Ab12Cd34" } ``` ### 403 — Error `303`: the page belongs to another partner or another seller. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | The error message, in the language you asked for. | | `status_additional_info` | string | Extra detail: usually the field at fault, the sale's current status, or the masked card number. | | `session` | string | PayMe's ID for this request. Quote it when you contact PayMe. | ```json { "status_code": 1, "status_error_details": "Could not access sale", "status_additional_info": "", "status_error_code": 303, "session": "Ab12Cd34" } ``` ### 500 — Request errors. `1`: a required field is missing (for example `sale_payme_id`) or no credential was sent. `200`: unknown partner key. `251`: unknown seller. `350`: no sale has this ID. `357`: the sale isn't a multi-payment page (`status_additional_info` holds its sale type number). `305`: the page isn't `initial` (its status, such as `canceled`, is in `status_additional_info`). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | The error message, in the language you asked for. | | `status_additional_info` | string | Extra detail: usually the field at fault, the sale's current status, or the masked card number. | | `session` | string | PayMe's ID for this request. Quote it when you contact PayMe. | ```json { "status_code": 1, "status_error_details": "Cannot perform action due to an incorrect status", "status_additional_info": "canceled", "status_error_code": 305, "session": "Ab12Cd34" } ```