# リーダーでコンテンツを印刷する リーダーの埋め込み型プリンターでコンテンツを印刷します。 Stripe Terminal を使用すると、レシート、チケット、その他の書類などのカスタムコンテンツをリーダーの埋め込み型プリンターで直接印刷できます。この機能は、白黒印刷が可能なサーマルプリンターを内蔵した [Verifone V660p](https://stripe.com/terminal/v660p) リーダーでのみ使用できます。 ## 印刷コンテンツを生成する 実装は、画像ファイルとして印刷するコンテンツを生成する役割を担います。印刷でサポートされる形式は画像のみです。画像を取得したら、実装タイプのネイティブ画像表現に変換します (たとえば、サーバー駆動型の場合は画像ファイル、Android の場合は[ビットマップ](https://developer.android.com/reference/kotlin/android/graphics/Bitmap.html))。 ### コンテンツのガイドライン 最良の結果を得るには、次の画像要件をお勧めします。 - 最大 384 ピクセル幅 - 白黒 (カラーなし) - 文字または線の最も細い部分の幅が 2 ピクセル以上になるようにデザインし、印刷が明確で読みやすくなるようにします > リーダーを使用して印刷するために Stripe に送信するコンテンツに関しては、お客様が法的責任を負います。また、レシートが適用法に準拠していることを確認する必要があります。(i) 第三者の権利を侵害する、(ii) 適用法に違反する、または (iii) 好ましくない、攻撃的、欺瞞的、不正確、または有害な内容を含む素材を含むレシートを印刷することはできません。 ## コンテンツを印刷する #### サーバー主導型 - [print_content](https://docs.stripe.com/api/terminal/readers/print_content.md) リーダーでコンテンツを印刷するには、[print_content](https://docs.stripe.com/api/terminal/readers/print_content.md)エンドポイントを呼び出します。`multipart/form-data` 本文を PNG または JPEG 画像ファイルと一緒に送信します。アップロードするファイルは 100 KB を超えてはなりません。 ```curl curl https://files.stripe.com/v1/terminal/readers/tmr_FDOt2wlRZEdpd7/print_content \ -u "<>:" \ -F type=image \ -F "image=@/path/to/a/image.png" ``` > このエンドポイントは、`api.stripe.com` ではなく `files.stripe.com` サブドメインに配置されます。 #### Android - [print (Android)](https://stripe.dev/stripe-terminal-android/core/com.stripe.stripeterminal/-terminal/print.html) Android SDK を使用してコンテンツを印刷するには、ネイティブの [Bitmap](https://developer.android.com/reference/kotlin/android/graphics/Bitmap.html) クラスのインスタンスを `PrintContent` として [print](https://stripe.dev/stripe-terminal-android/core/com.stripe.stripeterminal/-terminal/print.html) メソッドに渡します。 #### Kotlin ```kotlin val bitmap = createBitmap(384, /* some height */ ) // A width of 384 pixels is recommended // Generate print content here val printContent = PrintContent.Bitmap.create(bitmap) Terminal.getInstance().print( printContent, object : Callback { override fun onSuccess() { // Placeholder for handling successful operation } override fun onFailure(e: TerminalException) { // Placeholder for handling exception } } ) ``` #### iOS - [print (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPTerminal.html#/c:objc\(cs\)SCPTerminal\(im\)print:completion:) iOS SDK を使用してコンテンツを印刷するには、ネイティブの [UIImage](https://developer.apple.com/documentation/uikit/uiimage) クラスのインスタンスを [print](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPTerminal.html#/c:objc\(cs\)SCPTerminal\(im\)print:completion:) メソッドに渡します。 #### Swift ```swift let image = UIImage(named: "receipt") // Generate print content here let content = try PrintContentBuilder(image: image).build() Terminal.shared.print(content) { (error) in // Check for errors } ``` #### JavaScript - [print (JavaScript)](https://docs.stripe.com/terminal/references/api/js-sdk.md#print) JavaScript SDK を使用してコンテンツを印刷するには、ネイティブの [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement) オブジェクトを [print](https://docs.stripe.com/terminal/references/api/js-sdk.md#print) メソッドに渡します。 #### JavaScript ```javascript const canvas = document.createElement('canvas'); canvas.width = 384; canvas.height = /* some height */; // Generate print content here const result = await terminal.print(canvas); if ('error' in result) { // Placeholder for handling exception } else { // Placeholder for handling successful operation } ``` #### React Native - [print (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeTerminalSdkType.html#print) React Native SDK を使用してコンテンツを印刷するには、base64 文字列または `data:` URI スキームとしてエンコードされた画像を [print](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeTerminalSdkType.html#print) メソッドに渡します。 #### TypeScript ```typescript const { print } = useStripeTerminal(); // JPEG/PNG image encoded as a base64 string const imageUri = "iVBORw0KGgoAAAANSUhEUgAAAAcAAAAFCAYAAACJmvbYAAAAN0lEQVR4AUyLCQ4AQATExv7/z1YniERd5UnKgriVPpGIS9QAGsll7Rz0YMkV2HRijvns3RY+8wMAAP//S2WPFgAAAAZJREFUAwBWNAoHH+0LdQAAAABJRU5ErkJggg=="; const { error } = await print(imageUri); if (error) { // Placeholder for handling exception } else { // Placeholder for handling successful operation } ``` ## 印刷結果を処理する #### サーバー主導型 [print_content](https://docs.stripe.com/api/terminal/readers/print_content.md)エンドポイントは、print コマンドがリーダーに正常に送信されると、更新済みの [Reader](https://docs.stripe.com/api/terminal/readers/object.md)オブジェクトで応答します。次の応答例を参照してください。 ```json { "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" } ``` `action` オブジェクトは、`print_content` アクションが `in_progress` であることを示します。`print_content` オブジェクトには、印刷中の画像に関する情報が含まれます。 エンドポイントは、検証エラー (ファイルが大きすぎる、サポートされていない形式など) に対して、次のような `400` ステータスコードと本文ですぐに応答します。 ```json { "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 イベント 印刷操作が完了すると (正常終了かエラー終了かを問わず)、Stripe は [Webhook エンドポイント](https://docs.stripe.com/webhooks.md)にリクエストを送信します。 Stripe は 2 つの Webhook イベントを送信して、print コマンドの結果をバックエンドに通知します。 - `terminal.reader.action_succeeded`: print コマンドが成功しました。 - `terminal.reader.action_failed`: 印刷コマンドが失敗しました。たとえば、印刷中にプリンターの用紙がなくなったり、詰まったりしました。 Webhook ペイロードには [イベントオブジェクト](https://docs.stripe.com/api/events/object.md)が含まれます。ここで、`data.object`は更新された [Reader](https://docs.stripe.com/api/terminal/readers/object.md)オブジェクトです。 ##### `terminal.reader.action_succeeded` イベント `terminal.reader.action_succeeded` イベントの場合、`data` オブジェクトは次のようになります。 ```json { "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 } ``` `action.status`は `succeeded` に設定されます。この場合、`action.failure_code` と `action.failure_message` はどちらも `null` です。 ##### `terminal.reader.action_failed` イベント `terminal.reader.action_failed` イベントの場合、`data` オブジェクトは次のようになります。 ```json { "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 } ``` `action.status`は、`failed` に設定されます。`failure_code` フィールドには失敗の理由が含まれ、`failure_message` フィールドには失敗を説明する人間が読めるメッセージが含まれています。 `failure_code` フィールドに指定できる値は次のとおりです。 | エラーの説明 | 失敗コード | | ---------------------------- | ---------------------- | | プリンターは、現在印刷中です。 | `printer_busy` | | プリンターのロール紙が詰まっています。 | `printer_paperjam` | | プリンターの用紙が切れています。 | `printer_out_of_paper` | | プリンターのカバーまたはヘッドアセンブリが開いている。 | `printer_cover_open` | | 一般的な印刷の失敗 (その他のエラーはすべてキャッチ)。 | `printer_failure` | リーダーが印刷をサポートしていない場合、`failure_code` は `printer_not_supported` に設定され、[print_content](https://docs.stripe.com/api/terminal/readers/print_content.md)エンドポイントが呼び出された直後にエラーが返されます。`terminal.reader.action_failed` イベントは送信されません。 #### Android print コマンドが完了すると、Android SDK は [`Callback`](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.callable/-callback/index.html)オブジェクトの `onSuccess` 関数または `onFailure` 関数を呼び出します。 印刷が失敗した場合、`onFailure` 関数は、次のいずれかの `TerminalErrorCode` 値を持つ [`TerminalException`](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-terminal-exception/index.html)オブジェクトとともに呼び出されます。 - `PRINTER_BUSY` - `PRINTER_PAPERJAM` - `PRINTER_OUT_OF_PAPER` - `PRINTER_COVER_OPEN` - `PRINTER_ABSENT` - `PRINTER_UNAVAILABLE` - `PRINTER_ERROR` これらのエラーコードの詳細については、[`TerminalErrorCode` リファレンス](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-terminal-error-code/index.html#-556602182%2FClasslikes%2F-1219334616)を参照してください。 #### iOS print コマンドが完了すると、iOS SDK は指定された `completion` ブロックを呼び出します。成功すると、ブロックは `nil` で呼び出されます。印刷が失敗した場合は、以下の `SCPError` コードのいずれかを使用して `NSError` オブジェクトでブロックが呼び出されます。 | Objective-C | Swift | | -------------------- | -------------------- | | `PrinterBusy` | `printerBusy` | | `PrinterPaperJam` | `printerPaperJam` | | `PrinterOutOfPaper` | `printerOutOfPaper` | | `PrinterCoverOpen` | `printerCoverOpen` | | `PrinterAbsent` | `printerAbsent` | | `PrinterUnavailable` | `printerUnavailable` | | `PrinterError` | `printerError` | これらのエラーコードの詳細については、[`SCPError` リファレンス](https://stripe.dev/stripe-terminal-ios/docs/Enums/SCPError.html#/c:@E@SCPError@SCPErrorPrinterBusy) をご覧ください。 #### JavaScript [print](https://docs.stripe.com/terminal/references/api/js-sdk.md#print) メソッドは、print コマンドが成功すると空のオブジェクトに解決される `Promise` を返します。コマンドが失敗すると、`Promise` は `error` フィールドを持つオブジェクトに解決されます。`error` オブジェクトには、エラー `code` と人間が読める `message` が含まれます。 `code` フィールドに指定できる値は次のとおりです。 - `printer_busy` - `printer_paperjam` - `printer_cover_open` - `printer_out_of_paper` - `printer_absent` - `printer_unavailable` - `printer_error` [エラーコードリファレンス](https://docs.stripe.com/terminal/references/api/js-sdk.md#error-codes) を参照してください。 #### React Native [print](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeTerminalSdkType.html#print) メソッドは、print コマンドが成功すると空のオブジェクトに解決される `Promise` を返します。コマンドが失敗すると、`Promise` は `error` フィールドを持つオブジェクトに解決されます。`error` の値は、特定の [ErrorCode](https://stripe.dev/stripe-terminal-react-native/api-reference/types/ErrorCode.html)、人間が読める`メッセージ`、および `apiError` や `underlyingError` などの追加の詳細を含む [StripeError](https://stripe.dev/stripe-terminal-react-native/api-reference/interfaces/StripeError.html) オブジェクトです。