1 | type Stripe = { |
2 | token: string; |
3 | }; |
4 | |
5 | * Post invoices |
6 | * This endpoint creates a draft invoice for a given customer. The invoice remains a draft until you finalize the invoice, which allows you to pay or send the invoice to your customers. |
7 | */ |
8 | export async function main( |
9 | auth: Stripe, |
10 | body: { |
11 | account_tax_ids?: string[] | ""; |
12 | application_fee_amount?: number; |
13 | auto_advance?: boolean; |
14 | automatic_tax?: { |
15 | enabled: boolean; |
16 | liability?: { |
17 | account?: string; |
18 | type: "account" | "self"; |
19 | [k: string]: unknown; |
20 | }; |
21 | [k: string]: unknown; |
22 | }; |
23 | collection_method?: "charge_automatically" | "send_invoice"; |
24 | currency?: string; |
25 | custom_fields?: |
26 | | { name: string; value: string; [k: string]: unknown }[] |
27 | | ""; |
28 | customer?: string; |
29 | days_until_due?: number; |
30 | default_payment_method?: string; |
31 | default_source?: string; |
32 | default_tax_rates?: string[]; |
33 | description?: string; |
34 | discounts?: |
35 | | { coupon?: string; discount?: string; [k: string]: unknown }[] |
36 | | ""; |
37 | due_date?: number; |
38 | effective_at?: number; |
39 | expand?: string[]; |
40 | footer?: string; |
41 | from_invoice?: { |
42 | action: "revision"; |
43 | invoice: string; |
44 | [k: string]: unknown; |
45 | }; |
46 | issuer?: { |
47 | account?: string; |
48 | type: "account" | "self"; |
49 | [k: string]: unknown; |
50 | }; |
51 | metadata?: { [k: string]: string } | ""; |
52 | number?: string; |
53 | on_behalf_of?: string; |
54 | payment_settings?: { |
55 | default_mandate?: string | ""; |
56 | payment_method_options?: { |
57 | acss_debit?: |
58 | | { |
59 | mandate_options?: { |
60 | transaction_type?: "business" | "personal"; |
61 | [k: string]: unknown; |
62 | }; |
63 | verification_method?: "automatic" | "instant" | "microdeposits"; |
64 | [k: string]: unknown; |
65 | } |
66 | | ""; |
67 | bancontact?: |
68 | | { |
69 | preferred_language?: "de" | "en" | "fr" | "nl"; |
70 | [k: string]: unknown; |
71 | } |
72 | | ""; |
73 | card?: |
74 | | { |
75 | installments?: { |
76 | enabled?: boolean; |
77 | plan?: |
78 | | { |
79 | count: number; |
80 | interval: "month"; |
81 | type: "fixed_count"; |
82 | [k: string]: unknown; |
83 | } |
84 | | ""; |
85 | [k: string]: unknown; |
86 | }; |
87 | request_three_d_secure?: "any" | "automatic" | "challenge"; |
88 | [k: string]: unknown; |
89 | } |
90 | | ""; |
91 | customer_balance?: |
92 | | { |
93 | bank_transfer?: { |
94 | eu_bank_transfer?: { country: string; [k: string]: unknown }; |
95 | type?: string; |
96 | [k: string]: unknown; |
97 | }; |
98 | funding_type?: string; |
99 | [k: string]: unknown; |
100 | } |
101 | | ""; |
102 | konbini?: { [k: string]: unknown } | ""; |
103 | us_bank_account?: |
104 | | { |
105 | financial_connections?: { |
106 | permissions?: ( |
107 | | "balances" |
108 | | "ownership" |
109 | | "payment_method" |
110 | | "transactions" |
111 | )[]; |
112 | prefetch?: ("balances" | "transactions")[]; |
113 | [k: string]: unknown; |
114 | }; |
115 | verification_method?: "automatic" | "instant" | "microdeposits"; |
116 | [k: string]: unknown; |
117 | } |
118 | | ""; |
119 | [k: string]: unknown; |
120 | }; |
121 | payment_method_types?: |
122 | | ( |
123 | | "ach_credit_transfer" |
124 | | "ach_debit" |
125 | | "acss_debit" |
126 | | "au_becs_debit" |
127 | | "bacs_debit" |
128 | | "bancontact" |
129 | | "boleto" |
130 | | "card" |
131 | | "cashapp" |
132 | | "customer_balance" |
133 | | "eps" |
134 | | "fpx" |
135 | | "giropay" |
136 | | "grabpay" |
137 | | "ideal" |
138 | | "konbini" |
139 | | "link" |
140 | | "p24" |
141 | | "paynow" |
142 | | "paypal" |
143 | | "promptpay" |
144 | | "sepa_debit" |
145 | | "sofort" |
146 | | "us_bank_account" |
147 | | "wechat_pay" |
148 | )[] |
149 | | ""; |
150 | [k: string]: unknown; |
151 | }; |
152 | pending_invoice_items_behavior?: "exclude" | "include"; |
153 | rendering?: { |
154 | amount_tax_display?: "" | "exclude_tax" | "include_inclusive_tax"; |
155 | pdf?: { page_size?: "a4" | "auto" | "letter"; [k: string]: unknown }; |
156 | [k: string]: unknown; |
157 | }; |
158 | shipping_cost?: { |
159 | shipping_rate?: string; |
160 | shipping_rate_data?: { |
161 | delivery_estimate?: { |
162 | maximum?: { |
163 | unit: "business_day" | "day" | "hour" | "month" | "week"; |
164 | value: number; |
165 | [k: string]: unknown; |
166 | }; |
167 | minimum?: { |
168 | unit: "business_day" | "day" | "hour" | "month" | "week"; |
169 | value: number; |
170 | [k: string]: unknown; |
171 | }; |
172 | [k: string]: unknown; |
173 | }; |
174 | display_name: string; |
175 | fixed_amount?: { |
176 | amount: number; |
177 | currency: string; |
178 | currency_options?: { |
179 | [k: string]: { |
180 | amount: number; |
181 | tax_behavior?: "exclusive" | "inclusive" | "unspecified"; |
182 | [k: string]: unknown; |
183 | }; |
184 | }; |
185 | [k: string]: unknown; |
186 | }; |
187 | metadata?: { [k: string]: string }; |
188 | tax_behavior?: "exclusive" | "inclusive" | "unspecified"; |
189 | tax_code?: string; |
190 | type?: "fixed_amount"; |
191 | [k: string]: unknown; |
192 | }; |
193 | [k: string]: unknown; |
194 | }; |
195 | shipping_details?: { |
196 | address: { |
197 | city?: string; |
198 | country?: string; |
199 | line1?: string; |
200 | line2?: string; |
201 | postal_code?: string; |
202 | state?: string; |
203 | [k: string]: unknown; |
204 | }; |
205 | name: string; |
206 | phone?: string | ""; |
207 | [k: string]: unknown; |
208 | }; |
209 | statement_descriptor?: string; |
210 | subscription?: string; |
211 | transfer_data?: { |
212 | amount?: number; |
213 | destination: string; |
214 | [k: string]: unknown; |
215 | }; |
216 | } |
217 | ) { |
218 | const url = new URL(`https://api.stripe.com/v1/invoices`); |
219 |
|
220 | const response = await fetch(url, { |
221 | method: "POST", |
222 | headers: { |
223 | "Content-Type": "application/x-www-form-urlencoded", |
224 | Authorization: "Bearer " + auth.token, |
225 | }, |
226 | body: encodeParams(body), |
227 | }); |
228 | if (!response.ok) { |
229 | const text = await response.text(); |
230 | throw new Error(`${response.status} ${text}`); |
231 | } |
232 | return await response.json(); |
233 | } |
234 |
|
235 | function encodeParams(o: any) { |
236 | function iter(o: any, path: string) { |
237 | if (Array.isArray(o)) { |
238 | o.forEach(function (a) { |
239 | iter(a, path + "[]"); |
240 | }); |
241 | return; |
242 | } |
243 | if (o !== null && typeof o === "object") { |
244 | Object.keys(o).forEach(function (k) { |
245 | iter(o[k], path + "[" + k + "]"); |
246 | }); |
247 | return; |
248 | } |
249 | data.push(path + "=" + o); |
250 | } |
251 | const data: string[] = []; |
252 | Object.keys(o).forEach(function (k) { |
253 | if (o[k] !== undefined) { |
254 | iter(o[k], k); |
255 | } |
256 | }); |
257 | return new URLSearchParams(data.join("&")); |
258 | } |
259 |
|