@rikology/adonisjs-xendit 1.0.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.
@@ -0,0 +1,81 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
12
+ //#endregion
13
+ //#region src/xendit_exception.ts
14
+ var xendit_exception_exports = /* @__PURE__ */ __exportAll({
15
+ XenditAuthenticationError: () => XenditAuthenticationError,
16
+ XenditConflictError: () => XenditConflictError,
17
+ XenditException: () => XenditException,
18
+ XenditNetworkError: () => XenditNetworkError,
19
+ XenditNotFoundError: () => XenditNotFoundError,
20
+ XenditRateLimitError: () => XenditRateLimitError,
21
+ XenditServerError: () => XenditServerError,
22
+ XenditValidationError: () => XenditValidationError
23
+ });
24
+ var XenditException = class extends Error {
25
+ /**
26
+ * HTTP status code or 0 for network errors
27
+ */
28
+ status;
29
+ /**
30
+ * Xendit error code (e.g. 'INVALID_AMOUNT', 'UNAUTHORIZED')
31
+ */
32
+ code;
33
+ /**
34
+ * The raw JSON response body from Xendit API, if available
35
+ */
36
+ rawResponse;
37
+ constructor(status, code, message, rawResponse) {
38
+ super(message);
39
+ this.name = this.constructor.name;
40
+ this.status = status;
41
+ this.code = code;
42
+ this.rawResponse = rawResponse;
43
+ }
44
+ };
45
+ var XenditValidationError = class extends XenditException {
46
+ constructor(code, message, rawResponse) {
47
+ super(400, code, message, rawResponse);
48
+ }
49
+ };
50
+ var XenditAuthenticationError = class extends XenditException {
51
+ constructor(code, message, rawResponse) {
52
+ super(401, code, message, rawResponse);
53
+ }
54
+ };
55
+ var XenditNotFoundError = class extends XenditException {
56
+ constructor(code, message, rawResponse) {
57
+ super(404, code, message, rawResponse);
58
+ }
59
+ };
60
+ var XenditConflictError = class extends XenditException {
61
+ constructor(code, message, rawResponse) {
62
+ super(409, code, message, rawResponse);
63
+ }
64
+ };
65
+ var XenditRateLimitError = class extends XenditException {
66
+ constructor(code, message, rawResponse) {
67
+ super(429, code, message, rawResponse);
68
+ }
69
+ };
70
+ var XenditServerError = class extends XenditException {
71
+ constructor(code, message, rawResponse) {
72
+ super(500, code, message, rawResponse);
73
+ }
74
+ };
75
+ var XenditNetworkError = class extends XenditException {
76
+ constructor(code, message, rawResponse) {
77
+ super(0, code, message, rawResponse);
78
+ }
79
+ };
80
+ //#endregion
81
+ export { XenditNotFoundError as a, XenditValidationError as c, XenditNetworkError as i, xendit_exception_exports as l, XenditConflictError as n, XenditRateLimitError as o, XenditException as r, XenditServerError as s, XenditAuthenticationError as t };
@@ -0,0 +1,332 @@
1
+ import { a as XenditNotFoundError, c as XenditValidationError, i as XenditNetworkError, n as XenditConflictError, o as XenditRateLimitError, s as XenditServerError, t as XenditAuthenticationError } from "./xendit_exception-kaFnYOo7.js";
2
+ import { readFileSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ import { dirname, join } from "node:path";
5
+ //#region src/http_client.ts
6
+ const LIBRARY_VERSION = (() => {
7
+ try {
8
+ return JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf8")).version;
9
+ } catch {
10
+ return "unknown";
11
+ }
12
+ })();
13
+ var XenditHttpClient = class {
14
+ #baseUrl;
15
+ #secretKey;
16
+ #timeoutMs;
17
+ constructor(options) {
18
+ this.#baseUrl = options.baseUrl.replace(/\/$/, "");
19
+ this.#secretKey = options.secretKey;
20
+ this.#timeoutMs = options.timeoutMs ?? 3e4;
21
+ }
22
+ async request(method, path, options) {
23
+ return this.#requestWithRetry(method, path, options);
24
+ }
25
+ async #requestWithRetry(method, path, options) {
26
+ const url = `${this.#baseUrl}${path}`;
27
+ const headers = new Headers({
28
+ "Authorization": this.#authHeader(),
29
+ "Content-Type": "application/json",
30
+ ...this.#addTrackingHeaders(),
31
+ ...this.#addIdempotencyHeader(options?.idempotencyKey),
32
+ ...options?.headers
33
+ });
34
+ const body = options?.body ? JSON.stringify(options.body) : void 0;
35
+ const controller = new AbortController();
36
+ const timeoutId = setTimeout(() => controller.abort(), this.#timeoutMs);
37
+ try {
38
+ const response = await fetch(url, {
39
+ method,
40
+ headers,
41
+ body,
42
+ signal: controller.signal
43
+ });
44
+ clearTimeout(timeoutId);
45
+ if (!response.ok) {
46
+ const errorBody = await this.#safeParseJson(response);
47
+ throw this.#mapError(response.status, errorBody);
48
+ }
49
+ return await this.#safeParseJson(response);
50
+ } catch (error) {
51
+ clearTimeout(timeoutId);
52
+ if (error instanceof Error && error.name === "AbortError") throw new XenditNetworkError("TIMEOUT", `Request timed out after ${this.#timeoutMs}ms`);
53
+ if (error instanceof XenditValidationError || error instanceof XenditAuthenticationError || error instanceof XenditNotFoundError || error instanceof XenditConflictError || error instanceof XenditRateLimitError || error instanceof XenditServerError) throw error;
54
+ throw new XenditNetworkError("NETWORK_ERROR", error instanceof Error ? error.message : "Network request failed");
55
+ }
56
+ }
57
+ #authHeader() {
58
+ return `Basic ${Buffer.from(`${this.#secretKey}:`).toString("base64")}`;
59
+ }
60
+ #addTrackingHeaders() {
61
+ return {
62
+ "xendit-lib": "adonisjs",
63
+ "xendit-lib-ver": LIBRARY_VERSION
64
+ };
65
+ }
66
+ #addIdempotencyHeader(idempotencyKey) {
67
+ if (!idempotencyKey) return {};
68
+ return { "idempotency-key": idempotencyKey };
69
+ }
70
+ #mapError(status, body) {
71
+ const code = body?.error_code ?? "UNKNOWN_ERROR";
72
+ const message = body?.message ?? "An error occurred";
73
+ switch (status) {
74
+ case 400: return new XenditValidationError(code, message, body ?? void 0);
75
+ case 401: return new XenditAuthenticationError(code, message, body ?? void 0);
76
+ case 404: return new XenditNotFoundError(code, message, body ?? void 0);
77
+ case 409: return new XenditConflictError(code, message, body ?? void 0);
78
+ case 429: return new XenditRateLimitError(code, message, body ?? void 0);
79
+ default: return new XenditServerError(code, message, body ?? void 0);
80
+ }
81
+ }
82
+ async #safeParseJson(response) {
83
+ if (!(response.headers.get("content-type") ?? "").includes("application/json")) return null;
84
+ try {
85
+ return await response.json();
86
+ } catch {
87
+ return null;
88
+ }
89
+ }
90
+ };
91
+ //#endregion
92
+ //#region src/clients/balance_client.ts
93
+ var BalanceClient = class {
94
+ #http;
95
+ constructor(http) {
96
+ this.#http = http;
97
+ }
98
+ get() {
99
+ return this.#http.request("GET", "/balance");
100
+ }
101
+ getByAccountType(accountType) {
102
+ return this.#http.request("GET", `/balance?account_type=${accountType}`);
103
+ }
104
+ };
105
+ //#endregion
106
+ //#region src/clients/credit_card_client.ts
107
+ var CreditCardClient = class {
108
+ #http;
109
+ constructor(http) {
110
+ this.#http = http;
111
+ }
112
+ async createAuthorization(data) {
113
+ return this.#http.request("POST", "/credit_card_charges/auth", { body: data });
114
+ }
115
+ async createCharge(data) {
116
+ return this.#http.request("POST", "/credit_card_charges", { body: data });
117
+ }
118
+ async createRefund(chargeId, data) {
119
+ return this.#http.request("POST", `/credit_card_charges/${chargeId}/refunds`, { body: data });
120
+ }
121
+ async getCharge(chargeId) {
122
+ return this.#http.request("GET", `/credit_card_charges/${chargeId}`);
123
+ }
124
+ };
125
+ //#endregion
126
+ //#region src/clients/direct_debit_client.ts
127
+ var DirectDebitClient = class {
128
+ #http;
129
+ constructor(http) {
130
+ this.#http = http;
131
+ }
132
+ createPaymentMethod(data) {
133
+ return this.#http.request("POST", "/direct_debit/payment_methods", { body: data });
134
+ }
135
+ validateOTP(paymentMethodId, data) {
136
+ return this.#http.request("POST", `/direct_debit/payment_methods/${paymentMethodId}/validate`, { body: data });
137
+ }
138
+ createPayment(data) {
139
+ return this.#http.request("POST", "/direct_debit/payments", { body: data });
140
+ }
141
+ getPayment(paymentId) {
142
+ return this.#http.request("GET", `/direct_debit/payments/${paymentId}`);
143
+ }
144
+ };
145
+ //#endregion
146
+ //#region src/clients/disbursement_client.ts
147
+ var DisbursementClient = class {
148
+ #http;
149
+ constructor(http) {
150
+ this.#http = http;
151
+ }
152
+ create(data, options) {
153
+ return this.#http.request("POST", "/disbursements", {
154
+ body: data,
155
+ idempotencyKey: options?.idempotencyKey
156
+ });
157
+ }
158
+ getById(disbursementId) {
159
+ return this.#http.request("GET", `/disbursements/${disbursementId}`);
160
+ }
161
+ createBatch(data, options) {
162
+ return this.#http.request("POST", "/batch_disbursements", {
163
+ body: data,
164
+ idempotencyKey: options?.idempotencyKey
165
+ });
166
+ }
167
+ getAvailableBanks() {
168
+ return this.#http.request("GET", "/available_disbursements_banks");
169
+ }
170
+ };
171
+ //#endregion
172
+ //#region src/clients/ewallet_client.ts
173
+ var EWalletClient = class {
174
+ #http;
175
+ constructor(http) {
176
+ this.#http = http;
177
+ }
178
+ createOvo(data) {
179
+ return this.#createCharge(data, "ID_OVO");
180
+ }
181
+ createDana(data) {
182
+ return this.#createCharge(data, "ID_DANA");
183
+ }
184
+ createLinkAja(data) {
185
+ return this.#createCharge(data, "ID_LINKAJA");
186
+ }
187
+ createShopeepay(data) {
188
+ return this.#createCharge(data, "ID_SHOPEEPAY");
189
+ }
190
+ getStatus(chargeId) {
191
+ return this.#http.request("GET", `/ewallets/charges/${chargeId}`);
192
+ }
193
+ #createCharge(data, channelCode) {
194
+ return this.#http.request("POST", "/ewallets/charges", { body: {
195
+ ...data,
196
+ channel_code: channelCode
197
+ } });
198
+ }
199
+ };
200
+ //#endregion
201
+ //#region src/clients/invoice_client.ts
202
+ var InvoiceClient = class {
203
+ #http;
204
+ constructor(http) {
205
+ this.#http = http;
206
+ }
207
+ create(data, options) {
208
+ return this.#http.request("POST", "/v2/invoices", {
209
+ body: data,
210
+ idempotencyKey: options?.idempotencyKey
211
+ });
212
+ }
213
+ getById(invoiceId) {
214
+ return this.#http.request("GET", `/v2/invoices/${invoiceId}`);
215
+ }
216
+ list(params) {
217
+ const searchParams = new URLSearchParams();
218
+ if (params) {
219
+ for (const [key, value] of Object.entries(params)) if (value !== void 0 && value !== null) searchParams.append(key, String(value));
220
+ }
221
+ const query = searchParams.toString();
222
+ const path = query ? `/v2/invoices?${query}` : "/v2/invoices";
223
+ return this.#http.request("GET", path);
224
+ }
225
+ expire(invoiceId) {
226
+ return this.#http.request("POST", `/invoices/${invoiceId}/expire!`);
227
+ }
228
+ };
229
+ //#endregion
230
+ //#region src/clients/qris_client.ts
231
+ var QrisClient = class {
232
+ #http;
233
+ constructor(http) {
234
+ this.#http = http;
235
+ }
236
+ create(data) {
237
+ return this.#http.request("POST", "/qr_codes", { body: data });
238
+ }
239
+ getById(qrId) {
240
+ return this.#http.request("GET", `/qr_codes/${qrId}`);
241
+ }
242
+ simulate(qrId, data) {
243
+ return this.#http.request("POST", `/qr_codes/${qrId}/payments/simulate`, { body: data });
244
+ }
245
+ };
246
+ //#endregion
247
+ //#region src/clients/retail_outlet_client.ts
248
+ var RetailOutletClient = class {
249
+ constructor(http) {
250
+ this.http = http;
251
+ }
252
+ create(data) {
253
+ return this.http.request("POST", "/fixed_payment_code", { body: data });
254
+ }
255
+ getById(paymentId) {
256
+ return this.http.request("GET", `/fixed_payment_code/${paymentId}`);
257
+ }
258
+ update(paymentId, data) {
259
+ return this.http.request("PATCH", `/fixed_payment_code/${paymentId}`, { body: data });
260
+ }
261
+ };
262
+ //#endregion
263
+ //#region src/clients/va_client.ts
264
+ var VirtualAccountClient = class {
265
+ #http;
266
+ constructor(http) {
267
+ this.#http = http;
268
+ }
269
+ create(data) {
270
+ return this.#http.request("POST", "/callback_virtual_accounts", { body: data });
271
+ }
272
+ getById(vaId) {
273
+ return this.#http.request("GET", `/callback_virtual_accounts/${vaId}`);
274
+ }
275
+ update(vaId, data) {
276
+ return this.#http.request("PATCH", `/callback_virtual_accounts/${vaId}`, { body: data });
277
+ }
278
+ getPayment(vaId) {
279
+ return this.#http.request("GET", `/callback_virtual_accounts/${vaId}/payments`);
280
+ }
281
+ };
282
+ //#endregion
283
+ //#region src/xendit_manager.ts
284
+ const BASE_URLS = {
285
+ sandbox: "https://sandbox-api.xendit.co",
286
+ production: "https://api.xendit.co"
287
+ };
288
+ var XenditManager = class {
289
+ #http;
290
+ #clients = /* @__PURE__ */ new Map();
291
+ constructor(config) {
292
+ const baseUrl = BASE_URLS[config.environment];
293
+ this.#http = new XenditHttpClient({
294
+ baseUrl,
295
+ secretKey: config.secretKey,
296
+ timeoutMs: config.timeoutMs
297
+ });
298
+ }
299
+ invoice() {
300
+ return this.#cached("invoice", () => new InvoiceClient(this.#http));
301
+ }
302
+ va() {
303
+ return this.#cached("va", () => new VirtualAccountClient(this.#http));
304
+ }
305
+ ewallet() {
306
+ return this.#cached("ewallet", () => new EWalletClient(this.#http));
307
+ }
308
+ qris() {
309
+ return this.#cached("qris", () => new QrisClient(this.#http));
310
+ }
311
+ retailOutlet() {
312
+ return this.#cached("retailOutlet", () => new RetailOutletClient(this.#http));
313
+ }
314
+ creditCard() {
315
+ return this.#cached("creditCard", () => new CreditCardClient(this.#http));
316
+ }
317
+ directDebit() {
318
+ return this.#cached("directDebit", () => new DirectDebitClient(this.#http));
319
+ }
320
+ disbursement() {
321
+ return this.#cached("disbursement", () => new DisbursementClient(this.#http));
322
+ }
323
+ balance() {
324
+ return this.#cached("balance", () => new BalanceClient(this.#http));
325
+ }
326
+ #cached(key, factory) {
327
+ if (!this.#clients.has(key)) this.#clients.set(key, factory());
328
+ return this.#clients.get(key);
329
+ }
330
+ };
331
+ //#endregion
332
+ export { InvoiceClient as a, DirectDebitClient as c, QrisClient as i, CreditCardClient as l, VirtualAccountClient as n, EWalletClient as o, RetailOutletClient as r, DisbursementClient as s, XenditManager as t, BalanceClient as u };
package/package.json ADDED
@@ -0,0 +1,188 @@
1
+ {
2
+ "name": "@rikology/adonisjs-xendit",
3
+ "description": "AdonisJS v7 package for Xendit payment gateway integration",
4
+ "version": "1.0.0",
5
+ "engines": {
6
+ "node": ">=20.0.0"
7
+ },
8
+ "type": "module",
9
+ "files": [
10
+ "build",
11
+ "!build/bin",
12
+ "!build/tests",
13
+ "!build/**/*.map",
14
+ "LICENSE.md",
15
+ "README.md",
16
+ "CHANGELOG.md"
17
+ ],
18
+ "main": "build/index.js",
19
+ "module": "build/index.js",
20
+ "types": "build/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./build/index.d.ts",
24
+ "default": "./build/index.js"
25
+ },
26
+ "./types": {
27
+ "types": "./build/src/types.d.ts",
28
+ "default": "./build/src/types.js"
29
+ },
30
+ "./xendit_provider": {
31
+ "types": "./build/providers/xendit_provider.d.ts",
32
+ "default": "./build/providers/xendit_provider.js"
33
+ },
34
+ "./errors": {
35
+ "types": "./build/src/xendit_exception.d.ts",
36
+ "default": "./build/src/xendit_exception.js"
37
+ }
38
+ },
39
+ "scripts": {
40
+ "copy:templates": "copyfiles \"stubs/**/*.stub\" build",
41
+ "typecheck": "tsc --noEmit",
42
+ "lint": "eslint .",
43
+ "lint:fix": "eslint . --fix",
44
+ "format": "prettier --write .",
45
+ "format:check": "prettier --check .",
46
+ "quick:test": "node --import=@poppinss/ts-exec --enable-source-maps bin/test.ts",
47
+ "pretest": "npm run build",
48
+ "test": "c8 npm run quick:test",
49
+ "test:quick": "npm run quick:test",
50
+ "precompile": "npm run lint",
51
+ "compile": "tsdown && tsc --emitDeclarationOnly --declaration",
52
+ "postcompile": "npm run copy:templates",
53
+ "build": "npm run compile",
54
+ "clean": "rm -rf build coverage",
55
+ "release": "release-it",
56
+ "release:preview": "release-it --dry-run",
57
+ "version": "npm run build",
58
+ "prepublishOnly": "npm run build && npm run test"
59
+ },
60
+ "repository": {
61
+ "type": "git",
62
+ "url": "git+https://github.com/rikoriswandha/adonisjs-xendit.git"
63
+ },
64
+ "homepage": "https://github.com/rikoriswandha/adonisjs-xendit#readme",
65
+ "bugs": {
66
+ "url": "https://github.com/rikoriswandha/adonisjs-xendit/issues"
67
+ },
68
+ "keywords": [
69
+ "adonisjs",
70
+ "adonis",
71
+ "xendit",
72
+ "payment",
73
+ "payment-gateway",
74
+ "fintech",
75
+ "indonesia",
76
+ "virtual-account",
77
+ "ewallet",
78
+ "qris",
79
+ "invoice",
80
+ "disbursement",
81
+ "credit-card",
82
+ "direct-debit",
83
+ "payment-provider",
84
+ "typescript"
85
+ ],
86
+ "author": "Riko Riswandha <rikoriswandha@gmail.com>",
87
+ "license": "MIT",
88
+ "funding": {
89
+ "type": "github",
90
+ "url": "https://github.com/sponsors/rikoriswandha"
91
+ },
92
+ "devDependencies": {
93
+ "@adonisjs/assembler": "^8.0.0",
94
+ "@adonisjs/core": "^7.0.1",
95
+ "@adonisjs/eslint-config": "^3.0.0",
96
+ "@adonisjs/prettier-config": "^1.4.5",
97
+ "@adonisjs/tsconfig": "^2.0.0",
98
+ "@japa/assert": "^4.2.0",
99
+ "@japa/file-system": "^3.0.0",
100
+ "@japa/runner": "^5.3.0",
101
+ "@poppinss/ts-exec": "^1.4.4",
102
+ "@release-it/conventional-changelog": "^10.0.5",
103
+ "@types/node": "^22.0.0",
104
+ "c8": "^11.0.0",
105
+ "copyfiles": "^2.4.1",
106
+ "cross-env": "^10.1.0",
107
+ "eslint": "^10.0.3",
108
+ "prettier": "^3.8.1",
109
+ "release-it": "^19.2.4",
110
+ "tsdown": "^0.21.0",
111
+ "typescript": "^5.9.3"
112
+ },
113
+ "peerDependencies": {
114
+ "@adonisjs/assembler": "^8.0.0",
115
+ "@adonisjs/core": "^7.0.0"
116
+ },
117
+ "peerDependenciesMeta": {
118
+ "@adonisjs/assembler": {
119
+ "optional": true
120
+ }
121
+ },
122
+ "publishConfig": {
123
+ "access": "public",
124
+ "provenance": true,
125
+ "registry": "https://registry.npmjs.org/"
126
+ },
127
+ "tsdown": {
128
+ "entry": [
129
+ "./index.ts",
130
+ "./configure.ts",
131
+ "./providers/xendit_provider.ts",
132
+ "./src/types.ts",
133
+ "./src/xendit_exception.ts"
134
+ ],
135
+ "outDir": "./build",
136
+ "clean": true,
137
+ "format": "esm",
138
+ "minify": "dce-only",
139
+ "fixedExtension": false,
140
+ "dts": false,
141
+ "treeshake": false,
142
+ "sourcemaps": true,
143
+ "target": "esnext"
144
+ },
145
+ "release-it": {
146
+ "git": {
147
+ "requireCleanWorkingDir": true,
148
+ "requireUpstream": true,
149
+ "commitMessage": "chore(release): ${version}",
150
+ "tagAnnotation": "v${version}",
151
+ "push": true,
152
+ "tagName": "v${version}"
153
+ },
154
+ "github": {
155
+ "release": true
156
+ },
157
+ "npm": {
158
+ "publish": true,
159
+ "skipChecks": false
160
+ },
161
+ "plugins": {
162
+ "@release-it/conventional-changelog": {
163
+ "preset": {
164
+ "name": "angular"
165
+ }
166
+ }
167
+ }
168
+ },
169
+ "c8": {
170
+ "reporter": [
171
+ "text",
172
+ "html",
173
+ "lcov"
174
+ ],
175
+ "exclude": [
176
+ "tests/**",
177
+ "bin/**",
178
+ "build/**",
179
+ "coverage/**",
180
+ "stubs/**"
181
+ ],
182
+ "lines": 80,
183
+ "functions": 80,
184
+ "branches": 70,
185
+ "statements": 80
186
+ },
187
+ "prettier": "@adonisjs/prettier-config"
188
+ }