@dime-technology/dime-js-sdk 1.3.1 → 1.4.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 +164 -4
- package/dist/index.cjs +911 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +587 -88
- package/dist/index.d.ts +587 -88
- package/dist/index.js +897 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -69,15 +69,20 @@ them, in a `filters` object). All amounts are returned as strings to avoid float
|
|
|
69
69
|
|
|
70
70
|
| Property | Endpoints |
|
|
71
71
|
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
72
|
-
| `dime.transactions` | chargeCard, chargeAch, tokenizeCard, refund, void, show, list
|
|
72
|
+
| `dime.transactions` | chargeCard, chargeAch, tokenizeCard, authorize, capture, refund, void, show, list |
|
|
73
73
|
| `dime.customers` | list, show, create, update, delete |
|
|
74
74
|
| `dime.paymentMethods` | list, show, create, update, delete |
|
|
75
|
-
| `dime.merchants` | list, show, create, update, getFormLink
|
|
75
|
+
| `dime.merchants` | list, show, create, update, getFormLink, applicationStatus |
|
|
76
76
|
| `dime.addresses` | list, show, create, update, delete |
|
|
77
77
|
| `dime.deposits` | list, listWithTransactions, show |
|
|
78
78
|
| `dime.recurringPayments` | list, show, create, edit, pause, cancel, activate, delete |
|
|
79
79
|
| `dime.invoices` | list, show, create, update, delete, send, markSent, void, duplicate, pay, getLink, addLineItem, updateLineItem, deleteLineItem, listItems, createItem |
|
|
80
80
|
| `dime.recurringInvoices` | list, show, create, cancel |
|
|
81
|
+
| `dime.chargebacks` | list, show |
|
|
82
|
+
| `dime.documents` | upload, list |
|
|
83
|
+
| `dime.funds` | balance, transactions, release |
|
|
84
|
+
| `dime.subscriptionPlans` | list, show, create, edit, delete, publish, archive, unarchive, subscribe |
|
|
85
|
+
| `dime.subscriptions` | list, show, pause, resume, cancel |
|
|
81
86
|
|
|
82
87
|
### Transactions
|
|
83
88
|
|
|
@@ -123,6 +128,40 @@ await dime.transactions.void('000010', 'CC', 123456)
|
|
|
123
128
|
const txn = await dime.transactions.show('000010', { transaction_info_id: 123456 })
|
|
124
129
|
```
|
|
125
130
|
|
|
131
|
+
#### Authorize and capture
|
|
132
|
+
|
|
133
|
+
`authorize()` places a hold on a card without moving money; `capture()` collects it. The returned
|
|
134
|
+
`transactionNumber` is your handle on the hold. An authorization is captured once — capturing less
|
|
135
|
+
than the full amount settles that and releases the rest — so capture the true final amount, and
|
|
136
|
+
capture promptly (typically within 24 hours), since the issuer releases an uncaptured hold on its
|
|
137
|
+
own schedule.
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
const auth = await dime.transactions.authorize('000010', {
|
|
141
|
+
amount: '100.00',
|
|
142
|
+
token: 'tok_abc123', // or raw card fields, as for chargeCard
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
await dime.transactions.capture('000010', auth.transactionNumber!) // full amount
|
|
146
|
+
await dime.transactions.capture('000010', auth.transactionNumber!, '80.00') // or part of it
|
|
147
|
+
|
|
148
|
+
// Release the hold instead of capturing it
|
|
149
|
+
await dime.transactions.void('000010', 'CC', auth.transactionNumber!)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Merchant onboarding status
|
|
153
|
+
|
|
154
|
+
Follow up an application sent with `getFormLink()`. `boarded` is the ground truth for "can they
|
|
155
|
+
take money"; while `status` is `underwriting`, read `applicationStatus` — only `needs_documents`
|
|
156
|
+
asks anything of the merchant. Prefer the `application_status_changed` webhook to polling.
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
const onboarding = await dime.merchants.applicationStatus('000010')
|
|
160
|
+
onboarding.status // 'underwriting'
|
|
161
|
+
onboarding.applicationStatus // 'needs_documents'
|
|
162
|
+
onboarding.boarded // false
|
|
163
|
+
```
|
|
164
|
+
|
|
126
165
|
### Customers, payment methods, addresses
|
|
127
166
|
|
|
128
167
|
```ts
|
|
@@ -299,6 +338,126 @@ await dime.recurringInvoices.cancel('000010', template.id!)
|
|
|
299
338
|
const page = await dime.recurringInvoices.list('000010', { status: 'Active' })
|
|
300
339
|
```
|
|
301
340
|
|
|
341
|
+
### Chargebacks and documents
|
|
342
|
+
|
|
343
|
+
Chargebacks come from the processor's once-daily file, so they reflect the latest import rather
|
|
344
|
+
than live dispute activity. Pair these calls with the `chargeback_*` webhooks and use them to
|
|
345
|
+
reconcile. They need the `chargeback:read` ability.
|
|
346
|
+
|
|
347
|
+
```ts
|
|
348
|
+
const page = await dime.chargebacks.list('000010', {
|
|
349
|
+
start_date: '2026-04-01 00:00:00',
|
|
350
|
+
end_date: '2026-04-30 23:59:59',
|
|
351
|
+
representment_status: 'New', // optional
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
const chargeback = await dime.chargebacks.show('000010', '1134722723')
|
|
355
|
+
chargeback.chargebackAmount // '391.48'
|
|
356
|
+
chargeback.representmentDate // deadline for evidence
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
`documents.upload()` sends underwriting paperwork, identity verification and chargeback evidence
|
|
360
|
+
— up to 10 PDF, JPG, PNG, DOC, DOCX or RTF files of 9 MB or less per call. Pass `Blob`/`File`
|
|
361
|
+
objects, or raw bytes with a file name. It is the one `multipart/form-data` request in the API;
|
|
362
|
+
the SDK builds the form for you. Files are stored independently, so check `failed` and re-send
|
|
363
|
+
only those.
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
import { readFile } from 'node:fs/promises'
|
|
367
|
+
|
|
368
|
+
const result = await dime.documents.upload(
|
|
369
|
+
'000010',
|
|
370
|
+
'RetrievalRequest', // Verification | FraudHolds | Underwriting | RetrievalRequest
|
|
371
|
+
[{ content: await readFile('receipt.pdf'), filename: 'receipt.pdf' }],
|
|
372
|
+
chargeback.transactionInfoId, // optional: attach as evidence to this chargeback
|
|
373
|
+
)
|
|
374
|
+
result.failed // [] when everything stored
|
|
375
|
+
|
|
376
|
+
const documents = await dime.documents.list('000010', { doc_type: 'RetrievalRequest' })
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Uploading does not forward a document to the processor; our team reviews it and does that.
|
|
380
|
+
`sentToProcessorAt` is set once they have.
|
|
381
|
+
|
|
382
|
+
### Held funds
|
|
383
|
+
|
|
384
|
+
For merchants on a tier that holds their balance rather than sweeping it to their bank (others get
|
|
385
|
+
a 422). Reading needs `funds:read`; releasing needs `funds:release` and an affiliate key.
|
|
386
|
+
|
|
387
|
+
```ts
|
|
388
|
+
const balance = await dime.funds.balance('000010')
|
|
389
|
+
balance.releasable // '5172.72' — what a release is checked against
|
|
390
|
+
|
|
391
|
+
const { transactions } = await dime.funds.transactions('000010')
|
|
392
|
+
|
|
393
|
+
// Release by amount, or by transaction_info_ids (all or nothing)
|
|
394
|
+
const result = await dime.funds.release('000010', 'payout-2026-10-06-0001', { amount: '1500.00' })
|
|
395
|
+
await dime.funds.release('000010', 'payout-2026-10-06-0002', {
|
|
396
|
+
transaction_info_ids: transactions.map((t) => t.transactionInfoId!),
|
|
397
|
+
})
|
|
398
|
+
|
|
399
|
+
result.release.status // 'released' | 'failed' | 'unknown'
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Use a fresh idempotency key per intended release and **reuse it when retrying**: a release that
|
|
403
|
+
timed out may still have gone through, and the same key returns the original instead of sending the
|
|
404
|
+
money twice. Always check `release.status` — a declined (`failed`) release is returned, not thrown.
|
|
405
|
+
Requests that release nothing (an ineligible transaction, more than is releasable, a reused key, a
|
|
406
|
+
release already in flight) throw an `ApiException`; `getResponseBody()` carries the detail.
|
|
407
|
+
|
|
408
|
+
### Subscription plans and subscriptions
|
|
409
|
+
|
|
410
|
+
A plan is a recurring bundle of line items. It starts as a draft, is published to take
|
|
411
|
+
subscribers, and is archived to stop new ones. Subscribers keep the snapshot they signed up to, so
|
|
412
|
+
editing or archiving a plan never changes an existing subscription.
|
|
413
|
+
|
|
414
|
+
```ts
|
|
415
|
+
const plan = await dime.subscriptionPlans.create('000010', {
|
|
416
|
+
name: 'Monthly Membership',
|
|
417
|
+
recurrence_schedule: 'Monthly', // Weekly | Biweekly | FirstFifteenth | Monthly | Yearly
|
|
418
|
+
allow_public: true, // optional: list it in the public catalog
|
|
419
|
+
lines: [{ item_id: 96, name: 'Membership', quantity: 1, unit_price: 25 }],
|
|
420
|
+
})
|
|
421
|
+
|
|
422
|
+
await dime.subscriptionPlans.publish('000010', plan.id!)
|
|
423
|
+
plan.publicUrl // hosted subscribe page
|
|
424
|
+
|
|
425
|
+
// Charge the first payment to a saved payment method and enroll the customer
|
|
426
|
+
const { subscriptionId } = await dime.subscriptionPlans.subscribe(
|
|
427
|
+
'000010',
|
|
428
|
+
plan.id!,
|
|
429
|
+
customer.uuid!,
|
|
430
|
+
pm.id!,
|
|
431
|
+
)
|
|
432
|
+
|
|
433
|
+
// edit() replaces the plan wholesale — send every field, not just what changed
|
|
434
|
+
await dime.subscriptionPlans.edit('000010', plan.id!, {
|
|
435
|
+
name: 'Membership',
|
|
436
|
+
recurrence_schedule: 'Monthly',
|
|
437
|
+
lines: [{ item_id: 96, name: 'Membership', quantity: 1, unit_price: 30 }],
|
|
438
|
+
})
|
|
439
|
+
await dime.subscriptionPlans.archive('000010', plan.id!)
|
|
440
|
+
await dime.subscriptionPlans.unarchive('000010', plan.id!) // back to draft
|
|
441
|
+
await dime.subscriptionPlans.delete('000010', plan.id!) // only with no subscribers
|
|
442
|
+
|
|
443
|
+
const plans = await dime.subscriptionPlans.list('000010', 'active') // draft | active | archived
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
```ts
|
|
447
|
+
const page = await dime.subscriptions.list('000010', {
|
|
448
|
+
status: 'Active', // Active | Failed | Paused | Cancelled | Ended
|
|
449
|
+
customer_uuid: customer.uuid, // optional
|
|
450
|
+
})
|
|
451
|
+
|
|
452
|
+
const subscription = await dime.subscriptions.show('000010', subscriptionId!)
|
|
453
|
+
subscription.nextRunDate
|
|
454
|
+
subscription.items // the line items snapshotted at subscribe time
|
|
455
|
+
|
|
456
|
+
await dime.subscriptions.pause('000010', subscriptionId!, '2026-12-01') // omit the date to pause indefinitely
|
|
457
|
+
await dime.subscriptions.resume('000010', subscriptionId!)
|
|
458
|
+
await dime.subscriptions.cancel('000010', subscriptionId!)
|
|
459
|
+
```
|
|
460
|
+
|
|
302
461
|
## Pagination
|
|
303
462
|
|
|
304
463
|
List endpoints return a `CursorPage`. Iterate one page, walk pages manually, or stream every
|
|
@@ -366,8 +525,9 @@ try {
|
|
|
366
525
|
|
|
367
526
|
## Notes
|
|
368
527
|
|
|
369
|
-
- **GET
|
|
370
|
-
|
|
528
|
+
- **GET parameters travel in the query string.** The Dime API reads the same `{ data, filters }`
|
|
529
|
+
envelope from a JSON body or from bracketed query parameters (`data[sid]=…`). Fetch forbids a
|
|
530
|
+
body on `GET`, so the SDK sends reads as query parameters; you never build either by hand.
|
|
371
531
|
- **No API versioning.** Endpoints live under `/api` with no version prefix.
|
|
372
532
|
- **Browser use:** API tokens should generally not be exposed in browser environments. This SDK
|
|
373
533
|
is designed primarily for server-side use (Node.js, Next.js API routes, etc.).
|