medusa-paystack-plugin 0.1.1
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/.medusa/server/src/admin/index.js +135 -0
- package/.medusa/server/src/admin/index.mjs +134 -0
- package/.medusa/server/src/api/middlewares.js +9 -0
- package/.medusa/server/src/api/store/paystack/config/middlewares.js +13 -0
- package/.medusa/server/src/api/store/paystack/config/route.js +15 -0
- package/.medusa/server/src/api/store/paystack/validators.js +33 -0
- package/.medusa/server/src/api/store/paystack/webview/html.js +178 -0
- package/.medusa/server/src/api/store/paystack/webview/middlewares.js +13 -0
- package/.medusa/server/src/api/store/paystack/webview/route.js +27 -0
- package/.medusa/server/src/constants.js +9 -0
- package/.medusa/server/src/frontend.js +147 -0
- package/.medusa/server/src/lib/paystack-client.js +39 -0
- package/.medusa/server/src/lib/paystack-utils.js +59 -0
- package/.medusa/server/src/lib/plugin-config.js +56 -0
- package/.medusa/server/src/lib/store.js +36 -0
- package/.medusa/server/src/providers/paystack/index.js +11 -0
- package/.medusa/server/src/providers/paystack/service.js +150 -0
- package/.medusa/server/src/types.js +3 -0
- package/README.md +209 -0
- package/package.json +75 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toPaystackSubunit = exports.PAYSTACK_WEBVIEW_SOURCE = exports.buildPaystackReference = void 0;
|
|
4
|
+
exports.fetchPaystackConfig = fetchPaystackConfig;
|
|
5
|
+
exports.buildPaystackWebviewUrl = buildPaystackWebviewUrl;
|
|
6
|
+
exports.loadPaystackInlineScript = loadPaystackInlineScript;
|
|
7
|
+
exports.createPaystackSuccessHandler = createPaystackSuccessHandler;
|
|
8
|
+
exports.launchPaystackCheckout = launchPaystackCheckout;
|
|
9
|
+
const constants_1 = require("./constants");
|
|
10
|
+
Object.defineProperty(exports, "PAYSTACK_WEBVIEW_SOURCE", { enumerable: true, get: function () { return constants_1.PAYSTACK_WEBVIEW_SOURCE; } });
|
|
11
|
+
const paystack_utils_1 = require("./lib/paystack-utils");
|
|
12
|
+
Object.defineProperty(exports, "buildPaystackReference", { enumerable: true, get: function () { return paystack_utils_1.buildPaystackReference; } });
|
|
13
|
+
Object.defineProperty(exports, "toPaystackSubunit", { enumerable: true, get: function () { return paystack_utils_1.toPaystackSubunit; } });
|
|
14
|
+
let inlineScriptPromise = null;
|
|
15
|
+
function toAbsoluteUrl(baseUrl, path) {
|
|
16
|
+
const base = baseUrl || (typeof window !== "undefined" ? window.location.origin : "http://localhost");
|
|
17
|
+
return new URL(path, base);
|
|
18
|
+
}
|
|
19
|
+
function appendRedirectParams(redirectUrl, transaction) {
|
|
20
|
+
const url = new URL(redirectUrl);
|
|
21
|
+
url.searchParams.set("paystack_status", "success");
|
|
22
|
+
url.searchParams.set("paystack_payload", JSON.stringify(transaction));
|
|
23
|
+
url.searchParams.set("reference", transaction.reference);
|
|
24
|
+
return url.toString();
|
|
25
|
+
}
|
|
26
|
+
async function fetchPaystackConfig(options = {}) {
|
|
27
|
+
const fetcher = options.fetcher ?? fetch;
|
|
28
|
+
const url = toAbsoluteUrl(options.baseUrl, "/store/paystack/config");
|
|
29
|
+
if (options.storeId) {
|
|
30
|
+
url.searchParams.set("store_id", options.storeId);
|
|
31
|
+
}
|
|
32
|
+
const response = await fetcher(url.toString(), {
|
|
33
|
+
headers: options.publishableApiKey
|
|
34
|
+
? {
|
|
35
|
+
"x-publishable-api-key": options.publishableApiKey,
|
|
36
|
+
}
|
|
37
|
+
: undefined,
|
|
38
|
+
});
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
throw new Error(`Unable to load Paystack config (${response.status}).`);
|
|
41
|
+
}
|
|
42
|
+
return (await response.json());
|
|
43
|
+
}
|
|
44
|
+
function buildPaystackWebviewUrl(options) {
|
|
45
|
+
const url = toAbsoluteUrl(options.baseUrl, "/store/paystack/webview");
|
|
46
|
+
url.searchParams.set("amount", String(options.amount));
|
|
47
|
+
url.searchParams.set("currency", options.currency.toUpperCase());
|
|
48
|
+
url.searchParams.set("email", options.email);
|
|
49
|
+
url.searchParams.set("reference", options.reference ?? (0, paystack_utils_1.buildPaystackReference)());
|
|
50
|
+
if (options.callbackUrl) {
|
|
51
|
+
url.searchParams.set("callback_url", options.callbackUrl);
|
|
52
|
+
}
|
|
53
|
+
if (options.channels?.length) {
|
|
54
|
+
url.searchParams.set("channels", options.channels.join(","));
|
|
55
|
+
}
|
|
56
|
+
if (options.firstName) {
|
|
57
|
+
url.searchParams.set("first_name", options.firstName);
|
|
58
|
+
}
|
|
59
|
+
if (options.lastName) {
|
|
60
|
+
url.searchParams.set("last_name", options.lastName);
|
|
61
|
+
}
|
|
62
|
+
if (options.metadata) {
|
|
63
|
+
url.searchParams.set("metadata", JSON.stringify(options.metadata));
|
|
64
|
+
}
|
|
65
|
+
if (options.phone) {
|
|
66
|
+
url.searchParams.set("phone", options.phone);
|
|
67
|
+
}
|
|
68
|
+
if (options.storeId) {
|
|
69
|
+
url.searchParams.set("store_id", options.storeId);
|
|
70
|
+
}
|
|
71
|
+
return url.toString();
|
|
72
|
+
}
|
|
73
|
+
async function loadPaystackInlineScript(scriptUrl = constants_1.PAYSTACK_INLINE_SCRIPT_URL) {
|
|
74
|
+
if (typeof window === "undefined") {
|
|
75
|
+
throw new Error("Paystack InlineJS can only load in a browser.");
|
|
76
|
+
}
|
|
77
|
+
if (window.PaystackPop) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (!inlineScriptPromise) {
|
|
81
|
+
inlineScriptPromise = new Promise((resolve, reject) => {
|
|
82
|
+
const existingScript = document.querySelector(`script[src="${scriptUrl}"]`);
|
|
83
|
+
if (existingScript) {
|
|
84
|
+
existingScript.addEventListener("load", () => resolve(), {
|
|
85
|
+
once: true,
|
|
86
|
+
});
|
|
87
|
+
existingScript.addEventListener("error", () => reject(new Error("Unable to load Paystack InlineJS.")), { once: true });
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const script = document.createElement("script");
|
|
91
|
+
script.async = true;
|
|
92
|
+
script.src = scriptUrl;
|
|
93
|
+
script.onload = () => resolve();
|
|
94
|
+
script.onerror = () => reject(new Error("Unable to load Paystack InlineJS."));
|
|
95
|
+
document.head.appendChild(script);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
await inlineScriptPromise;
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
inlineScriptPromise = null;
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function createPaystackSuccessHandler(options) {
|
|
107
|
+
return async (transaction) => {
|
|
108
|
+
if (options.mode === "verified") {
|
|
109
|
+
if (!options.cartId || !options.sdk) {
|
|
110
|
+
throw new Error("Verified mode requires both cartId and a Medusa JS SDK instance.");
|
|
111
|
+
}
|
|
112
|
+
const result = await options.sdk.store.cart.complete(options.cartId);
|
|
113
|
+
if (result.type !== "order") {
|
|
114
|
+
throw new Error(result.error?.message ??
|
|
115
|
+
"Unable to complete the cart after Paystack payment.");
|
|
116
|
+
}
|
|
117
|
+
await options.onCompleteCart?.(result, transaction);
|
|
118
|
+
}
|
|
119
|
+
await options.onSuccess?.(transaction);
|
|
120
|
+
if (options.redirectUrl && typeof window !== "undefined") {
|
|
121
|
+
window.location.assign(appendRedirectParams(options.redirectUrl, transaction));
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
async function launchPaystackCheckout(options) {
|
|
126
|
+
await loadPaystackInlineScript();
|
|
127
|
+
if (!window.PaystackPop) {
|
|
128
|
+
throw new Error("Paystack InlineJS did not initialize correctly.");
|
|
129
|
+
}
|
|
130
|
+
const paystack = new window.PaystackPop();
|
|
131
|
+
return paystack.newTransaction({
|
|
132
|
+
key: options.key,
|
|
133
|
+
email: options.email,
|
|
134
|
+
amount: (0, paystack_utils_1.toPaystackSubunit)(options.amount),
|
|
135
|
+
currency: options.currency?.toUpperCase(),
|
|
136
|
+
reference: options.reference ?? (0, paystack_utils_1.buildPaystackReference)(),
|
|
137
|
+
metadata: options.metadata,
|
|
138
|
+
channels: options.channels,
|
|
139
|
+
firstName: options.firstName,
|
|
140
|
+
lastName: options.lastName,
|
|
141
|
+
phone: options.phone,
|
|
142
|
+
onCancel: options.onCancel,
|
|
143
|
+
onError: options.onError,
|
|
144
|
+
onSuccess: options.successHandler ?? options.onSuccess,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJvbnRlbmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZnJvbnRlbmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBdUdBLGtEQXVCQztBQUVELDBEQXVDQztBQUVELDREQStDQztBQUVELG9FQTZCQztBQUVELHdEQTBCQztBQW5SRCwyQ0FHb0I7QUFrUmEsd0dBblIvQixtQ0FBdUIsT0FtUitCO0FBalJ4RCx5REFBZ0Y7QUFpUnZFLHVHQWpSQSx1Q0FBc0IsT0FpUkE7QUFBMkIsa0dBalJ6QixrQ0FBaUIsT0FpUnlCO0FBbE0zRSxJQUFJLG1CQUFtQixHQUF5QixJQUFJLENBQUE7QUFFcEQsU0FBUyxhQUFhLENBQUMsT0FBMkIsRUFBRSxJQUFZO0lBQzlELE1BQU0sSUFBSSxHQUFHLE9BQU8sSUFBSSxDQUFDLE9BQU8sTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLENBQUE7SUFDckcsT0FBTyxJQUFJLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUE7QUFDNUIsQ0FBQztBQUVELFNBQVMsb0JBQW9CLENBQzNCLFdBQW1CLEVBQ25CLFdBQXNDO0lBRXRDLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFBO0lBRWhDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFLFNBQVMsQ0FBQyxDQUFBO0lBQ2xELEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQTtJQUNyRSxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFBO0lBRXhELE9BQU8sR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFBO0FB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
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PaystackClient = void 0;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
class PaystackClient {
|
|
6
|
+
constructor(secretKey) {
|
|
7
|
+
this.secretKey = secretKey;
|
|
8
|
+
}
|
|
9
|
+
async verifyTransaction(reference) {
|
|
10
|
+
return this.request(`/transaction/verify/${encodeURIComponent(reference)}`, { method: "GET" });
|
|
11
|
+
}
|
|
12
|
+
async refundTransaction(transactionId, amount) {
|
|
13
|
+
return this.request("/refund", {
|
|
14
|
+
body: {
|
|
15
|
+
amount,
|
|
16
|
+
transaction: transactionId,
|
|
17
|
+
},
|
|
18
|
+
method: "POST",
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async request(path, init) {
|
|
22
|
+
const response = await fetch(`${constants_1.PAYSTACK_API_BASE_URL}${path}`, {
|
|
23
|
+
body: init.body ? JSON.stringify(init.body) : undefined,
|
|
24
|
+
headers: {
|
|
25
|
+
Authorization: `Bearer ${this.secretKey}`,
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
},
|
|
28
|
+
method: init.method ?? "GET",
|
|
29
|
+
});
|
|
30
|
+
const payload = (await response.json().catch(() => undefined));
|
|
31
|
+
if (!response.ok || !payload?.status) {
|
|
32
|
+
const message = payload?.message || `Paystack request failed with ${response.status}`;
|
|
33
|
+
throw new Error(message);
|
|
34
|
+
}
|
|
35
|
+
return payload.data;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.PaystackClient = PaystackClient;
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF5c3RhY2stY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9wYXlzdGFjay1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNENBQW9EO0FBa0NwRCxNQUFhLGNBQWM7SUFDekIsWUFBNkIsU0FBaUI7UUFBakIsY0FBUyxHQUFULFNBQVMsQ0FBUTtJQUFHLENBQUM7SUFFbEQsS0FBSyxDQUFDLGlCQUFpQixDQUFDLFNBQWlCO1FBQ3ZDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FDakIsdUJBQXVCLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQ3RELEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUNsQixDQUFBO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxhQUFxQixFQUFFLE1BQWM7UUFDM0QsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFpQixTQUFTLEVBQUU7WUFDN0MsSUFBSSxFQUFFO2dCQUNKLE1BQU07Z0JBQ04sV0FBVyxFQUFFLGFBQWE7YUFDM0I7WUFDRCxNQUFNLEVBQUUsTUFBTTtTQUNmLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFTyxLQUFLLENBQUMsT0FBTyxDQUFJLElBQVksRUFBRSxJQUFxQjtRQUMxRCxNQUFNLFFBQVEsR0FBRyxNQUFNLEtBQUssQ0FBQyxHQUFHLGlDQUFxQixHQUFHLElBQUksRUFBRSxFQUFFO1lBQzlELElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztZQUN2RCxPQUFPLEVBQUU7Z0JBQ1AsYUFBYSxFQUFFLFVBQVUsSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFDekMsY0FBYyxFQUFFLGtCQUFrQjthQUNuQztZQUNELE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxJQUFJLEtBQUs7U0FDN0IsQ0FBQyxDQUFBO1FBRUYsTUFBTSxPQUFPLEdBQUcsQ0FBQyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLENBRWhELENBQUE7UUFFYixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQztZQUNyQyxNQUFNLE9BQU8sR0FBRyxPQUFPLEVBQUUsT0FBTyxJQUFJLGdDQUFnQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUE7WUFDckYsTUFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUMxQixDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFBO0lBQ3JCLENBQUM7Q0FDRjtBQXpDRCx3Q0F5Q0MifQ==
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildPaystackReference = buildPaystackReference;
|
|
7
|
+
exports.toPaystackSubunit = toPaystackSubunit;
|
|
8
|
+
exports.serializePayload = serializePayload;
|
|
9
|
+
exports.parseMetadataParam = parseMetadataParam;
|
|
10
|
+
exports.parseChannels = parseChannels;
|
|
11
|
+
exports.buildResultRedirectUrl = buildResultRedirectUrl;
|
|
12
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
13
|
+
function buildPaystackReference(prefix = "medusa-paystack") {
|
|
14
|
+
return `${prefix}-${node_crypto_1.default.randomUUID()}`;
|
|
15
|
+
}
|
|
16
|
+
function toPaystackSubunit(amount) {
|
|
17
|
+
const numericAmount = Number(amount);
|
|
18
|
+
if (!Number.isFinite(numericAmount) || numericAmount <= 0) {
|
|
19
|
+
throw new Error("Paystack amount must be a positive number.");
|
|
20
|
+
}
|
|
21
|
+
return Math.round(numericAmount * 100);
|
|
22
|
+
}
|
|
23
|
+
function serializePayload(payload) {
|
|
24
|
+
if (!payload) {
|
|
25
|
+
return "{}";
|
|
26
|
+
}
|
|
27
|
+
return JSON.stringify(payload);
|
|
28
|
+
}
|
|
29
|
+
function parseMetadataParam(metadata) {
|
|
30
|
+
if (!metadata) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const parsed = JSON.parse(metadata);
|
|
34
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
35
|
+
throw new Error("Metadata must be a JSON object.");
|
|
36
|
+
}
|
|
37
|
+
return parsed;
|
|
38
|
+
}
|
|
39
|
+
function parseChannels(channels) {
|
|
40
|
+
if (!channels) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
const values = channels
|
|
44
|
+
.split(",")
|
|
45
|
+
.map((channel) => channel.trim())
|
|
46
|
+
.filter(Boolean);
|
|
47
|
+
return values.length ? values : undefined;
|
|
48
|
+
}
|
|
49
|
+
function buildResultRedirectUrl(callbackUrl, status, payload) {
|
|
50
|
+
const url = new URL(callbackUrl);
|
|
51
|
+
url.searchParams.set("paystack_status", status);
|
|
52
|
+
url.searchParams.set("paystack_payload", serializePayload(payload));
|
|
53
|
+
const reference = payload?.reference;
|
|
54
|
+
if (typeof reference === "string" && reference.length) {
|
|
55
|
+
url.searchParams.set("reference", reference);
|
|
56
|
+
}
|
|
57
|
+
return url.toString();
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF5c3RhY2stdXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3BheXN0YWNrLXV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBRUEsd0RBRUM7QUFFRCw4Q0FRQztBQUVELDRDQVFDO0FBRUQsZ0RBWUM7QUFFRCxzQ0FXQztBQUVELHdEQWlCQztBQXRFRCw4REFBZ0M7QUFFaEMsU0FBZ0Isc0JBQXNCLENBQUMsTUFBTSxHQUFHLGlCQUFpQjtJQUMvRCxPQUFPLEdBQUcsTUFBTSxJQUFJLHFCQUFNLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQTtBQUMzQyxDQUFDO0FBRUQsU0FBZ0IsaUJBQWlCLENBQUMsTUFBdUI7SUFDdkQsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBRXBDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxJQUFJLGFBQWEsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUMxRCxNQUFNLElBQUksS0FBSyxDQUFDLDRDQUE0QyxDQUFDLENBQUE7SUFDL0QsQ0FBQztJQUVELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEdBQUcsR0FBRyxDQUFDLENBQUE7QUFDeEMsQ0FBQztBQUVELFNBQWdCLGdCQUFnQixDQUM5QixPQUE0QztJQUU1QyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDYixPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUE7QUFDaEMsQ0FBQztBQUVELFNBQWdCLGtCQUFrQixDQUFDLFFBQWlCO0lBQ2xELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNkLE9BQU8sU0FBUyxDQUFBO0lBQ2xCLENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBRW5DLElBQUksQ0FBQyxNQUFNLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUNuRSxNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUE7SUFDcEQsQ0FBQztJQUVELE9BQU8sTUFBaUMsQ0FBQTtBQUMxQyxDQUFDO0FBRUQsU0FBZ0IsYUFBYSxDQUFDLFFBQWlCO0lBQzdDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNkLE9BQU8sU0FBUyxDQUFBO0lBQ2xCLENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxRQUFRO1NBQ3BCLEtBQUssQ0FBQyxHQUFHLENBQUM7U0FDVixHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUNoQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUE7SUFFbEIsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQTtBQUMzQyxDQUFDO0FBRUQsU0FBZ0Isc0JBQXNCLENBQ3BDLFdBQW1CLEVBQ25CLE1BQXNDLEVBQ3RDLE9BQWlDO0lBRWpDLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFBO0lBRWhDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQy9DLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUE7SUFFbkUsTUFBTSxTQUFTLEdBQUcsT0FBTyxFQUFFLFNBQVMsQ0FBQTtJQUVwQyxJQUFJLE9BQU8sU0FBUyxLQUFLLFFBQVEsSUFBSSxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDdEQsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLFNBQVMsQ0FBQyxDQUFBO0lBQzlDLENBQUM7SUFFRCxPQUFPLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQTtBQUN2QixDQUFDIn0=
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectPaystackSecretKey = detectPaystackSecretKey;
|
|
4
|
+
exports.isVerifiedModeEnabled = isVerifiedModeEnabled;
|
|
5
|
+
function asEntries(value) {
|
|
6
|
+
if (Array.isArray(value)) {
|
|
7
|
+
return value.filter(Boolean);
|
|
8
|
+
}
|
|
9
|
+
if (value && typeof value === "object") {
|
|
10
|
+
return Object.values(value).filter(Boolean);
|
|
11
|
+
}
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
function getString(value) {
|
|
15
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
16
|
+
}
|
|
17
|
+
function looksLikePaystackResolve(resolve) {
|
|
18
|
+
if (!resolve) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return (resolve.includes("paystack") || resolve.endsWith("/providers/paystack"));
|
|
22
|
+
}
|
|
23
|
+
function detectPaystackProviderSecretKey(configModule) {
|
|
24
|
+
const config = (configModule ?? {});
|
|
25
|
+
for (const moduleConfig of asEntries(config.modules)) {
|
|
26
|
+
const moduleOptions = (moduleConfig.options ?? {});
|
|
27
|
+
const providers = Array.isArray(moduleOptions.providers)
|
|
28
|
+
? moduleOptions.providers
|
|
29
|
+
: [];
|
|
30
|
+
for (const provider of providers) {
|
|
31
|
+
const resolve = getString(provider.resolve);
|
|
32
|
+
const id = getString(provider.id);
|
|
33
|
+
const secretKey = getString(provider.options?.secret_key);
|
|
34
|
+
if (secretKey &&
|
|
35
|
+
(looksLikePaystackResolve(resolve) || id === "paystack")) {
|
|
36
|
+
return secretKey;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
function detectPaystackSecretKey(configModule) {
|
|
43
|
+
const config = (configModule ?? {});
|
|
44
|
+
for (const plugin of asEntries(config.plugins)) {
|
|
45
|
+
const resolve = getString(plugin.resolve);
|
|
46
|
+
const secretKey = getString(plugin.options?.secret_key);
|
|
47
|
+
if (secretKey && looksLikePaystackResolve(resolve)) {
|
|
48
|
+
return secretKey;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return detectPaystackProviderSecretKey(configModule);
|
|
52
|
+
}
|
|
53
|
+
function isVerifiedModeEnabled(configModule) {
|
|
54
|
+
return Boolean(detectPaystackProviderSecretKey(configModule));
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWNvbmZpZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcGx1Z2luLWNvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXNEQSwwREFhQztBQUVELHNEQUVDO0FBckVELFNBQVMsU0FBUyxDQUFDLEtBQWM7SUFDL0IsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDekIsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBb0IsQ0FBQTtJQUNqRCxDQUFDO0lBRUQsSUFBSSxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDdkMsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQXNCLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFvQixDQUFBO0lBQ2pGLENBQUM7SUFFRCxPQUFPLEVBQUUsQ0FBQTtBQUNYLENBQUM7QUFFRCxTQUFTLFNBQVMsQ0FBQyxLQUFjO0lBQy9CLE9BQU8sT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUE7QUFDN0UsQ0FBQztBQUVELFNBQVMsd0JBQXdCLENBQUMsT0FBMkI7SUFDM0QsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2IsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0lBRUQsT0FBTyxDQUNMLE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxDQUN4RSxDQUFBO0FBQ0gsQ0FBQztBQUVELFNBQVMsK0JBQStCLENBQUMsWUFBcUI7SUFDNUQsTUFBTSxNQUFNLEdBQUcsQ0FBQyxZQUFZLElBQUksRUFBRSxDQUFrQixDQUFBO0lBRXBELEtBQUssTUFBTSxZQUFZLElBQUksU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ3JELE1BQU0sYUFBYSxHQUFHLENBQUMsWUFBWSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQWtCLENBQUE7UUFDbkUsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDO1lBQ3RELENBQUMsQ0FBRSxhQUFhLENBQUMsU0FBNkI7WUFDOUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtRQUVOLEtBQUssTUFBTSxRQUFRLElBQUksU0FBUyxFQUFFLENBQUM7WUFDakMsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQTtZQUMzQyxNQUFNLEVBQUUsR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1lBQ2pDLE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBRSxRQUFRLENBQUMsT0FBcUMsRUFBRSxVQUFVLENBQUMsQ0FBQTtZQUV4RixJQUNFLFNBQVM7Z0JBQ1QsQ0FBQyx3QkFBd0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEtBQUssVUFBVSxDQUFDLEVBQ3hELENBQUM7Z0JBQ0QsT0FBTyxTQUFTLENBQUE7WUFDbEIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxTQUFTLENBQUE7QUFDbEIsQ0FBQztBQUVELFNBQWdCLHVCQUF1QixDQUFDLFlBQXFCO0lBQzNELE1BQU0sTUFBTSxHQUFHLENBQUMsWUFBWSxJQUFJLEVBQUUsQ0FBa0IsQ0FBQTtJQUVwRCxLQUFLLE1BQU0sTUFBTSxJQUFJLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUMvQyxNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ3pDLE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBRSxNQUFNLENBQUMsT0FBcUMsRUFBRSxVQUFVLENBQUMsQ0FBQTtRQUV0RixJQUFJLFNBQVMsSUFBSSx3QkFBd0IsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ25ELE9BQU8sU0FBUyxDQUFBO1FBQ2xCLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTywrQkFBK0IsQ0FBQyxZQUFZLENBQUMsQ0FBQTtBQUN0RCxDQUFDO0FBRUQsU0FBZ0IscUJBQXFCLENBQUMsWUFBcUI7SUFDekQsT0FBTyxPQUFPLENBQUMsK0JBQStCLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQTtBQUMvRCxDQUFDIn0=
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveStore = resolveStore;
|
|
4
|
+
exports.getStorePublishableKey = getStorePublishableKey;
|
|
5
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
|
+
async function resolveStore(scope, storeId) {
|
|
8
|
+
const query = scope.resolve("query");
|
|
9
|
+
const { data = [] } = await query.graph({
|
|
10
|
+
entity: "store",
|
|
11
|
+
fields: ["id", "metadata"],
|
|
12
|
+
filters: storeId ? { id: storeId } : {},
|
|
13
|
+
});
|
|
14
|
+
if (storeId) {
|
|
15
|
+
const store = data[0];
|
|
16
|
+
if (!store) {
|
|
17
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, `Store ${storeId} was not found.`);
|
|
18
|
+
}
|
|
19
|
+
return store;
|
|
20
|
+
}
|
|
21
|
+
if (data.length === 1) {
|
|
22
|
+
return data[0];
|
|
23
|
+
}
|
|
24
|
+
if (data.length === 0) {
|
|
25
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "No stores were found in this Medusa installation.");
|
|
26
|
+
}
|
|
27
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Multiple stores are configured. Pass store_id to select the Paystack key.");
|
|
28
|
+
}
|
|
29
|
+
function getStorePublishableKey(store) {
|
|
30
|
+
const key = store.metadata?.[constants_1.PAYSTACK_PUBLISHABLE_KEY_METADATA];
|
|
31
|
+
if (typeof key === "string" && key.trim()) {
|
|
32
|
+
return key.trim();
|
|
33
|
+
}
|
|
34
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Store ${store.id} does not have ${constants_1.PAYSTACK_PUBLISHABLE_KEY_METADATA} configured.`);
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBaUJBLG9DQXdDQztBQUVELHdEQVdDO0FBdEVELHFEQUF1RDtBQUV2RCw0Q0FBZ0U7QUFlekQsS0FBSyxVQUFVLFlBQVksQ0FDaEMsS0FBZ0IsRUFDaEIsT0FBZ0I7SUFFaEIsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQWlCLENBQUE7SUFFcEQsTUFBTSxFQUFFLElBQUksR0FBRyxFQUFFLEVBQUUsR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDdEMsTUFBTSxFQUFFLE9BQU87UUFDZixNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDO1FBQzFCLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO0tBQ3hDLENBQUMsQ0FBQTtJQUVGLElBQUksT0FBTyxFQUFFLENBQUM7UUFDWixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFFckIsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFDM0IsU0FBUyxPQUFPLGlCQUFpQixDQUNsQyxDQUFBO1FBQ0gsQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVELElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN0QixPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNoQixDQUFDO0lBRUQsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3RCLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQzNCLG1EQUFtRCxDQUNwRCxDQUFBO0lBQ0gsQ0FBQztJQUVELE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLDJFQUEyRSxDQUM1RSxDQUFBO0FBQ0gsQ0FBQztBQUVELFNBQWdCLHNCQUFzQixDQUFDLEtBQWtCO0lBQ3ZELE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyw2Q0FBaUMsQ0FBQyxDQUFBO0lBRS9ELElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQzFDLE9BQU8sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFBO0lBQ25CLENBQUM7SUFFRCxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixTQUFTLEtBQUssQ0FBQyxFQUFFLGtCQUFrQiw2Q0FBaUMsY0FBYyxDQUNuRixDQUFBO0FBQ0gsQ0FBQyJ9
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
7
|
+
const service_1 = __importDefault(require("./service"));
|
|
8
|
+
exports.default = (0, utils_1.ModuleProvider)(utils_1.Modules.PAYMENT, {
|
|
9
|
+
services: [service_1.default],
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvcHJvdmlkZXJzL3BheXN0YWNrL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEscURBQW1FO0FBRW5FLHdEQUVrQjtBQUVsQixrQkFBZSxJQUFBLHNCQUFjLEVBQUMsZUFBTyxDQUFDLE9BQU8sRUFBRTtJQUM3QyxRQUFRLEVBQUUsQ0FBQyxpQkFBOEIsQ0FBQztDQUMzQyxDQUFDLENBQUEifQ==
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const constants_1 = require("../../constants");
|
|
5
|
+
const paystack_client_1 = require("../../lib/paystack-client");
|
|
6
|
+
const paystack_utils_1 = require("../../lib/paystack-utils");
|
|
7
|
+
class PaystackPaymentProviderService extends utils_1.AbstractPaymentProvider {
|
|
8
|
+
constructor(cradle, options) {
|
|
9
|
+
super(cradle, options);
|
|
10
|
+
if (!options.secret_key) {
|
|
11
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_ARGUMENT, "Paystack verified mode requires secret_key in the provider options.");
|
|
12
|
+
}
|
|
13
|
+
this.client_ = new paystack_client_1.PaystackClient(options.secret_key);
|
|
14
|
+
}
|
|
15
|
+
async initiatePayment(input) {
|
|
16
|
+
const existingData = input.data;
|
|
17
|
+
const amount = Number(input.amount);
|
|
18
|
+
const reference = existingData?.paystack_reference ?? (0, paystack_utils_1.buildPaystackReference)();
|
|
19
|
+
return {
|
|
20
|
+
id: reference,
|
|
21
|
+
data: {
|
|
22
|
+
amount,
|
|
23
|
+
currency_code: input.currency_code.toUpperCase(),
|
|
24
|
+
paystack_reference: reference,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
async updatePayment(input) {
|
|
29
|
+
const existingData = input.data;
|
|
30
|
+
const amount = Number(input.amount);
|
|
31
|
+
const currencyCode = input.currency_code.toUpperCase();
|
|
32
|
+
const shouldRotateReference = existingData?.amount !== amount ||
|
|
33
|
+
existingData?.currency_code?.toUpperCase() !== currencyCode;
|
|
34
|
+
return {
|
|
35
|
+
data: {
|
|
36
|
+
amount,
|
|
37
|
+
currency_code: currencyCode,
|
|
38
|
+
paystack_reference: shouldRotateReference || !existingData?.paystack_reference
|
|
39
|
+
? (0, paystack_utils_1.buildPaystackReference)()
|
|
40
|
+
: existingData.paystack_reference,
|
|
41
|
+
},
|
|
42
|
+
status: utils_1.PaymentSessionStatus.PENDING,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
async authorizePayment(input) {
|
|
46
|
+
const paymentData = input.data;
|
|
47
|
+
if (!paymentData?.paystack_reference) {
|
|
48
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Missing paystack_reference in the payment session.");
|
|
49
|
+
}
|
|
50
|
+
const transaction = await this.client_.verifyTransaction(paymentData.paystack_reference);
|
|
51
|
+
const expectedAmount = (0, paystack_utils_1.toPaystackSubunit)(paymentData.amount);
|
|
52
|
+
const expectedCurrency = paymentData.currency_code.toUpperCase();
|
|
53
|
+
if (transaction.amount !== expectedAmount) {
|
|
54
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Paystack amount mismatch for ${paymentData.paystack_reference}.`);
|
|
55
|
+
}
|
|
56
|
+
if (transaction.currency.toUpperCase() !== expectedCurrency) {
|
|
57
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Paystack currency mismatch for ${paymentData.paystack_reference}.`);
|
|
58
|
+
}
|
|
59
|
+
if (transaction.status !== "success") {
|
|
60
|
+
return {
|
|
61
|
+
data: {
|
|
62
|
+
...paymentData,
|
|
63
|
+
paystack_transaction_data: transaction,
|
|
64
|
+
paystack_transaction_id: transaction.id,
|
|
65
|
+
paystack_transaction_status: transaction.status,
|
|
66
|
+
},
|
|
67
|
+
status: transaction.status === "failed"
|
|
68
|
+
? utils_1.PaymentSessionStatus.ERROR
|
|
69
|
+
: utils_1.PaymentSessionStatus.PENDING,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
data: {
|
|
74
|
+
...paymentData,
|
|
75
|
+
paystack_transaction_data: transaction,
|
|
76
|
+
paystack_transaction_id: transaction.id,
|
|
77
|
+
paystack_transaction_status: transaction.status,
|
|
78
|
+
},
|
|
79
|
+
status: utils_1.PaymentSessionStatus.CAPTURED,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
async retrievePayment(input) {
|
|
83
|
+
const paymentData = input.data;
|
|
84
|
+
if (!paymentData?.paystack_reference) {
|
|
85
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Missing paystack_reference in the payment data.");
|
|
86
|
+
}
|
|
87
|
+
const transaction = await this.client_.verifyTransaction(paymentData.paystack_reference);
|
|
88
|
+
return {
|
|
89
|
+
data: {
|
|
90
|
+
...paymentData,
|
|
91
|
+
paystack_transaction_data: transaction,
|
|
92
|
+
paystack_transaction_id: transaction.id,
|
|
93
|
+
paystack_transaction_status: transaction.status,
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async refundPayment(input) {
|
|
98
|
+
const paymentData = input.data;
|
|
99
|
+
const transactionId = paymentData.paystack_transaction_id ??
|
|
100
|
+
(await this.client_.verifyTransaction(paymentData.paystack_reference)).id;
|
|
101
|
+
const refund = await this.client_.refundTransaction(transactionId, (0, paystack_utils_1.toPaystackSubunit)(input.amount));
|
|
102
|
+
return {
|
|
103
|
+
data: {
|
|
104
|
+
...paymentData,
|
|
105
|
+
paystack_transaction_data: {
|
|
106
|
+
...(paymentData.paystack_transaction_data ?? {}),
|
|
107
|
+
refund,
|
|
108
|
+
},
|
|
109
|
+
paystack_transaction_id: transactionId,
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
async getPaymentStatus(input) {
|
|
114
|
+
const paymentData = input.data;
|
|
115
|
+
if (!paymentData?.paystack_reference) {
|
|
116
|
+
return { status: utils_1.PaymentSessionStatus.PENDING };
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
const transaction = await this.client_.verifyTransaction(paymentData.paystack_reference);
|
|
120
|
+
switch (transaction.status) {
|
|
121
|
+
case "success":
|
|
122
|
+
return { status: utils_1.PaymentSessionStatus.CAPTURED };
|
|
123
|
+
case "failed":
|
|
124
|
+
return { status: utils_1.PaymentSessionStatus.ERROR };
|
|
125
|
+
default:
|
|
126
|
+
return { status: utils_1.PaymentSessionStatus.PENDING };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return { status: utils_1.PaymentSessionStatus.ERROR };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async getWebhookActionAndData() {
|
|
134
|
+
return {
|
|
135
|
+
action: utils_1.PaymentActions.NOT_SUPPORTED,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
async capturePayment(input) {
|
|
139
|
+
return { data: input.data };
|
|
140
|
+
}
|
|
141
|
+
async cancelPayment(input) {
|
|
142
|
+
return { data: input.data };
|
|
143
|
+
}
|
|
144
|
+
async deletePayment(input) {
|
|
145
|
+
return { data: input.data };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
PaystackPaymentProviderService.identifier = constants_1.PAYSTACK_PROVIDER_IDENTIFIER;
|
|
149
|
+
exports.default = PaystackPaymentProviderService;
|
|
150
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9wcm92aWRlcnMvcGF5c3RhY2svc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXFCQSxxREFLa0M7QUFFbEMsK0NBQThEO0FBQzlELCtEQUEwRDtBQUMxRCw2REFHaUM7QUFlakMsTUFBTSw4QkFBK0IsU0FBUSwrQkFBZ0Q7SUFLM0YsWUFDRSxNQUErQixFQUMvQixPQUFnQztRQUVoQyxLQUFLLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFBO1FBRXRCLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDeEIsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUNsQyxxRUFBcUUsQ0FDdEUsQ0FBQTtRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksZ0NBQWMsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7SUFDdkQsQ0FBQztJQUVELEtBQUssQ0FBQyxlQUFlLENBQ25CLEtBQTJCO1FBRTNCLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxJQUFnRCxDQUFBO1FBQzNFLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDbkMsTUFBTSxTQUFTLEdBQ2IsWUFBWSxFQUFFLGtCQUFrQixJQUFJLElBQUEsdUNBQXNCLEdBQUUsQ0FBQTtRQUU5RCxPQUFPO1lBQ0wsRUFBRSxFQUFFLFNBQVM7WUFDYixJQUFJLEVBQUU7Z0JBQ0osTUFBTTtnQkFDTixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUU7Z0JBQ2hELGtCQUFrQixFQUFFLFNBQVM7YUFDOUI7U0FDRixDQUFBO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQ2pCLEtBQXlCO1FBRXpCLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxJQUFnRCxDQUFBO1FBQzNFLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDbkMsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtRQUN0RCxNQUFNLHFCQUFxQixHQUN6QixZQUFZLEVBQUUsTUFBTSxLQUFLLE1BQU07WUFDL0IsWUFBWSxFQUFFLGFBQWEsRUFBRSxXQUFXLEVBQUUsS0FBSyxZQUFZLENBQUE7UUFFN0QsT0FBTztZQUNMLElBQUksRUFBRTtnQkFDSixNQUFNO2dCQUNOLGFBQWEsRUFBRSxZQUFZO2dCQUMzQixrQkFBa0IsRUFDaEIscUJBQXFCLElBQUksQ0FBQyxZQUFZLEVBQUUsa0JBQWtCO29CQUN4RCxDQUFDLENBQUMsSUFBQSx1Q0FBc0IsR0FBRTtvQkFDMUIsQ0FBQyxDQUFDLFlBQVksQ0FBQyxrQkFBa0I7YUFDdEM7WUFDRCxNQUFNLEVBQUUsNEJBQW9CLENBQUMsT0FBTztTQUNyQyxDQUFBO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxnQkFBZ0IsQ0FDcEIsS0FBNEI7UUFFNUIsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLElBQTJCLENBQUE7UUFFckQsSUFBSSxDQUFDLFdBQVcsRUFBRSxrQkFBa0IsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLG9EQUFvRCxDQUNyRCxDQUFBO1FBQ0gsQ0FBQztRQUVELE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FDdEQsV0FBVyxDQUFDLGtCQUFrQixDQUMvQixDQUFBO1FBRUQsTUFBTSxjQUFjLEdBQUcsSUFBQSxrQ0FBaUIsRUFBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDNUQsTUFBTSxnQkFBZ0IsR0FBRyxXQUFXLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFBO1FBRWhFLElBQUksV0FBVyxDQUFDLE1BQU0sS0FBSyxjQUFjLEVBQUUsQ0FBQztZQUMxQyxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixnQ0FBZ0MsV0FBVyxDQUFDLGtCQUFrQixHQUFHLENBQ2xFLENBQUE7UUFDSCxDQUFDO1FBRUQsSUFBSSxXQUFXLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxLQUFLLGdCQUFnQixFQUFFLENBQUM7WUFDNUQsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsa0NBQWtDLFdBQVcsQ0FBQyxrQkFBa0IsR0FBRyxDQUNwRSxDQUFBO1FBQ0gsQ0FBQztRQUVELElBQUksV0FBVyxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNyQyxPQUFPO2dCQUNMLElBQUksRUFBRTtvQkFDSixHQUFHLFdBQVc7b0JBQ2QseUJBQXlCLEVBQUUsV0FBaUQ7b0JBQzVFLHVCQUF1QixFQUFFLFdBQVcsQ0FBQyxFQUFFO29CQUN2QywyQkFBMkIsRUFBRSxXQUFXLENBQUMsTUFBTTtpQkFDaEQ7Z0JBQ0QsTUFBTSxFQUNKLFdBQVcsQ0FBQyxNQUFNLEtBQUssUUFBUTtvQkFDN0IsQ0FBQyxDQUFDLDRCQUFvQixDQUFDLEtBQUs7b0JBQzVCLENBQUMsQ0FBQyw0QkFBb0IsQ0FBQyxPQUFPO2FBQ25DLENBQUE7UUFDSCxDQUFDO1FBRUQsT0FBTztZQUNMLElBQUksRUFBRTtnQkFDSixHQUFHLFdBQVc7Z0JBQ2QseUJBQXlCLEVBQUUsV0FBaUQ7Z0JBQzVFLHVCQUF1QixFQUFFLFdBQVcsQ0FBQyxFQUFFO2dCQUN2QywyQkFBMkIsRUFBRSxXQUFXLENBQUMsTUFBTTthQUNoRDtZQUNELE1BQU0sRUFBRSw0QkFBb0IsQ0FBQyxRQUFRO1NBQ3RDLENBQUE7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLGVBQWUsQ0FDbkIsS0FBMkI7UUFFM0IsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLElBQTJCLENBQUE7UUFFckQsSUFBSSxDQUFDLFdBQVcsRUFBRSxrQkFBa0IsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLGlEQUFpRCxDQUNsRCxDQUFBO1FBQ0gsQ0FBQztRQUVELE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FDdEQsV0FBVyxDQUFDLGtCQUFrQixDQUMvQixDQUFBO1FBRUQsT0FBTztZQUNMLElBQUksRUFBRTtnQkFDSixHQUFHLFdBQVc7Z0JBQ2QseUJBQXlCLEVBQUUsV0FBaUQ7Z0JBQzVFLHVCQUF1QixFQUFFLFdBQVcsQ0FBQyxFQUFFO2dCQUN2QywyQkFBMkIsRUFBRSxXQUFXLENBQUMsTUFBTTthQUNoRDtTQUNGLENBQUE7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWEsQ0FDakIsS0FBeUI7UUFFekIsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLElBQTJCLENBQUE7UUFFckQsTUFBTSxhQUFhLEdBQ2pCLFdBQVcsQ0FBQyx1QkFBdUI7WUFDbkMsQ0FBQyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUE7UUFFM0UsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUNqRCxhQUFhLEVBQ2IsSUFBQSxrQ0FBaUIsRUFBQyxLQUFLLENBQUMsTUFBeUIsQ0FBQyxDQUNuRCxDQUFBO1FBRUQsT0FBTztZQUNMLElBQUksRUFBRTtnQkFDSixHQUFHLFdBQVc7Z0JBQ2QseUJBQXlCLEVBQUU7b0JBQ3pCLEdBQUcsQ0FBQyxXQUFXLENBQUMseUJBQXlCLElBQUksRUFBRSxDQUFDO29CQUNoRCxNQUFNO2lCQUNQO2dCQUNELHVCQUF1QixFQUFFLGFBQWE7YUFDdkM7U0FDRixDQUFBO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxnQkFBZ0IsQ0FDcEIsS0FBNEI7UUFFNUIsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLElBQW9DLENBQUE7UUFFOUQsSUFBSSxDQUFDLFdBQVcsRUFBRSxrQkFBa0IsRUFBRSxDQUFDO1lBQ3JDLE9BQU8sRUFBRSxNQUFNLEVBQUUsNEJBQW9CLENBQUMsT0FBTyxFQUFFLENBQUE7UUFDakQsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FDdEQsV0FBVyxDQUFDLGtCQUFrQixDQUMvQixDQUFBO1lBRUQsUUFBUSxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQzNCLEtBQUssU0FBUztvQkFDWixPQUFPLEVBQUUsTUFBTSxFQUFFLDRCQUFvQixDQUFDLFFBQVEsRUFBRSxDQUFBO2dCQUNsRCxLQUFLLFFBQVE7b0JBQ1gsT0FBTyxFQUFFLE1BQU0sRUFBRSw0QkFBb0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtnQkFDL0M7b0JBQ0UsT0FBTyxFQUFFLE1BQU0sRUFBRSw0QkFBb0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQTtZQUNuRCxDQUFDO1FBQ0gsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sRUFBRSxNQUFNLEVBQUUsNEJBQW9CLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDL0MsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsdUJBQXVCO1FBQzNCLE9BQU87WUFDTCxNQUFNLEVBQUUsc0JBQWMsQ0FBQyxhQUFhO1NBQ3JDLENBQUE7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLGNBQWMsQ0FDbEIsS0FBMEI7UUFFMUIsT0FBTyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUE7SUFDN0IsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQ2pCLEtBQXlCO1FBRXpCLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFBO0lBQzdCLENBQUM7SUFFRCxLQUFLLENBQUMsYUFBYSxDQUNqQixLQUF5QjtRQUV6QixPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQTtJQUM3QixDQUFDOztBQTdOTSx5Q0FBVSxHQUFHLHdDQUE0QixDQUFBO0FBZ09sRCxrQkFBZSw4QkFBOEIsQ0FBQSJ9
|