0

CreateInvoiceAttachment

by
Published Oct 17, 2025

Uploads a file and attaches it to an invoice. This endpoint accepts HTTP multipart/form-data file uploads with a JSON `request` part and a `file` part. The `file` part must be a `readable stream` that contains a file in a supported format: GIF, JPEG, PNG, TIFF, BMP, or PDF. Invoices can have up to 10 attachments with a total file size of 25 MB. Attachments can be added only to invoices in the `DRAFT`, `SCHEDULED`, `UNPAID`, or `PARTIALLY_PAID` state.

Script square Verified

The script

Submitted by hugo697 Bun
Verified 235 days ago
1
//native
2
type Square = {
3
  token: string;
4
};
5
type Base64 = string;
6
/**
7
 * CreateInvoiceAttachment
8
 * Uploads a file and attaches it to an invoice. This endpoint accepts HTTP multipart/form-data file uploads
9
with a JSON `request` part and a `file` part. The `file` part must be a `readable stream` that contains a file
10
in a supported format: GIF, JPEG, PNG, TIFF, BMP, or PDF.
11

12
Invoices can have up to 10 attachments with a total file size of 25 MB. Attachments can be added only to invoices
13
in the `DRAFT`, `SCHEDULED`, `UNPAID`, or `PARTIALLY_PAID` state.
14
 */
15
export async function main(
16
  auth: Square,
17
  invoice_id: string,
18
  body: {
19
    request?: { idempotency_key?: string; description?: string };
20
    image_file?: {
21
      base64: Base64;
22
      type:
23
        | "image/png"
24
        | "image/jpeg"
25
        | "image/gif"
26
        | "application/pdf"
27
        | "appication/json"
28
        | "text/csv"
29
        | "text/plain"
30
        | "audio/mpeg"
31
        | "audio/wav"
32
        | "video/mp4";
33
      name: string;
34
    };
35
  },
36
) {
37
  const url = new URL(
38
    `https://connect.squareup.com/v2/invoices/${invoice_id}/attachments`,
39
  );
40

41
  const formData = new FormData();
42
  for (const [k, v] of Object.entries(body)) {
43
    if (v !== undefined) {
44
      if (["image_file"].includes(k)) {
45
        const { base64, type, name } = v as {
46
          base64: Base64;
47
          type: string;
48
          name: string;
49
        };
50
        formData.append(
51
          k,
52
          new Blob([Uint8Array.from(atob(base64), (m) => m.codePointAt(0)!)], {
53
            type,
54
          }),
55
          name,
56
        );
57
      } else {
58
        formData.append(k, String(v));
59
      }
60
    }
61
  }
62
  const response = await fetch(url, {
63
    method: "POST",
64
    headers: {
65
      Authorization: "Bearer " + auth.token,
66
    },
67
    body: formData,
68
  });
69
  if (!response.ok) {
70
    const text = await response.text();
71
    throw new Error(`${response.status} ${text}`);
72
  }
73
  return await response.json();
74
}
75