I'm trying to add some files (identity documents) to stripe to create a connected account, but I'm having trouble with uploading them from client side to stripe. My backend is in Node.js and the Stripe documentation says it should use this format:
const Stripe = require('stripe');
const stripe = Stripe('stripeAPIKEY');
var fp = fs.readFileSync('/path/to/a/file.jpg');
var file = await stripe.files.create({
purpose: 'identity_document',
file: {
data: fp,
name: 'file.jpg',
type: 'image/jpg',
},
});
I need to upload the file data (the variable fp), but I can't seem to get the relevant path for when the user uploads their document in the client side in Javascript. Here is my function call to Stripe:
export const uploadPersonIdFile = async (identityDocument: any) => {
const fp = fs.readFileSync(identityDocument);
const personId = await stripe.files.create({
purpose: 'identity_document',
file: {
data: fp,
name: 'idDocument.jpg',
type: 'image/jpg',
},
});
return personId;
}
My client side looks like this:
const inpFileU = $("#utilityButton");
const previewImage = $("#image-preview__image-U");
const previewDefaultText = $("#image-preview__default-text-U");
inpFileU.change(function(){
const file = this.files[0];
if(file){
const reader = new FileReader();
previewImage.css("display", "block");
reader.addEventListener("load", function(){
previewImage.attr("src", this.result);
});
reader.readAsDataURL(file);
utilityFileName = file.name;
await uploadMerchantUtilityDocument({
utilityDocument: utilityFileName
}).then((result) => {
/** @type {any} */
const data = result.data;
const textData = data.text;
console.log(JSON.stringify(data));
console.log(JSON.stringify(textData));
}).catch((error) => {
console.log("Error message: " + error.message);
console.log("Error details: " + error.details);
});
} else {
console.log('no file');
}
});
I upload the file and then the error message response I keep getting is this: Error: ENOENT: no such file or directory, open 'insuranceImage.jpeg'
How should I upload my file? I think my fp variable is wrong, but I don't know what to replace it with
As far as I understood you are uploading files from the client to the server and from the server you want to upload to stripe API. In this case, when you read a file with fs default encoding is utf8 but maybe when the file uploaded it was encoded as base64. I do not know too much about jquery. Check how it was encoded, so use the correct encoding.
const image= fs.readFileSync('/path/to/file.jpg', {encoding: 'base64'});
I think somehow the image is broken. If the image path is correct, just manually place an image in that directory, and then read from it as utf8 encoding.
since u got this error base64 string is too large to process in fs.readFileSync which means your path is correct.
reader = fs.createReadStream('imagePath', {
flag: 'a+',
// then try this to base64
encoding: 'UTF-8',
start: 5,
end: 64,
highWaterMark: 16
});
// Read and display the file data on console
reader.on('data', function (chunk) {
console.log(chunk);
});
Based on the error and the comment it looks like the path you're providing to readFileSync isn't pointing to where the file you're trying to read exists. From the error it looks like you're passing insuranceImage.jpeg and that the system can't find that file.
Try confirming whether the relative path you're providing is correct, or construct and provide an absolute path instead.
Ok, so after a while I was helped by a pro online. Here's what he did (because stripe's documentation isn't too great on file uploading)...
I created a base64 variable from FileReader(), which came from creating an array base64String = [] This array took hold of the result from reader.load, like so:
reader.addEventListener("load", function(){
base64String.push(this.result);
});
This base64String array was then used as the identityDocument variable for the backend function.
So my base64 variable in the client-side kept on starting with 'image/jpeg; base64,' and I needed to get rid of that. No point using the fs.readFileSync as we're not uploading a file to stripe, we're uploading raw base64 data. So, the following code in node.js fits in well to solve this:
const parts = utilityDocument.split(",");
const base64 = parts[1];
const buffer = Buffer.from(base64, "base64");
so the full function that calls to stripe is so:
export const uploadPersonIdFile = async (uid: any, identityDocument: any) => {
const parts = identityDocument.split(",");
const base64 = parts[1];
const buffer = Buffer.from(base64, "base64");
const personId = await stripe.files.create({
purpose: 'identity_document',
file: {
data: buffer,
name: 'identity.jpg',
type: 'image/jpg',
},
});
await updateMerchantId(uid, { idDocument: personId.id });
return personId;
}