@curless/shopify-adapter 0.1.1 → 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/README.md +34 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/orders.d.ts +2 -1
- package/dist/orders.d.ts.map +1 -1
- package/dist/orders.js +115 -1
- package/dist/orders.js.map +1 -1
- package/dist/types.d.ts +20 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -13,13 +13,14 @@ which prices and opens the checkout.
|
|
|
13
13
|
npm install @curless/shopify-adapter
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
## The
|
|
16
|
+
## The three halves
|
|
17
17
|
|
|
18
18
|
```ts
|
|
19
19
|
import {
|
|
20
20
|
shopifyConfigFromEnv,
|
|
21
21
|
fetchShopifyCatalog,
|
|
22
22
|
writebackShopifyOrder,
|
|
23
|
+
refundShopifyOrder,
|
|
23
24
|
} from '@curless/shopify-adapter';
|
|
24
25
|
|
|
25
26
|
const shopify = shopifyConfigFromEnv(); // null unless SHOPIFY_* env is set
|
|
@@ -46,9 +47,33 @@ await writebackShopifyOrder(shopify, {
|
|
|
46
47
|
});
|
|
47
48
|
```
|
|
48
49
|
|
|
49
|
-
No money moves in Shopify
|
|
50
|
-
|
|
51
|
-
never
|
|
50
|
+
No money moves in Shopify. The order is booked with a **SALE transaction on the
|
|
51
|
+
`agentbank` gateway** (not just `financialStatus: PAID`, which paints the label and
|
|
52
|
+
creates no transaction — such an order can never be refunded) and tagged `agentbank` +
|
|
53
|
+
`protocol:…` + the agentbank order id, so it's traceable and never mistaken for a
|
|
54
|
+
Shopify Payments sale. Pass `unitPriceMinor` + `currency` or there is no total to book
|
|
55
|
+
the transaction with, and the order won't be reversible.
|
|
56
|
+
|
|
57
|
+
**3. Refund** — when agentbank refunds the sale, stop the Shopify order reading as paid:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
// e.g. from your `order.refunded` webhook handler
|
|
61
|
+
await refundShopifyOrder(shopify, {
|
|
62
|
+
agentbankOrderId: [`order_${paymentIntentId}`, paymentIntentId], // any tag you wrote back with
|
|
63
|
+
reason: 'guest cancelled',
|
|
64
|
+
});
|
|
65
|
+
// → { refunded: true, id } | { refunded: false, reason }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
It **records** the reversal rather than processing one — the sale was booked on our
|
|
69
|
+
own gateway, so the matching REFUND transaction moves no real money. It does have to
|
|
70
|
+
BE a transaction, though: a refund with none attached is a 0.00 refund and the order
|
|
71
|
+
goes on reading PAID. An order written back before this adapter recorded a sale
|
|
72
|
+
transaction has no parent to refund against and comes back
|
|
73
|
+
`{refunded:false, reason:'…no SALE transaction…'}` — reverse those in the admin once.
|
|
74
|
+
|
|
75
|
+
Full-order only — agentbank refunds the whole captured amount, and inventing a partial
|
|
76
|
+
here would let you record a reversal that doesn't match the money that actually went back.
|
|
52
77
|
|
|
53
78
|
## Notes
|
|
54
79
|
|
|
@@ -69,6 +94,11 @@ never mistaken for a Shopify Payments sale.
|
|
|
69
94
|
refresh, so two writebacks fired within a second can both miss and duplicate — add
|
|
70
95
|
your own in-process guard on the order id if you fire them rapidly; the tag search
|
|
71
96
|
is the cross-restart backstop.
|
|
97
|
+
- **Refunds are idempotent and safe to miss.** `refundShopifyOrder` takes one id or a
|
|
98
|
+
list, tries them in order, and returns `{refunded:false, reason}` — never throws —
|
|
99
|
+
when nothing matches or the order is already REFUNDED. Ids that could false-match a
|
|
100
|
+
Shopify search (spaces, operators) are dropped rather than searched: refunding the
|
|
101
|
+
wrong order is worse than refunding none.
|
|
72
102
|
- **Pagination.** Products paginate to completion. A single product with more than
|
|
73
103
|
250 variants has its tail dropped **with a warning** (not silently).
|
|
74
104
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { shopifyConfigFromEnv, exchangeToken, shopifyGraphql } from './client.js';
|
|
2
2
|
export { fetchShopifyCatalog, productsToItems } from './catalog.js';
|
|
3
|
-
export { writebackShopifyOrder } from './orders.js';
|
|
3
|
+
export { writebackShopifyOrder, refundShopifyOrder } from './orders.js';
|
|
4
4
|
export { decimalsFor, toMinor, toMajorString } from './money.js';
|
|
5
|
-
export type { CatalogItem, ShopifyConfig, OrderWriteback, WritebackResult, } from './types.js';
|
|
5
|
+
export type { CatalogItem, ShopifyConfig, OrderWriteback, WritebackResult, OrderRefund, RefundResult, } from './types.js';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACjE,YAAY,EACV,WAAW,EACX,aAAa,EACb,cAAc,EACd,eAAe,EACf,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
// // …after the agent pays through agentbank:
|
|
11
11
|
// await writebackShopifyOrder(shopify, { variantId, quantity, protocol, agentbankOrderId,
|
|
12
12
|
// unitPriceMinor, currency });
|
|
13
|
+
// // …and when agentbank refunds that sale (your `order.refunded` webhook):
|
|
14
|
+
// await refundShopifyOrder(shopify, { agentbankOrderId, reason });
|
|
13
15
|
export { shopifyConfigFromEnv, exchangeToken, shopifyGraphql } from './client.js';
|
|
14
16
|
export { fetchShopifyCatalog, productsToItems } from './catalog.js';
|
|
15
|
-
export { writebackShopifyOrder } from './orders.js';
|
|
17
|
+
export { writebackShopifyOrder, refundShopifyOrder } from './orders.js';
|
|
16
18
|
export { decimalsFor, toMinor, toMajorString } from './money.js';
|
|
17
19
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,8DAA8D;AAC9D,EAAE;AACF,gFAAgF;AAChF,uCAAuC;AACvC,EAAE;AACF,iFAAiF;AACjF,uFAAuF;AACvF,4EAA4E;AAC5E,gDAAgD;AAChD,4FAA4F;AAC5F,wEAAwE;AACxE,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,8DAA8D;AAC9D,EAAE;AACF,gFAAgF;AAChF,uCAAuC;AACvC,EAAE;AACF,iFAAiF;AACjF,uFAAuF;AACvF,4EAA4E;AAC5E,gDAAgD;AAChD,4FAA4F;AAC5F,wEAAwE;AACxE,8EAA8E;AAC9E,qEAAqE;AACrE,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/orders.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import type { OrderWriteback, ShopifyConfig, WritebackResult } from './types.js';
|
|
1
|
+
import type { OrderRefund, OrderWriteback, RefundResult, ShopifyConfig, WritebackResult } from './types.js';
|
|
2
2
|
export declare const writebackShopifyOrder: (config: ShopifyConfig, input: OrderWriteback, fetchImpl?: typeof fetch) => Promise<WritebackResult>;
|
|
3
|
+
export declare const refundShopifyOrder: (config: ShopifyConfig, input: OrderRefund, fetchImpl?: typeof fetch) => Promise<RefundResult>;
|
|
3
4
|
//# sourceMappingURL=orders.d.ts.map
|
package/dist/orders.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orders.d.ts","sourceRoot":"","sources":["../src/orders.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"orders.d.ts","sourceRoot":"","sources":["../src/orders.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACZ,aAAa,EACb,eAAe,EAChB,MAAM,YAAY,CAAC;AAUpB,eAAO,MAAM,qBAAqB,GAChC,QAAQ,aAAa,EACrB,OAAO,cAAc,EACrB,YAAW,OAAO,KAAa,KAC9B,OAAO,CAAC,eAAe,CAyFzB,CAAC;AAiBF,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,aAAa,EACrB,OAAO,WAAW,EAClB,YAAW,OAAO,KAAa,KAC9B,OAAO,CAAC,YAAY,CA+FtB,CAAC"}
|
package/dist/orders.js
CHANGED
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
import { exchangeToken, shopifyGraphql } from './client.js';
|
|
15
15
|
import { toMajorString } from './money.js';
|
|
16
16
|
const FIND_BY_TAG = 'query($q:String!){ orders(first:1, query:$q){ nodes{ id name } } }';
|
|
17
|
+
// The gateway name on the transactions we write. Shopify shows it verbatim in the
|
|
18
|
+
// order's payment section and in finance reports, so it says where the money
|
|
19
|
+
// actually is rather than implying a Shopify Payments sale.
|
|
20
|
+
const SALE_GATEWAY = 'agentbank';
|
|
17
21
|
const ORDER_CREATE = 'mutation($o:OrderCreateOrderInput!){ orderCreate(order:$o){ order{ id name } userErrors{ field message } } }';
|
|
18
22
|
export const writebackShopifyOrder = async (config, input, fetchImpl = fetch) => {
|
|
19
23
|
const token = await exchangeToken(config, fetchImpl);
|
|
@@ -45,13 +49,41 @@ export const writebackShopifyOrder = async (config, input, fetchImpl = fetch) =>
|
|
|
45
49
|
// records what was really paid rather than Shopify re-deriving it from the
|
|
46
50
|
// variant's current price. Omitting unitPriceMinor/currency keeps the variant
|
|
47
51
|
// price (Shopify's default).
|
|
52
|
+
const transactions = [];
|
|
48
53
|
if (input.unitPriceMinor != null && input.currency) {
|
|
49
54
|
const currencyCode = input.currency.toUpperCase(); // Shopify's CurrencyCode enum is upper-case
|
|
50
55
|
lineItem.priceSet = {
|
|
51
56
|
shopMoney: { amount: toMajorString(input.unitPriceMinor, currencyCode), currencyCode },
|
|
52
57
|
};
|
|
58
|
+
// A SALE transaction on our own gateway, not just financialStatus:'PAID'.
|
|
59
|
+
//
|
|
60
|
+
// `financialStatus` alone paints the label and creates NO transaction, and an
|
|
61
|
+
// order with no transaction cannot be refunded: Shopify requires a REFUND
|
|
62
|
+
// transaction to carry a parent, so the reversal has nothing to attach to and
|
|
63
|
+
// records a 0.00 refund that leaves the order reading PAID forever. It is also
|
|
64
|
+
// simply more truthful — the sale really was collected on an external gateway,
|
|
65
|
+
// which is what the store's own finance reporting needs to see.
|
|
66
|
+
transactions.push({
|
|
67
|
+
kind: 'SALE',
|
|
68
|
+
status: 'SUCCESS',
|
|
69
|
+
gateway: SALE_GATEWAY,
|
|
70
|
+
amountSet: {
|
|
71
|
+
shopMoney: {
|
|
72
|
+
amount: toMajorString(input.unitPriceMinor * input.quantity, currencyCode),
|
|
73
|
+
currencyCode,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
});
|
|
53
77
|
}
|
|
54
|
-
const data = await shopifyGraphql(config, token, ORDER_CREATE, {
|
|
78
|
+
const data = await shopifyGraphql(config, token, ORDER_CREATE, {
|
|
79
|
+
o: {
|
|
80
|
+
lineItems: [lineItem],
|
|
81
|
+
financialStatus: 'PAID',
|
|
82
|
+
note,
|
|
83
|
+
tags,
|
|
84
|
+
...(transactions.length ? { transactions } : {}),
|
|
85
|
+
},
|
|
86
|
+
}, fetchImpl);
|
|
55
87
|
const errs = data.orderCreate?.userErrors ?? [];
|
|
56
88
|
if (errs.length)
|
|
57
89
|
return { created: false, reason: errs.map((e) => e.message).join('; ') };
|
|
@@ -60,4 +92,86 @@ export const writebackShopifyOrder = async (config, input, fetchImpl = fetch) =>
|
|
|
60
92
|
return { created: false, reason: 'orderCreate returned no order' };
|
|
61
93
|
return { created: true, name: order.name, id: order.id };
|
|
62
94
|
};
|
|
95
|
+
const FIND_FOR_REFUND = 'query($q:String!){ orders(first:1, query:$q){ nodes{ id name displayFinancialStatus ' +
|
|
96
|
+
'totalPriceSet{ shopMoney{ amount currencyCode } } ' +
|
|
97
|
+
'transactions{ id kind status gateway amountSet{ shopMoney{ amount } } } ' +
|
|
98
|
+
'lineItems(first:50){ nodes{ id quantity } } } } }';
|
|
99
|
+
const REFUND_CREATE = 'mutation($i:RefundInput!){ refundCreate(input:$i){ refund{ id } userErrors{ field message } } }';
|
|
100
|
+
// Mark an agentbank-settled Shopify order as refunded. See OrderRefund for why
|
|
101
|
+
// this records a refund rather than processing one.
|
|
102
|
+
//
|
|
103
|
+
// Deliberately full-order only: agentbank refunds the whole captured amount
|
|
104
|
+
// (Curless refunds nothing else), so every line goes back in full. A partial
|
|
105
|
+
// would need to say WHICH lines and how many, and inventing that here would let
|
|
106
|
+
// a caller record a refund that doesn't match the money actually returned.
|
|
107
|
+
export const refundShopifyOrder = async (config, input, fetchImpl = fetch) => {
|
|
108
|
+
// Same reasoning as the writeback's idempotency tag: an id carrying a space or
|
|
109
|
+
// a Shopify search operator would false-match an unrelated order — and
|
|
110
|
+
// refunding the WRONG order is worse than not refunding this one. Unsafe
|
|
111
|
+
// candidates are dropped rather than searched.
|
|
112
|
+
const candidates = (Array.isArray(input.agentbankOrderId) ? input.agentbankOrderId : [input.agentbankOrderId]).filter((t) => typeof t === 'string' && /^[A-Za-z0-9_.:-]{1,255}$/.test(t));
|
|
113
|
+
if (candidates.length === 0) {
|
|
114
|
+
return { refunded: false, reason: 'no safe agentbank id to search by' };
|
|
115
|
+
}
|
|
116
|
+
const token = await exchangeToken(config, fetchImpl);
|
|
117
|
+
let order;
|
|
118
|
+
for (const tag of candidates) {
|
|
119
|
+
const found = await shopifyGraphql(config, token, FIND_FOR_REFUND, { q: `tag:${tag}` }, fetchImpl);
|
|
120
|
+
order = found.orders.nodes[0];
|
|
121
|
+
if (order)
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
// No order is not an error worth retrying: this sale may predate the
|
|
125
|
+
// writeback, or the store may not be the one it was written to.
|
|
126
|
+
if (!order)
|
|
127
|
+
return { refunded: false, reason: 'no Shopify order tagged with that agentbank id' };
|
|
128
|
+
// Idempotent: a redelivered refund event finds it already refunded.
|
|
129
|
+
if (/REFUNDED/i.test(order.displayFinancialStatus)) {
|
|
130
|
+
return { refunded: false, reason: `already refunded (${order.name})` };
|
|
131
|
+
}
|
|
132
|
+
// The transaction the refund attaches to. Shopify rejects a REFUND transaction
|
|
133
|
+
// with no `parentId` on any gateway but store-credit/exchange-credit/cash, and
|
|
134
|
+
// a refund with NO transactions at all is a 0.00 refund: it files a refund
|
|
135
|
+
// record and leaves the order reading PAID. So a missing sale transaction is a
|
|
136
|
+
// hard stop, not something to paper over — say so instead of writing a reversal
|
|
137
|
+
// that reverses nothing.
|
|
138
|
+
const sale = order.transactions.find((t) => t.kind?.toUpperCase() === 'SALE' && t.status?.toUpperCase() === 'SUCCESS');
|
|
139
|
+
if (!sale) {
|
|
140
|
+
return {
|
|
141
|
+
refunded: false,
|
|
142
|
+
reason: `Shopify order ${order.name} has no SALE transaction to refund against (written back before the adapter recorded one) — reverse it in the Shopify admin`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const data = await shopifyGraphql(config, token, REFUND_CREATE, {
|
|
146
|
+
i: {
|
|
147
|
+
orderId: order.id,
|
|
148
|
+
note: input.reason ? `Refunded via agentbank · ${input.reason}` : 'Refunded via agentbank',
|
|
149
|
+
// A REFUND transaction against the sale, for the full order total. This
|
|
150
|
+
// moves no real money — the gateway is ours, and Shopify never held the
|
|
151
|
+
// funds — but it is what actually flips the order to REFUNDED, which
|
|
152
|
+
// refundLineItems alone does not do.
|
|
153
|
+
transactions: [
|
|
154
|
+
{
|
|
155
|
+
orderId: order.id,
|
|
156
|
+
parentId: sale.id,
|
|
157
|
+
gateway: sale.gateway,
|
|
158
|
+
kind: 'REFUND',
|
|
159
|
+
amount: order.totalPriceSet.shopMoney.amount,
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
refundLineItems: order.lineItems.nodes.map((li) => ({
|
|
163
|
+
lineItemId: li.id,
|
|
164
|
+
quantity: li.quantity,
|
|
165
|
+
restockType: input.restock ? 'RETURN' : 'NO_RESTOCK',
|
|
166
|
+
})),
|
|
167
|
+
},
|
|
168
|
+
}, fetchImpl);
|
|
169
|
+
const errs = data.refundCreate?.userErrors ?? [];
|
|
170
|
+
if (errs.length)
|
|
171
|
+
return { refunded: false, reason: errs.map((e) => e.message).join('; ') };
|
|
172
|
+
const refund = data.refundCreate?.refund;
|
|
173
|
+
if (!refund)
|
|
174
|
+
return { refunded: false, reason: 'refundCreate returned no refund' };
|
|
175
|
+
return { refunded: true, id: refund.id };
|
|
176
|
+
};
|
|
63
177
|
//# sourceMappingURL=orders.js.map
|
package/dist/orders.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orders.js","sourceRoot":"","sources":["../src/orders.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,gFAAgF;AAChF,+EAA+E;AAC/E,gFAAgF;AAChF,+DAA+D;AAC/D,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,iFAAiF;AACjF,gFAAgF;AAChF,kFAAkF;AAClF,6EAA6E;AAC7E,mCAAmC;AACnC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"orders.js","sourceRoot":"","sources":["../src/orders.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,gFAAgF;AAChF,+EAA+E;AAC/E,gFAAgF;AAChF,+DAA+D;AAC/D,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,iFAAiF;AACjF,gFAAgF;AAChF,kFAAkF;AAClF,6EAA6E;AAC7E,mCAAmC;AACnC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAS3C,MAAM,WAAW,GAAG,oEAAoE,CAAC;AACzF,kFAAkF;AAClF,6EAA6E;AAC7E,4DAA4D;AAC5D,MAAM,YAAY,GAAG,WAAW,CAAC;AACjC,MAAM,YAAY,GAChB,8GAA8G,CAAC;AAEjH,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EACxC,MAAqB,EACrB,KAAqB,EACrB,YAA0B,KAAK,EACL,EAAE;IAC5B,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAErD,+EAA+E;IAC/E,2EAA2E;IAC3E,6EAA6E;IAC7E,8EAA8E;IAC9E,gFAAgF;IAChF,+CAA+C;IAC/C,MAAM,OAAO,GACX,KAAK,CAAC,gBAAgB,IAAI,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC;QAC/E,CAAC,CAAC,KAAK,CAAC,gBAAgB;QACxB,CAAC,CAAC,SAAS,CAAC;IAEhB,2EAA2E;IAC3E,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,MAAM,cAAc,CAChC,MAAM,EACN,KAAK,EACL,WAAW,EACX,EAAE,CAAC,EAAE,OAAO,OAAO,EAAE,EAAE,EACvB,SAAS,CACV,CAAC;QACF,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,QAAQ;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,QAAQ,CAAC,IAAI,GAAG,EAAE,CAAC;IAC7F,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,WAAW,EAAE,YAAY,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IACzD,IAAI,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,iCAAiC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,YAAY,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAEpI,MAAM,QAAQ,GAA4B;QACxC,SAAS,EAAE,gCAAgC,KAAK,CAAC,SAAS,EAAE;QAC5D,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC;IACF,6EAA6E;IAC7E,2EAA2E;IAC3E,8EAA8E;IAC9E,6BAA6B;IAC7B,MAAM,YAAY,GAAmC,EAAE,CAAC;IACxD,IAAI,KAAK,CAAC,cAAc,IAAI,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnD,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,4CAA4C;QAC/F,QAAQ,CAAC,QAAQ,GAAG;YAClB,SAAS,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,cAAc,EAAE,YAAY,CAAC,EAAE,YAAY,EAAE;SACvF,CAAC;QACF,0EAA0E;QAC1E,EAAE;QACF,8EAA8E;QAC9E,0EAA0E;QAC1E,8EAA8E;QAC9E,+EAA+E;QAC/E,+EAA+E;QAC/E,gEAAgE;QAChE,YAAY,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,SAAS;YACjB,OAAO,EAAE,YAAY;YACrB,SAAS,EAAE;gBACT,SAAS,EAAE;oBACT,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC,QAAQ,EAAE,YAAY,CAAC;oBAC1E,YAAY;iBACb;aACF;SACF,CAAC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,cAAc,CAG/B,MAAM,EACN,KAAK,EACL,YAAY,EACZ;QACE,CAAC,EAAE;YACD,SAAS,EAAE,CAAC,QAAQ,CAAC;YACrB,eAAe,EAAE,MAAM;YACvB,IAAI;YACJ,IAAI;YACJ,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjD;KACF,EACD,SAAS,CACV,CAAC;IAEF,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,IAAI,EAAE,CAAC;IAChD,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC1F,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC;IACtC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC;IAC/E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;AAC3D,CAAC,CAAC;AAEF,MAAM,eAAe,GACnB,sFAAsF;IACtF,oDAAoD;IACpD,0EAA0E;IAC1E,mDAAmD,CAAC;AACtD,MAAM,aAAa,GACjB,iGAAiG,CAAC;AAEpG,+EAA+E;AAC/E,oDAAoD;AACpD,EAAE;AACF,4EAA4E;AAC5E,6EAA6E;AAC7E,gFAAgF;AAChF,2EAA2E;AAC3E,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACrC,MAAqB,EACrB,KAAkB,EAClB,YAA0B,KAAK,EACR,EAAE;IACzB,+EAA+E;IAC/E,uEAAuE;IACvE,yEAAyE;IACzE,+CAA+C;IAC/C,MAAM,UAAU,GAAG,CACjB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAC1F,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,mCAAmC,EAAE,CAAC;IAC1E,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAUrD,IAAI,KAA6B,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,cAAc,CAChC,MAAM,EACN,KAAK,EACL,eAAe,EACf,EAAE,CAAC,EAAE,OAAO,GAAG,EAAE,EAAE,EACnB,SAAS,CACV,CAAC;QACF,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,KAAK;YAAE,MAAM;IACnB,CAAC;IACD,qEAAqE;IACrE,gEAAgE;IAChE,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,gDAAgD,EAAE,CAAC;IACjG,oEAAoE;IACpE,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,EAAE,CAAC;QACnD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC;IACzE,CAAC;IAED,+EAA+E;IAC/E,+EAA+E;IAC/E,2EAA2E;IAC3E,+EAA+E;IAC/E,gFAAgF;IAChF,yBAAyB;IACzB,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,SAAS,CACjF,CAAC;IACF,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,iBAAiB,KAAK,CAAC,IAAI,6HAA6H;SACjK,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,cAAc,CAG/B,MAAM,EACN,KAAK,EACL,aAAa,EACb;QACE,CAAC,EAAE;YACD,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,4BAA4B,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,wBAAwB;YAC1F,wEAAwE;YACxE,wEAAwE;YACxE,qEAAqE;YACrE,qCAAqC;YACrC,YAAY,EAAE;gBACZ;oBACE,OAAO,EAAE,KAAK,CAAC,EAAE;oBACjB,QAAQ,EAAE,IAAI,CAAC,EAAE;oBACjB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM;iBAC7C;aACF;YACD,eAAe,EAAE,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBAClD,UAAU,EAAE,EAAE,CAAC,EAAE;gBACjB,QAAQ,EAAE,EAAE,CAAC,QAAQ;gBACrB,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY;aACrD,CAAC,CAAC;SACJ;KACF,EACD,SAAS,CACV,CAAC;IAEF,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,IAAI,EAAE,CAAC;IACjD,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC3F,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC;IACzC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAC;IACnF,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;AAC3C,CAAC,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -43,4 +43,24 @@ export type WritebackResult = {
|
|
|
43
43
|
created: false;
|
|
44
44
|
reason: string;
|
|
45
45
|
};
|
|
46
|
+
export type OrderRefund = {
|
|
47
|
+
/**
|
|
48
|
+
* The tag the writeback used. Accepts SEVERAL candidates, tried in order,
|
|
49
|
+
* because the writeback keys on `orderId ?? sessionId ?? paymentIntentId` —
|
|
50
|
+
* which of the three it landed on depends on the protocol, and a refund event
|
|
51
|
+
* doesn't know. Pass every id you hold rather than guessing one.
|
|
52
|
+
*/
|
|
53
|
+
agentbankOrderId: string | string[];
|
|
54
|
+
/** Shown on the Shopify refund. */
|
|
55
|
+
reason?: string;
|
|
56
|
+
/** Put the units back into inventory. Default false — a booking has nothing to restock. */
|
|
57
|
+
restock?: boolean;
|
|
58
|
+
};
|
|
59
|
+
export type RefundResult = {
|
|
60
|
+
refunded: true;
|
|
61
|
+
id: string;
|
|
62
|
+
} | {
|
|
63
|
+
refunded: false;
|
|
64
|
+
reason: string;
|
|
65
|
+
};
|
|
46
66
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,WAAW,GAAG;IACxB,oFAAoF;IACpF,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,uFAAuF;IACvF,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,sGAAsG;IACtG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,YAAY,EAAE,MAAM,CAAC;IACrB,gGAAgG;IAChG,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAKF,MAAM,MAAM,cAAc,GAAG;IAC3B,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,8FAA8F;IAC9F,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAO1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,eAAe,GACvB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,WAAW,GAAG;IACxB,oFAAoF;IACpF,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,uFAAuF;IACvF,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,sGAAsG;IACtG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,YAAY,EAAE,MAAM,CAAC;IACrB,gGAAgG;IAChG,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAKF,MAAM,MAAM,cAAc,GAAG;IAC3B,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,8FAA8F;IAC9F,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAO1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,eAAe,GACvB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAavC,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACpC,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAOF,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@curless/shopify-adapter",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Use a Shopify store as an agentbank catalog source, and record agent-settled sales back as paid Shopify orders. Maps Shopify Admin products → a generic CatalogItem your merchant backend prices from,
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Use a Shopify store as an agentbank catalog source, and record agent-settled sales back as paid Shopify orders. Maps Shopify Admin products → a generic CatalogItem your merchant backend prices from, writes an order back after an agent pays through agentbank, and records the reversal when that sale is refunded. Zero runtime dependencies (uses the platform fetch).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|