> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.runpayments.io/reference/terminal-api/receipt/print-receipt/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.runpayments.io/_mcp/server. # Print a receipt POST https://javelin.runpayments.io/api/terminal/{device_id}/print-receipt Content-Type: application/json Prints or reprints a receipt for a past transaction. Connects a terminal session automatically if none is active. The transaction must belong to the authenticated merchant and be the most recent transaction within its order. The merchant is resolved from `trans_id`, and the print uses that merchant's existing terminal session if one is active. Returns the terminal vendor's print response, passed through unmodified. Only Clover Flex and Clover Mini can print. All other terminals return `400 Not supported` here. `printer: false` is a permanent hardware limitation, so check `capabilities.printer` from [List terminals](/reference/terminal-api/terminals/list-terminals) before offering a reprint in your UI. ### 400 error messages | Message | Cause | | ------------------------------------------------------------------- | ---------------------------------------------- | | `Field trans_id is required` | Missing or invalid parameter. | | `Not supported` | The terminal has no printer. | | `No transaction found for the given trans_id` | No matching transaction for this merchant. | | `No order_id found for the given transaction` | The transaction exists but has no order. | | `trans_id is not for the most recent transaction within this order` | The transaction isn't the latest in its order. | | `Terminal is unavailable.` | The terminal is offline or busy. | | `Terminal in merchant mode. Launch customer mode and try again.` | The terminal is in the wrong mode. | | `Interaction was cancelled.` | Cancelled at the terminal. | Some terminal vendor errors also return `400` with the vendor's own message. Match on the messages above, but expect others. Reference: https://docs.runpayments.io/reference/terminal-api/receipt/print-receipt ## Authentication - `Authorization` header (bearer token, required) — Use a Payments API key as the bearer token: `Authorization: Bearer `. Get a fresh key from [Refresh API Keys](/reference/authentication/refresh-api-keys). ## Request ### Path parameters - `device_id` (string, required) — Hardware Serial Number (HSN) of the terminal, provided by your Integration Delivery lead. ### Query parameters - `mid` (string, optional) — Merchant ID. Required when your bearer token is an ISV token acting on behalf of a merchant. If the `mid` can't be resolved to an authorized account, the request returns `400`. ### Body (application/json) This endpoint expects an object. - `trans_id` (string, required) — Transaction to print. Must belong to the authenticated merchant and be the most recent transaction within its order. - `delay` (string, optional) — Delay before printing. - `extra_receipt` (boolean, optional) — Print an additional copy. ## Response ### 200 Terminal vendor print response, passed through unmodified. - `map from string to any` ## Errors ### 400 Bad Request Error The receipt couldn't be printed. See the table above for possible messages. - `error` (string, optional) — Error message. ### 401 Unauthorized Error Authentication failed. Bearer token rejections return `{"errors": ["Access denied"]}` and set the `WWW-Authenticate` header. Upstream terminal authentication failures return `{"error": "Failed CardPointe terminal authentication"}` and don't set the header. - `PrintReceiptRequestUnauthorizedError` ### 403 Forbidden Error This `device_id` isn't associated with the calling merchant. - `error` (string, optional) — Error message. ### 404 Not Found Error Terminal not found on this account. - `error` (string, optional) — Error message. ### 409 Conflict Error Terminal already connected. - `error` (string, optional) — Error message. ### 429 Too Many Requests Error Rate limit exceeded. All Terminal API endpoints share a per-credential rate limit. - `any` ### 500 Internal Server Error Upstream service timed out. - `error` (string, optional) — Error message. ### 503 Service Unavailable Error Service temporarily unavailable. - `error` (string, optional) — Error message. ## Types ### ErrorsResponse - `errors` (list of string, optional) — Error messages. ### ErrorResponse - `error` (string, optional) — Error message. ## Examples **Request** ```json { "trans_id": "987654321" } ``` **Response** ```json {} ``` **SDK Code** ```python import requests url = "https://javelin.runpayments.io/api/terminal/HSN123456789/print-receipt" payload = { "trans_id": "987654321" } headers = { "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```javascript const url = 'https://javelin.runpayments.io/api/terminal/HSN123456789/print-receipt'; const options = { method: 'POST', headers: {Authorization: 'Bearer ', 'Content-Type': 'application/json'}, body: '{"trans_id":"987654321"}' }; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://javelin.runpayments.io/api/terminal/HSN123456789/print-receipt" payload := strings.NewReader("{\n \"trans_id\": \"987654321\"\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Authorization", "Bearer ") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby require 'uri' require 'net/http' url = URI("https://javelin.runpayments.io/api/terminal/HSN123456789/print-receipt") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["Authorization"] = 'Bearer ' request["Content-Type"] = 'application/json' request.body = "{\n \"trans_id\": \"987654321\"\n}" response = http.request(request) puts response.read_body ``` ```java import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://javelin.runpayments.io/api/terminal/HSN123456789/print-receipt") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"trans_id\": \"987654321\"\n}") .asString(); ``` ```php request('POST', 'https://javelin.runpayments.io/api/terminal/HSN123456789/print-receipt', [ 'body' => '{ "trans_id": "987654321" }', 'headers' => [ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', ], ]); echo $response->getBody(); ``` ```csharp using RestSharp; var client = new RestClient("https://javelin.runpayments.io/api/terminal/HSN123456789/print-receipt"); var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer "); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"trans_id\": \"987654321\"\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` ```swift import Foundation let headers = [ "Authorization": "Bearer ", "Content-Type": "application/json" ] let parameters = ["trans_id": "987654321"] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://javelin.runpayments.io/api/terminal/HSN123456789/print-receipt")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "POST" request.allHTTPHeaderFields = headers request.httpBody = postData as Data let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in if (error != nil) { print(error as Any) } else { let httpResponse = response as? HTTPURLResponse print(httpResponse) } }) dataTask.resume() ```