@legenki/print2medusa 0.1.0 → 0.3.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/.medusa/server/src/admin/index.js +138 -1
- package/.medusa/server/src/admin/index.mjs +139 -2
- package/.medusa/server/src/api/admin/printful/webhook/route.js +78 -0
- package/.medusa/server/src/api/hooks/printful/[token]/route.js +80 -0
- package/.medusa/server/src/api/middlewares.js +60 -0
- package/.medusa/server/src/jobs/retry-webhook-events.js +65 -0
- package/.medusa/server/src/modules/printful/migrations/Migration20260731000000.js +62 -0
- package/.medusa/server/src/modules/printful/models/printful-webhook-event.js +18 -0
- package/.medusa/server/src/modules/printful/service.js +123 -3
- package/.medusa/server/src/providers/printful-fulfillment/service.js +272 -15
- package/.medusa/server/src/subscribers/payment-captured.js +1 -1
- package/.medusa/server/src/utils/mappers.js +78 -21
- package/.medusa/server/src/utils/order-state.js +58 -0
- package/.medusa/server/src/utils/printful-client.js +37 -1
- package/.medusa/server/src/utils/shipping-rates.js +156 -0
- package/.medusa/server/src/utils/webhook-events.js +117 -0
- package/.medusa/server/src/utils/webhook-path.js +44 -0
- package/.medusa/server/src/workflows/apply-order-status.js +244 -0
- package/.medusa/server/src/workflows/create-printful-order.js +3 -2
- package/.medusa/server/src/workflows/index.js +5 -2
- package/.medusa/server/src/workflows/sync-products.js +1 -1
- package/README.md +193 -18
- package/package.json +6 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Migration20260731000000 = void 0;
|
|
4
|
+
const migrations_1 = require("@medusajs/framework/mikro-orm/migrations");
|
|
5
|
+
class Migration20260731000000 extends migrations_1.Migration {
|
|
6
|
+
async up() {
|
|
7
|
+
this.addSql(`
|
|
8
|
+
create table if not exists "printful_webhook_event" (
|
|
9
|
+
"id" text not null,
|
|
10
|
+
"event_id" text not null,
|
|
11
|
+
"type" text not null,
|
|
12
|
+
"printful_order_id" text not null,
|
|
13
|
+
"printful_shipment_id" text null,
|
|
14
|
+
"payload" jsonb not null default '{}'::jsonb,
|
|
15
|
+
"status" text not null default 'received',
|
|
16
|
+
"attempts" integer not null default 0,
|
|
17
|
+
"next_retry_at" timestamptz null,
|
|
18
|
+
"processed_at" timestamptz null,
|
|
19
|
+
"error_message" text null,
|
|
20
|
+
"created_at" timestamptz not null default now(),
|
|
21
|
+
"updated_at" timestamptz not null default now(),
|
|
22
|
+
"deleted_at" timestamptz null,
|
|
23
|
+
constraint "printful_webhook_event_pkey" primary key ("id")
|
|
24
|
+
);
|
|
25
|
+
`);
|
|
26
|
+
this.addSql(`
|
|
27
|
+
create unique index if not exists "IDX_printful_webhook_event_event_id"
|
|
28
|
+
on "printful_webhook_event" ("event_id")
|
|
29
|
+
where deleted_at is null;
|
|
30
|
+
`);
|
|
31
|
+
this.addSql(`
|
|
32
|
+
create index if not exists "IDX_printful_webhook_event_order"
|
|
33
|
+
on "printful_webhook_event" ("printful_order_id")
|
|
34
|
+
where deleted_at is null;
|
|
35
|
+
`);
|
|
36
|
+
this.addSql(`
|
|
37
|
+
create index if not exists "IDX_printful_webhook_event_shipment"
|
|
38
|
+
on "printful_webhook_event" ("printful_shipment_id")
|
|
39
|
+
where deleted_at is null;
|
|
40
|
+
`);
|
|
41
|
+
this.addSql(`
|
|
42
|
+
create index if not exists "IDX_printful_webhook_event_retry"
|
|
43
|
+
on "printful_webhook_event" ("status", "next_retry_at")
|
|
44
|
+
where deleted_at is null;
|
|
45
|
+
`);
|
|
46
|
+
// Webhooks arrive knowing only the Printful order id, so this lookup must
|
|
47
|
+
// not be a sequential scan. The sentinel written by claimOrderLink is
|
|
48
|
+
// excluded: without that exclusion, two concurrent claims would collide
|
|
49
|
+
// here instead of on medusa_order_id, breaking insert-first protection.
|
|
50
|
+
this.addSql(`
|
|
51
|
+
create unique index if not exists "IDX_printful_order_link_printful"
|
|
52
|
+
on "printful_order_link" ("printful_order_id")
|
|
53
|
+
where deleted_at is null and "printful_order_id" <> 'pending';
|
|
54
|
+
`);
|
|
55
|
+
}
|
|
56
|
+
async down() {
|
|
57
|
+
this.addSql(`drop index if exists "IDX_printful_order_link_printful";`);
|
|
58
|
+
this.addSql(`drop table if exists "printful_webhook_event" cascade;`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.Migration20260731000000 = Migration20260731000000;
|
|
62
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWlncmF0aW9uMjAyNjA3MzEwMDAwMDAuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9wcmludGZ1bC9taWdyYXRpb25zL01pZ3JhdGlvbjIwMjYwNzMxMDAwMDAwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlFQUFvRTtBQUVwRSxNQUFhLHVCQUF3QixTQUFRLHNCQUFTO0lBQzNDLEtBQUssQ0FBQyxFQUFFO1FBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0tBa0JYLENBQUMsQ0FBQTtRQUNGLElBQUksQ0FBQyxNQUFNLENBQUM7Ozs7S0FJWCxDQUFDLENBQUE7UUFDRixJQUFJLENBQUMsTUFBTSxDQUFDOzs7O0tBSVgsQ0FBQyxDQUFBO1FBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQzs7OztLQUlYLENBQUMsQ0FBQTtRQUNGLElBQUksQ0FBQyxNQUFNLENBQUM7Ozs7S0FJWCxDQUFDLENBQUE7UUFFRiwwRUFBMEU7UUFDMUUsc0VBQXNFO1FBQ3RFLHdFQUF3RTtRQUN4RSx3RUFBd0U7UUFDeEUsSUFBSSxDQUFDLE1BQU0sQ0FBQzs7OztLQUlYLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFUSxLQUFLLENBQUMsSUFBSTtRQUNqQixJQUFJLENBQUMsTUFBTSxDQUFDLDBEQUEwRCxDQUFDLENBQUE7UUFDdkUsSUFBSSxDQUFDLE1BQU0sQ0FBQyx3REFBd0QsQ0FBQyxDQUFBO0lBQ3ZFLENBQUM7Q0FDRjtBQXpERCwwREF5REMifQ==
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const PrintfulWebhookEvent = utils_1.model.define("printful_webhook_event", {
|
|
5
|
+
id: utils_1.model.id().primaryKey(),
|
|
6
|
+
event_id: utils_1.model.text().unique(),
|
|
7
|
+
type: utils_1.model.text(),
|
|
8
|
+
printful_order_id: utils_1.model.text(),
|
|
9
|
+
printful_shipment_id: utils_1.model.text().nullable(),
|
|
10
|
+
payload: utils_1.model.json(),
|
|
11
|
+
status: utils_1.model.text().default("received"),
|
|
12
|
+
attempts: utils_1.model.number().default(0),
|
|
13
|
+
next_retry_at: utils_1.model.dateTime().nullable(),
|
|
14
|
+
processed_at: utils_1.model.dateTime().nullable(),
|
|
15
|
+
error_message: utils_1.model.text().nullable(),
|
|
16
|
+
});
|
|
17
|
+
exports.default = PrintfulWebhookEvent;
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpbnRmdWwtd2ViaG9vay1ldmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL3ByaW50ZnVsL21vZGVscy9wcmludGZ1bC13ZWJob29rLWV2ZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEscURBQWlEO0FBRWpELE1BQU0sb0JBQW9CLEdBQUcsYUFBSyxDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsRUFBRTtJQUNsRSxFQUFFLEVBQUUsYUFBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLFVBQVUsRUFBRTtJQUMzQixRQUFRLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sRUFBRTtJQUMvQixJQUFJLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRTtJQUNsQixpQkFBaUIsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFO0lBQy9CLG9CQUFvQixFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDN0MsT0FBTyxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUU7SUFDckIsTUFBTSxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDO0lBQ3hDLFFBQVEsRUFBRSxhQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNuQyxhQUFhLEVBQUUsYUFBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMxQyxZQUFZLEVBQUUsYUFBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUN6QyxhQUFhLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtDQUN2QyxDQUFDLENBQUE7QUFFRixrQkFBZSxvQkFBb0IsQ0FBQSJ9
|
|
@@ -3,20 +3,63 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.PENDING_PRINTFUL_ORDER_ID = void 0;
|
|
6
|
+
exports.MAX_WEBHOOK_ATTEMPTS = exports.PENDING_PRINTFUL_ORDER_ID = void 0;
|
|
7
|
+
exports.nextRetryDelayMs = nextRetryDelayMs;
|
|
8
|
+
exports.lockKeyFor = lockKeyFor;
|
|
7
9
|
exports.isUniqueViolation = isUniqueViolation;
|
|
8
10
|
const utils_1 = require("@medusajs/framework/utils");
|
|
11
|
+
const crypto_1 = require("crypto");
|
|
9
12
|
const printful_client_1 = require("../../utils/printful-client");
|
|
10
13
|
const printful_order_link_1 = __importDefault(require("./models/printful-order-link"));
|
|
11
14
|
const printful_product_link_1 = __importDefault(require("./models/printful-product-link"));
|
|
12
15
|
const printful_sync_log_1 = __importDefault(require("./models/printful-sync-log"));
|
|
13
16
|
const printful_variant_link_1 = __importDefault(require("./models/printful-variant-link"));
|
|
14
|
-
|
|
17
|
+
const printful_webhook_event_1 = __importDefault(require("./models/printful-webhook-event"));
|
|
18
|
+
/**
|
|
19
|
+
* Sentinel stored in a placeholder link before the Printful order exists.
|
|
20
|
+
*
|
|
21
|
+
* Migration20260731000000 excludes this exact value from the unique index on
|
|
22
|
+
* printful_order_id. Changing it without updating that migration reintroduces
|
|
23
|
+
* the concurrent-claim race; tests/order-link.test.ts guards the pairing.
|
|
24
|
+
*/
|
|
15
25
|
exports.PENDING_PRINTFUL_ORDER_ID = "pending";
|
|
26
|
+
/** Attempts before an event is parked as permanently failed. */
|
|
27
|
+
exports.MAX_WEBHOOK_ATTEMPTS = 20;
|
|
28
|
+
/** Backoff: 5 minutes doubling per attempt, capped at 6 hours. */
|
|
29
|
+
function nextRetryDelayMs(attempts) {
|
|
30
|
+
const FIVE_MINUTES = 5 * 60 * 1000;
|
|
31
|
+
const SIX_HOURS = 6 * 60 * 60 * 1000;
|
|
32
|
+
return Math.min(FIVE_MINUTES * Math.pow(2, attempts), SIX_HOURS);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Stable 32-bit key for pg_advisory_xact_lock, derived from the order id.
|
|
36
|
+
*
|
|
37
|
+
* readInt32BE yields a signed 32-bit integer, which is exactly the width
|
|
38
|
+
* pg_advisory_xact_lock's single-argument form takes. The order id itself never
|
|
39
|
+
* reaches SQL — only this number does, and it is passed as a bind parameter.
|
|
40
|
+
*
|
|
41
|
+
* 32 bits means distinct orders can collide (~2 per 200k ids). A collision
|
|
42
|
+
* only serializes two unrelated orders against each other, which is slower
|
|
43
|
+
* but never incorrect, so the simpler single-argument lock form is worth it.
|
|
44
|
+
*/
|
|
45
|
+
function lockKeyFor(printfulOrderId) {
|
|
46
|
+
const digest = (0, crypto_1.createHash)("sha256").update(String(printfulOrderId)).digest();
|
|
47
|
+
return digest.readInt32BE(0);
|
|
48
|
+
}
|
|
16
49
|
/**
|
|
17
50
|
* Detect a Postgres unique-constraint violation (SQLSTATE 23505) regardless of
|
|
18
51
|
* how the ORM wraps the driver error. Used to turn a lost insert race into a
|
|
19
52
|
* clean "already claimed" signal instead of a thrown error.
|
|
53
|
+
*
|
|
54
|
+
* The mapped-MedusaError branch is load-bearing and cannot be dropped. Medusa's
|
|
55
|
+
* dbErrorMapper (@medusajs/utils dal/mikro-orm/db-error-mapper) intercepts the
|
|
56
|
+
* driver's 23505 and throws a BRAND NEW MedusaError carrying only
|
|
57
|
+
* `type: "invalid_data"` and a prose message ending "already exists." — no
|
|
58
|
+
* `code`, no `cause` chain, and no "23505" anywhere in the text. Every other
|
|
59
|
+
* branch here misses it. Without this check a redelivered webhook (which
|
|
60
|
+
* Printful sends by design) surfaces as a 500 instead of being absorbed as a
|
|
61
|
+
* duplicate, and Printful then retries an event that can never succeed.
|
|
62
|
+
* Verified against a real Postgres in tests/webhook-route.integration.test.ts.
|
|
20
63
|
*/
|
|
21
64
|
function isUniqueViolation(err) {
|
|
22
65
|
if (!err || typeof err !== "object") {
|
|
@@ -29,6 +72,11 @@ function isUniqueViolation(err) {
|
|
|
29
72
|
if (typeof e.message === "string" && e.message.includes("23505")) {
|
|
30
73
|
return true;
|
|
31
74
|
}
|
|
75
|
+
if (e.type === "invalid_data" &&
|
|
76
|
+
typeof e.message === "string" &&
|
|
77
|
+
/already exists\.?$/i.test(e.message.trim())) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
32
80
|
if (e.cause && e.cause !== err) {
|
|
33
81
|
return isUniqueViolation(e.cause);
|
|
34
82
|
}
|
|
@@ -39,6 +87,7 @@ class PrintfulModuleService extends (0, utils_1.MedusaService)({
|
|
|
39
87
|
PrintfulVariantLink: printful_variant_link_1.default,
|
|
40
88
|
PrintfulSyncLog: printful_sync_log_1.default,
|
|
41
89
|
PrintfulOrderLink: printful_order_link_1.default,
|
|
90
|
+
PrintfulWebhookEvent: printful_webhook_event_1.default,
|
|
42
91
|
}) {
|
|
43
92
|
constructor(container, options) {
|
|
44
93
|
// MedusaService multi-arg constructor
|
|
@@ -92,6 +141,77 @@ class PrintfulModuleService extends (0, utils_1.MedusaService)({
|
|
|
92
141
|
});
|
|
93
142
|
return link ?? null;
|
|
94
143
|
}
|
|
144
|
+
/** Reverse lookup used by webhooks, which only know the Printful order id. */
|
|
145
|
+
async findOrderLinkByPrintfulId(printfulOrderId) {
|
|
146
|
+
const [link] = await this.listPrintfulOrderLinks({
|
|
147
|
+
printful_order_id: String(printfulOrderId),
|
|
148
|
+
});
|
|
149
|
+
return link ?? null;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Store an inbound event. Returns null when the event_id already exists,
|
|
153
|
+
* which is how redelivered webhooks are absorbed.
|
|
154
|
+
*/
|
|
155
|
+
async recordWebhookEvent(input) {
|
|
156
|
+
try {
|
|
157
|
+
return await this.createPrintfulWebhookEvents({
|
|
158
|
+
event_id: input.event_id,
|
|
159
|
+
type: input.type,
|
|
160
|
+
printful_order_id: input.printful_order_id,
|
|
161
|
+
printful_shipment_id: input.printful_shipment_id ?? null,
|
|
162
|
+
payload: input.payload,
|
|
163
|
+
status: input.status ?? "received",
|
|
164
|
+
attempts: 0,
|
|
165
|
+
next_retry_at: new Date(),
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
if (isUniqueViolation(err)) {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
throw err;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async findWebhookEvent(eventId) {
|
|
176
|
+
const [event] = await this.listPrintfulWebhookEvents({ event_id: eventId });
|
|
177
|
+
return event ?? null;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Events due for another processing attempt, most overdue first. Ordering by
|
|
181
|
+
* next_retry_at (not created_at) lets the ("status", "next_retry_at") index
|
|
182
|
+
* satisfy the sort instead of paying an explicit Sort node on every sweep.
|
|
183
|
+
*/
|
|
184
|
+
async listDueWebhookEvents(limit = 50) {
|
|
185
|
+
return this.listPrintfulWebhookEvents({
|
|
186
|
+
status: ["received", "deferred"],
|
|
187
|
+
next_retry_at: { $lte: new Date() },
|
|
188
|
+
attempts: { $lt: exports.MAX_WEBHOOK_ATTEMPTS },
|
|
189
|
+
}, { take: limit, order: { next_retry_at: "ASC" } });
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Serialize work per Printful order. Two events for one order must not be
|
|
193
|
+
* applied concurrently: both could pass the "shipment already recorded"
|
|
194
|
+
* check before either writes, producing two fulfillments for one parcel.
|
|
195
|
+
* Different orders remain parallel.
|
|
196
|
+
*
|
|
197
|
+
* This provides serialization, NOT atomicity. Work performed inside `fn`
|
|
198
|
+
* (core-flow runs, module-service writes) uses its own managers and commits
|
|
199
|
+
* independently of this transaction, so a later failure does not roll the
|
|
200
|
+
* earlier writes back. Callers must not assume all-or-nothing semantics.
|
|
201
|
+
*
|
|
202
|
+
* Uses the transaction-scoped lock deliberately. The session-scoped variant
|
|
203
|
+
* cannot work here: getActiveManager() forks without a transaction context,
|
|
204
|
+
* so knex takes a fresh pool connection per statement and the unlock can land
|
|
205
|
+
* on a different connection than the lock — leaking the lock permanently.
|
|
206
|
+
* pg_advisory_xact_lock is released by Postgres on commit or rollback.
|
|
207
|
+
*/
|
|
208
|
+
async withOrderLock(printfulOrderId, fn) {
|
|
209
|
+
const key = lockKeyFor(printfulOrderId);
|
|
210
|
+
return this.baseRepository_.transaction(async (txManager) => {
|
|
211
|
+
await txManager.execute("select pg_advisory_xact_lock(?)", [key]);
|
|
212
|
+
return await fn();
|
|
213
|
+
});
|
|
214
|
+
}
|
|
95
215
|
/**
|
|
96
216
|
* Atomically claim an order for Printful creation. Relies on the unique index
|
|
97
217
|
* on `medusa_order_id` so that concurrent captures cannot both proceed to
|
|
@@ -123,4 +243,4 @@ class PrintfulModuleService extends (0, utils_1.MedusaService)({
|
|
|
123
243
|
}
|
|
124
244
|
}
|
|
125
245
|
exports.default = PrintfulModuleService;
|
|
126
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
246
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL3ByaW50ZnVsL3NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBZ0RBLDRDQUlDO0FBYUQsZ0NBR0M7QUFpQkQsOENBMkJDO0FBaEhELHFEQUF5RDtBQUN6RCxtQ0FBbUM7QUFDbkMsaUVBQTREO0FBRTVELHVGQUE0RDtBQUM1RCwyRkFBZ0U7QUFDaEUsbUZBQXdEO0FBQ3hELDJGQUFnRTtBQUNoRSw2RkFBa0U7QUEyQmxFOzs7Ozs7R0FNRztBQUNVLFFBQUEseUJBQXlCLEdBQUcsU0FBUyxDQUFBO0FBRWxELGdFQUFnRTtBQUNuRCxRQUFBLG9CQUFvQixHQUFHLEVBQUUsQ0FBQTtBQUV0QyxrRUFBa0U7QUFDbEUsU0FBZ0IsZ0JBQWdCLENBQUMsUUFBZ0I7SUFDL0MsTUFBTSxZQUFZLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUE7SUFDbEMsTUFBTSxTQUFTLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFBO0lBQ3BDLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUE7QUFDbEUsQ0FBQztBQUVEOzs7Ozs7Ozs7O0dBVUc7QUFDSCxTQUFnQixVQUFVLENBQUMsZUFBdUI7SUFDaEQsTUFBTSxNQUFNLEdBQUcsSUFBQSxtQkFBVSxFQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQTtJQUM1RSxPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFDOUIsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsU0FBZ0IsaUJBQWlCLENBQUMsR0FB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
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const utils_1 = require("@medusajs/framework/utils");
|
|
4
4
|
const printful_client_1 = require("../../utils/printful-client");
|
|
5
|
+
const mappers_1 = require("../../utils/mappers");
|
|
6
|
+
const shipping_rates_1 = require("../../utils/shipping-rates");
|
|
5
7
|
class PrintfulFulfillmentProviderService extends utils_1.AbstractFulfillmentProviderService {
|
|
6
8
|
constructor(container, options) {
|
|
7
9
|
super();
|
|
@@ -10,6 +12,34 @@ class PrintfulFulfillmentProviderService extends utils_1.AbstractFulfillmentProv
|
|
|
10
12
|
if (!this.options_.apiToken) {
|
|
11
13
|
this.logger_.warn("Printful fulfillment provider: apiToken is missing from options");
|
|
12
14
|
}
|
|
15
|
+
this.query_ = container.query;
|
|
16
|
+
this.cache_ = container.caching;
|
|
17
|
+
if (this.options_.liveShippingRates && !this.query_) {
|
|
18
|
+
this.logger_.error("Printful live shipping rates need variant metadata, which requires " +
|
|
19
|
+
'adding dependencies: ["query"] to the @medusajs/medusa/fulfillment ' +
|
|
20
|
+
"module in medusa-config.ts. Falling back to flat rates until then.");
|
|
21
|
+
}
|
|
22
|
+
if (this.options_.liveShippingRates &&
|
|
23
|
+
!this.options_.fallbackShippingRates) {
|
|
24
|
+
this.logger_.error("Printful live shipping rates are enabled without fallbackShippingRates. " +
|
|
25
|
+
"A Printful outage will price shipping at zero.");
|
|
26
|
+
}
|
|
27
|
+
// Coerce the TTLs once here rather than trusting them on every call: they
|
|
28
|
+
// arrive from user config and may be strings, zero, or absent.
|
|
29
|
+
const freshSeconds = Number(this.options_.shippingRateCacheTtlSeconds) > 0
|
|
30
|
+
? Number(this.options_.shippingRateCacheTtlSeconds)
|
|
31
|
+
: 600;
|
|
32
|
+
const staleSeconds = Number(this.options_.shippingRateStaleSeconds) > 0
|
|
33
|
+
? Number(this.options_.shippingRateStaleSeconds)
|
|
34
|
+
: 86400;
|
|
35
|
+
// The stale tier cannot outlive the cache entry, so retention must be at
|
|
36
|
+
// least the freshness window.
|
|
37
|
+
this.freshnessMs_ = freshSeconds * 1000;
|
|
38
|
+
this.staleSeconds_ = Math.max(freshSeconds, staleSeconds);
|
|
39
|
+
if (staleSeconds < freshSeconds) {
|
|
40
|
+
this.logger_.warn("shippingRateStaleSeconds is below shippingRateCacheTtlSeconds; " +
|
|
41
|
+
"raising it, since a stale quote cannot outlive its cache entry.");
|
|
42
|
+
}
|
|
13
43
|
this.client_ = new printful_client_1.PrintfulClient({
|
|
14
44
|
apiToken: this.options_.apiToken || "",
|
|
15
45
|
storeId: this.options_.storeId,
|
|
@@ -17,32 +47,259 @@ class PrintfulFulfillmentProviderService extends utils_1.AbstractFulfillmentProv
|
|
|
17
47
|
}
|
|
18
48
|
async getFulfillmentOptions() {
|
|
19
49
|
return [
|
|
50
|
+
...shipping_rates_1.PRINTFUL_SHIPPING_METHODS.map((id) => ({
|
|
51
|
+
id,
|
|
52
|
+
name: `Printful ${id}`,
|
|
53
|
+
})),
|
|
20
54
|
{
|
|
21
|
-
id:
|
|
22
|
-
name: "Printful Standard",
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
id: "printful-return",
|
|
55
|
+
id: shipping_rates_1.PRINTFUL_RETURN_OPTION_ID,
|
|
26
56
|
name: "Printful Return",
|
|
27
57
|
is_return: true,
|
|
28
58
|
},
|
|
29
59
|
];
|
|
30
60
|
}
|
|
31
61
|
async validateOption(data) {
|
|
32
|
-
|
|
62
|
+
const id = data?.id;
|
|
63
|
+
return (typeof id === "string" &&
|
|
64
|
+
(shipping_rates_1.PRINTFUL_SHIPPING_METHODS.includes(id) ||
|
|
65
|
+
id === shipping_rates_1.PRINTFUL_RETURN_OPTION_ID));
|
|
33
66
|
}
|
|
34
67
|
async validateFulfillmentData(optionData, data, _context) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
68
|
+
// Runs when the method is added to the cart, not on every price refresh, so
|
|
69
|
+
// throwing here does not violate calculatePrice's never-throw constraint.
|
|
70
|
+
// Inventing a default would record one method on the order while the
|
|
71
|
+
// customer was priced for another.
|
|
72
|
+
const id = optionData?.id;
|
|
73
|
+
if (typeof id !== "string" ||
|
|
74
|
+
!shipping_rates_1.PRINTFUL_SHIPPING_METHODS.includes(id)) {
|
|
75
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Printful shipping option has an unrecognized method id ` +
|
|
76
|
+
`(${JSON.stringify(id)}). Recreate it against one of: ` +
|
|
77
|
+
`${shipping_rates_1.PRINTFUL_SHIPPING_METHODS.join(", ")}.`);
|
|
78
|
+
}
|
|
79
|
+
return { ...data, printful_option_id: id };
|
|
80
|
+
}
|
|
81
|
+
async canCalculate(data) {
|
|
82
|
+
const optionId = data?.data?.id;
|
|
83
|
+
// Printful quotes outbound shipping only — a return has no live rate, so
|
|
84
|
+
// it must be priced flat by the admin rather than resolving to zero.
|
|
85
|
+
if (optionId === shipping_rates_1.PRINTFUL_RETURN_OPTION_ID) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return Boolean(this.options_.liveShippingRates);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Price one shipping option.
|
|
92
|
+
*
|
|
93
|
+
* This method must never throw and must always return a `calculated_amount`.
|
|
94
|
+
* Medusa blocks checkout when it does not, so every failure — Printful down,
|
|
95
|
+
* method missing, currency unusable, config incomplete — resolves to a
|
|
96
|
+
* fallback rather than an exception.
|
|
97
|
+
*/
|
|
98
|
+
async calculatePrice(optionData, _data, context) {
|
|
99
|
+
const methodId = String(optionData?.id ?? "");
|
|
100
|
+
try {
|
|
101
|
+
return await this.quote(methodId, context);
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
// A bug in our own code must not block a cart either.
|
|
105
|
+
this.logger_.error(`Printful rate calculation failed unexpectedly: ${err instanceof Error ? err.message : String(err)}`);
|
|
106
|
+
return this.fallback(methodId, "printful_unreachable");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async quote(methodId, context) {
|
|
110
|
+
const ctx = context;
|
|
111
|
+
if (!this.query_) {
|
|
112
|
+
return this.fallback(methodId, "query_unavailable");
|
|
113
|
+
}
|
|
114
|
+
const addr = ctx.shipping_address ?? {};
|
|
115
|
+
const countryCode = (addr.country_code ?? "").toUpperCase();
|
|
116
|
+
const stateCode = (0, mappers_1.resolveStateCode)(addr.province, countryCode);
|
|
117
|
+
if (!(0, shipping_rates_1.isAddressQuotable)({ country_code: countryCode, state_code: stateCode })) {
|
|
118
|
+
return this.fallback(methodId, "incomplete_address");
|
|
119
|
+
}
|
|
120
|
+
const lines = (ctx.items ?? [])
|
|
121
|
+
.filter((i) => i.variant?.id)
|
|
122
|
+
.map((i) => ({
|
|
123
|
+
variant_id: i.variant.id,
|
|
124
|
+
quantity: Number(i.quantity ?? 1),
|
|
125
|
+
unit_price: i.unit_price,
|
|
126
|
+
}));
|
|
127
|
+
let catalogIds;
|
|
128
|
+
try {
|
|
129
|
+
catalogIds = await this.catalogIdsFor(lines.map((l) => l.variant_id));
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
// Our own database, not Printful. Misreporting this sends the operator
|
|
133
|
+
// to Printful's status page during their own incident.
|
|
134
|
+
this.logger_.error(`Printful rate lookup: variant query failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
135
|
+
return this.fallback(methodId, "query_unavailable");
|
|
136
|
+
}
|
|
137
|
+
const items = (0, shipping_rates_1.buildRateItems)(lines, catalogIds);
|
|
138
|
+
if (!items.length) {
|
|
139
|
+
return this.fallback(methodId, "no_printful_items");
|
|
140
|
+
}
|
|
141
|
+
const currency = (ctx.currency_code ?? "").toUpperCase();
|
|
142
|
+
const recipient = {
|
|
143
|
+
country_code: countryCode,
|
|
144
|
+
...(stateCode ? { state_code: stateCode } : {}),
|
|
145
|
+
...(addr.city ? { city: addr.city } : {}),
|
|
146
|
+
...(addr.postal_code ? { zip: addr.postal_code } : {}),
|
|
147
|
+
...(addr.address_1 ? { address1: addr.address_1 } : {}),
|
|
148
|
+
...(addr.address_2 ? { address2: addr.address_2 } : {}),
|
|
38
149
|
};
|
|
150
|
+
const cacheKey = (0, shipping_rates_1.buildRateCacheKey)({ address: recipient, items, currency });
|
|
151
|
+
const cached = await this.readCache(cacheKey);
|
|
152
|
+
// A negative age means the entry is dated in the future — clock skew on the
|
|
153
|
+
// cache node — which would otherwise read as fresh until that date passes.
|
|
154
|
+
const age = cached ? Date.now() - cached.cached_at : 0;
|
|
155
|
+
if (cached && age >= 0 && age < this.freshnessMs_) {
|
|
156
|
+
const hit = (0, shipping_rates_1.selectRate)(cached.rates, methodId, currency);
|
|
157
|
+
if (hit.ok) {
|
|
158
|
+
return this.priced(hit.amount, methodId, "fresh_cache");
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
let rates;
|
|
162
|
+
try {
|
|
163
|
+
rates = await this.client_.getShippingRates({
|
|
164
|
+
recipient,
|
|
165
|
+
items,
|
|
166
|
+
...(currency ? { currency } : {}),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
this.logger_.warn(`Printful shipping rates unavailable: ${err instanceof Error ? err.message : String(err)}`);
|
|
171
|
+
return this.staleOrFlat(cached, methodId, currency, "printful_unreachable");
|
|
172
|
+
}
|
|
173
|
+
await this.writeCache(cacheKey, { rates, currency, cached_at: Date.now() }, this.staleSeconds_);
|
|
174
|
+
const selected = (0, shipping_rates_1.selectRate)(rates, methodId, currency);
|
|
175
|
+
if (!selected.ok) {
|
|
176
|
+
this.logger_.warn(`Printful rate for ${methodId} unusable (${selected.reason}); falling back`);
|
|
177
|
+
return this.staleOrFlat(cached, methodId, currency, selected.reason);
|
|
178
|
+
}
|
|
179
|
+
return this.priced(selected.amount, methodId, "live");
|
|
39
180
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
181
|
+
/** Look up Printful catalog variant ids for a set of Medusa variant ids. */
|
|
182
|
+
async catalogIdsFor(variantIds) {
|
|
183
|
+
const map = new Map();
|
|
184
|
+
if (!this.query_ || !variantIds.length) {
|
|
185
|
+
return map;
|
|
186
|
+
}
|
|
187
|
+
const { data } = await this.query_.graph({
|
|
188
|
+
entity: "product_variant",
|
|
189
|
+
fields: ["id", "metadata"],
|
|
190
|
+
filters: { id: variantIds },
|
|
191
|
+
});
|
|
192
|
+
// `graph` is expected to return an array; a non-array result (schema drift,
|
|
193
|
+
// an error envelope) would otherwise throw on iteration.
|
|
194
|
+
const rows = Array.isArray(data)
|
|
195
|
+
? data
|
|
196
|
+
: [];
|
|
197
|
+
for (const row of rows) {
|
|
198
|
+
const catalogId = row.metadata?.printful_catalog_variant_id;
|
|
199
|
+
if (catalogId != null && catalogId !== "") {
|
|
200
|
+
map.set(row.id, String(catalogId));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return map;
|
|
43
204
|
}
|
|
44
|
-
async
|
|
45
|
-
|
|
205
|
+
async readCache(key) {
|
|
206
|
+
if (!this.cache_) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
const value = await this.cache_.get(key);
|
|
211
|
+
// Treat a malformed entry as a miss. Schema drift from an older version
|
|
212
|
+
// or a partial write would otherwise throw inside the fresh-path check,
|
|
213
|
+
// blocking the live API for the whole stale window while Printful is up.
|
|
214
|
+
if (!value ||
|
|
215
|
+
!Array.isArray(value.rates) ||
|
|
216
|
+
typeof value.cached_at !== "number" ||
|
|
217
|
+
!Number.isFinite(value.cached_at)) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
return value;
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// A cache failure must not fail the quote.
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
async writeCache(key, value, ttlSeconds) {
|
|
228
|
+
if (!this.cache_) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
try {
|
|
232
|
+
// TTL is the STALE window, not the freshness window: an aged entry must
|
|
233
|
+
// survive so it can serve as a fallback.
|
|
234
|
+
await this.cache_.set(key, value, ttlSeconds);
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
// Non-fatal.
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
staleOrFlat(cached, methodId, currency, reason) {
|
|
241
|
+
if (cached) {
|
|
242
|
+
const stale = (0, shipping_rates_1.selectRate)(cached.rates, methodId, currency);
|
|
243
|
+
if (stale.ok) {
|
|
244
|
+
return this.priced(stale.amount, methodId, "stale_cache");
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return this.fallback(methodId, reason);
|
|
248
|
+
}
|
|
249
|
+
fallback(methodId, reason) {
|
|
250
|
+
// Read as an own property: a method id like "toString" would otherwise
|
|
251
|
+
// resolve up the prototype chain to a function, which JSON.stringify drops
|
|
252
|
+
// from the response entirely — the exact missing-field condition that
|
|
253
|
+
// blocks checkout. Type-check it too, since a rate from JSON or an env var
|
|
254
|
+
// arrives as a string.
|
|
255
|
+
const table = this.options_.fallbackShippingRates;
|
|
256
|
+
const configured = Object.prototype.hasOwnProperty.call(table ?? {}, methodId)
|
|
257
|
+
? table[methodId]
|
|
258
|
+
: undefined;
|
|
259
|
+
const flat = typeof configured === "number" &&
|
|
260
|
+
Number.isFinite(configured) &&
|
|
261
|
+
configured >= 0
|
|
262
|
+
? configured
|
|
263
|
+
: undefined;
|
|
264
|
+
if (flat == null) {
|
|
265
|
+
// calculatePrice cannot throw, so a legacy option row silently prices at
|
|
266
|
+
// zero. Naming the id is the only mitigation available.
|
|
267
|
+
if (shipping_rates_1.LEGACY_OPTION_IDS.has(methodId)) {
|
|
268
|
+
this.logger_.error(`Shipping option uses the pre-0.3.0 id "${methodId}", which Printful ` +
|
|
269
|
+
`never returns, so it is pricing at zero. Recreate this option ` +
|
|
270
|
+
`against one of: ${shipping_rates_1.PRINTFUL_SHIPPING_METHODS.join(", ")}.`);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
this.logger_.error(`No usable fallbackShippingRates entry for "${methodId}" — pricing ` +
|
|
274
|
+
"shipping at zero. Every method in the allowlist needs a " +
|
|
275
|
+
"non-negative numeric entry.");
|
|
276
|
+
}
|
|
277
|
+
return this.priced(0, methodId, "misconfigured_zero");
|
|
278
|
+
}
|
|
279
|
+
if (reason === "incomplete_address" || reason === "no_printful_items") {
|
|
280
|
+
this.logger_.debug?.(`Printful rates skipped: ${reason}`);
|
|
281
|
+
}
|
|
282
|
+
else if (reason === "query_unavailable") {
|
|
283
|
+
// Only advise the config change when query really is absent; a query that
|
|
284
|
+
// exists but failed has already logged its own, accurate reason.
|
|
285
|
+
if (!this.query_) {
|
|
286
|
+
this.logger_.error('Printful live rates need dependencies: ["query"] on the fulfillment module');
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
this.logger_.warn(`Printful rate fallback (${reason}) for ${methodId}`);
|
|
291
|
+
}
|
|
292
|
+
return this.priced(flat, methodId, "flat_fallback");
|
|
293
|
+
}
|
|
294
|
+
priced(amount, _methodId, _source) {
|
|
295
|
+
// The source is deliberately not returned. Medusa reads only
|
|
296
|
+
// calculated_amount and is_calculated_price_tax_inclusive off this result
|
|
297
|
+
// (core-flows add-shipping-method-to-cart.js) — a `data` field here is
|
|
298
|
+
// discarded, so stamping provenance on it would be silently dead code.
|
|
299
|
+
return {
|
|
300
|
+
calculated_amount: amount,
|
|
301
|
+
is_calculated_price_tax_inclusive: false,
|
|
302
|
+
};
|
|
46
303
|
}
|
|
47
304
|
async createFulfillment(data, items, order, fulfillment) {
|
|
48
305
|
// Prefer order created by payment.captured subscriber; attach id if present.
|
|
@@ -94,4 +351,4 @@ class PrintfulFulfillmentProviderService extends utils_1.AbstractFulfillmentProv
|
|
|
94
351
|
}
|
|
95
352
|
PrintfulFulfillmentProviderService.identifier = "printful";
|
|
96
353
|
exports.default = PrintfulFulfillmentProviderService;
|
|
97
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9wcm92aWRlcnMvcHJpbnRmdWwtZnVsZmlsbG1lbnQvc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFEQUdrQztBQVdsQyxpRUFBNEQ7QUFXNUQsTUFBTSxrQ0FBbUMsU0FBUSwwQ0FBa0M7SUFPakYsWUFBWSxTQUErQixFQUFFLE9BQThCO1FBQ3pFLEtBQUssRUFBRSxDQUFBO1FBQ1AsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFBO1FBQy9CLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxJQUFLLEVBQTRCLENBQUE7UUFFeEQsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDNUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQ2YsaUVBQWlFLENBQ2xFLENBQUE7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLGdDQUFjLENBQUM7WUFDaEMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxJQUFJLEVBQUU7WUFDdEMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTztTQUMvQixDQUFDLENBQUE7SUFDSixDQUFDO0lBRUQsS0FBSyxDQUFDLHFCQUFxQjtRQUN6QixPQUFPO1lBQ0w7Z0JBQ0UsRUFBRSxFQUFFLG1CQUFtQjtnQkFDdkIsSUFBSSxFQUFFLG1CQUFtQjthQUMxQjtZQUNEO2dCQUNFLEVBQUUsRUFBRSxpQkFBaUI7Z0JBQ3JCLElBQUksRUFBRSxpQkFBaUI7Z0JBQ3ZCLFNBQVMsRUFBRSxJQUFJO2FBQ2hCO1NBQ0YsQ0FBQTtJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsY0FBYyxDQUFDLElBQTZCO1FBQ2hELE9BQU8sT0FBTyxJQUFJLEVBQUUsRUFBRSxLQUFLLFFBQVEsSUFBSSxJQUFJLEVBQUUsRUFB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
|
|
354
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9wcm92aWRlcnMvcHJpbnRmdWwtZnVsZmlsbG1lbnQvc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFEQUdrQztBQVlsQyxpRUFBNEQ7QUFDNUQsaURBQXNEO0FBQ3RELCtEQVFtQztBQXVDbkMsTUFBTSxrQ0FBbUMsU0FBUSwwQ0FBa0M7SUFhakYsWUFBWSxTQUErQixFQUFFLE9BQThCO1FBQ3pFLEtBQUssRUFBRSxDQUFBO1FBQ1AsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFBO1FBQy9CLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxJQUFLLEVBQTRCLENBQUE7UUFFeEQsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDNUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQ2YsaUVBQWlFLENBQ2xFLENBQUE7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFBO1FBQzdCLElBQUksQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQTtRQUUvQixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDcEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQ2hCLHFFQUFxRTtnQkFDbkUscUVBQXFFO2dCQUNyRSxvRUFBb0UsQ0FDdkUsQ0FBQTtRQUNILENBQUM7UUFFRCxJQUNFLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCO1lBQy9CLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsRUFDcEMsQ0FBQztZQUNELElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUNoQiwwRUFBMEU7Z0JBQ3hFLGdEQUFnRCxDQUNuRCxDQUFBO1FB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
|
|
@@ -58,4 +58,4 @@ async function resolveOrderIdFromPayment(container, paymentId) {
|
|
|
58
58
|
exports.config = {
|
|
59
59
|
event: "payment.captured",
|
|
60
60
|
};
|
|
61
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
61
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF5bWVudC1jYXB0dXJlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zdWJzY3JpYmVycy9wYXltZW50LWNhcHR1cmVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQVVBLHlDQStCQztBQXZDRCxxREFBOEU7QUFDOUUsK0ZBQTRFO0FBRTVFOzs7O0dBSUc7QUFDWSxLQUFLLFVBQVUsc0JBQXNCLENBQUMsRUFDbkQsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQ2YsU0FBUyxHQUNzQjtJQUMvQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFBO0lBQ3pCLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNmLE9BQU07SUFDUixDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxNQUFNLENBR2hFLENBQUE7SUFFRCxJQUFJLENBQUM7UUFDSCxNQUFNLE9BQU8sR0FBRyxNQUFNLHlCQUF5QixDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQTtRQUNyRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixNQUFNLENBQUMsS0FBSyxDQUFDLGlEQUFpRCxTQUFTLEVBQUUsQ0FBQyxDQUFBO1lBQzFFLE9BQU07UUFDUixDQUFDO1FBRUQsTUFBTSxJQUFBLCtCQUEyQixFQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUMvQyxLQUFLLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFO1NBQzdCLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsTUFBTSxDQUFDLEtBQUssQ0FDVixnREFBZ0QsU0FBUyxLQUN2RCxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUNqRCxFQUFFLENBQ0gsQ0FBQTtJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQsS0FBSyxVQUFVLHlCQUF5QixDQUN0QyxTQUEwQixFQUMxQixTQUFpQjtJQUVqQixNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLGVBQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUN4RCxNQUFNLE9BQU8sR0FBRyxNQUFNLGFBQWEsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDOUQsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLHFCQUEyQyxDQUFBO0lBQ3hFLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNsQixPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFFRCxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ2hFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDakMsTUFBTSxFQUFFLDBCQUEwQjtRQUNsQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDO1FBQ2hDLE9BQU8sRUFBRTtZQUNQLHFCQUFxQixFQUFFLFlBQVk7U0FDcEM7S0FDRixDQUFDLENBQUE7SUFFRixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtJQUNoRCxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDVCxPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFFRCxPQUFPLENBQ0osR0FBc0QsQ0FBQyxRQUFRO1FBQy9ELEdBQW1DLENBQUMsS0FBSyxFQUFFLEVBQUU7UUFDOUMsSUFBSSxDQUNMLENBQUE7QUFDSCxDQUFDO0FBRVksUUFBQSxNQUFNLEdBQXFCO0lBQ3RDLEtBQUssRUFBRSxrQkFBa0I7Q0FDMUIsQ0FBQSJ9
|