1 | |
2 | type Paypal = { |
3 | clientId: string; |
4 | clientSecret: string; |
5 | }; |
6 |
|
7 | async function getToken(auth: Paypal): Promise<string> { |
8 | const url = new URL(`https://api-m.paypal.com/v1/oauth2/token`); |
9 | const response = await fetch(url, { |
10 | method: "POST", |
11 | headers: { |
12 | Authorization: `Basic ${btoa(`${auth.clientId}:${auth.clientSecret}`)}`, |
13 | }, |
14 | body: new URLSearchParams({ |
15 | grant_type: "client_credentials", |
16 | }), |
17 | }); |
18 | if (!response.ok) { |
19 | const text = await response.text(); |
20 | throw new Error(`Could not get token: ${response.status} ${text}`); |
21 | } |
22 | const json = await response.json(); |
23 | return json.access_token; |
24 | } |
25 | type Base64 = string; |
26 | |
27 | * Acknowledge returned item |
28 | * Acknowledges that the customer returned an item for a dispute, by ID. A merchant can make this request for disputes with the `MERCHANDISE_OR_SERVICE_NOT_AS_DESCRIBED` reason. Allowed acknowledgement_type values for the request is available in dispute details allowed response options object. For constraints and rules regarding documents, see documents. |
29 | */ |
30 | export async function main( |
31 | auth: Paypal, |
32 | id: string, |
33 | body: { |
34 | acknowledgement_document?: { |
35 | base64: Base64; |
36 | type: |
37 | | "image/png" |
38 | | "image/jpeg" |
39 | | "image/gif" |
40 | | "application/pdf" |
41 | | "appication/json" |
42 | | "text/csv" |
43 | | "text/plain" |
44 | | "audio/mpeg" |
45 | | "audio/wav" |
46 | | "video/mp4"; |
47 | name: string; |
48 | }; |
49 | }, |
50 | ) { |
51 | const token = await getToken(auth); |
52 | const url = new URL( |
53 | `https://api-m.paypal.com/v1/customer/disputes/${id}/acknowledge-return-item`, |
54 | ); |
55 |
|
56 | const formData = new FormData(); |
57 | for (const [k, v] of Object.entries(body)) { |
58 | if (v !== undefined) { |
59 | if (["acknowledgement_document"].includes(k)) { |
60 | const { base64, type, name } = v as { |
61 | base64: Base64; |
62 | type: string; |
63 | name: string; |
64 | }; |
65 | formData.append( |
66 | k, |
67 | new Blob([Uint8Array.from(atob(base64), (m) => m.codePointAt(0)!)], { |
68 | type, |
69 | }), |
70 | name, |
71 | ); |
72 | } else { |
73 | formData.append(k, String(v)); |
74 | } |
75 | } |
76 | } |
77 | const response = await fetch(url, { |
78 | method: "POST", |
79 | headers: { |
80 | Authorization: "Bearer " + token, |
81 | }, |
82 | body: formData, |
83 | }); |
84 | if (!response.ok) { |
85 | const text = await response.text(); |
86 | throw new Error(`${response.status} ${text}`); |
87 | } |
88 | return await response.json(); |
89 | } |
90 |
|