@mooj/sdk 0.1.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 +100 -0
- package/dist/index.d.ts +133 -0
- package/dist/index.js +89 -0
- package/package.json +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# @mooj/sdk
|
|
2
|
+
|
|
3
|
+
The official Mooj SDK. Issue capped virtual cards and let your agent complete real checkouts. Card controls, 3DS, and fraud caps are handled for you.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
npm install @mooj/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires Node 18+ (uses the built-in `fetch`).
|
|
12
|
+
|
|
13
|
+
## Quickstart
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { Mooj } from '@mooj/sdk';
|
|
17
|
+
|
|
18
|
+
const mooj = new Mooj(process.env.MOOJ_API_KEY!); // key looks like mk_live_...
|
|
19
|
+
|
|
20
|
+
// Issue a single-use card capped at $20
|
|
21
|
+
const card = await mooj.cards.create({
|
|
22
|
+
amount: 20,
|
|
23
|
+
merchant: 'namecheap',
|
|
24
|
+
single_use: true,
|
|
25
|
+
});
|
|
26
|
+
console.log(card.id, card.last4, card.spend_limit);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Get your API key from the Mooj console (Developer -> API keys). Keep it server-side; never commit it.
|
|
30
|
+
|
|
31
|
+
## Tools
|
|
32
|
+
|
|
33
|
+
### Cards
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
const card = await mooj.cards.create({ amount: 20, merchant: 'namecheap', single_use: true });
|
|
37
|
+
const full = await mooj.cards.reveal(card.id); // { number, cvc, exp, ... } — use at the moment of purchase
|
|
38
|
+
const closed = await mooj.cards.close(card.id); // release the unused reserve back to your wallet
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Spend status
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
const spend = await mooj.spend.get(card.spend_request_id!);
|
|
45
|
+
// spend.status: 'not_started' | 'authorized' | 'cleared' | 'declined'
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Checkout (Mooj drives the buy)
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
const run = await mooj.checkout.create({
|
|
52
|
+
task: 'buy the domain mooj.click for 1 year',
|
|
53
|
+
merchant: 'namecheap',
|
|
54
|
+
amount: 20,
|
|
55
|
+
confirm_pay: false, // dry run: stops at the final review. true = pay up to the cap.
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// poll until it finishes
|
|
59
|
+
let status = await mooj.checkout.get(run.checkout_id);
|
|
60
|
+
// status.status: 'queued' | 'running' | 'awaiting_approval' | 'needs_login' | 'submitted' | 'blocked'
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Connections (login-gated merchants)
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
const conn = await mooj.connections.create({ merchant: 'namecheap', user_ref: 'user-123' });
|
|
67
|
+
// open conn.connect_url so the user signs in, then:
|
|
68
|
+
await mooj.connections.complete(conn.connection_id);
|
|
69
|
+
// now pass connection_id to checkout.create to run signed-in
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Errors
|
|
73
|
+
|
|
74
|
+
Any non-2xx response throws a `MoojError` with the HTTP status, the Mooj error code, and the request id.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { Mooj, MoojError } from '@mooj/sdk';
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
await mooj.cards.create({ amount: 999999, merchant: 'namecheap' });
|
|
81
|
+
} catch (e) {
|
|
82
|
+
if (e instanceof MoojError) {
|
|
83
|
+
console.error(e.status, e.code, e.requestId, e.message);
|
|
84
|
+
// e.g. 402 insufficient_funds
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Configuration
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
new Mooj({
|
|
93
|
+
apiKey: process.env.MOOJ_API_KEY!,
|
|
94
|
+
baseUrl: 'https://mooj-api-277196974190.us-central1.run.app', // optional override
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Docs
|
|
99
|
+
|
|
100
|
+
Full API reference: https://storage.googleapis.com/mooj-docs/index.html
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @mooj/sdk — the official Mooj SDK.
|
|
3
|
+
*
|
|
4
|
+
* A thin, typed wrapper over the Mooj REST API (v1). Issue capped virtual cards and let your
|
|
5
|
+
* agent complete real checkouts; card controls, 3DS, and fraud caps are handled for you.
|
|
6
|
+
*
|
|
7
|
+
* import { Mooj } from '@mooj/sdk';
|
|
8
|
+
* const mooj = new Mooj(process.env.MOOJ_API_KEY!);
|
|
9
|
+
* const card = await mooj.cards.create({ amount: 20, merchant: 'namecheap', single_use: true });
|
|
10
|
+
*/
|
|
11
|
+
export interface MoojOptions {
|
|
12
|
+
/** Your secret API key, e.g. "mk_live_...". Create one in the Mooj console. */
|
|
13
|
+
apiKey: string;
|
|
14
|
+
/** Override the API base URL (defaults to the live Mooj gateway). */
|
|
15
|
+
baseUrl?: string;
|
|
16
|
+
/** Provide a custom fetch implementation (defaults to global fetch, Node 18+). */
|
|
17
|
+
fetch?: typeof fetch;
|
|
18
|
+
}
|
|
19
|
+
/** Thrown on any non-2xx response. Carries the HTTP status, the Mooj error code, and the request id. */
|
|
20
|
+
export declare class MoojError extends Error {
|
|
21
|
+
readonly status: number;
|
|
22
|
+
readonly code?: string;
|
|
23
|
+
readonly requestId?: string;
|
|
24
|
+
constructor(message: string, status: number, code?: string, requestId?: string);
|
|
25
|
+
}
|
|
26
|
+
export interface Card {
|
|
27
|
+
id: string;
|
|
28
|
+
brand: string;
|
|
29
|
+
last4: string;
|
|
30
|
+
exp_month: number;
|
|
31
|
+
exp_year: number;
|
|
32
|
+
spend_limit: number;
|
|
33
|
+
single_use: boolean;
|
|
34
|
+
status: string;
|
|
35
|
+
spend_request_id: string | null;
|
|
36
|
+
}
|
|
37
|
+
export interface RevealedCard {
|
|
38
|
+
id: string;
|
|
39
|
+
last4: string;
|
|
40
|
+
number: string;
|
|
41
|
+
number_formatted: string;
|
|
42
|
+
cvc: string;
|
|
43
|
+
exp: string;
|
|
44
|
+
}
|
|
45
|
+
export interface ClosedCard {
|
|
46
|
+
id: string;
|
|
47
|
+
status: string;
|
|
48
|
+
released_display: string;
|
|
49
|
+
available_to_issue_display: string;
|
|
50
|
+
}
|
|
51
|
+
export interface SpendStatus {
|
|
52
|
+
spend_request_id: string;
|
|
53
|
+
merchant: string;
|
|
54
|
+
decision: string;
|
|
55
|
+
status: 'not_started' | 'authorized' | 'cleared' | 'declined' | string;
|
|
56
|
+
settled: boolean;
|
|
57
|
+
amount: number;
|
|
58
|
+
}
|
|
59
|
+
export interface Checkout {
|
|
60
|
+
checkout_id: string;
|
|
61
|
+
status: 'queued' | 'running' | 'awaiting_approval' | 'needs_login' | 'submitted' | 'blocked' | string;
|
|
62
|
+
poll?: string;
|
|
63
|
+
task?: string;
|
|
64
|
+
merchant?: string;
|
|
65
|
+
amount?: number;
|
|
66
|
+
card_last4?: string;
|
|
67
|
+
review_total?: number;
|
|
68
|
+
order_id?: string | null;
|
|
69
|
+
order_total?: number | null;
|
|
70
|
+
needs_login?: boolean;
|
|
71
|
+
error_reason?: string | null;
|
|
72
|
+
}
|
|
73
|
+
export interface Connection {
|
|
74
|
+
connection_id: string;
|
|
75
|
+
connect_url?: string;
|
|
76
|
+
status: 'pending' | 'connected' | string;
|
|
77
|
+
}
|
|
78
|
+
export interface CreateCardParams {
|
|
79
|
+
/** Spend cap in US dollars. Per-card ceiling is $5,000. */
|
|
80
|
+
amount: number;
|
|
81
|
+
merchant: string;
|
|
82
|
+
/** Default true. Auto-freezes after the first charge. */
|
|
83
|
+
single_use?: boolean;
|
|
84
|
+
network?: 'auto' | 'visa' | 'mastercard';
|
|
85
|
+
card_name?: string;
|
|
86
|
+
}
|
|
87
|
+
export interface CreateCheckoutParams {
|
|
88
|
+
task: string;
|
|
89
|
+
merchant: string;
|
|
90
|
+
/** Maximum USD to spend (becomes the card cap). */
|
|
91
|
+
amount: number;
|
|
92
|
+
/** false (default) = dry run, stops at review. true = pay autonomously up to the cap. */
|
|
93
|
+
confirm_pay?: boolean;
|
|
94
|
+
connection_id?: string;
|
|
95
|
+
card_holder_name?: string;
|
|
96
|
+
start_url?: string;
|
|
97
|
+
}
|
|
98
|
+
export interface CreateConnectionParams {
|
|
99
|
+
merchant: string;
|
|
100
|
+
user_ref?: string;
|
|
101
|
+
}
|
|
102
|
+
export declare class Mooj {
|
|
103
|
+
private readonly apiKey;
|
|
104
|
+
private readonly baseUrl;
|
|
105
|
+
private readonly _fetch;
|
|
106
|
+
constructor(options: MoojOptions | string);
|
|
107
|
+
private request;
|
|
108
|
+
/** Virtual cards: issue, reveal the PAN, and close. */
|
|
109
|
+
readonly cards: {
|
|
110
|
+
create: (params: CreateCardParams) => Promise<Card>;
|
|
111
|
+
reveal: (id: string) => Promise<RevealedCard>;
|
|
112
|
+
close: (id: string) => Promise<ClosedCard>;
|
|
113
|
+
};
|
|
114
|
+
/** Spend status for a card issued with cards.create (pass the spend_request_id). */
|
|
115
|
+
readonly spend: {
|
|
116
|
+
get: (spendRequestId: string) => Promise<SpendStatus>;
|
|
117
|
+
};
|
|
118
|
+
/** Let Mooj drive a full checkout. create() is async; poll with get(). */
|
|
119
|
+
readonly checkout: {
|
|
120
|
+
create: (params: CreateCheckoutParams) => Promise<Checkout>;
|
|
121
|
+
get: (checkoutId: string) => Promise<Checkout>;
|
|
122
|
+
};
|
|
123
|
+
/** Reusable merchant logins for login-gated stores. */
|
|
124
|
+
readonly connections: {
|
|
125
|
+
create: (params: CreateConnectionParams) => Promise<Connection>;
|
|
126
|
+
complete: (id: string) => Promise<Connection>;
|
|
127
|
+
list: () => Promise<Connection[] | {
|
|
128
|
+
connections?: Connection[];
|
|
129
|
+
}>;
|
|
130
|
+
get: (id: string) => Promise<Connection>;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
export default Mooj;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @mooj/sdk — the official Mooj SDK.
|
|
4
|
+
*
|
|
5
|
+
* A thin, typed wrapper over the Mooj REST API (v1). Issue capped virtual cards and let your
|
|
6
|
+
* agent complete real checkouts; card controls, 3DS, and fraud caps are handled for you.
|
|
7
|
+
*
|
|
8
|
+
* import { Mooj } from '@mooj/sdk';
|
|
9
|
+
* const mooj = new Mooj(process.env.MOOJ_API_KEY!);
|
|
10
|
+
* const card = await mooj.cards.create({ amount: 20, merchant: 'namecheap', single_use: true });
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.Mooj = exports.MoojError = void 0;
|
|
14
|
+
const DEFAULT_BASE_URL = 'https://mooj-api-277196974190.us-central1.run.app';
|
|
15
|
+
/** Thrown on any non-2xx response. Carries the HTTP status, the Mooj error code, and the request id. */
|
|
16
|
+
class MoojError extends Error {
|
|
17
|
+
constructor(message, status, code, requestId) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.name = 'MoojError';
|
|
20
|
+
this.status = status;
|
|
21
|
+
this.code = code;
|
|
22
|
+
this.requestId = requestId;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.MoojError = MoojError;
|
|
26
|
+
class Mooj {
|
|
27
|
+
constructor(options) {
|
|
28
|
+
/** Virtual cards: issue, reveal the PAN, and close. */
|
|
29
|
+
this.cards = {
|
|
30
|
+
create: (params) => this.request('POST', '/v1/cards', params),
|
|
31
|
+
reveal: (id) => this.request('GET', `/v1/cards/${encodeURIComponent(id)}`),
|
|
32
|
+
close: (id) => this.request('POST', `/v1/cards/${encodeURIComponent(id)}/close`),
|
|
33
|
+
};
|
|
34
|
+
/** Spend status for a card issued with cards.create (pass the spend_request_id). */
|
|
35
|
+
this.spend = {
|
|
36
|
+
get: (spendRequestId) => this.request('GET', `/v1/spend/${encodeURIComponent(spendRequestId)}`),
|
|
37
|
+
};
|
|
38
|
+
/** Let Mooj drive a full checkout. create() is async; poll with get(). */
|
|
39
|
+
this.checkout = {
|
|
40
|
+
create: (params) => this.request('POST', '/v1/checkout', params),
|
|
41
|
+
get: (checkoutId) => this.request('GET', `/v1/checkout/${encodeURIComponent(checkoutId)}`),
|
|
42
|
+
};
|
|
43
|
+
/** Reusable merchant logins for login-gated stores. */
|
|
44
|
+
this.connections = {
|
|
45
|
+
create: (params) => this.request('POST', '/v1/connections', params),
|
|
46
|
+
complete: (id) => this.request('POST', `/v1/connections/${encodeURIComponent(id)}/complete`),
|
|
47
|
+
list: () => this.request('GET', '/v1/connections'),
|
|
48
|
+
get: (id) => this.request('GET', `/v1/connections/${encodeURIComponent(id)}`),
|
|
49
|
+
};
|
|
50
|
+
const o = typeof options === 'string' ? { apiKey: options } : options;
|
|
51
|
+
if (!o || !o.apiKey)
|
|
52
|
+
throw new Error('Mooj: apiKey is required');
|
|
53
|
+
this.apiKey = o.apiKey;
|
|
54
|
+
this.baseUrl = (o.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
55
|
+
const f = o.fetch || globalThis.fetch;
|
|
56
|
+
if (!f)
|
|
57
|
+
throw new Error('Mooj: no fetch available. Use Node 18+ or pass options.fetch.');
|
|
58
|
+
this._fetch = f;
|
|
59
|
+
}
|
|
60
|
+
async request(method, path, body) {
|
|
61
|
+
const res = await this._fetch(`${this.baseUrl}${path}`, {
|
|
62
|
+
method,
|
|
63
|
+
headers: {
|
|
64
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
65
|
+
...(body !== undefined ? { 'Content-Type': 'application/json' } : {}),
|
|
66
|
+
},
|
|
67
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
68
|
+
});
|
|
69
|
+
const requestId = res.headers.get('X-Mooj-Request-Id') || undefined;
|
|
70
|
+
const text = await res.text();
|
|
71
|
+
let data = null;
|
|
72
|
+
if (text) {
|
|
73
|
+
try {
|
|
74
|
+
data = JSON.parse(text);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
data = text;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (!res.ok) {
|
|
81
|
+
const d = (data ?? {});
|
|
82
|
+
const message = d.message || d.error || `Mooj API error ${res.status}`;
|
|
83
|
+
throw new MoojError(message, res.status, d.error, d.request_id || requestId);
|
|
84
|
+
}
|
|
85
|
+
return data;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.Mooj = Mooj;
|
|
89
|
+
exports.default = Mooj;
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mooj/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official Mooj SDK. Issue capped virtual cards and let your agent complete real checkouts. 3DS handled.",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"mooj",
|
|
17
|
+
"payments",
|
|
18
|
+
"ai-agents",
|
|
19
|
+
"virtual-cards",
|
|
20
|
+
"checkout",
|
|
21
|
+
"3ds"
|
|
22
|
+
],
|
|
23
|
+
"author": "Mooj",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"homepage": "https://storage.googleapis.com/mooj-docs/index.html",
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=18"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"typescript": "^5.4.5"
|
|
31
|
+
}
|
|
32
|
+
}
|