@dime-technology/dime-js-sdk 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,13 +46,15 @@ import { Client, Config } from '@dime-technology/dime-js-sdk'
46
46
  const dime = new Client('your-api-token', 'https://staging.dimepayments.com')
47
47
 
48
48
  // Full control
49
- const dime = new Client(new Config({
50
- token: 'your-api-token',
51
- baseUrl: 'https://app.dimepayments.com',
52
- timeout: 30, // seconds
53
- maxRetries: 2, // retries 429 / 5xx / network errors with backoff
54
- retryBaseDelay: 0.5,
55
- }))
49
+ const dime = new Client(
50
+ new Config({
51
+ token: 'your-api-token',
52
+ baseUrl: 'https://app.dimepayments.com',
53
+ timeout: 30, // seconds
54
+ maxRetries: 2, // retries 429 / 5xx / network errors with backoff
55
+ retryBaseDelay: 0.5,
56
+ }),
57
+ )
56
58
  ```
57
59
 
58
60
  The SDK sends `Authorization: Bearer <token>` and JSON headers on every request. Transient
@@ -65,15 +67,17 @@ Every resource hangs off the client as a property. The merchant `sid` is always
65
67
  explicitly; remaining fields go in an attributes object (and lookups, where the API expects
66
68
  them, in a `filters` object). All amounts are returned as strings to avoid float rounding.
67
69
 
68
- | Property | Endpoints |
69
- | ---------------------------- | ---------------------------------------------------------------- |
70
- | `dime.transactions` | chargeCard, chargeAch, tokenizeCard, refund, void, show, list |
71
- | `dime.customers` | list, show, create, update, delete |
72
- | `dime.paymentMethods` | list, show, create, update, delete |
73
- | `dime.merchants` | list, show, create, update, getFormLink |
74
- | `dime.addresses` | list, show, create, update, delete |
75
- | `dime.deposits` | list, listWithTransactions, show |
76
- | `dime.recurringPayments` | list, show, create, edit, pause, cancel, activate, delete |
70
+ | Property | Endpoints |
71
+ | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
72
+ | `dime.transactions` | chargeCard, chargeAch, tokenizeCard, refund, void, show, list |
73
+ | `dime.customers` | list, show, create, update, delete |
74
+ | `dime.paymentMethods` | list, show, create, update, delete |
75
+ | `dime.merchants` | list, show, create, update, getFormLink |
76
+ | `dime.addresses` | list, show, create, update, delete |
77
+ | `dime.deposits` | list, listWithTransactions, show |
78
+ | `dime.recurringPayments` | list, show, create, edit, pause, cancel, activate, delete |
79
+ | `dime.invoices` | list, show, create, update, delete, send, markSent, void, duplicate, pay, getLink, addLineItem, updateLineItem, deleteLineItem, listItems, createItem |
80
+ | `dime.recurringInvoices` | list, show, create, cancel |
77
81
 
78
82
  ### Transactions
79
83
 
@@ -164,6 +168,90 @@ await dime.recurringPayments.activate('000010', rp.id!)
164
168
  await dime.recurringPayments.cancel('000010', rp.id!)
165
169
  ```
166
170
 
171
+ ### Invoices
172
+
173
+ Invoices are scoped to a merchant `sid` and built from line items that each reference a merchant
174
+ item (a fund/designation). Draft invoices can be edited; once sent they are locked. Amounts are
175
+ returned as strings.
176
+
177
+ Identify the customer with `customer_uuid` — the same uuid every other resource uses, and the only
178
+ identifier the customer endpoints return. `customer_id` is still accepted for older integrations.
179
+
180
+ ```ts
181
+ // Look up (or create) the items a line can reference
182
+ const items = await dime.invoices.listItems('000010')
183
+ const item = await dime.invoices.createItem('000010', {
184
+ name: 'Consulting',
185
+ price: 125,
186
+ tax_deductible: false,
187
+ })
188
+
189
+ // Create a draft invoice with one or more line items
190
+ const invoice = await dime.invoices.create('000010', {
191
+ customer_uuid: customer.uuid,
192
+ customer_name: 'Jane Doe',
193
+ customer_email: 'jane@example.com',
194
+ payment_terms: 'net_15', // due_on_receipt | net_15 | net_30 | net_60
195
+ lines: [
196
+ { item_id: item.id, name: 'Consulting', description: '2 hours', quantity: 2, unit_price: 125 },
197
+ ],
198
+ })
199
+
200
+ // Tweak the draft's line items (each returns the refreshed invoice)
201
+ await dime.invoices.addLineItem('000010', invoice.id!, {
202
+ item_id: item.id!,
203
+ name: 'Setup',
204
+ quantity: 1,
205
+ unit_price: 50,
206
+ })
207
+ await dime.invoices.updateLineItem('000010', invoice.id!, invoice.items[0]!.id!, { quantity: 3 })
208
+ await dime.invoices.deleteLineItem('000010', invoice.id!, invoice.items[0]!.id!)
209
+
210
+ // Email it to the customer, or activate the pay link without emailing
211
+ await dime.invoices.send('000010', invoice.id!)
212
+ await dime.invoices.markSent('000010', invoice.id!)
213
+
214
+ // Share the public pay link
215
+ const { publicUrl } = await dime.invoices.getLink('000010', invoice.id!)
216
+
217
+ // Take a merchant-initiated (MOTO) payment against an open invoice
218
+ await dime.invoices.pay('000010', invoice.id!, {
219
+ payment_type: 'cc', // cc | ach
220
+ token: 'tok_abc123',
221
+ amount: 100, // optional partial amount when the invoice allows it
222
+ })
223
+
224
+ // Duplicate, void, delete
225
+ const copy = await dime.invoices.duplicate('000010', invoice.id!)
226
+ await dime.invoices.void('000010', invoice.id!)
227
+ await dime.invoices.delete('000010', copy.id!) // drafts only
228
+
229
+ // List, optionally filtered by status
230
+ const page = await dime.invoices.list('000010', { status: 'sent' })
231
+ ```
232
+
233
+ ### Recurring invoices
234
+
235
+ Recurring-invoice templates generate and send invoices on a schedule.
236
+
237
+ ```ts
238
+ const template = await dime.recurringInvoices.create('000010', {
239
+ customer_uuid: customer.uuid,
240
+ payment_terms: 'net_15',
241
+ recurring_frequency: 'Monthly', // Weekly | Biweekly | FirstFifteenth | Monthly | Yearly
242
+ recurring_start_date: '2026-08-01',
243
+ recurring_end_date: '2027-08-01', // optional
244
+ lines: [{ item_id: 5, name: 'Monthly retainer', quantity: 1, unit_price: 500 }],
245
+ })
246
+
247
+ const detail = await dime.recurringInvoices.show('000010', template.id!)
248
+ detail.upcomingRunDates // ['2026-08-01', '2026-09-01', ...]
249
+
250
+ await dime.recurringInvoices.cancel('000010', template.id!)
251
+
252
+ const page = await dime.recurringInvoices.list('000010', { status: 'Active' })
253
+ ```
254
+
167
255
  ## Pagination
168
256
 
169
257
  List endpoints return a `CursorPage`. Iterate one page, walk pages manually, or stream every
@@ -206,28 +294,28 @@ try {
206
294
  await dime.transactions.chargeCard('000010', { amount: '0' })
207
295
  } catch (e) {
208
296
  if (e instanceof ValidationException) {
209
- e.getErrors() // { 'data.amount': ['must be greater than 0'] }
297
+ e.getErrors() // { 'data.amount': ['must be greater than 0'] }
210
298
  e.firstError()
211
299
  } else if (e instanceof RateLimitException) {
212
300
  const wait = e.getRetryAfter() ?? 1
213
- await new Promise(r => setTimeout(r, wait * 1000))
301
+ await new Promise((r) => setTimeout(r, wait * 1000))
214
302
  } else if (e instanceof DimeException) {
215
- e.getStatusCode() // HTTP status
216
- e.getResponseBody() // decoded API body
303
+ e.getStatusCode() // HTTP status
304
+ e.getResponseBody() // decoded API body
217
305
  }
218
306
  }
219
307
  ```
220
308
 
221
- | Exception | When |
222
- | ---------------------------- | ------------------------------------------------------------ |
223
- | `ValidationException` | HTTP 400/422 with field errors |
224
- | `AuthenticationException` | HTTP 401 (missing/invalid token) |
225
- | `PermissionDeniedException` | HTTP 403 (belongs-to-company guard) |
226
- | `NotFoundException` | HTTP 404 |
227
- | `RateLimitException` | HTTP 429 (carries `Retry-After`) |
228
- | `ServerException` | HTTP 5xx |
229
- | `ConnectionException` | No HTTP response (DNS, timeout, network error) |
230
- | `ApiException` | Any other non-2xx |
309
+ | Exception | When |
310
+ | --------------------------- | ---------------------------------------------- |
311
+ | `ValidationException` | HTTP 400/422 with field errors |
312
+ | `AuthenticationException` | HTTP 401 (missing/invalid token) |
313
+ | `PermissionDeniedException` | HTTP 403 (belongs-to-company guard) |
314
+ | `NotFoundException` | HTTP 404 |
315
+ | `RateLimitException` | HTTP 429 (carries `Retry-After`) |
316
+ | `ServerException` | HTTP 5xx |
317
+ | `ConnectionException` | No HTTP response (DNS, timeout, network error) |
318
+ | `ApiException` | Any other non-2xx |
231
319
 
232
320
  ## Notes
233
321