@voyantjs/plugin-netopia 0.24.1 → 0.24.3
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/dist/checkout.d.ts +4 -0
- package/dist/checkout.d.ts.map +1 -0
- package/dist/checkout.js +20 -0
- package/dist/client.d.ts +22 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +129 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/notification-runtime.d.ts +13 -0
- package/dist/notification-runtime.d.ts.map +1 -0
- package/dist/notification-runtime.js +22 -0
- package/dist/plugin.d.ts +714 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +168 -0
- package/dist/service-callback.d.ts +8 -0
- package/dist/service-callback.d.ts.map +1 -0
- package/dist/service-callback.js +113 -0
- package/dist/service-collect.d.ts +9 -0
- package/dist/service-collect.d.ts.map +1 -0
- package/dist/service-collect.js +70 -0
- package/dist/service-shared.d.ts +33 -0
- package/dist/service-shared.d.ts.map +1 -0
- package/dist/service-shared.js +40 -0
- package/dist/service-start.d.ts +6 -0
- package/dist/service-start.d.ts.map +1 -0
- package/dist/service-start.js +81 -0
- package/dist/service.d.ts +13 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +12 -0
- package/dist/types.d.ts +169 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/validation.d.ts +518 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +132 -0
- package/package.json +7 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEhE,OAAO,EAAoB,KAAK,UAAU,EAAiB,MAAM,gBAAgB,CAAA;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAKjE,OAAO,KAAK,EAAE,qBAAqB,EAAiC,MAAM,YAAY,CAAA;AAStF,KAAK,GAAG,GAAG;IACT,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,SAAS,EAAE;QACT,SAAS,EAAE,eAAe,CAAA;QAC1B,EAAE,EAAE,kBAAkB,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,eAAO,MAAM,6BAA6B,8BAA8B,CAAA;AAkBxE,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,qBAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAgK7E;AAOD,wBAAgB,6BAA6B,CAAC,OAAO,GAAE,qBAA0B,GAAG,aAAa,CAKhG;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,qBAA0B,GAAG,UAAU,CAoBjF;AAED,oDAAoD;AACpD,eAAO,MAAM,iBAAiB,0BAAoB,CAAA;AAElD,eAAO,MAAM,uBAAuB,eAAkC,CAAA"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { FINANCE_ROUTE_RUNTIME_CONTAINER_KEY } from "@voyantjs/finance";
|
|
2
|
+
import { defineHonoBundle, parseJsonBody } from "@voyantjs/hono";
|
|
3
|
+
import { Hono } from "hono";
|
|
4
|
+
import { resolveNetopiaRuntimeOptions } from "./client.js";
|
|
5
|
+
import { netopiaService } from "./service.js";
|
|
6
|
+
import { netopiaCollectBookingGuaranteeSchema, netopiaCollectBookingScheduleSchema, netopiaCollectInvoiceSchema, netopiaStartPaymentSessionSchema, netopiaWebhookPayloadSchema, } from "./validation.js";
|
|
7
|
+
export const NETOPIA_RUNTIME_CONTAINER_KEY = "providers.netopia.runtime";
|
|
8
|
+
function getNetopiaRuntime(bindings, options, resolveFromContainer) {
|
|
9
|
+
if (resolveFromContainer) {
|
|
10
|
+
try {
|
|
11
|
+
return resolveFromContainer(NETOPIA_RUNTIME_CONTAINER_KEY);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
// Fall through to per-request resolution when bootstrap has not run.
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return resolveNetopiaRuntimeOptions(bindings, options);
|
|
18
|
+
}
|
|
19
|
+
export function createNetopiaFinanceRoutes(options = {}) {
|
|
20
|
+
const handleNetopiaError = (message) => {
|
|
21
|
+
if (message.includes("not found") ||
|
|
22
|
+
message.includes("Payment schedule not found") ||
|
|
23
|
+
message.includes("Booking guarantee not found") ||
|
|
24
|
+
message.includes("Invoice not found")) {
|
|
25
|
+
return { status: 404, message };
|
|
26
|
+
}
|
|
27
|
+
if (message.includes("not startable") || message.includes("already assigned")) {
|
|
28
|
+
return { status: 409, message };
|
|
29
|
+
}
|
|
30
|
+
if (message.includes("Cannot create payment session") ||
|
|
31
|
+
message.includes("outstanding balance") ||
|
|
32
|
+
message.includes("No recipient available")) {
|
|
33
|
+
return { status: 409, message };
|
|
34
|
+
}
|
|
35
|
+
if (message.includes("Missing Netopia config")) {
|
|
36
|
+
return { status: 500, message };
|
|
37
|
+
}
|
|
38
|
+
return { status: 502, message };
|
|
39
|
+
};
|
|
40
|
+
const resolveRuntime = (c) => getNetopiaRuntime(c.env, options, (key) => c.var.container.resolve(key));
|
|
41
|
+
return new Hono()
|
|
42
|
+
.post("/providers/netopia/payment-sessions/:sessionId/start", async (c) => {
|
|
43
|
+
try {
|
|
44
|
+
const data = await parseJsonBody(c, netopiaStartPaymentSessionSchema);
|
|
45
|
+
const runtime = resolveRuntime(c);
|
|
46
|
+
const result = await netopiaService.startPaymentSession(c.get("db"), c.req.param("sessionId"), data, runtime, undefined);
|
|
47
|
+
return c.json({ data: result }, 201);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
const message = error instanceof Error ? error.message : "Failed to start Netopia payment";
|
|
51
|
+
if (message.includes("Payment session not found")) {
|
|
52
|
+
return c.json({ error: message }, 404);
|
|
53
|
+
}
|
|
54
|
+
if (message.includes("not startable") || message.includes("already assigned")) {
|
|
55
|
+
return c.json({ error: message }, 409);
|
|
56
|
+
}
|
|
57
|
+
if (message.includes("Missing Netopia config")) {
|
|
58
|
+
return c.json({ error: message }, 500);
|
|
59
|
+
}
|
|
60
|
+
return c.json({ error: message }, 502);
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
.post("/providers/netopia/bookings/:bookingId/payment-schedules/:scheduleId/collect", async (c) => {
|
|
64
|
+
try {
|
|
65
|
+
const data = await parseJsonBody(c, netopiaCollectBookingScheduleSchema);
|
|
66
|
+
const runtime = resolveRuntime(c);
|
|
67
|
+
const result = await netopiaService.collectBookingSchedule(c.get("db"), c.req.param("scheduleId"), data, runtime, undefined, undefined, c.env);
|
|
68
|
+
return c.json({ data: result }, 201);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
const message = error instanceof Error ? error.message : "Failed to collect schedule payment";
|
|
72
|
+
const response = handleNetopiaError(message);
|
|
73
|
+
return c.json({ error: response.message }, response.status);
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
.post("/providers/netopia/bookings/:bookingId/guarantees/:guaranteeId/collect", async (c) => {
|
|
77
|
+
try {
|
|
78
|
+
const data = await parseJsonBody(c, netopiaCollectBookingGuaranteeSchema);
|
|
79
|
+
const runtime = resolveRuntime(c);
|
|
80
|
+
const result = await netopiaService.collectBookingGuarantee(c.get("db"), c.req.param("guaranteeId"), data, runtime, undefined, undefined, c.env);
|
|
81
|
+
return c.json({ data: result }, 201);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
const message = error instanceof Error ? error.message : "Failed to collect guarantee payment";
|
|
85
|
+
const response = handleNetopiaError(message);
|
|
86
|
+
return c.json({ error: response.message }, response.status);
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
.post("/providers/netopia/invoices/:invoiceId/collect", async (c) => {
|
|
90
|
+
try {
|
|
91
|
+
const data = await parseJsonBody(c, netopiaCollectInvoiceSchema);
|
|
92
|
+
const runtime = resolveRuntime(c);
|
|
93
|
+
const result = await netopiaService.collectInvoice(c.get("db"), c.req.param("invoiceId"), data, runtime, undefined, undefined, c.env);
|
|
94
|
+
return c.json({ data: result }, 201);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
const message = error instanceof Error ? error.message : "Failed to collect invoice payment";
|
|
98
|
+
const response = handleNetopiaError(message);
|
|
99
|
+
return c.json({ error: response.message }, response.status);
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
.post("/providers/netopia/callback", async (c) => {
|
|
103
|
+
const payload = await parseJsonBody(c, netopiaWebhookPayloadSchema);
|
|
104
|
+
const runtime = resolveRuntime(c);
|
|
105
|
+
const financeRuntime = (() => {
|
|
106
|
+
try {
|
|
107
|
+
return c.var.container?.resolve(FINANCE_ROUTE_RUNTIME_CONTAINER_KEY);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
})();
|
|
113
|
+
const result = await netopiaService.handleCallback(c.get("db"), payload, runtime, c.env, financeRuntime ? { eventBus: financeRuntime.eventBus } : undefined);
|
|
114
|
+
return c.json({ data: result });
|
|
115
|
+
})
|
|
116
|
+
.get("/providers/netopia/config", async (c) => {
|
|
117
|
+
try {
|
|
118
|
+
const runtime = resolveRuntime(c);
|
|
119
|
+
return c.json({
|
|
120
|
+
data: {
|
|
121
|
+
apiUrl: runtime.apiUrl,
|
|
122
|
+
notifyUrl: runtime.notifyUrl,
|
|
123
|
+
redirectUrl: runtime.redirectUrl,
|
|
124
|
+
emailTemplate: runtime.emailTemplate,
|
|
125
|
+
language: runtime.language,
|
|
126
|
+
successStatuses: runtime.successStatuses,
|
|
127
|
+
processingStatuses: runtime.processingStatuses,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
const message = error instanceof Error ? error.message : "Missing Netopia config";
|
|
133
|
+
return c.json({ error: message }, 500);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const netopiaFinanceExtensionDef = {
|
|
138
|
+
name: "netopia-finance",
|
|
139
|
+
module: "finance",
|
|
140
|
+
};
|
|
141
|
+
export function createNetopiaFinanceExtension(options = {}) {
|
|
142
|
+
return {
|
|
143
|
+
extension: netopiaFinanceExtensionDef,
|
|
144
|
+
routes: createNetopiaFinanceRoutes(options),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
export function netopiaHonoBundle(options = {}) {
|
|
148
|
+
return defineHonoBundle({
|
|
149
|
+
name: "netopia",
|
|
150
|
+
version: "0.1.0",
|
|
151
|
+
bootstrap: ({ bindings, container }) => {
|
|
152
|
+
try {
|
|
153
|
+
container.register(NETOPIA_RUNTIME_CONTAINER_KEY, resolveNetopiaRuntimeOptions(bindings, options));
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
// Defer resolution to per-request handlers. Missing env should only fail
|
|
157
|
+
// Netopia-owned routes, not the whole app — `getNetopiaRuntime` will retry
|
|
158
|
+
// from bindings on each request and surface the same error on Netopia calls.
|
|
159
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
160
|
+
console.warn(`[netopia] Runtime bootstrap skipped: ${message}`);
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
extensions: [createNetopiaFinanceExtension(options)],
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/** @deprecated Prefer {@link netopiaHonoBundle}. */
|
|
167
|
+
export const netopiaHonoPlugin = netopiaHonoBundle;
|
|
168
|
+
export const netopiaFinanceExtension = createNetopiaFinanceExtension();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { EventBus } from "@voyantjs/core";
|
|
2
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
3
|
+
import { type NetopiaCallbackResult } from "./service-shared.js";
|
|
4
|
+
import type { NetopiaRuntimeOptions, NetopiaWebhookPayload } from "./types.js";
|
|
5
|
+
export declare function handleCallback(db: PostgresJsDatabase, payload: NetopiaWebhookPayload, runtimeOptions?: NetopiaRuntimeOptions, bindings?: Record<string, unknown>, financeRuntime?: {
|
|
6
|
+
eventBus?: EventBus;
|
|
7
|
+
}): Promise<NetopiaCallbackResult>;
|
|
8
|
+
//# sourceMappingURL=service-callback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-callback.d.ts","sourceRoot":"","sources":["../src/service-callback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAGjE,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAE9E,wBAAsB,cAAc,CAClC,EAAE,EAAE,kBAAkB,EACtB,OAAO,EAAE,qBAAqB,EAC9B,cAAc,GAAE,qBAA0B,EAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,cAAc,GAAE;IAAE,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAO,GAC3C,OAAO,CAAC,qBAAqB,CAAC,CAqIhC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { resolveNetopiaRuntimeOptions } from "./client.js";
|
|
2
|
+
import { financeService, mapNetopiaPaymentStatus, mergeRecord, } from "./service-shared.js";
|
|
3
|
+
export async function handleCallback(db, payload, runtimeOptions = {}, bindings, financeRuntime = {}) {
|
|
4
|
+
const runtime = resolveNetopiaRuntimeOptions(bindings, runtimeOptions);
|
|
5
|
+
const orderId = payload.order.orderID;
|
|
6
|
+
const lookup = await financeService.listPaymentSessions(db, {
|
|
7
|
+
provider: "netopia",
|
|
8
|
+
externalReference: orderId,
|
|
9
|
+
limit: 1,
|
|
10
|
+
offset: 0,
|
|
11
|
+
});
|
|
12
|
+
let session = lookup.data[0] ?? null;
|
|
13
|
+
if (!session) {
|
|
14
|
+
session = await financeService.getPaymentSessionById(db, orderId);
|
|
15
|
+
}
|
|
16
|
+
if (!session) {
|
|
17
|
+
return {
|
|
18
|
+
action: "ignored",
|
|
19
|
+
reason: "payment_session_not_found",
|
|
20
|
+
session: null,
|
|
21
|
+
orderId,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const callbackState = mapNetopiaPaymentStatus(payload.payment.status, runtime);
|
|
25
|
+
const providerPayload = mergeRecord(session.providerPayload, {
|
|
26
|
+
netopiaCallback: payload,
|
|
27
|
+
});
|
|
28
|
+
// Note: we intentionally don't validate `payment.amount` / `payment.currency`
|
|
29
|
+
// against the session. Netopia auto-converts non-RON orders into RON for
|
|
30
|
+
// processing (so an EUR session always callbacks with `currency: "RON"` and
|
|
31
|
+
// a converted amount). Any strict equality check here would reject every
|
|
32
|
+
// legitimate cross-currency payment. The trustworthy field is
|
|
33
|
+
// `payment.status` — the orderID is the unguessable secret that ties the
|
|
34
|
+
// callback to the session, and Netopia is the only party that knows it.
|
|
35
|
+
// For tamper detection beyond that, wrap this handler at the route layer
|
|
36
|
+
// and verify the processed amount via your own FX source.
|
|
37
|
+
if (callbackState === "processing") {
|
|
38
|
+
const updated = await financeService.updatePaymentSession(db, session.id, {
|
|
39
|
+
status: "processing",
|
|
40
|
+
provider: "netopia",
|
|
41
|
+
providerSessionId: payload.payment.ntpID,
|
|
42
|
+
providerPaymentId: payload.payment.ntpID,
|
|
43
|
+
externalReference: orderId,
|
|
44
|
+
providerPayload,
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
action: "processing",
|
|
48
|
+
session: updated,
|
|
49
|
+
orderId,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (callbackState === "completed") {
|
|
53
|
+
if (session.status === "paid" || session.status === "authorized") {
|
|
54
|
+
const current = await financeService.updatePaymentSession(db, session.id, {
|
|
55
|
+
provider: "netopia",
|
|
56
|
+
providerSessionId: payload.payment.ntpID,
|
|
57
|
+
providerPaymentId: payload.payment.ntpID,
|
|
58
|
+
externalReference: orderId,
|
|
59
|
+
providerPayload,
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
action: "ignored",
|
|
63
|
+
reason: "already_completed",
|
|
64
|
+
session: current,
|
|
65
|
+
orderId,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const completed = await financeService.completePaymentSession(db, session.id, {
|
|
69
|
+
status: "paid",
|
|
70
|
+
captureMode: "manual",
|
|
71
|
+
paymentMethod: "credit_card",
|
|
72
|
+
providerSessionId: payload.payment.ntpID,
|
|
73
|
+
providerPaymentId: payload.payment.ntpID,
|
|
74
|
+
externalReference: orderId,
|
|
75
|
+
externalAuthorizationId: typeof payload.payment.data?.AuthCode === "string"
|
|
76
|
+
? payload.payment.data.AuthCode
|
|
77
|
+
: payload.payment.ntpID,
|
|
78
|
+
externalCaptureId: typeof payload.payment.data?.RRN === "string"
|
|
79
|
+
? payload.payment.data.RRN
|
|
80
|
+
: payload.payment.ntpID,
|
|
81
|
+
approvalCode: typeof payload.payment.data?.AuthCode === "string"
|
|
82
|
+
? payload.payment.data.AuthCode
|
|
83
|
+
: undefined,
|
|
84
|
+
referenceNumber: typeof payload.payment.data?.RRN === "string" ? payload.payment.data.RRN : undefined,
|
|
85
|
+
authorizedAt: new Date().toISOString(),
|
|
86
|
+
capturedAt: new Date().toISOString(),
|
|
87
|
+
paymentDate: new Date().toISOString(),
|
|
88
|
+
providerPayload,
|
|
89
|
+
}, { eventBus: financeRuntime.eventBus });
|
|
90
|
+
return {
|
|
91
|
+
action: "completed",
|
|
92
|
+
session: completed,
|
|
93
|
+
orderId,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const failed = await financeService.failPaymentSession(db, session.id, {
|
|
97
|
+
providerSessionId: payload.payment.ntpID,
|
|
98
|
+
providerPaymentId: payload.payment.ntpID,
|
|
99
|
+
externalReference: orderId,
|
|
100
|
+
failureCode: typeof payload.payment.code === "string" && payload.payment.code.length > 0
|
|
101
|
+
? payload.payment.code
|
|
102
|
+
: `netopia_status_${payload.payment.status}`,
|
|
103
|
+
failureMessage: typeof payload.payment.message === "string" && payload.payment.message.length > 0
|
|
104
|
+
? payload.payment.message
|
|
105
|
+
: "Netopia payment was not approved",
|
|
106
|
+
providerPayload,
|
|
107
|
+
});
|
|
108
|
+
return {
|
|
109
|
+
action: "failed",
|
|
110
|
+
session: failed,
|
|
111
|
+
orderId,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type NotificationService } from "@voyantjs/notifications";
|
|
2
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
3
|
+
import type { NetopiaClientApi } from "./client.js";
|
|
4
|
+
import { type NetopiaCollectBookingGuaranteeInput, type NetopiaCollectBookingScheduleInput, type NetopiaCollectInvoiceInput, type NetopiaCollectPaymentResult } from "./service-shared.js";
|
|
5
|
+
import type { NetopiaRuntimeOptions } from "./types.js";
|
|
6
|
+
export declare function collectBookingSchedule(db: PostgresJsDatabase, scheduleId: string, input: NetopiaCollectBookingScheduleInput, runtimeOptions?: NetopiaRuntimeOptions, clientOverride?: NetopiaClientApi, dispatcherOverride?: NotificationService, bindings?: Record<string, unknown>): Promise<NetopiaCollectPaymentResult>;
|
|
7
|
+
export declare function collectBookingGuarantee(db: PostgresJsDatabase, guaranteeId: string, input: NetopiaCollectBookingGuaranteeInput, runtimeOptions?: NetopiaRuntimeOptions, clientOverride?: NetopiaClientApi, dispatcherOverride?: NotificationService, bindings?: Record<string, unknown>): Promise<NetopiaCollectPaymentResult>;
|
|
8
|
+
export declare function collectInvoice(db: PostgresJsDatabase, invoiceId: string, input: NetopiaCollectInvoiceInput, runtimeOptions?: NetopiaRuntimeOptions, clientOverride?: NetopiaClientApi, dispatcherOverride?: NotificationService, bindings?: Record<string, unknown>): Promise<NetopiaCollectPaymentResult>;
|
|
9
|
+
//# sourceMappingURL=service-collect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-collect.d.ts","sourceRoot":"","sources":["../src/service-collect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAwB,MAAM,yBAAyB,CAAA;AACxF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAEL,KAAK,mCAAmC,EACxC,KAAK,kCAAkC,EACvC,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAEjC,MAAM,qBAAqB,CAAA;AAE5B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAEvD,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,kCAAkC,EACzC,cAAc,GAAE,qBAA0B,EAC1C,cAAc,CAAC,EAAE,gBAAgB,EACjC,kBAAkB,CAAC,EAAE,mBAAmB,EACxC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,2BAA2B,CAAC,CAsCtC;AAED,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,kBAAkB,EACtB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,mCAAmC,EAC1C,cAAc,GAAE,qBAA0B,EAC1C,cAAc,CAAC,EAAE,gBAAgB,EACjC,kBAAkB,CAAC,EAAE,mBAAmB,EACxC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,2BAA2B,CAAC,CAsCtC;AAED,wBAAsB,cAAc,CAClC,EAAE,EAAE,kBAAkB,EACtB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,0BAA0B,EACjC,cAAc,GAAE,qBAA0B,EAC1C,cAAc,CAAC,EAAE,gBAAgB,EACjC,kBAAkB,CAAC,EAAE,mBAAmB,EACxC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,2BAA2B,CAAC,CAiDtC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { notificationsService } from "@voyantjs/notifications";
|
|
2
|
+
import { financeService, resolveNotificationDispatcher, } from "./service-shared.js";
|
|
3
|
+
import * as startService from "./service-start.js";
|
|
4
|
+
export async function collectBookingSchedule(db, scheduleId, input, runtimeOptions = {}, clientOverride, dispatcherOverride, bindings) {
|
|
5
|
+
const session = await financeService.createPaymentSessionFromBookingSchedule(db, scheduleId, {
|
|
6
|
+
...(input.paymentSession ?? {}),
|
|
7
|
+
provider: "netopia",
|
|
8
|
+
});
|
|
9
|
+
if (!session) {
|
|
10
|
+
throw new Error("Payment schedule not found");
|
|
11
|
+
}
|
|
12
|
+
const started = await startService.startPaymentSession(db, session.id, input.netopia, runtimeOptions, clientOverride, bindings);
|
|
13
|
+
const dispatcher = input.notification
|
|
14
|
+
? resolveNotificationDispatcher(bindings, runtimeOptions, dispatcherOverride)
|
|
15
|
+
: null;
|
|
16
|
+
const paymentSessionNotification = input.notification && dispatcher
|
|
17
|
+
? await notificationsService.sendPaymentSessionNotification(db, dispatcher, started.session.id, input.notification)
|
|
18
|
+
: null;
|
|
19
|
+
return {
|
|
20
|
+
...started,
|
|
21
|
+
paymentSessionNotification,
|
|
22
|
+
invoiceNotification: null,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export async function collectBookingGuarantee(db, guaranteeId, input, runtimeOptions = {}, clientOverride, dispatcherOverride, bindings) {
|
|
26
|
+
const session = await financeService.createPaymentSessionFromBookingGuarantee(db, guaranteeId, {
|
|
27
|
+
...(input.paymentSession ?? {}),
|
|
28
|
+
provider: "netopia",
|
|
29
|
+
});
|
|
30
|
+
if (!session) {
|
|
31
|
+
throw new Error("Booking guarantee not found");
|
|
32
|
+
}
|
|
33
|
+
const started = await startService.startPaymentSession(db, session.id, input.netopia, runtimeOptions, clientOverride, bindings);
|
|
34
|
+
const dispatcher = input.notification
|
|
35
|
+
? resolveNotificationDispatcher(bindings, runtimeOptions, dispatcherOverride)
|
|
36
|
+
: null;
|
|
37
|
+
const paymentSessionNotification = input.notification && dispatcher
|
|
38
|
+
? await notificationsService.sendPaymentSessionNotification(db, dispatcher, started.session.id, input.notification)
|
|
39
|
+
: null;
|
|
40
|
+
return {
|
|
41
|
+
...started,
|
|
42
|
+
paymentSessionNotification,
|
|
43
|
+
invoiceNotification: null,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export async function collectInvoice(db, invoiceId, input, runtimeOptions = {}, clientOverride, dispatcherOverride, bindings) {
|
|
47
|
+
const session = await financeService.createPaymentSessionFromInvoice(db, invoiceId, {
|
|
48
|
+
...(input.paymentSession ?? {}),
|
|
49
|
+
provider: "netopia",
|
|
50
|
+
});
|
|
51
|
+
if (!session) {
|
|
52
|
+
throw new Error("Invoice not found");
|
|
53
|
+
}
|
|
54
|
+
const started = await startService.startPaymentSession(db, session.id, input.netopia, runtimeOptions, clientOverride, bindings);
|
|
55
|
+
const shouldNotify = Boolean(input.paymentSessionNotification || input.invoiceNotification);
|
|
56
|
+
const dispatcher = shouldNotify
|
|
57
|
+
? resolveNotificationDispatcher(bindings, runtimeOptions, dispatcherOverride)
|
|
58
|
+
: null;
|
|
59
|
+
const paymentSessionNotification = input.paymentSessionNotification && dispatcher
|
|
60
|
+
? await notificationsService.sendPaymentSessionNotification(db, dispatcher, started.session.id, input.paymentSessionNotification)
|
|
61
|
+
: null;
|
|
62
|
+
const invoiceNotification = input.invoiceNotification && dispatcher
|
|
63
|
+
? await notificationsService.sendInvoiceNotification(db, dispatcher, invoiceId, input.invoiceNotification)
|
|
64
|
+
: null;
|
|
65
|
+
return {
|
|
66
|
+
...started,
|
|
67
|
+
paymentSessionNotification,
|
|
68
|
+
invoiceNotification,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { financeService, type PaymentSession } from "@voyantjs/finance";
|
|
2
|
+
import type { NotificationDelivery, NotificationService } from "@voyantjs/notifications";
|
|
3
|
+
import type { z } from "zod";
|
|
4
|
+
import type { NetopiaProductLine, NetopiaRuntimeOptions, NetopiaStartPaymentResponse, ResolvedNetopiaRuntimeOptions } from "./types.js";
|
|
5
|
+
import type { netopiaCollectBookingGuaranteeSchema, netopiaCollectBookingScheduleSchema, netopiaCollectInvoiceSchema } from "./validation.js";
|
|
6
|
+
export interface NetopiaStartPaymentResult {
|
|
7
|
+
session: PaymentSession;
|
|
8
|
+
providerResponse: NetopiaStartPaymentResponse;
|
|
9
|
+
orderId: string;
|
|
10
|
+
}
|
|
11
|
+
export interface NetopiaCallbackResult {
|
|
12
|
+
action: "processing" | "completed" | "failed" | "ignored";
|
|
13
|
+
reason?: string;
|
|
14
|
+
session: PaymentSession | null;
|
|
15
|
+
orderId: string;
|
|
16
|
+
}
|
|
17
|
+
export interface NetopiaCollectPaymentResult extends NetopiaStartPaymentResult {
|
|
18
|
+
paymentSessionNotification: NotificationDelivery | null;
|
|
19
|
+
invoiceNotification: NotificationDelivery | null;
|
|
20
|
+
}
|
|
21
|
+
export type NetopiaCollectBookingScheduleInput = z.infer<typeof netopiaCollectBookingScheduleSchema>;
|
|
22
|
+
export type NetopiaCollectBookingGuaranteeInput = z.infer<typeof netopiaCollectBookingGuaranteeSchema>;
|
|
23
|
+
export type NetopiaCollectInvoiceInput = z.infer<typeof netopiaCollectInvoiceSchema>;
|
|
24
|
+
export declare function centsToAmount(cents: number): number;
|
|
25
|
+
export declare function amountToCents(amount: number): number;
|
|
26
|
+
export declare function normalizeCurrency(currency: string): string;
|
|
27
|
+
export declare function mergeRecord(base: Record<string, unknown> | null | undefined, extra: Record<string, unknown>): Record<string, unknown>;
|
|
28
|
+
export declare function buildDefaultProducts(session: PaymentSession, description: string): NetopiaProductLine[];
|
|
29
|
+
export declare function deriveNetopiaOrderId(session: PaymentSession): string;
|
|
30
|
+
export declare function mapNetopiaPaymentStatus(status: number, options: Pick<ResolvedNetopiaRuntimeOptions, "successStatuses" | "processingStatuses">): "completed" | "processing" | "failed";
|
|
31
|
+
export declare function resolveNotificationDispatcher(bindings: Record<string, unknown> | undefined, runtimeOptions: NetopiaRuntimeOptions, dispatcherOverride?: NotificationService): NotificationService;
|
|
32
|
+
export { financeService };
|
|
33
|
+
//# sourceMappingURL=service-shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-shared.d.ts","sourceRoot":"","sources":["../src/service-shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AACxF,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAG5B,OAAO,KAAK,EACV,kBAAkB,EAClB,qBAAqB,EACrB,2BAA2B,EAC3B,6BAA6B,EAC9B,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EACV,oCAAoC,EACpC,mCAAmC,EACnC,2BAA2B,EAC5B,MAAM,iBAAiB,CAAA;AAExB,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,cAAc,CAAA;IACvB,gBAAgB,EAAE,2BAA2B,CAAA;IAC7C,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,YAAY,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAA;IACzD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,cAAc,GAAG,IAAI,CAAA;IAC9B,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,2BAA4B,SAAQ,yBAAyB;IAC5E,0BAA0B,EAAE,oBAAoB,GAAG,IAAI,CAAA;IACvD,mBAAmB,EAAE,oBAAoB,GAAG,IAAI,CAAA;CACjD;AAED,MAAM,MAAM,kCAAkC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAA;AACpG,MAAM,MAAM,mCAAmC,GAAG,CAAC,CAAC,KAAK,CACvD,OAAO,oCAAoC,CAC5C,CAAA;AACD,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAEpF,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,UAE1C;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,UAE3C;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,UAEjD;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAChD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKzB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,MAAM,GAClB,kBAAkB,EAAE,CAQtB;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,cAAc,UAE3D;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,IAAI,CAAC,6BAA6B,EAAE,iBAAiB,GAAG,oBAAoB,CAAC,GACrF,WAAW,GAAG,YAAY,GAAG,QAAQ,CAIvC;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC7C,cAAc,EAAE,qBAAqB,EACrC,kBAAkB,CAAC,EAAE,mBAAmB,uBAGzC;AAED,OAAO,EAAE,cAAc,EAAE,CAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { financeService } from "@voyantjs/finance";
|
|
2
|
+
import { buildNetopiaNotificationRuntime } from "./notification-runtime.js";
|
|
3
|
+
export function centsToAmount(cents) {
|
|
4
|
+
return Number((cents / 100).toFixed(2));
|
|
5
|
+
}
|
|
6
|
+
export function amountToCents(amount) {
|
|
7
|
+
return Math.round(amount * 100);
|
|
8
|
+
}
|
|
9
|
+
export function normalizeCurrency(currency) {
|
|
10
|
+
return currency.trim().toUpperCase();
|
|
11
|
+
}
|
|
12
|
+
export function mergeRecord(base, extra) {
|
|
13
|
+
return {
|
|
14
|
+
...(base ?? {}),
|
|
15
|
+
...extra,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function buildDefaultProducts(session, description) {
|
|
19
|
+
return [
|
|
20
|
+
{
|
|
21
|
+
name: description,
|
|
22
|
+
price: centsToAmount(session.amountCents),
|
|
23
|
+
vat: 0,
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
export function deriveNetopiaOrderId(session) {
|
|
28
|
+
return session.externalReference ?? session.clientReference ?? session.id;
|
|
29
|
+
}
|
|
30
|
+
export function mapNetopiaPaymentStatus(status, options) {
|
|
31
|
+
if (options.successStatuses.includes(status))
|
|
32
|
+
return "completed";
|
|
33
|
+
if (options.processingStatuses.includes(status))
|
|
34
|
+
return "processing";
|
|
35
|
+
return "failed";
|
|
36
|
+
}
|
|
37
|
+
export function resolveNotificationDispatcher(bindings, runtimeOptions, dispatcherOverride) {
|
|
38
|
+
return buildNetopiaNotificationRuntime(bindings, runtimeOptions, dispatcherOverride).dispatcher;
|
|
39
|
+
}
|
|
40
|
+
export { financeService };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
2
|
+
import { type NetopiaClientApi } from "./client.js";
|
|
3
|
+
import { type NetopiaStartPaymentResult } from "./service-shared.js";
|
|
4
|
+
import type { NetopiaRuntimeOptions, NetopiaStartPaymentInput } from "./types.js";
|
|
5
|
+
export declare function startPaymentSession(db: PostgresJsDatabase, sessionId: string, input: NetopiaStartPaymentInput, runtimeOptions?: NetopiaRuntimeOptions, clientOverride?: NetopiaClientApi, bindings?: Record<string, unknown>): Promise<NetopiaStartPaymentResult>;
|
|
6
|
+
//# sourceMappingURL=service-start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-start.d.ts","sourceRoot":"","sources":["../src/service-start.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAEjE,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,aAAa,CAAA;AACpB,OAAO,EAML,KAAK,yBAAyB,EAE/B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EACV,qBAAqB,EACrB,wBAAwB,EAEzB,MAAM,YAAY,CAAA;AAEnB,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,kBAAkB,EACtB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,wBAAwB,EAC/B,cAAc,GAAE,qBAA0B,EAC1C,cAAc,CAAC,EAAE,gBAAgB,EACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,yBAAyB,CAAC,CA0FpC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { createNetopiaClient, resolveNetopiaRuntimeOptions, } from "./client.js";
|
|
2
|
+
import { buildDefaultProducts, centsToAmount, deriveNetopiaOrderId, financeService, mergeRecord, normalizeCurrency, } from "./service-shared.js";
|
|
3
|
+
export async function startPaymentSession(db, sessionId, input, runtimeOptions = {}, clientOverride, bindings) {
|
|
4
|
+
const session = await financeService.getPaymentSessionById(db, sessionId);
|
|
5
|
+
if (!session) {
|
|
6
|
+
throw new Error("Payment session not found");
|
|
7
|
+
}
|
|
8
|
+
if (session.provider && session.provider !== "netopia") {
|
|
9
|
+
throw new Error(`Payment session ${sessionId} is already assigned to provider "${session.provider}"`);
|
|
10
|
+
}
|
|
11
|
+
if (["paid", "authorized", "cancelled", "expired"].includes(session.status)) {
|
|
12
|
+
throw new Error(`Payment session ${sessionId} is not startable from status "${session.status}"`);
|
|
13
|
+
}
|
|
14
|
+
const runtime = resolveNetopiaRuntimeOptions(bindings, runtimeOptions);
|
|
15
|
+
const client = clientOverride ??
|
|
16
|
+
createNetopiaClient({
|
|
17
|
+
apiUrl: runtime.apiUrl,
|
|
18
|
+
apiKey: runtime.apiKey,
|
|
19
|
+
fetch: runtime.fetch,
|
|
20
|
+
});
|
|
21
|
+
const description = input.description ?? session.notes ?? `Payment ${session.id}`;
|
|
22
|
+
const orderId = deriveNetopiaOrderId(session);
|
|
23
|
+
const request = {
|
|
24
|
+
config: {
|
|
25
|
+
emailTemplate: input.emailTemplate ?? runtime.emailTemplate,
|
|
26
|
+
notifyUrl: input.notifyUrl ?? runtime.notifyUrl,
|
|
27
|
+
redirectUrl: input.returnUrl ?? runtime.redirectUrl,
|
|
28
|
+
language: input.language ?? runtime.language,
|
|
29
|
+
},
|
|
30
|
+
payment: {
|
|
31
|
+
options: input.options ?? { installments: 1 },
|
|
32
|
+
instrument: input.instrument,
|
|
33
|
+
data: input.browserData,
|
|
34
|
+
},
|
|
35
|
+
order: {
|
|
36
|
+
ntpID: "",
|
|
37
|
+
posSignature: runtime.posSignature,
|
|
38
|
+
dateTime: new Date().toISOString(),
|
|
39
|
+
description,
|
|
40
|
+
orderID: orderId,
|
|
41
|
+
amount: centsToAmount(session.amountCents),
|
|
42
|
+
currency: normalizeCurrency(session.currency),
|
|
43
|
+
billing: input.billing,
|
|
44
|
+
shipping: input.shipping ?? input.billing,
|
|
45
|
+
products: input.products && input.products.length > 0
|
|
46
|
+
? input.products
|
|
47
|
+
: buildDefaultProducts(session, description),
|
|
48
|
+
installments: input.installments ?? { selected: 1, available: [0] },
|
|
49
|
+
data: input.orderData,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
const providerResponse = await client.startCardPayment(request);
|
|
53
|
+
const payment = providerResponse.payment;
|
|
54
|
+
if (!payment?.paymentURL) {
|
|
55
|
+
throw new Error("Netopia start payment succeeded without paymentURL");
|
|
56
|
+
}
|
|
57
|
+
const updated = await financeService.markPaymentSessionRequiresRedirect(db, session.id, {
|
|
58
|
+
provider: "netopia",
|
|
59
|
+
providerSessionId: payment.ntpID ?? null,
|
|
60
|
+
providerPaymentId: payment.ntpID ?? null,
|
|
61
|
+
externalReference: orderId,
|
|
62
|
+
redirectUrl: payment.paymentURL,
|
|
63
|
+
returnUrl: input.returnUrl ?? runtime.redirectUrl,
|
|
64
|
+
cancelUrl: input.cancelUrl ?? null,
|
|
65
|
+
callbackUrl: input.callbackUrl ?? input.notifyUrl ?? runtime.notifyUrl,
|
|
66
|
+
providerPayload: mergeRecord(session.providerPayload, {
|
|
67
|
+
netopiaStartRequest: request,
|
|
68
|
+
netopiaStartResponse: providerResponse,
|
|
69
|
+
}),
|
|
70
|
+
metadata: input.metadata ?? undefined,
|
|
71
|
+
notes: input.notes ?? session.notes ?? undefined,
|
|
72
|
+
});
|
|
73
|
+
if (!updated) {
|
|
74
|
+
throw new Error("Payment session disappeared while saving Netopia redirect state");
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
session: updated,
|
|
78
|
+
providerResponse,
|
|
79
|
+
orderId,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { handleCallback } from "./service-callback.js";
|
|
2
|
+
import { collectBookingGuarantee, collectBookingSchedule, collectInvoice } from "./service-collect.js";
|
|
3
|
+
import { deriveNetopiaOrderId, mapNetopiaPaymentStatus, type NetopiaCallbackResult, type NetopiaCollectPaymentResult, type NetopiaStartPaymentResult } from "./service-shared.js";
|
|
4
|
+
import { startPaymentSession } from "./service-start.js";
|
|
5
|
+
export { deriveNetopiaOrderId, mapNetopiaPaymentStatus, type NetopiaCallbackResult, type NetopiaCollectPaymentResult, type NetopiaStartPaymentResult, };
|
|
6
|
+
export declare const netopiaService: {
|
|
7
|
+
startPaymentSession: typeof startPaymentSession;
|
|
8
|
+
collectBookingSchedule: typeof collectBookingSchedule;
|
|
9
|
+
collectBookingGuarantee: typeof collectBookingGuarantee;
|
|
10
|
+
collectInvoice: typeof collectInvoice;
|
|
11
|
+
handleCallback: typeof handleCallback;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,cAAc,EACf,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,EAC/B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAExD,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,GAC/B,CAAA;AAED,eAAO,MAAM,cAAc;;;;;;CAM1B,CAAA"}
|
package/dist/service.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { handleCallback } from "./service-callback.js";
|
|
2
|
+
import { collectBookingGuarantee, collectBookingSchedule, collectInvoice, } from "./service-collect.js";
|
|
3
|
+
import { deriveNetopiaOrderId, mapNetopiaPaymentStatus, } from "./service-shared.js";
|
|
4
|
+
import { startPaymentSession } from "./service-start.js";
|
|
5
|
+
export { deriveNetopiaOrderId, mapNetopiaPaymentStatus, };
|
|
6
|
+
export const netopiaService = {
|
|
7
|
+
startPaymentSession,
|
|
8
|
+
collectBookingSchedule,
|
|
9
|
+
collectBookingGuarantee,
|
|
10
|
+
collectInvoice,
|
|
11
|
+
handleCallback,
|
|
12
|
+
};
|