Stripe | Financial Infrastructure to Grow Your Revenue

Stripe | Financial Infrastructure to Grow Your Revenue

5282 articles

Print content on a reader


Print content on a reader

With Stripe Terminal, you can print custom content – such as receipts, tickets, or other documents – directly on a reader’s embedded printer. This feature is only available for the Verifone V660p reader, which is equipped with an embedded thermal printer capable of printing in black and white.

Generating print content

Your integration is responsible for generating the content to print as an image file. Images are the only format that we support for printing. After you have an image, convert it to the native image representation for your integration type (for example, an image file for server-driven or a Bitmap for Android).

Content guidelines

For best results, we recommend images that are:

  • At most 384 pixels wide
  • Black and white (no colour)
  • Designed so that the thinnest part of any character or line is at least 2 pixels wide, to make sure printing is clear and legible

Note

You’re legally responsible for any content submitted to Stripe for printing using readers, and must make sure your receipts comply with applicable law. You’re prohibited from printing receipts containing materials that (i) infringe on the rights of any third party, (ii) violate applicable law, or (iii) contain objectionable, offensive, deceptive, inaccurate, or harmful content.

Printing content

To print content on a reader, call the print_content endpoint. Send a multipart/form-data body with your PNG or the related setting image file. The uploaded file must not exceed 100 KB.

Command Line

cURL

Note

This endpoint lives on the files.stripe.com subdomain instead of api.stripe.com.

Handle the print result

The print_content endpoint responds with an updated Reader object when the print command successfully sends to the reader. See the following example response:

{
 "id": "tmr_FDOt2wlRZEdpd7",
 "object": "terminal.reader",
 "action": {
 "failure_code": null,
 "failure_message": null,
 "print_content": {
 "image": {
 "created_at": 1748971913,
 "filename": "image.png",
 "size": 15864,
 "type": "png"
 },
 "type": "image"
 },
 "status": "in_progress",
 "type": "print_content"
 },
 "device_sw_version": "2.37.2.0",
 "device_type": "verifone_v660p",
 "ip_address": "0.0.0.0",
 "label": "Blue Rabbit",
 "last_seen_at": 1695166525506,
 "livemode": false,
 "location": "tml_FDOtHwxAAdIJOh",
 "metadata": {},
 "serial_number": "452-406-028",
 "status": "online"
}

The action object shows that a print_content action is in_progress. The print_content object contains information about the image being printed.

The endpoint immediately responds to a validation error (for example, file too large or unsupported format) with a 400 status code and a body, such as the following:

{
 "error": {
 "message": "The file you uploaded was too large. Please upload a file smaller than 100 KB",
 "param": "image",
 "request_log_url": "https://dashboard.stripe.com/...",
 "type": "invalid_request_error"
 }
}

Webhook events

When the print operation completes (either successfully or with an error), Stripe sends a request to your webhook endpoint.

Stripe sends two webhook events to notify your back end of the print command’s result:

  • terminal. reader. action _ succeeded : The print command succeeded.
  • terminal. reader. action _ failed : The print command failed. For example, the printer ran out of paper or jammed during printing.

The webhook payload contains an event object where data.object is an updated Reader object.

The terminal.reader.action_succeeded event

For a terminal.reader.action_succeeded event, the data object looks like the following:

{
 "object": {
 "id": "tmr_FDOt2wlRZEdpd7",
 "object": "terminal.reader",
 "action": {
 "failure_code": null,
 "failure_message": null,
 "print_content": {
 "image": {
 "created_at": 1748971913,
 "filename": "image.png",
 "size": 15864,
 "type": "png"
 },
 "type": "image"
 },
 "status": "succeeded",
 "type": "print_content"
 },
 "device_deploy_group": "",
 "device_sw_version": "2.34.0.0",
 "device_type": "verifone_v660p",
 "ip_address": "10.244.38.93",
 "label": "test",
 "livemode": false,
 "location": "tml_GEPlmAJnZUoXI6",
 "metadata": {},
 "serial_number": "452-406-028",
 "software": null,
 "status": "online"
 },
 "previous_attributes": null
}

The action.status is set to succeeded. The action.failure_code and action.failure_message are both null in this case.

The terminal.reader.action_failed event

For a terminal.reader.action_failed event, the data object looks like the following:

{
 "object": {
 "id": "tmr_FDOt2wlRZEdpd7",
 "object": "terminal.reader",
 "action": {
 "failure_code": "reason_out_of_paper",
 "failure_message": "The printer is out of paper.",
 "print_content": {
 "image": {
 "created_at": 1748971913,
 "filename": "image.png",
 "size": 15864,
 "type": "png"
 },
 "type": "image"
 },
 "status": "failed",
 "type": "print_content"
 },
 "device_deploy_group": "",
 "device_sw_version": "2.34.0.0",
 "device_type": "verifone_v660p",
 "ip_address": "10.244.35.107",
 "label": "test",
 "livemode": false,
 "location": "tml_GEPlmAJnZUoXI6",
 "metadata": {},
 "serial_number": "452-406-028",
 "software": null,
 "status": "online"
 },
 "previous_attributes": null
}

The action.status is set to failed. The failure_code field contains the reason for the failure, and the failure_message field contains a human readable message describing the failure.

The possible values for the failure_code field are:

Error DescriptionFailure Code
The printer is currently printing.reason_busy
The printer paper roll is jammed.reason_paperjam
The printer is out of paper.reason_out_of_paper
The printer’s cover or head assembly is open.reason_cover_open
The reader doesn’t have an embedded printer.reason_absent
The reader has an embedded printer, but it’s currently unavailable.reason_unavailable
The reader’s battery is too low to print. Charge the reader and try again.reason_low_battery
General failure to print (catch all for any other error).reason_generic_failure

If the reader doesn’t support printing, the print_content request immediately returns a printer_not_supported error. Because the request doesn’t create an action, Stripe doesn’t send a terminal.reader.action_failed event.

Last verified 2026-09-25

Is this helpful?