# Capture an authorized sale Building with an AI agent? Start at https://docs.payme.io/agents.md - Sandbox: `POST https://sandbox.payme.io/api/capture-sale` - Production: `POST https://live.payme.io/api/capture-sale` ## Credentials - Request body field `payme_client_key` (optional): Partners: your partner key. You can send it in the `PayMe-Partner-Key` header instead. A seller leaves it out. - Request body field `seller_payme_id` (optional): The seller's MPL. Required unless you send `seller_id` with `payme_client_key`. ## Overview Charges a sale that was authorized with `sale_type: "authorize"`. Capture once, for the authorized amount or less, within 7 days of the authorization. To capture in several parts, use [multi-capture](/accepting-payments/capture-and-saved-cards/multi-capture). The whole flow is in [Authorize now, capture later](/accepting-payments/capture-and-saved-cards/capture-sale). ### Credentials The same as [`refund-sale`](/payments/post-sale-actions/post-refund-sale): send `seller_payme_id`, or `seller_id` with your partner key (`payme_client_key`). A partner key on its own fails with error `1`. The sale must belong to the seller you name. ### Rules - The sale must be `authorized`. A sale whose capture was declined (`failed`) can be captured again while the authorization is still valid. Any other status returns error `305`, with the status in `status_additional_info`. - Leave out `sale_price` to capture the full authorized amount; send a lower `sale_price` to capture less. - `sale_price` must be at least the account's minimum sale value (500 by default) and at most the authorized amount, unless PayMe has set a higher capture limit on your account. `0` or an amount outside these limits returns `352`; a decimal returns `42`. - More than 7 days (168 hours) after the authorization, the call fails with `516`. The error doesn't release the hold: void it with [`refund-sale`](/payments/post-sale-actions/void-sale). - `518` means the sale's authorization is no longer open, for example because the authorization failed. ### Result A successful capture returns the sale with `sale_status: "completed"`, and PayMe sends a `sale-complete` callback. A declined capture returns HTTP 200 with `status_code: 1`, `status_error_code` and `status_error_details`, and the sale becomes `failed`; you can retry while the authorization is still valid and within the 7 days. ## Parameters This endpoint takes no path, query or header parameters. ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_client_key` | string | no | Partners: your partner key. You can send it in the `PayMe-Partner-Key` header instead. A seller leaves it out. | | `seller_payme_id` | string | no | The seller's MPL. Required unless you send `seller_id` with `payme_client_key`. | | `seller_id` | string | no | Partners: your own ID for the seller (the `seller_id` you set when you created it). Send it with `payme_client_key` instead of `seller_payme_id`. | | `payme_sale_id` | string | yes | The authorized sale. | | `sale_price` | integer | no | Amount to capture, in minor units (`10000` = 100.00). Leave it out to capture the full authorized amount. At least the account's minimum sale value (500 by default); at most the authorized amount, unless PayMe has set a higher capture limit on your account. | | `installments` | integer | no | Number of installments, `1`–`36`. Leave it out to keep the sale's installments. | | `transaction_id` | string | no | Your own reference for the sale. Replaces the `transaction_id` you sent on `generate-sale`. | | `sale_additional_data` | object | no | Extra data to store on the sale. | | `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", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "sale_price": 8000, "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/capture-sale' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "sale_price": 8000, "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/capture-sale", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "sale_price": 8000, "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/capture-sale", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "sale_price": 8000, "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 capture result: captured (`status_code` `0`) or declined (`1`). A decline also returns HTTP 200. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0`: captured. `1`: the capture was declined; the sale is now `failed`. | | `status_error_code` | integer | `0` on success; the decline code when `status_code` is `1`. | | `status_error_details` | string | The decline reason, when `status_code` is `1`. | | `payme_status` | string | Legacy field. Read `status_code` instead. | | `payme_sale_id` | string | The sale's ID. | | `payme_sale_code` | integer | The sale's numeric code. | | `sale_created` | string | When the sale was created, `YYYY-MM-DD HH:MM:SS` (Israel time). | | `sale_status` | string | The sale's status, for example `completed`, `authorized` or `failed`. See [Sale Statuses](/payments/codes-statuses/sale-statuses). | | `payme_sale_status` | string | Same as `sale_status`. | | `sale_type` | string | The sale type as responses name it, for example `Sale` (also for an authorization) or `Token`. | | `sale_payment_method` | string | Payment method, for example `credit-card`. | | `currency` | string | Sale currency, an ISO 4217 code such as `ILS`. | | `price` | integer | Sale price in minor units (`10000` = 100.00). | | `transaction_id` | string | Your own reference for the sale. | | `sale_description` | string | The sale's description. | | `sale_deferred_months` | integer | Deferred months on the sale, or `null`. | | `is_token_sale` | boolean | `true` for a `token` sale, which saves the card without charging it. | | `payme_signature` | string | PayMe's signature for this payment. | | `payme_transaction_id` | string | PayMe's ID of the payment transaction. | | `payme_transaction_total` | string | Amount of the transaction, in minor units. | | `payme_transaction_card_brand` | string | Card brand, for example `Mastercard`. | | `payme_transaction_auth_number` | string | Authorization number from the card issuer. | | `payme_transaction_voucher` | string | Voucher number of the transaction. | | `payme_transaction_emv_uid` | string | EMV UID of the transaction, when the acquirer returns one; usually `null`. | | `payme_transaction_acquirer` | string | The acquirer, for example `PayMe`. | | `payme_transaction_auth_source` | string | Authorization source reported for the transaction. | | `payme_transaction_card_issuer` | string | Card issuer, for example `Isracard`. | | `payme_transaction_credit_type` | string | Credit type, for example `RegularCredit`. | | `buyer_name` | string | Buyer's full name. | | `buyer_email` | string | Buyer's email address. | | `buyer_phone` | string | Buyer's phone number, or `null`. | | `buyer_card_mask` | string | Masked card number, for example `532610******5846`. | | `buyer_card_exp` | string | Card expiry, `MMYY`. | | `buyer_card_is_foreign` | boolean | `true` for a card issued outside Israel. | | `buyer_social_id` | string | Buyer's national ID number, or `null`. | | `installments` | integer | Number of installments. | | `transaction_first_payment` | integer | First installment, in minor units. | | `transaction_periodical_payment` | integer | Each later installment, in minor units; `0` for a single payment. | | `transaction_arn` | string | Acquirer reference (EMV UID) when the acquirer returns one; usually `null`. | | `sale_paid_date` | string | When the payment was made, `YYYY-MM-DD HH:MM:SS` (Israel time). | | `sale_release_date` | string | Date the funds are released to the seller, `YYYY-MM-DD`, or `null`. | | `sale_3ds` | boolean | `true` when the payment passed 3D Secure. | | `session` | string | PayMe's ID for this request. Quote it when you contact PayMe. | ```json { "status_code": 0, "status_error_code": 0, "payme_status": "success", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "payme_sale_code": 1111111, "sale_created": "2026-11-09 10:15:02", "sale_status": "completed", "payme_sale_status": "completed", "sale_type": "Sale", "sale_payment_method": "credit-card", "currency": "ILS", "price": 8000, "transaction_id": "order-1234", "sale_description": "Shirt", "sale_deferred_months": null, "is_token_sale": false, "payme_signature": "b71e**************ca5a", "payme_transaction_id": "TRANDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "payme_transaction_total": "8000", "payme_transaction_card_brand": "Mastercard", "payme_transaction_auth_number": "0123456", "payme_transaction_voucher": "111111", "payme_transaction_emv_uid": null, "payme_transaction_acquirer": "PayMe", "payme_transaction_auth_source": "VoiceMail", "payme_transaction_card_issuer": "Isracard", "payme_transaction_credit_type": "RegularCredit", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": null, "buyer_card_mask": "532610******5846", "buyer_card_exp": "1230", "buyer_card_is_foreign": false, "buyer_social_id": "008336174", "installments": 1, "transaction_first_payment": 8000, "transaction_periodical_payment": 0, "transaction_arn": null, "sale_paid_date": "2026-11-09 10:16:40", "sale_release_date": null, "sale_3ds": false, "session": "Ab12Cd34" } ``` ### 400 — Error `1`: no seller named (a partner key on its own). Error `352`: `sale_price` is above the authorized amount (or your capture limit). Error `20`: the seller doesn't belong to the partner key sent. (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": "Invalid price, out of min-max bounds", "status_additional_info": "12000", "status_error_code": 352, "session": "Ab12Cd34" } ``` ### 403 — Error `303`: the sale 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" } ``` ### 429 — Error `998`: another call for this sale is still running, or too many requests. Wait, then check the sale before retrying. (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": "Operation is not permitted", "status_additional_info": "Duplicated action detected, please retry later", "status_error_code": 998, "session": "Ab12Cd34" } ``` ### 500 — Request errors. `1`: a required field is missing. `350`: no sale has this ID. `305`: the sale isn't `authorized` or `failed`. `518`: the authorization is no longer open. `516`: more than 7 days since the authorization. `352`: `sale_price` below the account minimum. `42`: `sale_price` isn't a whole number. `351`: invalid `installments`. `251`: unknown 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": "Sale authorization has been expired", "status_additional_info": "", "status_error_code": 516, "session": "Ab12Cd34" } ```