@takeal/cusfront-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/CHANGELOG.md +66 -0
- package/LICENSE +21 -0
- package/README.md +283 -0
- package/dist/customer-CoxPwe5o.d.cts +32 -0
- package/dist/customer-CoxPwe5o.d.ts +32 -0
- package/dist/http-BkZZZI8K.d.cts +72 -0
- package/dist/http-BkZZZI8K.d.ts +72 -0
- package/dist/index.cjs +486 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +149 -0
- package/dist/index.d.ts +149 -0
- package/dist/index.js +478 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.cjs +82 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +93 -0
- package/dist/react/index.d.ts +93 -0
- package/dist/react/index.js +75 -0
- package/dist/react/index.js.map +1 -0
- package/dist/resources/auth.cjs +88 -0
- package/dist/resources/auth.cjs.map +1 -0
- package/dist/resources/auth.d.cts +132 -0
- package/dist/resources/auth.d.ts +132 -0
- package/dist/resources/auth.js +86 -0
- package/dist/resources/auth.js.map +1 -0
- package/dist/resources/balance.cjs +21 -0
- package/dist/resources/balance.cjs.map +1 -0
- package/dist/resources/balance.d.cts +27 -0
- package/dist/resources/balance.d.ts +27 -0
- package/dist/resources/balance.js +19 -0
- package/dist/resources/balance.js.map +1 -0
- package/dist/resources/blog.cjs +39 -0
- package/dist/resources/blog.cjs.map +1 -0
- package/dist/resources/blog.d.cts +112 -0
- package/dist/resources/blog.d.ts +112 -0
- package/dist/resources/blog.js +37 -0
- package/dist/resources/blog.js.map +1 -0
- package/dist/resources/branding.cjs +16 -0
- package/dist/resources/branding.cjs.map +1 -0
- package/dist/resources/branding.d.cts +35 -0
- package/dist/resources/branding.d.ts +35 -0
- package/dist/resources/branding.js +14 -0
- package/dist/resources/branding.js.map +1 -0
- package/dist/resources/cards.cjs +91 -0
- package/dist/resources/cards.cjs.map +1 -0
- package/dist/resources/cards.d.cts +166 -0
- package/dist/resources/cards.d.ts +166 -0
- package/dist/resources/cards.js +89 -0
- package/dist/resources/cards.js.map +1 -0
- package/dist/resources/deposits.cjs +52 -0
- package/dist/resources/deposits.cjs.map +1 -0
- package/dist/resources/deposits.d.cts +168 -0
- package/dist/resources/deposits.d.ts +168 -0
- package/dist/resources/deposits.js +50 -0
- package/dist/resources/deposits.js.map +1 -0
- package/dist/resources/subscriptions.cjs +24 -0
- package/dist/resources/subscriptions.cjs.map +1 -0
- package/dist/resources/subscriptions.d.cts +36 -0
- package/dist/resources/subscriptions.d.ts +36 -0
- package/dist/resources/subscriptions.js +22 -0
- package/dist/resources/subscriptions.js.map +1 -0
- package/dist/telegram.cjs +557 -0
- package/dist/telegram.cjs.map +1 -0
- package/dist/telegram.d.cts +105 -0
- package/dist/telegram.d.ts +105 -0
- package/dist/telegram.js +550 -0
- package/dist/telegram.js.map +1 -0
- package/dist/webhooks.cjs +78 -0
- package/dist/webhooks.cjs.map +1 -0
- package/dist/webhooks.d.cts +70 -0
- package/dist/webhooks.d.ts +70 -0
- package/dist/webhooks.js +72 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +123 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/resources/blog.ts"],"names":[],"mappings":";AAmFO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,IAAA,CAAK,KAAA,GAAuB,EAAC,EAAsB;AACvD,IAAA,MAAM,CAAA,GAAI,IAAI,eAAA,EAAgB;AAC9B,IAAA,IAAI,KAAA,CAAM,MAAM,CAAA,CAAE,GAAA,CAAI,QAAQ,MAAA,CAAO,KAAA,CAAM,IAAI,CAAC,CAAA;AAChD,IAAA,IAAI,KAAA,CAAM,SAAS,CAAA,CAAE,GAAA,CAAI,YAAY,MAAA,CAAO,KAAA,CAAM,OAAO,CAAC,CAAA;AAC1D,IAAA,IAAI,MAAM,GAAA,EAAK,CAAA,CAAE,GAAA,CAAI,KAAA,EAAO,MAAM,GAAG,CAAA;AACrC,IAAA,IAAI,MAAM,MAAA,EAAQ,CAAA,CAAE,GAAA,CAAI,QAAA,EAAU,MAAM,MAAM,CAAA;AAC9C,IAAA,MAAM,EAAA,GAAK,EAAE,QAAA,EAAS;AACtB,IAAA,OAAO,IAAA,CAAK,KAAK,GAAA,CAAc,CAAA,WAAA,EAAc,KAAK,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA,EAAI;AAAA,MACjE,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,IAAI,IAAA,EAAiC;AACzC,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAc,eAAe,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAA,EAAI;AAAA,MACxE,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAA,CAAS,SAAiB,IAAA,EAAsB;AAC9C,IAAA,IAAI,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACvC,IAAA,OAAO,CAAA,EAAG,OAAA,CAAQ,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAC,CAAA,EAAG,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GAAI,EAAA,GAAK,GAAG,GAAG,IAAI,CAAA,CAAA;AAAA,EAC/E;AACF","file":"blog.js","sourcesContent":["import type { HttpClient } from \"../http.js\";\n\n/**\n * Blog resource — `client.blog.*`.\n *\n * Posts are public: these calls work before the user logs in, which is what\n * a marketing page or a Mini App landing screen needs.\n *\n * A post arrives as a **structured document**, not as HTML. `body_blocks` is\n * a flat list of typed nodes; map each `type` onto your own component and the\n * post inherits your site's styling. `body_markdown` is there too if you'd\n * rather run your own renderer.\n *\n * ```ts\n * const { posts } = await client.blog.list({ perPage: 5 });\n * const post = await client.blog.get(posts[0].slug);\n *\n * post.body_blocks.map((b) => {\n * switch (b.type) {\n * case \"heading\": return <Heading level={b.level}>{b.text}</Heading>;\n * case \"paragraph\": return <P>{b.text}</P>;\n * case \"image\": return <Figure src={b.url} alt={b.alt} caption={b.caption} />;\n * case \"list\": return <List ordered={b.ordered} items={b.items} />;\n * case \"quote\": return <Quote>{b.text}</Quote>;\n * case \"code\": return <Code lang={b.lang}>{b.text}</Code>;\n * case \"divider\": return <Hr />;\n * }\n * });\n * ```\n *\n * Inline emphasis (`**bold**`, `[link](url)`) is left as Markdown inside\n * block text — every renderer already knows what to do with it.\n */\n\n/** One node of a post body. Discriminated on `type`. */\nexport type BlogBlock =\n | { type: \"heading\"; level: number; text: string }\n | { type: \"paragraph\"; text: string }\n | { type: \"image\"; url: string; alt?: string; caption?: string }\n | { type: \"list\"; ordered: boolean; items: string[] }\n | { type: \"quote\"; text: string }\n | { type: \"code\"; lang?: string; text: string }\n | { type: \"divider\" };\n\nexport interface BlogPost {\n /** Stable public key — link by this. */\n slug: string;\n title: string;\n /** Teaser for cards; falls back to the first paragraph. */\n excerpt: string;\n /** Image URL, relative to the API origin. Absent when no cover is set. */\n cover_url?: string;\n /** Raw Markdown, for consumers that bring their own renderer. */\n body_markdown: string;\n /** The recommended input for rendering — see the module docs. */\n body_blocks: BlogBlock[];\n tags: string[];\n /** Present only when the post declares one. */\n locale?: string;\n /** Rough read time in minutes (minimum 1). */\n reading_minutes: number;\n published_at: string | null;\n updated_at: string;\n}\n\nexport interface BlogListInput {\n /** 1-based. Default 1. */\n page?: number;\n /** 1..=50. Default 10. */\n perPage?: number;\n /** Only posts carrying this tag. */\n tag?: string;\n /** Only posts in this locale. */\n locale?: string;\n}\n\nexport interface BlogList {\n posts: BlogPost[];\n total: number;\n page: number;\n per_page: number;\n}\n\nexport class BlogResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Published posts, newest first. No authentication required. */\n async list(input: BlogListInput = {}): Promise<BlogList> {\n const q = new URLSearchParams();\n if (input.page) q.set(\"page\", String(input.page));\n if (input.perPage) q.set(\"per_page\", String(input.perPage));\n if (input.tag) q.set(\"tag\", input.tag);\n if (input.locale) q.set(\"locale\", input.locale);\n const qs = q.toString();\n return this.http.get<BlogList>(`/blog/posts${qs ? `?${qs}` : \"\"}`, {\n skipAuth: true,\n });\n }\n\n /** One post by slug. No authentication required. */\n async get(slug: string): Promise<BlogPost> {\n return this.http.get<BlogPost>(`/blog/posts/${encodeURIComponent(slug)}`, {\n skipAuth: true,\n });\n }\n\n /**\n * Absolute URL for an image path returned inside a post (`cover_url`, or an\n * image block's `url`). Handy when the app renders on a different origin\n * than the API.\n */\n imageUrl(baseUrl: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${baseUrl.replace(/\\/$/, \"\")}${path.startsWith(\"/\") ? \"\" : \"/\"}${path}`;\n }\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/resources/branding.ts
|
|
4
|
+
var BrandingResource = class {
|
|
5
|
+
constructor(http) {
|
|
6
|
+
this.http = http;
|
|
7
|
+
}
|
|
8
|
+
/** Fetch the deployment's public brand config. Safe to call before login. */
|
|
9
|
+
async get(opts = {}) {
|
|
10
|
+
return this.http.get("/branding", { skipAuth: true, signal: opts.signal });
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
exports.BrandingResource = BrandingResource;
|
|
15
|
+
//# sourceMappingURL=branding.cjs.map
|
|
16
|
+
//# sourceMappingURL=branding.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/resources/branding.ts"],"names":[],"mappings":";;;AA2BO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,GAAA,CAAI,IAAA,GAAiC,EAAC,EAAsB;AAChE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAc,WAAA,EAAa,EAAE,UAAU,IAAA,EAAM,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,CAAA;AAAA,EACrF;AACF","file":"branding.cjs","sourcesContent":["import type { HttpClient } from \"../http.js\";\n\n/**\n * Branding resource — `client.branding.*`.\n *\n * Runtime white-label config published by the deployment at `GET /branding`\n * (public, no auth). Lets a Cusfront re-theme itself on the fly — platform\n * name, logo, favicon and the label used for the end-user's balance — without\n * a rebuild. Pairs with the build-time `BrandConfig`: the server-side values\n * win whenever both are present.\n */\n\n/** Public brand config of the deployment. All strings; empty = use the client default. */\nexport interface Branding {\n /** Platform display name (e.g. the white-label brand). */\n platform_name: string;\n /** Name of the merchant-facing portal. */\n merchant_portal_name: string;\n /** Logo image — absolute URL or `data:` URI. Empty → client default. */\n logo_url: string;\n /** Favicon — absolute URL or `data:` URI. Empty → client default. */\n favicon_url: string;\n /** User-facing name of the balance, e.g. `\"Wallet\"` or `\"Acme Wallet\"`.\n * Display-only: the `balance` API shape never changes with it. */\n wallet_label: string;\n}\n\nexport class BrandingResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Fetch the deployment's public brand config. Safe to call before login. */\n async get(opts: { signal?: AbortSignal } = {}): Promise<Branding> {\n return this.http.get<Branding>(\"/branding\", { skipAuth: true, signal: opts.signal });\n }\n}\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { H as HttpClient } from '../http-BkZZZI8K.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Branding resource — `client.branding.*`.
|
|
5
|
+
*
|
|
6
|
+
* Runtime white-label config published by the deployment at `GET /branding`
|
|
7
|
+
* (public, no auth). Lets a Cusfront re-theme itself on the fly — platform
|
|
8
|
+
* name, logo, favicon and the label used for the end-user's balance — without
|
|
9
|
+
* a rebuild. Pairs with the build-time `BrandConfig`: the server-side values
|
|
10
|
+
* win whenever both are present.
|
|
11
|
+
*/
|
|
12
|
+
/** Public brand config of the deployment. All strings; empty = use the client default. */
|
|
13
|
+
interface Branding {
|
|
14
|
+
/** Platform display name (e.g. the white-label brand). */
|
|
15
|
+
platform_name: string;
|
|
16
|
+
/** Name of the merchant-facing portal. */
|
|
17
|
+
merchant_portal_name: string;
|
|
18
|
+
/** Logo image — absolute URL or `data:` URI. Empty → client default. */
|
|
19
|
+
logo_url: string;
|
|
20
|
+
/** Favicon — absolute URL or `data:` URI. Empty → client default. */
|
|
21
|
+
favicon_url: string;
|
|
22
|
+
/** User-facing name of the balance, e.g. `"Wallet"` or `"Acme Wallet"`.
|
|
23
|
+
* Display-only: the `balance` API shape never changes with it. */
|
|
24
|
+
wallet_label: string;
|
|
25
|
+
}
|
|
26
|
+
declare class BrandingResource {
|
|
27
|
+
private readonly http;
|
|
28
|
+
constructor(http: HttpClient);
|
|
29
|
+
/** Fetch the deployment's public brand config. Safe to call before login. */
|
|
30
|
+
get(opts?: {
|
|
31
|
+
signal?: AbortSignal;
|
|
32
|
+
}): Promise<Branding>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { type Branding, BrandingResource };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { H as HttpClient } from '../http-BkZZZI8K.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Branding resource — `client.branding.*`.
|
|
5
|
+
*
|
|
6
|
+
* Runtime white-label config published by the deployment at `GET /branding`
|
|
7
|
+
* (public, no auth). Lets a Cusfront re-theme itself on the fly — platform
|
|
8
|
+
* name, logo, favicon and the label used for the end-user's balance — without
|
|
9
|
+
* a rebuild. Pairs with the build-time `BrandConfig`: the server-side values
|
|
10
|
+
* win whenever both are present.
|
|
11
|
+
*/
|
|
12
|
+
/** Public brand config of the deployment. All strings; empty = use the client default. */
|
|
13
|
+
interface Branding {
|
|
14
|
+
/** Platform display name (e.g. the white-label brand). */
|
|
15
|
+
platform_name: string;
|
|
16
|
+
/** Name of the merchant-facing portal. */
|
|
17
|
+
merchant_portal_name: string;
|
|
18
|
+
/** Logo image — absolute URL or `data:` URI. Empty → client default. */
|
|
19
|
+
logo_url: string;
|
|
20
|
+
/** Favicon — absolute URL or `data:` URI. Empty → client default. */
|
|
21
|
+
favicon_url: string;
|
|
22
|
+
/** User-facing name of the balance, e.g. `"Wallet"` or `"Acme Wallet"`.
|
|
23
|
+
* Display-only: the `balance` API shape never changes with it. */
|
|
24
|
+
wallet_label: string;
|
|
25
|
+
}
|
|
26
|
+
declare class BrandingResource {
|
|
27
|
+
private readonly http;
|
|
28
|
+
constructor(http: HttpClient);
|
|
29
|
+
/** Fetch the deployment's public brand config. Safe to call before login. */
|
|
30
|
+
get(opts?: {
|
|
31
|
+
signal?: AbortSignal;
|
|
32
|
+
}): Promise<Branding>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { type Branding, BrandingResource };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/resources/branding.ts
|
|
2
|
+
var BrandingResource = class {
|
|
3
|
+
constructor(http) {
|
|
4
|
+
this.http = http;
|
|
5
|
+
}
|
|
6
|
+
/** Fetch the deployment's public brand config. Safe to call before login. */
|
|
7
|
+
async get(opts = {}) {
|
|
8
|
+
return this.http.get("/branding", { skipAuth: true, signal: opts.signal });
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export { BrandingResource };
|
|
13
|
+
//# sourceMappingURL=branding.js.map
|
|
14
|
+
//# sourceMappingURL=branding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/resources/branding.ts"],"names":[],"mappings":";AA2BO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,GAAA,CAAI,IAAA,GAAiC,EAAC,EAAsB;AAChE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAc,WAAA,EAAa,EAAE,UAAU,IAAA,EAAM,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,CAAA;AAAA,EACrF;AACF","file":"branding.js","sourcesContent":["import type { HttpClient } from \"../http.js\";\n\n/**\n * Branding resource — `client.branding.*`.\n *\n * Runtime white-label config published by the deployment at `GET /branding`\n * (public, no auth). Lets a Cusfront re-theme itself on the fly — platform\n * name, logo, favicon and the label used for the end-user's balance — without\n * a rebuild. Pairs with the build-time `BrandConfig`: the server-side values\n * win whenever both are present.\n */\n\n/** Public brand config of the deployment. All strings; empty = use the client default. */\nexport interface Branding {\n /** Platform display name (e.g. the white-label brand). */\n platform_name: string;\n /** Name of the merchant-facing portal. */\n merchant_portal_name: string;\n /** Logo image — absolute URL or `data:` URI. Empty → client default. */\n logo_url: string;\n /** Favicon — absolute URL or `data:` URI. Empty → client default. */\n favicon_url: string;\n /** User-facing name of the balance, e.g. `\"Wallet\"` or `\"Acme Wallet\"`.\n * Display-only: the `balance` API shape never changes with it. */\n wallet_label: string;\n}\n\nexport class BrandingResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Fetch the deployment's public brand config. Safe to call before login. */\n async get(opts: { signal?: AbortSignal } = {}): Promise<Branding> {\n return this.http.get<Branding>(\"/branding\", { skipAuth: true, signal: opts.signal });\n }\n}\n"]}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/resources/cards.ts
|
|
4
|
+
var CardsResource = class {
|
|
5
|
+
constructor(http) {
|
|
6
|
+
this.http = http;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Issue a card backed by the user's wallet balance. Resolves to the new
|
|
10
|
+
* `Card`. On a ledger failure after provider creation, the Takeal API rolls the row
|
|
11
|
+
* to `failed` (never an orphaned active card); inspect `status` /
|
|
12
|
+
* `failure_reason` on the result.
|
|
13
|
+
*/
|
|
14
|
+
async create(input) {
|
|
15
|
+
const { idempotencyKey, ...body } = input;
|
|
16
|
+
return this.http.post("/me/cards", {
|
|
17
|
+
body,
|
|
18
|
+
idempotencyKey
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/** Fetch one card by id. */
|
|
22
|
+
async get(id) {
|
|
23
|
+
return this.http.get(`/me/cards/${encodeURIComponent(id)}`);
|
|
24
|
+
}
|
|
25
|
+
/** List the caller's cards, most recent first. */
|
|
26
|
+
async list() {
|
|
27
|
+
return this.http.get("/me/cards");
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Remaining balance of a prepaid card. `currency` is required by the Takeal API and
|
|
31
|
+
* forwarded as a query param.
|
|
32
|
+
*/
|
|
33
|
+
async balance(id, currency) {
|
|
34
|
+
const q = new URLSearchParams({ currency }).toString();
|
|
35
|
+
return this.http.get(
|
|
36
|
+
`/me/cards/${encodeURIComponent(id)}/balance?${q}`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Freeze the caller's own card. Reversible via {@link unfreeze}. The optional
|
|
41
|
+
* `reason` is recorded on the audit trail. Resolves to the updated card.
|
|
42
|
+
* 404 if the card isn't the caller's; 501 if the issuer can't freeze.
|
|
43
|
+
*/
|
|
44
|
+
async freeze(id, reason) {
|
|
45
|
+
return this.http.post(
|
|
46
|
+
`/me/cards/${encodeURIComponent(id)}/freeze`,
|
|
47
|
+
{ body: { reason } }
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Reveal the FULL PAN + CVV for the caller's own card. Re-auth gated
|
|
52
|
+
* (password, + TOTP when the user has it enrolled) and rate-limited
|
|
53
|
+
* server-side. The Takeal API never persists this data and marks the
|
|
54
|
+
* response no-store; the SDK returns it verbatim and holds nothing.
|
|
55
|
+
*
|
|
56
|
+
* **Consumer security duties** (the SDK can't enforce these for you):
|
|
57
|
+
* keep the result in volatile memory only, never write it to
|
|
58
|
+
* localStorage / logs, and clear it within `expires_in_seconds`.
|
|
59
|
+
*
|
|
60
|
+
* 401 bad re-auth · 403 not your card · 429 rate-limited · 501 connector
|
|
61
|
+
* has no sensitive-data endpoint · 503 provider error.
|
|
62
|
+
*/
|
|
63
|
+
async reveal(id, input) {
|
|
64
|
+
return this.http.post(
|
|
65
|
+
`/me/cards/${encodeURIComponent(id)}/reveal`,
|
|
66
|
+
{ body: { password: input.password, totp_code: input.totpCode } }
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
/** Unfreeze a previously-frozen card. Idempotent on an already-active card. */
|
|
70
|
+
async unfreeze(id) {
|
|
71
|
+
return this.http.post(
|
|
72
|
+
`/me/cards/${encodeURIComponent(id)}/unfreeze`,
|
|
73
|
+
{ body: {} }
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Terminate the caller's own card. **One-way** — a terminated card cannot be
|
|
78
|
+
* reactivated. The optional `reason` is audited. Idempotent on an
|
|
79
|
+
* already-terminated card.
|
|
80
|
+
*/
|
|
81
|
+
async terminate(id, reason) {
|
|
82
|
+
return this.http.post(
|
|
83
|
+
`/me/cards/${encodeURIComponent(id)}/terminate`,
|
|
84
|
+
{ body: { reason } }
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
exports.CardsResource = CardsResource;
|
|
90
|
+
//# sourceMappingURL=cards.cjs.map
|
|
91
|
+
//# sourceMappingURL=cards.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/resources/cards.ts"],"names":[],"mappings":";;;AAkIO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQhD,MAAM,OAAO,KAAA,EAAuC;AAClD,IAAA,MAAM,EAAE,cAAA,EAAgB,GAAG,IAAA,EAAK,GAAI,KAAA;AACpC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAW,WAAA,EAAa;AAAA,MACvC,IAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,IAAI,EAAA,EAA2B;AACnC,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAU,aAAa,kBAAA,CAAmB,EAAE,CAAC,CAAA,CAAE,CAAA;AAAA,EAClE;AAAA;AAAA,EAGA,MAAM,IAAA,GAAwB;AAC5B,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAY,WAAW,CAAA;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAA,CAAQ,EAAA,EAAY,QAAA,EAAwC;AAChE,IAAA,MAAM,IAAI,IAAI,eAAA,CAAgB,EAAE,QAAA,EAAU,EAAE,QAAA,EAAS;AACrD,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA;AAAA,MACf,CAAA,UAAA,EAAa,kBAAA,CAAmB,EAAE,CAAC,YAAY,CAAC,CAAA;AAAA,KAClD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAA,CAAO,EAAA,EAAY,MAAA,EAAgC;AACvD,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA;AAAA,MACf,CAAA,UAAA,EAAa,kBAAA,CAAmB,EAAE,CAAC,CAAA,OAAA,CAAA;AAAA,MACnC,EAAE,IAAA,EAAM,EAAE,MAAA,EAAO;AAAE,KACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,MAAA,CAAO,EAAA,EAAY,KAAA,EAA+C;AACtE,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA;AAAA,MACf,CAAA,UAAA,EAAa,kBAAA,CAAmB,EAAE,CAAC,CAAA,OAAA,CAAA;AAAA,MACnC,EAAE,MAAM,EAAE,QAAA,EAAU,MAAM,QAAA,EAAU,SAAA,EAAW,KAAA,CAAM,QAAA,EAAS;AAAE,KAClE;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,SAAS,EAAA,EAA2B;AACxC,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA;AAAA,MACf,CAAA,UAAA,EAAa,kBAAA,CAAmB,EAAE,CAAC,CAAA,SAAA,CAAA;AAAA,MACnC,EAAE,IAAA,EAAM,EAAC;AAAE,KACb;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAAA,CAAU,EAAA,EAAY,MAAA,EAAgC;AAC1D,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA;AAAA,MACf,CAAA,UAAA,EAAa,kBAAA,CAAmB,EAAE,CAAC,CAAA,UAAA,CAAA;AAAA,MACnC,EAAE,IAAA,EAAM,EAAE,MAAA,EAAO;AAAE,KACrB;AAAA,EACF;AACF","file":"cards.cjs","sourcesContent":["import type { HttpClient } from \"../http.js\";\nimport type { CustomerInfo } from \"../types/customer.js\";\n\n/**\n * Cards resource — `client.cards.*`.\n *\n * The end-user \"money OUT\" surface: a user issues themselves a card backed by\n * their wallet balance via an issuer connector. Mirrors the Takeal API's\n * `/me/cards` routes:\n *\n * POST /me/cards → create\n * GET /me/cards → list (most recent first)\n * GET /me/cards/{id} → get\n * GET /me/cards/{id}/balance → balance (prepaid remaining)\n * POST /me/cards/{id}/freeze → freeze\n * POST /me/cards/{id}/unfreeze → unfreeze\n * POST /me/cards/{id}/terminate → terminate (one-way)\n *\n * The lifecycle actions are ownership-gated server-side: a caller can only\n * freeze / unfreeze / terminate a card that belongs to them (else 404).\n *\n * ## What is intentionally NOT here\n *\n * Card-data reveal (PAN / CVV) is a separate, security-sensitive flow with its\n * own re-auth + rate-limit + audit contract and is intentionally\n * NOT part of this resource (tracked separately).\n *\n * Today only PREPAID is wired end-to-end; CREDIT and GIFT return 400 from\n * the Takeal API until their issuer flows land.\n */\n\n/** Card product. Only `prepaid` is fully implemented today. */\nexport type CardType = \"credit\" | \"prepaid\" | \"gift\";\n\n/**\n * Card lifecycle state.\n *\n * `pending_payment` is a transient state: the row exists but the\n * per-card issuance-fee debit has not yet succeeded; such cards have no\n * provider reference and no user-visible side effects.\n */\nexport type CardStatus =\n | \"pending_payment\"\n | \"active\"\n | \"frozen\"\n | \"terminated\"\n | \"redeemed\"\n | \"failed\";\n\n/**\n * A card record as the Takeal API returns it. Mirrors the `cards` table. Note the\n * SDK never receives the full PAN or CVV here — only `last4` + expiry. The\n * gift-card `redemption_code` is returned exactly once (on create) and\n * scrubbed from subsequent list/get responses.\n */\nexport interface Card {\n id: string;\n user_id: string;\n card_type: CardType;\n /** Slug of the issuer that minted this card, as configured by the deployment. */\n connector_slug: string;\n /** The connector's own reference, populated once it responds. */\n provider_reference: string | null;\n status: CardStatus;\n /** Last four digits of the PAN — safe to display. */\n last4: string | null;\n expiry_month: number | null;\n expiry_year: number | null;\n /** Gift cards only, present once on create then scrubbed. */\n redemption_code?: string;\n /** Decimal as a string. */\n initial_amount: string | null;\n currency: string;\n failure_reason: string | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface CreateCardInput {\n /** `prepaid` (the only fully-wired type today), `credit`, or `gift`. */\n type: CardType;\n /** Decimal as a string. The prepaid load amount drained from wallet balance. */\n initial_amount?: string;\n /** ISO 4217 code, e.g. `\"USD\"`. */\n currency: string;\n /**\n * Optional. Slug of a specific issuer to mint with. Omit to let\n * the Takeal API pick the first active issuer. Unknown slug → 400; empty issuer\n * list → 503.\n */\n issuer_slug?: string;\n metadata?: Record<string, string>;\n /** Structured billing details — real issuers require these for 3DS / KYC. */\n customer?: CustomerInfo;\n /**\n * Required by the Takeal API on this write endpoint. Same key + body replays the\n * original card; same key + different body returns 409.\n */\n idempotencyKey: string;\n}\n\n/** Remaining balance of a prepaid card. */\nexport interface CardBalance {\n amount: string;\n currency: string;\n}\n\n/** Re-auth gate for {@link CardsResource.reveal}. */\nexport interface RevealCardInput {\n /** The user's account password — mandatory re-auth. */\n password: string;\n /** TOTP code; required only when the user has TOTP enrolled. */\n totpCode?: string;\n}\n\n/**\n * Full card data from a successful reveal. **Security**: never persist this —\n * keep it in volatile memory only, clear it within `expires_in_seconds`, and\n * never write it to localStorage / logs (the API marks the response no-store).\n */\nexport interface RevealedCard {\n pan: string;\n cvv: string;\n expiry_month: number;\n expiry_year: number;\n holder_name: string;\n /** Display window before the client should auto-clear the data. */\n expires_in_seconds: number;\n}\n\nexport class CardsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Issue a card backed by the user's wallet balance. Resolves to the new\n * `Card`. On a ledger failure after provider creation, the Takeal API rolls the row\n * to `failed` (never an orphaned active card); inspect `status` /\n * `failure_reason` on the result.\n */\n async create(input: CreateCardInput): Promise<Card> {\n const { idempotencyKey, ...body } = input;\n return this.http.post<Card>(\"/me/cards\", {\n body,\n idempotencyKey,\n });\n }\n\n /** Fetch one card by id. */\n async get(id: string): Promise<Card> {\n return this.http.get<Card>(`/me/cards/${encodeURIComponent(id)}`);\n }\n\n /** List the caller's cards, most recent first. */\n async list(): Promise<Card[]> {\n return this.http.get<Card[]>(\"/me/cards\");\n }\n\n /**\n * Remaining balance of a prepaid card. `currency` is required by the Takeal API and\n * forwarded as a query param.\n */\n async balance(id: string, currency: string): Promise<CardBalance> {\n const q = new URLSearchParams({ currency }).toString();\n return this.http.get<CardBalance>(\n `/me/cards/${encodeURIComponent(id)}/balance?${q}`,\n );\n }\n\n /**\n * Freeze the caller's own card. Reversible via {@link unfreeze}. The optional\n * `reason` is recorded on the audit trail. Resolves to the updated card.\n * 404 if the card isn't the caller's; 501 if the issuer can't freeze.\n */\n async freeze(id: string, reason?: string): Promise<Card> {\n return this.http.post<Card>(\n `/me/cards/${encodeURIComponent(id)}/freeze`,\n { body: { reason } },\n );\n }\n\n /**\n * Reveal the FULL PAN + CVV for the caller's own card. Re-auth gated\n * (password, + TOTP when the user has it enrolled) and rate-limited\n * server-side. The Takeal API never persists this data and marks the\n * response no-store; the SDK returns it verbatim and holds nothing.\n *\n * **Consumer security duties** (the SDK can't enforce these for you):\n * keep the result in volatile memory only, never write it to\n * localStorage / logs, and clear it within `expires_in_seconds`.\n *\n * 401 bad re-auth · 403 not your card · 429 rate-limited · 501 connector\n * has no sensitive-data endpoint · 503 provider error.\n */\n async reveal(id: string, input: RevealCardInput): Promise<RevealedCard> {\n return this.http.post<RevealedCard>(\n `/me/cards/${encodeURIComponent(id)}/reveal`,\n { body: { password: input.password, totp_code: input.totpCode } },\n );\n }\n\n /** Unfreeze a previously-frozen card. Idempotent on an already-active card. */\n async unfreeze(id: string): Promise<Card> {\n return this.http.post<Card>(\n `/me/cards/${encodeURIComponent(id)}/unfreeze`,\n { body: {} },\n );\n }\n\n /**\n * Terminate the caller's own card. **One-way** — a terminated card cannot be\n * reactivated. The optional `reason` is audited. Idempotent on an\n * already-terminated card.\n */\n async terminate(id: string, reason?: string): Promise<Card> {\n return this.http.post<Card>(\n `/me/cards/${encodeURIComponent(id)}/terminate`,\n { body: { reason } },\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { H as HttpClient } from '../http-BkZZZI8K.cjs';
|
|
2
|
+
import { C as CustomerInfo } from '../customer-CoxPwe5o.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Cards resource — `client.cards.*`.
|
|
6
|
+
*
|
|
7
|
+
* The end-user "money OUT" surface: a user issues themselves a card backed by
|
|
8
|
+
* their wallet balance via an issuer connector. Mirrors the Takeal API's
|
|
9
|
+
* `/me/cards` routes:
|
|
10
|
+
*
|
|
11
|
+
* POST /me/cards → create
|
|
12
|
+
* GET /me/cards → list (most recent first)
|
|
13
|
+
* GET /me/cards/{id} → get
|
|
14
|
+
* GET /me/cards/{id}/balance → balance (prepaid remaining)
|
|
15
|
+
* POST /me/cards/{id}/freeze → freeze
|
|
16
|
+
* POST /me/cards/{id}/unfreeze → unfreeze
|
|
17
|
+
* POST /me/cards/{id}/terminate → terminate (one-way)
|
|
18
|
+
*
|
|
19
|
+
* The lifecycle actions are ownership-gated server-side: a caller can only
|
|
20
|
+
* freeze / unfreeze / terminate a card that belongs to them (else 404).
|
|
21
|
+
*
|
|
22
|
+
* ## What is intentionally NOT here
|
|
23
|
+
*
|
|
24
|
+
* Card-data reveal (PAN / CVV) is a separate, security-sensitive flow with its
|
|
25
|
+
* own re-auth + rate-limit + audit contract and is intentionally
|
|
26
|
+
* NOT part of this resource (tracked separately).
|
|
27
|
+
*
|
|
28
|
+
* Today only PREPAID is wired end-to-end; CREDIT and GIFT return 400 from
|
|
29
|
+
* the Takeal API until their issuer flows land.
|
|
30
|
+
*/
|
|
31
|
+
/** Card product. Only `prepaid` is fully implemented today. */
|
|
32
|
+
type CardType = "credit" | "prepaid" | "gift";
|
|
33
|
+
/**
|
|
34
|
+
* Card lifecycle state.
|
|
35
|
+
*
|
|
36
|
+
* `pending_payment` is a transient state: the row exists but the
|
|
37
|
+
* per-card issuance-fee debit has not yet succeeded; such cards have no
|
|
38
|
+
* provider reference and no user-visible side effects.
|
|
39
|
+
*/
|
|
40
|
+
type CardStatus = "pending_payment" | "active" | "frozen" | "terminated" | "redeemed" | "failed";
|
|
41
|
+
/**
|
|
42
|
+
* A card record as the Takeal API returns it. Mirrors the `cards` table. Note the
|
|
43
|
+
* SDK never receives the full PAN or CVV here — only `last4` + expiry. The
|
|
44
|
+
* gift-card `redemption_code` is returned exactly once (on create) and
|
|
45
|
+
* scrubbed from subsequent list/get responses.
|
|
46
|
+
*/
|
|
47
|
+
interface Card {
|
|
48
|
+
id: string;
|
|
49
|
+
user_id: string;
|
|
50
|
+
card_type: CardType;
|
|
51
|
+
/** Slug of the issuer that minted this card, as configured by the deployment. */
|
|
52
|
+
connector_slug: string;
|
|
53
|
+
/** The connector's own reference, populated once it responds. */
|
|
54
|
+
provider_reference: string | null;
|
|
55
|
+
status: CardStatus;
|
|
56
|
+
/** Last four digits of the PAN — safe to display. */
|
|
57
|
+
last4: string | null;
|
|
58
|
+
expiry_month: number | null;
|
|
59
|
+
expiry_year: number | null;
|
|
60
|
+
/** Gift cards only, present once on create then scrubbed. */
|
|
61
|
+
redemption_code?: string;
|
|
62
|
+
/** Decimal as a string. */
|
|
63
|
+
initial_amount: string | null;
|
|
64
|
+
currency: string;
|
|
65
|
+
failure_reason: string | null;
|
|
66
|
+
created_at: string;
|
|
67
|
+
updated_at: string;
|
|
68
|
+
}
|
|
69
|
+
interface CreateCardInput {
|
|
70
|
+
/** `prepaid` (the only fully-wired type today), `credit`, or `gift`. */
|
|
71
|
+
type: CardType;
|
|
72
|
+
/** Decimal as a string. The prepaid load amount drained from wallet balance. */
|
|
73
|
+
initial_amount?: string;
|
|
74
|
+
/** ISO 4217 code, e.g. `"USD"`. */
|
|
75
|
+
currency: string;
|
|
76
|
+
/**
|
|
77
|
+
* Optional. Slug of a specific issuer to mint with. Omit to let
|
|
78
|
+
* the Takeal API pick the first active issuer. Unknown slug → 400; empty issuer
|
|
79
|
+
* list → 503.
|
|
80
|
+
*/
|
|
81
|
+
issuer_slug?: string;
|
|
82
|
+
metadata?: Record<string, string>;
|
|
83
|
+
/** Structured billing details — real issuers require these for 3DS / KYC. */
|
|
84
|
+
customer?: CustomerInfo;
|
|
85
|
+
/**
|
|
86
|
+
* Required by the Takeal API on this write endpoint. Same key + body replays the
|
|
87
|
+
* original card; same key + different body returns 409.
|
|
88
|
+
*/
|
|
89
|
+
idempotencyKey: string;
|
|
90
|
+
}
|
|
91
|
+
/** Remaining balance of a prepaid card. */
|
|
92
|
+
interface CardBalance {
|
|
93
|
+
amount: string;
|
|
94
|
+
currency: string;
|
|
95
|
+
}
|
|
96
|
+
/** Re-auth gate for {@link CardsResource.reveal}. */
|
|
97
|
+
interface RevealCardInput {
|
|
98
|
+
/** The user's account password — mandatory re-auth. */
|
|
99
|
+
password: string;
|
|
100
|
+
/** TOTP code; required only when the user has TOTP enrolled. */
|
|
101
|
+
totpCode?: string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Full card data from a successful reveal. **Security**: never persist this —
|
|
105
|
+
* keep it in volatile memory only, clear it within `expires_in_seconds`, and
|
|
106
|
+
* never write it to localStorage / logs (the API marks the response no-store).
|
|
107
|
+
*/
|
|
108
|
+
interface RevealedCard {
|
|
109
|
+
pan: string;
|
|
110
|
+
cvv: string;
|
|
111
|
+
expiry_month: number;
|
|
112
|
+
expiry_year: number;
|
|
113
|
+
holder_name: string;
|
|
114
|
+
/** Display window before the client should auto-clear the data. */
|
|
115
|
+
expires_in_seconds: number;
|
|
116
|
+
}
|
|
117
|
+
declare class CardsResource {
|
|
118
|
+
private readonly http;
|
|
119
|
+
constructor(http: HttpClient);
|
|
120
|
+
/**
|
|
121
|
+
* Issue a card backed by the user's wallet balance. Resolves to the new
|
|
122
|
+
* `Card`. On a ledger failure after provider creation, the Takeal API rolls the row
|
|
123
|
+
* to `failed` (never an orphaned active card); inspect `status` /
|
|
124
|
+
* `failure_reason` on the result.
|
|
125
|
+
*/
|
|
126
|
+
create(input: CreateCardInput): Promise<Card>;
|
|
127
|
+
/** Fetch one card by id. */
|
|
128
|
+
get(id: string): Promise<Card>;
|
|
129
|
+
/** List the caller's cards, most recent first. */
|
|
130
|
+
list(): Promise<Card[]>;
|
|
131
|
+
/**
|
|
132
|
+
* Remaining balance of a prepaid card. `currency` is required by the Takeal API and
|
|
133
|
+
* forwarded as a query param.
|
|
134
|
+
*/
|
|
135
|
+
balance(id: string, currency: string): Promise<CardBalance>;
|
|
136
|
+
/**
|
|
137
|
+
* Freeze the caller's own card. Reversible via {@link unfreeze}. The optional
|
|
138
|
+
* `reason` is recorded on the audit trail. Resolves to the updated card.
|
|
139
|
+
* 404 if the card isn't the caller's; 501 if the issuer can't freeze.
|
|
140
|
+
*/
|
|
141
|
+
freeze(id: string, reason?: string): Promise<Card>;
|
|
142
|
+
/**
|
|
143
|
+
* Reveal the FULL PAN + CVV for the caller's own card. Re-auth gated
|
|
144
|
+
* (password, + TOTP when the user has it enrolled) and rate-limited
|
|
145
|
+
* server-side. The Takeal API never persists this data and marks the
|
|
146
|
+
* response no-store; the SDK returns it verbatim and holds nothing.
|
|
147
|
+
*
|
|
148
|
+
* **Consumer security duties** (the SDK can't enforce these for you):
|
|
149
|
+
* keep the result in volatile memory only, never write it to
|
|
150
|
+
* localStorage / logs, and clear it within `expires_in_seconds`.
|
|
151
|
+
*
|
|
152
|
+
* 401 bad re-auth · 403 not your card · 429 rate-limited · 501 connector
|
|
153
|
+
* has no sensitive-data endpoint · 503 provider error.
|
|
154
|
+
*/
|
|
155
|
+
reveal(id: string, input: RevealCardInput): Promise<RevealedCard>;
|
|
156
|
+
/** Unfreeze a previously-frozen card. Idempotent on an already-active card. */
|
|
157
|
+
unfreeze(id: string): Promise<Card>;
|
|
158
|
+
/**
|
|
159
|
+
* Terminate the caller's own card. **One-way** — a terminated card cannot be
|
|
160
|
+
* reactivated. The optional `reason` is audited. Idempotent on an
|
|
161
|
+
* already-terminated card.
|
|
162
|
+
*/
|
|
163
|
+
terminate(id: string, reason?: string): Promise<Card>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export { type Card, type CardBalance, type CardStatus, type CardType, CardsResource, type CreateCardInput, type RevealCardInput, type RevealedCard };
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { H as HttpClient } from '../http-BkZZZI8K.js';
|
|
2
|
+
import { C as CustomerInfo } from '../customer-CoxPwe5o.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Cards resource — `client.cards.*`.
|
|
6
|
+
*
|
|
7
|
+
* The end-user "money OUT" surface: a user issues themselves a card backed by
|
|
8
|
+
* their wallet balance via an issuer connector. Mirrors the Takeal API's
|
|
9
|
+
* `/me/cards` routes:
|
|
10
|
+
*
|
|
11
|
+
* POST /me/cards → create
|
|
12
|
+
* GET /me/cards → list (most recent first)
|
|
13
|
+
* GET /me/cards/{id} → get
|
|
14
|
+
* GET /me/cards/{id}/balance → balance (prepaid remaining)
|
|
15
|
+
* POST /me/cards/{id}/freeze → freeze
|
|
16
|
+
* POST /me/cards/{id}/unfreeze → unfreeze
|
|
17
|
+
* POST /me/cards/{id}/terminate → terminate (one-way)
|
|
18
|
+
*
|
|
19
|
+
* The lifecycle actions are ownership-gated server-side: a caller can only
|
|
20
|
+
* freeze / unfreeze / terminate a card that belongs to them (else 404).
|
|
21
|
+
*
|
|
22
|
+
* ## What is intentionally NOT here
|
|
23
|
+
*
|
|
24
|
+
* Card-data reveal (PAN / CVV) is a separate, security-sensitive flow with its
|
|
25
|
+
* own re-auth + rate-limit + audit contract and is intentionally
|
|
26
|
+
* NOT part of this resource (tracked separately).
|
|
27
|
+
*
|
|
28
|
+
* Today only PREPAID is wired end-to-end; CREDIT and GIFT return 400 from
|
|
29
|
+
* the Takeal API until their issuer flows land.
|
|
30
|
+
*/
|
|
31
|
+
/** Card product. Only `prepaid` is fully implemented today. */
|
|
32
|
+
type CardType = "credit" | "prepaid" | "gift";
|
|
33
|
+
/**
|
|
34
|
+
* Card lifecycle state.
|
|
35
|
+
*
|
|
36
|
+
* `pending_payment` is a transient state: the row exists but the
|
|
37
|
+
* per-card issuance-fee debit has not yet succeeded; such cards have no
|
|
38
|
+
* provider reference and no user-visible side effects.
|
|
39
|
+
*/
|
|
40
|
+
type CardStatus = "pending_payment" | "active" | "frozen" | "terminated" | "redeemed" | "failed";
|
|
41
|
+
/**
|
|
42
|
+
* A card record as the Takeal API returns it. Mirrors the `cards` table. Note the
|
|
43
|
+
* SDK never receives the full PAN or CVV here — only `last4` + expiry. The
|
|
44
|
+
* gift-card `redemption_code` is returned exactly once (on create) and
|
|
45
|
+
* scrubbed from subsequent list/get responses.
|
|
46
|
+
*/
|
|
47
|
+
interface Card {
|
|
48
|
+
id: string;
|
|
49
|
+
user_id: string;
|
|
50
|
+
card_type: CardType;
|
|
51
|
+
/** Slug of the issuer that minted this card, as configured by the deployment. */
|
|
52
|
+
connector_slug: string;
|
|
53
|
+
/** The connector's own reference, populated once it responds. */
|
|
54
|
+
provider_reference: string | null;
|
|
55
|
+
status: CardStatus;
|
|
56
|
+
/** Last four digits of the PAN — safe to display. */
|
|
57
|
+
last4: string | null;
|
|
58
|
+
expiry_month: number | null;
|
|
59
|
+
expiry_year: number | null;
|
|
60
|
+
/** Gift cards only, present once on create then scrubbed. */
|
|
61
|
+
redemption_code?: string;
|
|
62
|
+
/** Decimal as a string. */
|
|
63
|
+
initial_amount: string | null;
|
|
64
|
+
currency: string;
|
|
65
|
+
failure_reason: string | null;
|
|
66
|
+
created_at: string;
|
|
67
|
+
updated_at: string;
|
|
68
|
+
}
|
|
69
|
+
interface CreateCardInput {
|
|
70
|
+
/** `prepaid` (the only fully-wired type today), `credit`, or `gift`. */
|
|
71
|
+
type: CardType;
|
|
72
|
+
/** Decimal as a string. The prepaid load amount drained from wallet balance. */
|
|
73
|
+
initial_amount?: string;
|
|
74
|
+
/** ISO 4217 code, e.g. `"USD"`. */
|
|
75
|
+
currency: string;
|
|
76
|
+
/**
|
|
77
|
+
* Optional. Slug of a specific issuer to mint with. Omit to let
|
|
78
|
+
* the Takeal API pick the first active issuer. Unknown slug → 400; empty issuer
|
|
79
|
+
* list → 503.
|
|
80
|
+
*/
|
|
81
|
+
issuer_slug?: string;
|
|
82
|
+
metadata?: Record<string, string>;
|
|
83
|
+
/** Structured billing details — real issuers require these for 3DS / KYC. */
|
|
84
|
+
customer?: CustomerInfo;
|
|
85
|
+
/**
|
|
86
|
+
* Required by the Takeal API on this write endpoint. Same key + body replays the
|
|
87
|
+
* original card; same key + different body returns 409.
|
|
88
|
+
*/
|
|
89
|
+
idempotencyKey: string;
|
|
90
|
+
}
|
|
91
|
+
/** Remaining balance of a prepaid card. */
|
|
92
|
+
interface CardBalance {
|
|
93
|
+
amount: string;
|
|
94
|
+
currency: string;
|
|
95
|
+
}
|
|
96
|
+
/** Re-auth gate for {@link CardsResource.reveal}. */
|
|
97
|
+
interface RevealCardInput {
|
|
98
|
+
/** The user's account password — mandatory re-auth. */
|
|
99
|
+
password: string;
|
|
100
|
+
/** TOTP code; required only when the user has TOTP enrolled. */
|
|
101
|
+
totpCode?: string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Full card data from a successful reveal. **Security**: never persist this —
|
|
105
|
+
* keep it in volatile memory only, clear it within `expires_in_seconds`, and
|
|
106
|
+
* never write it to localStorage / logs (the API marks the response no-store).
|
|
107
|
+
*/
|
|
108
|
+
interface RevealedCard {
|
|
109
|
+
pan: string;
|
|
110
|
+
cvv: string;
|
|
111
|
+
expiry_month: number;
|
|
112
|
+
expiry_year: number;
|
|
113
|
+
holder_name: string;
|
|
114
|
+
/** Display window before the client should auto-clear the data. */
|
|
115
|
+
expires_in_seconds: number;
|
|
116
|
+
}
|
|
117
|
+
declare class CardsResource {
|
|
118
|
+
private readonly http;
|
|
119
|
+
constructor(http: HttpClient);
|
|
120
|
+
/**
|
|
121
|
+
* Issue a card backed by the user's wallet balance. Resolves to the new
|
|
122
|
+
* `Card`. On a ledger failure after provider creation, the Takeal API rolls the row
|
|
123
|
+
* to `failed` (never an orphaned active card); inspect `status` /
|
|
124
|
+
* `failure_reason` on the result.
|
|
125
|
+
*/
|
|
126
|
+
create(input: CreateCardInput): Promise<Card>;
|
|
127
|
+
/** Fetch one card by id. */
|
|
128
|
+
get(id: string): Promise<Card>;
|
|
129
|
+
/** List the caller's cards, most recent first. */
|
|
130
|
+
list(): Promise<Card[]>;
|
|
131
|
+
/**
|
|
132
|
+
* Remaining balance of a prepaid card. `currency` is required by the Takeal API and
|
|
133
|
+
* forwarded as a query param.
|
|
134
|
+
*/
|
|
135
|
+
balance(id: string, currency: string): Promise<CardBalance>;
|
|
136
|
+
/**
|
|
137
|
+
* Freeze the caller's own card. Reversible via {@link unfreeze}. The optional
|
|
138
|
+
* `reason` is recorded on the audit trail. Resolves to the updated card.
|
|
139
|
+
* 404 if the card isn't the caller's; 501 if the issuer can't freeze.
|
|
140
|
+
*/
|
|
141
|
+
freeze(id: string, reason?: string): Promise<Card>;
|
|
142
|
+
/**
|
|
143
|
+
* Reveal the FULL PAN + CVV for the caller's own card. Re-auth gated
|
|
144
|
+
* (password, + TOTP when the user has it enrolled) and rate-limited
|
|
145
|
+
* server-side. The Takeal API never persists this data and marks the
|
|
146
|
+
* response no-store; the SDK returns it verbatim and holds nothing.
|
|
147
|
+
*
|
|
148
|
+
* **Consumer security duties** (the SDK can't enforce these for you):
|
|
149
|
+
* keep the result in volatile memory only, never write it to
|
|
150
|
+
* localStorage / logs, and clear it within `expires_in_seconds`.
|
|
151
|
+
*
|
|
152
|
+
* 401 bad re-auth · 403 not your card · 429 rate-limited · 501 connector
|
|
153
|
+
* has no sensitive-data endpoint · 503 provider error.
|
|
154
|
+
*/
|
|
155
|
+
reveal(id: string, input: RevealCardInput): Promise<RevealedCard>;
|
|
156
|
+
/** Unfreeze a previously-frozen card. Idempotent on an already-active card. */
|
|
157
|
+
unfreeze(id: string): Promise<Card>;
|
|
158
|
+
/**
|
|
159
|
+
* Terminate the caller's own card. **One-way** — a terminated card cannot be
|
|
160
|
+
* reactivated. The optional `reason` is audited. Idempotent on an
|
|
161
|
+
* already-terminated card.
|
|
162
|
+
*/
|
|
163
|
+
terminate(id: string, reason?: string): Promise<Card>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export { type Card, type CardBalance, type CardStatus, type CardType, CardsResource, type CreateCardInput, type RevealCardInput, type RevealedCard };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// src/resources/cards.ts
|
|
2
|
+
var CardsResource = class {
|
|
3
|
+
constructor(http) {
|
|
4
|
+
this.http = http;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Issue a card backed by the user's wallet balance. Resolves to the new
|
|
8
|
+
* `Card`. On a ledger failure after provider creation, the Takeal API rolls the row
|
|
9
|
+
* to `failed` (never an orphaned active card); inspect `status` /
|
|
10
|
+
* `failure_reason` on the result.
|
|
11
|
+
*/
|
|
12
|
+
async create(input) {
|
|
13
|
+
const { idempotencyKey, ...body } = input;
|
|
14
|
+
return this.http.post("/me/cards", {
|
|
15
|
+
body,
|
|
16
|
+
idempotencyKey
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/** Fetch one card by id. */
|
|
20
|
+
async get(id) {
|
|
21
|
+
return this.http.get(`/me/cards/${encodeURIComponent(id)}`);
|
|
22
|
+
}
|
|
23
|
+
/** List the caller's cards, most recent first. */
|
|
24
|
+
async list() {
|
|
25
|
+
return this.http.get("/me/cards");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Remaining balance of a prepaid card. `currency` is required by the Takeal API and
|
|
29
|
+
* forwarded as a query param.
|
|
30
|
+
*/
|
|
31
|
+
async balance(id, currency) {
|
|
32
|
+
const q = new URLSearchParams({ currency }).toString();
|
|
33
|
+
return this.http.get(
|
|
34
|
+
`/me/cards/${encodeURIComponent(id)}/balance?${q}`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Freeze the caller's own card. Reversible via {@link unfreeze}. The optional
|
|
39
|
+
* `reason` is recorded on the audit trail. Resolves to the updated card.
|
|
40
|
+
* 404 if the card isn't the caller's; 501 if the issuer can't freeze.
|
|
41
|
+
*/
|
|
42
|
+
async freeze(id, reason) {
|
|
43
|
+
return this.http.post(
|
|
44
|
+
`/me/cards/${encodeURIComponent(id)}/freeze`,
|
|
45
|
+
{ body: { reason } }
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Reveal the FULL PAN + CVV for the caller's own card. Re-auth gated
|
|
50
|
+
* (password, + TOTP when the user has it enrolled) and rate-limited
|
|
51
|
+
* server-side. The Takeal API never persists this data and marks the
|
|
52
|
+
* response no-store; the SDK returns it verbatim and holds nothing.
|
|
53
|
+
*
|
|
54
|
+
* **Consumer security duties** (the SDK can't enforce these for you):
|
|
55
|
+
* keep the result in volatile memory only, never write it to
|
|
56
|
+
* localStorage / logs, and clear it within `expires_in_seconds`.
|
|
57
|
+
*
|
|
58
|
+
* 401 bad re-auth · 403 not your card · 429 rate-limited · 501 connector
|
|
59
|
+
* has no sensitive-data endpoint · 503 provider error.
|
|
60
|
+
*/
|
|
61
|
+
async reveal(id, input) {
|
|
62
|
+
return this.http.post(
|
|
63
|
+
`/me/cards/${encodeURIComponent(id)}/reveal`,
|
|
64
|
+
{ body: { password: input.password, totp_code: input.totpCode } }
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
/** Unfreeze a previously-frozen card. Idempotent on an already-active card. */
|
|
68
|
+
async unfreeze(id) {
|
|
69
|
+
return this.http.post(
|
|
70
|
+
`/me/cards/${encodeURIComponent(id)}/unfreeze`,
|
|
71
|
+
{ body: {} }
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Terminate the caller's own card. **One-way** — a terminated card cannot be
|
|
76
|
+
* reactivated. The optional `reason` is audited. Idempotent on an
|
|
77
|
+
* already-terminated card.
|
|
78
|
+
*/
|
|
79
|
+
async terminate(id, reason) {
|
|
80
|
+
return this.http.post(
|
|
81
|
+
`/me/cards/${encodeURIComponent(id)}/terminate`,
|
|
82
|
+
{ body: { reason } }
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export { CardsResource };
|
|
88
|
+
//# sourceMappingURL=cards.js.map
|
|
89
|
+
//# sourceMappingURL=cards.js.map
|