0

Update Invoice Item

by
Published Oct 30, 2023

Update an invoice item while its invoice is still a draft. Empty fields are left unchanged. `extra_params` passes any other documented field through as-is.

Script stripe Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 2 hours ago
1
//native
2

3
/**
4
 * Update Invoice Item
5
 * Update an invoice item while its invoice is still a draft. Empty fields are left unchanged. `extra_params` passes any other documented field through as-is.
6
 */
7
export async function main(
8
  auth: RT.Stripe,
9
  invoice_item_id: string,
10
  price: string | undefined,
11
  quantity: number | undefined,
12
  amount: number | undefined,
13
  description: string | undefined,
14
  metadata: { [key: string]: string } | undefined,
15
  extra_params: { [key: string]: any } | undefined
16
) {
17
  const response = await fetch(
18
    `https://api.stripe.com/v1/invoiceitems/${invoice_item_id}`,
19
    {
20
      method: "POST",
21
      headers: {
22
        Authorization: `Bearer ${auth.token}`,
23
        "Content-Type": "application/x-www-form-urlencoded",
24
        Accept: "application/json",
25
        "Stripe-Version": "2025-03-31.basil",
26
      },
27
      body: toForm({
28
        pricing: { price },
29
        quantity,
30
        amount,
31
        description,
32
        metadata,
33
        ...extra_params,
34
      }),
35
    }
36
  )
37

38
  if (!response.ok) {
39
    throw new Error(`${response.status} ${await response.text()}`)
40
  }
41

42
  return await response.json()
43
}
44

45
// Stripe takes form-encoded params with bracketed nesting: metadata[key]=v, items[0][price]=p
46
function toForm(
47
  params: { [key: string]: any },
48
  prefix = "",
49
  out = new URLSearchParams()
50
) {
51
  for (const [key, value] of Object.entries(params)) {
52
    if (value == null || value === "") continue
53
    const name = prefix ? `${prefix}[${key}]` : key
54
    if (typeof value === "object") toForm(value, name, out)
55
    else out.append(name, String(value))
56
  }
57
  return out
58
}
59

Other submissions
  • Submitted by hugo697 Typescript (fetch-only)
    Created 528 days ago
    1
    type Stripe = {
    2
      token: string;
    3
    };
    4
    /**
    5
     * Post invoiceitems invoiceitem
    6
     * Updates the amount or description of an invoice item on an upcoming invoice. Updating an invoice item is only possible before the invoice it’s attached to is closed.
    7
     */
    8
    export async function main(
    9
      auth: Stripe,
    10
      invoiceitem: string,
    11
      body: {
    12
        amount?: number;
    13
        description?: string;
    14
        discountable?: boolean;
    15
        discounts?:
    16
          | { coupon?: string; discount?: string; [k: string]: unknown }[]
    17
          | "";
    18
        expand?: string[];
    19
        metadata?: { [k: string]: string } | "";
    20
        period?: { end: number; start: number; [k: string]: unknown };
    21
        price?: string;
    22
        price_data?: {
    23
          currency: string;
    24
          product: string;
    25
          tax_behavior?: "exclusive" | "inclusive" | "unspecified";
    26
          unit_amount?: number;
    27
          unit_amount_decimal?: string;
    28
          [k: string]: unknown;
    29
        };
    30
        quantity?: number;
    31
        tax_behavior?: "exclusive" | "inclusive" | "unspecified";
    32
        tax_code?: string | "";
    33
        tax_rates?: string[] | "";
    34
        unit_amount?: number;
    35
        unit_amount_decimal?: string;
    36
      }
    37
    ) {
    38
      const url = new URL(`https://api.stripe.com/v1/invoiceitems/${invoiceitem}`);
    39
    
    
    40
      const response = await fetch(url, {
    41
        method: "POST",
    42
        headers: {
    43
          "Content-Type": "application/x-www-form-urlencoded",
    44
          Authorization: "Bearer " + auth.token,
    45
        },
    46
        body: encodeParams(body),
    47
      });
    48
      if (!response.ok) {
    49
        const text = await response.text();
    50
        throw new Error(`${response.status} ${text}`);
    51
      }
    52
      return await response.json();
    53
    }
    54
    
    
    55
    function encodeParams(o: any) {
    56
      function iter(o: any, path: string) {
    57
        if (Array.isArray(o)) {
    58
          o.forEach(function (a) {
    59
            iter(a, path + "[]");
    60
          });
    61
          return;
    62
        }
    63
        if (o !== null && typeof o === "object") {
    64
          Object.keys(o).forEach(function (k) {
    65
            iter(o[k], path + "[" + k + "]");
    66
          });
    67
          return;
    68
        }
    69
        data.push(path + "=" + o);
    70
      }
    71
      const data: string[] = [];
    72
      Object.keys(o).forEach(function (k) {
    73
        if (o[k] !== undefined) {
    74
          iter(o[k], k);
    75
        }
    76
      });
    77
      return new URLSearchParams(data.join("&"));
    78
    }
    79