liqpay-mcp-server 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.
- package/LICENSE +21 -0
- package/README.md +189 -0
- package/dist/auth.d.ts +3 -0
- package/dist/auth.js +13 -0
- package/dist/auth.js.map +1 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.js +44 -0
- package/dist/client.js.map +1 -0
- package/dist/constants.d.ts +22 -0
- package/dist/constants.js +30 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js +41 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/holds.d.ts +3 -0
- package/dist/tools/holds.js +147 -0
- package/dist/tools/holds.js.map +1 -0
- package/dist/tools/payments.d.ts +3 -0
- package/dist/tools/payments.js +98 -0
- package/dist/tools/payments.js.map +1 -0
- package/dist/tools/payouts.d.ts +3 -0
- package/dist/tools/payouts.js +57 -0
- package/dist/tools/payouts.js.map +1 -0
- package/dist/tools/refunds.d.ts +3 -0
- package/dist/tools/refunds.js +48 -0
- package/dist/tools/refunds.js.map +1 -0
- package/dist/tools/reports.d.ts +3 -0
- package/dist/tools/reports.js +58 -0
- package/dist/tools/reports.js.map +1 -0
- package/dist/tools/subscriptions.d.ts +3 -0
- package/dist/tools/subscriptions.js +84 -0
- package/dist/tools/subscriptions.js.map +1 -0
- package/dist/tools/webhooks.d.ts +2 -0
- package/dist/tools/webhooks.js +45 -0
- package/dist/tools/webhooks.js.map +1 -0
- package/dist/types.d.ts +91 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerPaymentTools(server, client) {
|
|
3
|
+
server.registerTool("liqpay_create_checkout_url", {
|
|
4
|
+
title: "Create LiqPay Checkout URL",
|
|
5
|
+
description: "Generate a hosted checkout URL for a LiqPay payment (PCI DSS safe). " +
|
|
6
|
+
"Use when initiating a payment without handling card data directly. " +
|
|
7
|
+
"Do not use for server-to-server card charges — use liqpay_create_hold instead. " +
|
|
8
|
+
"Returns { checkout_url: string }.",
|
|
9
|
+
inputSchema: {
|
|
10
|
+
amount: z.number().positive().describe("Payment amount in currency units (e.g. 99.99 for ₴99.99)"),
|
|
11
|
+
currency: z.enum(["UAH", "USD", "EUR"]).describe("ISO 4217 currency code"),
|
|
12
|
+
description: z.string().min(1).max(500).describe("Payment description shown to payer (max 500 chars, e.g. 'Order #42 — iPhone case')"),
|
|
13
|
+
order_id: z.string().min(1).describe("Unique order ID in your system (e.g. 'order-2026-001')"),
|
|
14
|
+
result_url: z.string().url().optional().describe("Redirect URL after payment completion"),
|
|
15
|
+
server_url: z.string().url().optional().describe("Webhook URL for server-to-server notification"),
|
|
16
|
+
language: z.enum(["uk", "en"]).default("uk").describe("Payment page language"),
|
|
17
|
+
},
|
|
18
|
+
outputSchema: {
|
|
19
|
+
checkout_url: z.string().describe("Direct link to LiqPay hosted payment page"),
|
|
20
|
+
},
|
|
21
|
+
annotations: {
|
|
22
|
+
readOnlyHint: false,
|
|
23
|
+
destructiveHint: false,
|
|
24
|
+
idempotentHint: true,
|
|
25
|
+
openWorldHint: true,
|
|
26
|
+
},
|
|
27
|
+
}, async ({ amount, currency, description, order_id, result_url, server_url, language }) => {
|
|
28
|
+
const params = {
|
|
29
|
+
action: "pay",
|
|
30
|
+
amount,
|
|
31
|
+
currency,
|
|
32
|
+
description,
|
|
33
|
+
order_id,
|
|
34
|
+
language,
|
|
35
|
+
};
|
|
36
|
+
if (result_url)
|
|
37
|
+
params["result_url"] = result_url;
|
|
38
|
+
if (server_url)
|
|
39
|
+
params["server_url"] = server_url;
|
|
40
|
+
const checkout_url = client.buildCheckoutUrl(params);
|
|
41
|
+
const output = { checkout_url };
|
|
42
|
+
return {
|
|
43
|
+
content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
|
|
44
|
+
structuredContent: output,
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
server.registerTool("liqpay_get_payment_status", {
|
|
48
|
+
title: "Get LiqPay Payment Status",
|
|
49
|
+
description: "Fetch the current status of a payment by order ID (action: status). " +
|
|
50
|
+
"Use when checking whether a payment succeeded, failed, or is still pending. " +
|
|
51
|
+
"Do not use to list multiple payments — use liqpay_get_payments_list instead. " +
|
|
52
|
+
"Returns { status, payment_id, amount, currency, description, create_date, end_date, transaction_id }.",
|
|
53
|
+
inputSchema: {
|
|
54
|
+
order_id: z.string().min(1).describe("Order ID used when creating the payment (e.g. 'order-2026-001')"),
|
|
55
|
+
},
|
|
56
|
+
outputSchema: {
|
|
57
|
+
status: z.string().describe("Payment status (e.g. success, failure, processing)"),
|
|
58
|
+
payment_id: z.number().describe("LiqPay internal payment ID"),
|
|
59
|
+
amount: z.number().describe("Payment amount"),
|
|
60
|
+
currency: z.string().describe("ISO 4217 currency code"),
|
|
61
|
+
description: z.string().optional().describe("Payment description"),
|
|
62
|
+
create_date: z.number().optional().describe("Payment creation timestamp (ms)"),
|
|
63
|
+
end_date: z.number().optional().describe("Payment completion timestamp (ms)"),
|
|
64
|
+
transaction_id: z.number().optional().describe("Bank transaction ID"),
|
|
65
|
+
},
|
|
66
|
+
annotations: {
|
|
67
|
+
readOnlyHint: true,
|
|
68
|
+
destructiveHint: false,
|
|
69
|
+
idempotentHint: true,
|
|
70
|
+
openWorldHint: true,
|
|
71
|
+
},
|
|
72
|
+
}, async ({ order_id }) => {
|
|
73
|
+
try {
|
|
74
|
+
const result = await client.request({ action: "status", order_id });
|
|
75
|
+
const output = {
|
|
76
|
+
status: result.status,
|
|
77
|
+
payment_id: result.payment_id,
|
|
78
|
+
amount: result.amount,
|
|
79
|
+
currency: result.currency,
|
|
80
|
+
description: result.description,
|
|
81
|
+
create_date: result.create_date,
|
|
82
|
+
end_date: result.end_date,
|
|
83
|
+
transaction_id: result.transaction_id,
|
|
84
|
+
};
|
|
85
|
+
return {
|
|
86
|
+
content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
|
|
87
|
+
structuredContent: output,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
return {
|
|
92
|
+
content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
|
|
93
|
+
isError: true,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=payments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payments.js","sourceRoot":"","sources":["../../src/tools/payments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerPayoutTools(server, client) {
|
|
3
|
+
server.registerTool("liqpay_create_payout", {
|
|
4
|
+
title: "Create LiqPay Payout",
|
|
5
|
+
description: "Send money directly to a card — P2P transfer (action: p2p). " +
|
|
6
|
+
"Use when the merchant needs to pay out funds to a recipient's card. " +
|
|
7
|
+
"Do not use without payout feature enabled on the merchant account. " +
|
|
8
|
+
"Returns { payment_id, status, amount, currency }.",
|
|
9
|
+
inputSchema: {
|
|
10
|
+
amount: z.number().positive().describe("Payout amount in currency units (e.g. 500.00)"),
|
|
11
|
+
currency: z.enum(["UAH", "USD", "EUR"]).describe("ISO 4217 currency code"),
|
|
12
|
+
description: z.string().min(1).max(500).describe("Purpose of payout (e.g. 'Salary payout — May 2026')"),
|
|
13
|
+
order_id: z.string().min(1).describe("Unique payout ID (e.g. 'payout-2026-001')"),
|
|
14
|
+
card: z.string().regex(/^\d{16}$/).describe("Recipient card number — exactly 16 digits (e.g. '5168742060221193')"),
|
|
15
|
+
},
|
|
16
|
+
outputSchema: {
|
|
17
|
+
payment_id: z.number().describe("LiqPay internal payment ID"),
|
|
18
|
+
status: z.string().describe("Payout status (e.g. success, processing)"),
|
|
19
|
+
amount: z.number().describe("Payout amount"),
|
|
20
|
+
currency: z.string().describe("ISO 4217 currency code"),
|
|
21
|
+
},
|
|
22
|
+
annotations: {
|
|
23
|
+
readOnlyHint: false,
|
|
24
|
+
destructiveHint: true,
|
|
25
|
+
idempotentHint: false,
|
|
26
|
+
openWorldHint: true,
|
|
27
|
+
},
|
|
28
|
+
}, async ({ amount, currency, description, order_id, card }) => {
|
|
29
|
+
try {
|
|
30
|
+
const result = await client.request({
|
|
31
|
+
action: "p2p",
|
|
32
|
+
amount,
|
|
33
|
+
currency,
|
|
34
|
+
description,
|
|
35
|
+
order_id,
|
|
36
|
+
card,
|
|
37
|
+
});
|
|
38
|
+
const output = {
|
|
39
|
+
payment_id: result.payment_id,
|
|
40
|
+
status: result.status,
|
|
41
|
+
amount: result.amount,
|
|
42
|
+
currency: result.currency,
|
|
43
|
+
};
|
|
44
|
+
return {
|
|
45
|
+
content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
|
|
46
|
+
structuredContent: output,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
return {
|
|
51
|
+
content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
|
|
52
|
+
isError: true,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=payouts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payouts.js","sourceRoot":"","sources":["../../src/tools/payouts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,MAAoB;IACzE,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,8DAA8D;YAC9D,sEAAsE;YACtE,qEAAqE;YACrE,mDAAmD;QACrD,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;YACvF,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YAC1E,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,qDAAqD,CAAC;YACvG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,2CAA2C,CAAC;YACjF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,qEAAqE,CAAC;SACnH;QACD,YAAY,EAAE;YACZ,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YAC7D,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;YACvE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;YAC5C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SACxD;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE;QAC1D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAiB;gBAClD,MAAM,EAAE,KAAK;gBACb,MAAM;gBACN,QAAQ;gBACR,WAAW;gBACX,QAAQ;gBACR,IAAI;aACL,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG;gBACb,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;gBAC3E,iBAAiB,EAAE,MAAM;aAC1B,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClG,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerRefundTools(server, client) {
|
|
3
|
+
server.registerTool("liqpay_create_refund", {
|
|
4
|
+
title: "Create LiqPay Refund",
|
|
5
|
+
description: "Refund a completed payment — full or partial (action: refund). " +
|
|
6
|
+
"Use when a customer requests a return or when a charge was made in error. " +
|
|
7
|
+
"Do not use on holds — cancel the hold with liqpay_cancel_hold instead. " +
|
|
8
|
+
"Returns { payment_id, status, amount }.",
|
|
9
|
+
inputSchema: {
|
|
10
|
+
order_id: z.string().min(1).describe("Order ID of the original payment to refund (e.g. 'order-2026-001')"),
|
|
11
|
+
amount: z.number().positive().optional().describe("Amount to refund in currency units (e.g. 50.00); omit for full refund"),
|
|
12
|
+
},
|
|
13
|
+
outputSchema: {
|
|
14
|
+
payment_id: z.number().describe("LiqPay internal payment ID"),
|
|
15
|
+
status: z.string().describe("Refund status (e.g. reversed, processing)"),
|
|
16
|
+
amount: z.number().optional().describe("Refunded amount"),
|
|
17
|
+
},
|
|
18
|
+
annotations: {
|
|
19
|
+
readOnlyHint: false,
|
|
20
|
+
destructiveHint: true,
|
|
21
|
+
idempotentHint: false,
|
|
22
|
+
openWorldHint: true,
|
|
23
|
+
},
|
|
24
|
+
}, async ({ order_id, amount }) => {
|
|
25
|
+
try {
|
|
26
|
+
const params = { action: "refund", order_id };
|
|
27
|
+
if (amount !== undefined)
|
|
28
|
+
params["amount"] = amount;
|
|
29
|
+
const result = await client.request(params);
|
|
30
|
+
const output = {
|
|
31
|
+
payment_id: result.payment_id,
|
|
32
|
+
status: result.status,
|
|
33
|
+
amount: result.amount,
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
|
|
37
|
+
structuredContent: output,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
return {
|
|
42
|
+
content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
|
|
43
|
+
isError: true,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=refunds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refunds.js","sourceRoot":"","sources":["../../src/tools/refunds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,MAAoB;IACzE,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,iEAAiE;YACjE,4EAA4E;YAC5E,yEAAyE;YACzE,yCAAyC;QAC3C,WAAW,EAAE;YACX,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oEAAoE,CAAC;YAC1G,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uEAAuE,CAAC;SAC3H;QACD,YAAY,EAAE;YACZ,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YAC7D,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;YACxE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;SAC1D;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE;QAC7B,IAAI,CAAC;YACH,MAAM,MAAM,GAA4B,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;YACvE,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;YAEpD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAiB,MAAM,CAAC,CAAC;YAE5D,MAAM,MAAM,GAAG;gBACb,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;gBAC3E,iBAAiB,EAAE,MAAM;aAC1B,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClG,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CHARACTER_LIMIT } from "../constants.js";
|
|
3
|
+
export function registerReportTools(server, client) {
|
|
4
|
+
server.registerTool("liqpay_get_payments_list", {
|
|
5
|
+
title: "Get LiqPay Payments List",
|
|
6
|
+
description: "Retrieve a list of payments filtered by date range (action: reports). " +
|
|
7
|
+
"Use when reviewing transaction history for a specific period (max 31 days). " +
|
|
8
|
+
"Do not use for a single payment — use liqpay_get_payment_status instead. " +
|
|
9
|
+
"Returns { count, data: Payment[] }.",
|
|
10
|
+
inputSchema: {
|
|
11
|
+
date_from: z.number().int().positive().describe("Start of date range as Unix timestamp in ms (e.g. 1716768000000)"),
|
|
12
|
+
date_to: z.number().int().positive().describe("End of date range as Unix timestamp in ms (max 31 days from date_from)"),
|
|
13
|
+
status: z.string().optional().describe("Filter by payment status (e.g. 'success', 'failure', 'reversed')"),
|
|
14
|
+
},
|
|
15
|
+
outputSchema: {
|
|
16
|
+
count: z.number().describe("Total number of payments in the result"),
|
|
17
|
+
data: z.array(z.record(z.unknown())).describe("Array of payment records"),
|
|
18
|
+
},
|
|
19
|
+
annotations: {
|
|
20
|
+
readOnlyHint: true,
|
|
21
|
+
destructiveHint: false,
|
|
22
|
+
idempotentHint: true,
|
|
23
|
+
openWorldHint: true,
|
|
24
|
+
},
|
|
25
|
+
}, async ({ date_from, date_to, status }) => {
|
|
26
|
+
try {
|
|
27
|
+
const params = { action: "reports", date_from, date_to };
|
|
28
|
+
if (status)
|
|
29
|
+
params["status"] = status;
|
|
30
|
+
const result = await client.request(params);
|
|
31
|
+
const output = {
|
|
32
|
+
count: result.count ?? result.data?.length ?? 0,
|
|
33
|
+
data: result.data ?? [],
|
|
34
|
+
};
|
|
35
|
+
let text = JSON.stringify(output, null, 2);
|
|
36
|
+
if (text.length > CHARACTER_LIMIT) {
|
|
37
|
+
const truncated = output.data.slice(0, Math.ceil(output.data.length / 2));
|
|
38
|
+
const truncatedOutput = { count: output.count, data: truncated, truncated: true, truncation_message: `Response truncated from ${output.data.length} to ${truncated.length} records. Narrow the date range or add a status filter.` };
|
|
39
|
+
text = JSON.stringify(truncatedOutput, null, 2);
|
|
40
|
+
return {
|
|
41
|
+
content: [{ type: "text", text }],
|
|
42
|
+
structuredContent: truncatedOutput,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
content: [{ type: "text", text }],
|
|
47
|
+
structuredContent: output,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
return {
|
|
52
|
+
content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
|
|
53
|
+
isError: true,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=reports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reports.js","sourceRoot":"","sources":["../../src/tools/reports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerSubscriptionTools(server, client) {
|
|
3
|
+
server.registerTool("liqpay_create_subscription", {
|
|
4
|
+
title: "Create LiqPay Subscription",
|
|
5
|
+
description: "Create a recurring payment subscription via hosted checkout page (action: subscribe). " +
|
|
6
|
+
"Use when setting up periodic charges (daily, weekly, monthly, yearly). " +
|
|
7
|
+
"Do not use for one-time payments — use liqpay_create_checkout_url instead. " +
|
|
8
|
+
"Returns { checkout_url: string }.",
|
|
9
|
+
inputSchema: {
|
|
10
|
+
amount: z.number().positive().describe("Amount per billing cycle in currency units (e.g. 299.00)"),
|
|
11
|
+
currency: z.enum(["UAH", "USD", "EUR"]).describe("ISO 4217 currency code"),
|
|
12
|
+
description: z.string().min(1).max(500).describe("Subscription description (max 500 chars, e.g. 'Monthly Pro plan')"),
|
|
13
|
+
order_id: z.string().min(1).describe("Unique subscription ID (e.g. 'sub-2026-001')"),
|
|
14
|
+
subscribe_date_start: z.string().regex(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/).describe("First charge date in 'YYYY-MM-DD HH:mm:ss' format (e.g. '2026-06-01 00:00:00')"),
|
|
15
|
+
subscribe_periodicity: z.enum(["day", "week", "month", "year"]).describe("Billing cycle interval"),
|
|
16
|
+
result_url: z.string().url().optional().describe("Redirect URL after subscription setup"),
|
|
17
|
+
server_url: z.string().url().optional().describe("Webhook URL for recurring charge notifications"),
|
|
18
|
+
},
|
|
19
|
+
outputSchema: {
|
|
20
|
+
checkout_url: z.string().describe("Checkout page URL for the subscriber to enter card details"),
|
|
21
|
+
},
|
|
22
|
+
annotations: {
|
|
23
|
+
readOnlyHint: false,
|
|
24
|
+
destructiveHint: false,
|
|
25
|
+
idempotentHint: true,
|
|
26
|
+
openWorldHint: true,
|
|
27
|
+
},
|
|
28
|
+
}, async ({ amount, currency, description, order_id, subscribe_date_start, subscribe_periodicity, result_url, server_url }) => {
|
|
29
|
+
const params = {
|
|
30
|
+
action: "subscribe",
|
|
31
|
+
amount,
|
|
32
|
+
currency,
|
|
33
|
+
description,
|
|
34
|
+
order_id,
|
|
35
|
+
subscribe_date_start,
|
|
36
|
+
subscribe_periodicity,
|
|
37
|
+
};
|
|
38
|
+
if (result_url)
|
|
39
|
+
params["result_url"] = result_url;
|
|
40
|
+
if (server_url)
|
|
41
|
+
params["server_url"] = server_url;
|
|
42
|
+
const checkout_url = client.buildCheckoutUrl(params);
|
|
43
|
+
const output = { checkout_url };
|
|
44
|
+
return {
|
|
45
|
+
content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
|
|
46
|
+
structuredContent: output,
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
server.registerTool("liqpay_cancel_subscription", {
|
|
50
|
+
title: "Cancel LiqPay Subscription",
|
|
51
|
+
description: "Cancel an active recurring subscription (action: unsubscribe). " +
|
|
52
|
+
"Use when a subscriber wants to stop recurring charges. " +
|
|
53
|
+
"Do not use if the subscription is already inactive — check status first with liqpay_get_payment_status. " +
|
|
54
|
+
"Returns { status: string }.",
|
|
55
|
+
inputSchema: {
|
|
56
|
+
order_id: z.string().min(1).describe("Subscription order ID (e.g. 'sub-2026-001')"),
|
|
57
|
+
},
|
|
58
|
+
outputSchema: {
|
|
59
|
+
status: z.string().describe("Cancellation result (e.g. unsubscribed, error)"),
|
|
60
|
+
},
|
|
61
|
+
annotations: {
|
|
62
|
+
readOnlyHint: false,
|
|
63
|
+
destructiveHint: true,
|
|
64
|
+
idempotentHint: true,
|
|
65
|
+
openWorldHint: true,
|
|
66
|
+
},
|
|
67
|
+
}, async ({ order_id }) => {
|
|
68
|
+
try {
|
|
69
|
+
const result = await client.request({ action: "unsubscribe", order_id });
|
|
70
|
+
const output = { status: result.status };
|
|
71
|
+
return {
|
|
72
|
+
content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
|
|
73
|
+
structuredContent: output,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return {
|
|
78
|
+
content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
|
|
79
|
+
isError: true,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=subscriptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscriptions.js","sourceRoot":"","sources":["../../src/tools/subscriptions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { createSignature, decodeData } from "../auth.js";
|
|
3
|
+
export function registerWebhookTools(server, privateKey) {
|
|
4
|
+
server.registerTool("liqpay_verify_callback", {
|
|
5
|
+
title: "Verify LiqPay Callback",
|
|
6
|
+
description: "Validate an incoming LiqPay webhook signature to confirm authenticity. " +
|
|
7
|
+
"Use when processing a callback from LiqPay to verify it was not tampered with. " +
|
|
8
|
+
"Do not use for outgoing requests — signature is built automatically by the client. " +
|
|
9
|
+
"Returns { valid: boolean, decoded_data: object }.",
|
|
10
|
+
inputSchema: {
|
|
11
|
+
data: z.string().min(1).describe("Raw 'data' field from the webhook POST body (base64-encoded string)"),
|
|
12
|
+
signature: z.string().min(1).describe("Raw 'signature' field from the webhook POST body (base64-encoded string)"),
|
|
13
|
+
},
|
|
14
|
+
outputSchema: {
|
|
15
|
+
valid: z.boolean().describe("Whether the signature is authentic"),
|
|
16
|
+
decoded_data: z.record(z.unknown()).optional().describe("Decoded payment data from the callback (only if valid)"),
|
|
17
|
+
},
|
|
18
|
+
annotations: {
|
|
19
|
+
readOnlyHint: true,
|
|
20
|
+
destructiveHint: false,
|
|
21
|
+
idempotentHint: true,
|
|
22
|
+
openWorldHint: false,
|
|
23
|
+
},
|
|
24
|
+
}, async ({ data, signature }) => {
|
|
25
|
+
try {
|
|
26
|
+
const expectedSignature = createSignature(data, privateKey);
|
|
27
|
+
const valid = expectedSignature === signature;
|
|
28
|
+
const output = { valid };
|
|
29
|
+
if (valid) {
|
|
30
|
+
output.decoded_data = decodeData(data);
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
|
|
34
|
+
structuredContent: output,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
return {
|
|
39
|
+
content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
|
|
40
|
+
isError: true,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=webhooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/tools/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,UAAkB;IACxE,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,yEAAyE;YACzE,iFAAiF;YACjF,qFAAqF;YACrF,mDAAmD;QACrD,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qEAAqE,CAAC;YACvG,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0EAA0E,CAAC;SAClH;QACD,YAAY,EAAE;YACZ,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;YACjE,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;SAClH;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE;QAC5B,IAAI,CAAC;YACH,MAAM,iBAAiB,GAAG,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YAC5D,MAAM,KAAK,GAAG,iBAAiB,KAAK,SAAS,CAAC;YAE9C,MAAM,MAAM,GAA+D,EAAE,KAAK,EAAE,CAAC;YAErF,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,CAAC,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YACzC,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;gBAC3E,iBAAiB,EAAE,MAAM;aAC1B,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClG,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { LiqPayAction, LiqPayStatus, SupportedCurrency, SubscribePeriodicity } from "./constants.js";
|
|
2
|
+
export interface LiqPayBasePayload {
|
|
3
|
+
version: number;
|
|
4
|
+
public_key: string;
|
|
5
|
+
action: LiqPayAction;
|
|
6
|
+
}
|
|
7
|
+
export interface LiqPayCheckoutPayload extends LiqPayBasePayload {
|
|
8
|
+
action: "pay";
|
|
9
|
+
amount: number;
|
|
10
|
+
currency: SupportedCurrency;
|
|
11
|
+
description: string;
|
|
12
|
+
order_id: string;
|
|
13
|
+
result_url?: string;
|
|
14
|
+
server_url?: string;
|
|
15
|
+
language?: "uk" | "en";
|
|
16
|
+
}
|
|
17
|
+
export interface LiqPayStatusPayload extends LiqPayBasePayload {
|
|
18
|
+
action: "status";
|
|
19
|
+
order_id: string;
|
|
20
|
+
}
|
|
21
|
+
export interface LiqPayHoldPayload extends LiqPayBasePayload {
|
|
22
|
+
action: "hold";
|
|
23
|
+
amount: number;
|
|
24
|
+
currency: SupportedCurrency;
|
|
25
|
+
description: string;
|
|
26
|
+
order_id: string;
|
|
27
|
+
card: string;
|
|
28
|
+
card_exp_month: string;
|
|
29
|
+
card_exp_year: string;
|
|
30
|
+
card_cvv: string;
|
|
31
|
+
}
|
|
32
|
+
export interface LiqPayHoldCompletionPayload extends LiqPayBasePayload {
|
|
33
|
+
action: "hold_completion";
|
|
34
|
+
order_id: string;
|
|
35
|
+
amount?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface LiqPayRefundPayload extends LiqPayBasePayload {
|
|
38
|
+
action: "refund";
|
|
39
|
+
order_id: string;
|
|
40
|
+
amount?: number;
|
|
41
|
+
}
|
|
42
|
+
export interface LiqPaySubscribePayload extends LiqPayBasePayload {
|
|
43
|
+
action: "subscribe";
|
|
44
|
+
amount: number;
|
|
45
|
+
currency: SupportedCurrency;
|
|
46
|
+
description: string;
|
|
47
|
+
order_id: string;
|
|
48
|
+
subscribe_date_start: string;
|
|
49
|
+
subscribe_periodicity: SubscribePeriodicity;
|
|
50
|
+
result_url?: string;
|
|
51
|
+
server_url?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface LiqPayUnsubscribePayload extends LiqPayBasePayload {
|
|
54
|
+
action: "unsubscribe";
|
|
55
|
+
order_id: string;
|
|
56
|
+
}
|
|
57
|
+
export interface LiqPayP2PPayload extends LiqPayBasePayload {
|
|
58
|
+
action: "p2p";
|
|
59
|
+
amount: number;
|
|
60
|
+
currency: SupportedCurrency;
|
|
61
|
+
description: string;
|
|
62
|
+
order_id: string;
|
|
63
|
+
card: string;
|
|
64
|
+
}
|
|
65
|
+
export interface LiqPayReportsPayload extends LiqPayBasePayload {
|
|
66
|
+
action: "reports";
|
|
67
|
+
date_from: number;
|
|
68
|
+
date_to: number;
|
|
69
|
+
status?: LiqPayStatus;
|
|
70
|
+
}
|
|
71
|
+
export interface LiqPayResponse {
|
|
72
|
+
result: string;
|
|
73
|
+
status: LiqPayStatus;
|
|
74
|
+
payment_id?: number;
|
|
75
|
+
action?: string;
|
|
76
|
+
amount?: number;
|
|
77
|
+
currency?: SupportedCurrency;
|
|
78
|
+
description?: string;
|
|
79
|
+
order_id?: string;
|
|
80
|
+
create_date?: number;
|
|
81
|
+
end_date?: number;
|
|
82
|
+
transaction_id?: number;
|
|
83
|
+
err_code?: string;
|
|
84
|
+
err_description?: string;
|
|
85
|
+
}
|
|
86
|
+
export interface LiqPayReportsResponse {
|
|
87
|
+
result: string;
|
|
88
|
+
count: number;
|
|
89
|
+
data: LiqPayResponse[];
|
|
90
|
+
}
|
|
91
|
+
export type LiqPayPayload = LiqPayCheckoutPayload | LiqPayStatusPayload | LiqPayHoldPayload | LiqPayHoldCompletionPayload | LiqPayRefundPayload | LiqPaySubscribePayload | LiqPayUnsubscribePayload | LiqPayP2PPayload | LiqPayReportsPayload;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "liqpay-mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for LiqPay payment gateway — payments, holds, refunds, subscriptions, payouts",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"liqpay-mcp-server": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/index.js",
|
|
13
|
+
"dev": "tsx watch src/index.ts",
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"prepublishOnly": "npm run build"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"mcp",
|
|
19
|
+
"model-context-protocol",
|
|
20
|
+
"liqpay",
|
|
21
|
+
"payment",
|
|
22
|
+
"ukraine",
|
|
23
|
+
"privatbank",
|
|
24
|
+
"ai",
|
|
25
|
+
"llm",
|
|
26
|
+
"agent",
|
|
27
|
+
"payments-gateway",
|
|
28
|
+
"fintech"
|
|
29
|
+
],
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/serhiizghama/liqpay-mcp"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/serhiizghama/liqpay-mcp#readme",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/serhiizghama/liqpay-mcp/issues"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist"
|
|
41
|
+
],
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
47
|
+
"zod": "^3.24.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^22.10.0",
|
|
51
|
+
"tsx": "^4.19.0",
|
|
52
|
+
"typescript": "^5.7.0",
|
|
53
|
+
"vitest": "^2.1.0"
|
|
54
|
+
}
|
|
55
|
+
}
|