checkout / checkout-sdk-net

Checkout SDK for Microsoft .NET
https://checkout.com
MIT License
21 stars 23 forks source link

Report Files content is assumed to always be text #320

Open miguel-ferreira-cko opened 1 year ago

miguel-ferreira-cko commented 1 year ago

Environment

Description

Report File content should not always be treated as text. In some cases it can be a binary format (e.g. PDF) which cannot be encoded as a text in .NET (be it ASCII, UTF8...) and must be treated as a byte array / stream / base64 so that it can be properly stored.

Expected behavior

Report File content accurately contains the original file bytes.

Current behavior

Report File content contains a string encoding of the original file bytes, which when encoded back into binary form will be missing data.

Steps to reproduce

  1. Download the PDF file via command line (e.g. PowerShell) Invoke-RestMethod -Method Get -Uri 'https://api.checkout.com/reports/REPORT_ID/files/FILE_ID' -Headers @{"Authorization"="SECRET"} -OutFile original.pdf
  2. Download the same PDF file using the Checkout SDK and attempt to save in any of the available text encodings
    
    using Checkout;
    using System.Text;

ICheckoutApi api = CheckoutSdk.Builder().StaticKeys() .SecretKey("SECRET") .Environment(Checkout.Environment.Production) .Build();

var reportId = "REPORT ID WHERE .Files[0].Format == PDF";

var report = await api .ReportsClient() .GetReportDetails(reportId);

var file = await api .ReportsClient() .GetReportFile(reportId, report.Files[0].Id);

File.WriteAllBytes("report.pdf", Encoding.Unicode.GetBytes(file.Body)); File.WriteAllBytes("report2.pdf", Encoding.UTF8.GetBytes(file.Body)); File.WriteAllBytes("report3.pdf", Encoding.ASCII.GetBytes(file.Body)); File.WriteAllBytes("report4.pdf", Encoding.UTF32.GetBytes(file.Body)); File.WriteAllBytes("report5.pdf", Encoding.Latin1.GetBytes(file.Body)); File.WriteAllText("report6.pdf", file.Body, Encoding.ASCII);


3. Observe that none of the PDF files that had their bytes text encoded previously is keeping the original file bytes:
![image](https://github.com/checkout/checkout-sdk-net/assets/88899602/481a9532-feb5-4003-af9d-9b0d2a84f017)

### Possible solution
<!--- Feel free to suggest a solution -->
<!--- PLEASE DO NOT SHARE ANY CREDENTIALS -->

- [ ] I may be able to implement this bug fix

### Additional information
<!--- Feel free to add any additional information that can help to diagnose and fix the issue -->
<!--- PLEASE DO NOT SHARE ANY CREDENTIALS -->
armando-rodriguez-cko commented 1 year ago

Thank you @miguel-ferreira-cko, we will review the information you provided shortly and get back to you to resolve this issue.

a-ibarra commented 1 year ago

@miguel-ferreira-cko We raised this issue time ago, the thing is that this endpoint is a redirect, and previously this endpoint was always returning a string, in worst case we should return only the string of the redirect and merchant should handle the type of the content based on the response.

miguel-ferreira-cko commented 1 year ago

@armando-ibarra-cko this endpoint has always returned 302 Redirect into a pre-signed location within AWS S3 that downloads a file. The HttpClient in .NET follows redirect links by default.

The response type of GetReportFile on the SDK could simply be the HttpClient Response itself

armando-rodriguez-cko commented 1 year ago

Thank you @miguel-ferreira-cko for the information, we will review and we will try to improve this point. We will let you know when we have something.

armando-rodriguez-cko commented 5 days ago

@miguel-ferreira-cko can you please confirm that this behavior is no longer happening?