|
3 | 3 | import com.twikey.callback.InvoiceCallback; |
4 | 4 | import com.twikey.modal.InvoiceRequests; |
5 | 5 | import com.twikey.modal.InvoiceResponse; |
| 6 | +import com.twikey.modal.ResponseUtils; |
6 | 7 | import org.json.JSONArray; |
7 | 8 | import org.json.JSONException; |
8 | 9 | import org.json.JSONObject; |
9 | 10 | import org.json.JSONTokener; |
10 | 11 |
|
11 | 12 | import java.io.IOException; |
| 13 | +import java.io.InputStream; |
12 | 14 | import java.net.http.HttpRequest; |
13 | 15 | import java.net.http.HttpResponse; |
14 | 16 | import java.nio.file.Path; |
@@ -287,12 +289,12 @@ public InvoiceResponse.BulkInvoiceDetail batchDetails(String batchId) throws IOE |
287 | 289 |
|
288 | 290 |
|
289 | 291 | /** |
290 | | - * Get updates about all mandates (new/updated/cancelled) |
| 292 | + * Get updates about all invoice states (BOOKED, PENDING, EXPIRED, PAID) |
291 | 293 | * |
292 | 294 | * @param invoiceCallback Callback for every change |
293 | 295 | * @param sideloads items to include in the sideloading @link <a href="https://www.twikey.com/api/#invoice-feed">www.twikey.com/api/#invoice-feed</a> |
294 | 296 | * @throws IOException When a network issue happened |
295 | | - * @throws TwikeyClient.UserException When there was an issue while retrieving the mandates (eg. invalid apikey) |
| 297 | + * @throws TwikeyClient.UserException When there was an issue while retrieving the invoice states (eg. invalid apikey) |
296 | 298 | */ |
297 | 299 | public void feed(InvoiceCallback invoiceCallback, String... sideloads) throws IOException, TwikeyClient.UserException { |
298 | 300 |
|
@@ -326,4 +328,56 @@ public void feed(InvoiceCallback invoiceCallback, String... sideloads) throws IO |
326 | 328 | } |
327 | 329 | } while (!isEmpty); |
328 | 330 | } |
| 331 | + |
| 332 | + |
| 333 | + /** |
| 334 | + * See <a href="https://www.twikey.com/api/#retrieve-invoice-pdf">Twikey API - Retrieve Invoice PDF</a> |
| 335 | + * <p> |
| 336 | + * Retrieves the PDF for a specific invoice using its UUID. The API will return |
| 337 | + * the raw PDF content along with the filename as set by the server. |
| 338 | + * </p> |
| 339 | + * |
| 340 | + * @param request An {@link InvoiceRequests.InvoicePdfRequest} containing the invoice UUID. |
| 341 | + * @return {@link InvoiceResponse.Pdf} A structured response object containing |
| 342 | + * the PDF content and filename. |
| 343 | + * @throws IOException If a network error occurs during the request. |
| 344 | + * @throws TwikeyClient.UserException If the API returns an error response. |
| 345 | + * |
| 346 | + * <p>Example usage:</p> |
| 347 | + * <pre>{@code |
| 348 | + * InvoiceRequests.InvoicePdfRequest pdfRequest = new InvoiceRequests.InvoicePdfRequest("032f42b8-9afc-459d-b0f5-b81a85a69e95"); |
| 349 | + * InvoiceResponse.Pdf pdf = invoiceGateway.pdf(pdfRequest); |
| 350 | + * byte[] content = pdf.getContent(); |
| 351 | + * String filename = pdf.getFilename(); |
| 352 | + * }</pre> |
| 353 | + */ |
| 354 | + public InvoiceResponse.Pdf pdf(InvoiceRequests.InvoicePdfRequest request) |
| 355 | + throws IOException, TwikeyClient.UserException { |
| 356 | + HttpRequest httpRequest = HttpRequest.newBuilder( |
| 357 | + twikeyClient.getUrl("/invoice/%s/pdf".formatted(request.id())) |
| 358 | + ) |
| 359 | + .header("Accept", "application/pdf") |
| 360 | + .header("User-Agent", twikeyClient.getUserAgent()) |
| 361 | + .header("Authorization", twikeyClient.getSessionToken()) |
| 362 | + .GET() |
| 363 | + .build(); |
| 364 | + |
| 365 | + HttpResponse<InputStream> response = twikeyClient.send( |
| 366 | + httpRequest, |
| 367 | + HttpResponse.BodyHandlers.ofInputStream() |
| 368 | + ); |
| 369 | + |
| 370 | + |
| 371 | + if (response.statusCode() == 200) { |
| 372 | + String filename = ResponseUtils.extractFilenameFromContentDisposition(response.headers()) |
| 373 | + .orElse(request.id() + ".pdf"); |
| 374 | + |
| 375 | + return new InvoiceResponse.Pdf(response.body(), filename); |
| 376 | + } else { |
| 377 | + throw new TwikeyClient.UserException(apiError(response)); |
| 378 | + } |
| 379 | + } |
| 380 | + |
| 381 | + |
| 382 | + |
329 | 383 | } |
0 commit comments