@kiva/kv-shop 1.3.2 → 1.4.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.
Files changed (56) hide show
  1. package/dist/basket.cjs +44 -15
  2. package/dist/basket.d.ts +4 -4
  3. package/dist/basket.js +5 -8
  4. package/dist/basketCredits.cjs +197 -0
  5. package/dist/basketCredits.d.ts +18 -0
  6. package/dist/basketCredits.js +12 -0
  7. package/dist/basketItems.cjs +70 -33
  8. package/dist/basketItems.d.ts +11 -1
  9. package/dist/basketItems.js +5 -3
  10. package/dist/basketTotals.cjs +228 -0
  11. package/dist/basketTotals.d.ts +37 -0
  12. package/dist/basketTotals.js +12 -0
  13. package/dist/basketVerification.cjs +41 -0
  14. package/dist/basketVerification.d.ts +10 -0
  15. package/dist/basketVerification.js +8 -0
  16. package/dist/checkoutStatus.cjs +110 -0
  17. package/dist/checkoutStatus.d.ts +20 -0
  18. package/dist/checkoutStatus.js +10 -0
  19. package/dist/{chunk-B7RLQXI6.js → chunk-2NC7LGGO.js} +14 -12
  20. package/dist/{chunk-IYCMZ5WV.js → chunk-4ODZGLWK.js} +21 -0
  21. package/dist/chunk-AI6E33YE.js +33 -0
  22. package/dist/chunk-CBJJUUVR.js +121 -0
  23. package/dist/chunk-DZGZX4F6.js +45 -0
  24. package/dist/chunk-EJ5NGYPO.js +145 -0
  25. package/dist/chunk-FCAOCO7O.js +17 -0
  26. package/dist/chunk-JBQ2KNMP.js +50 -0
  27. package/dist/{chunk-SLMBU6L7.js → chunk-JXQPCEKG.js} +9 -2
  28. package/dist/{chunk-TIASV6B2.js → chunk-KV4SOUVF.js} +1 -1
  29. package/dist/chunk-LZ4UMRCV.js +16 -0
  30. package/dist/chunk-MRCBNXPS.js +35 -0
  31. package/dist/chunk-PC4WUPYU.js +78 -0
  32. package/dist/chunk-TPJPGUO7.js +12 -0
  33. package/dist/components/KvPaymentSelect.vue +8 -1
  34. package/dist/index.cjs +489 -56
  35. package/dist/index.d.ts +12 -5
  36. package/dist/index.js +55 -21
  37. package/dist/oneTimeCheckout.cjs +396 -9
  38. package/dist/oneTimeCheckout.d.ts +11 -10
  39. package/dist/oneTimeCheckout.js +10 -5
  40. package/dist/shopError.cjs +21 -0
  41. package/dist/shopError.d.ts +2 -0
  42. package/dist/shopError.js +1 -1
  43. package/dist/shopQueries.cjs +248 -0
  44. package/dist/shopQueries.d.ts +8 -0
  45. package/dist/shopQueries.js +13 -0
  46. package/dist/subscriptionCheckout.cjs +21 -0
  47. package/dist/subscriptionCheckout.js +2 -2
  48. package/dist/useBraintreeDropIn.cjs +29 -1
  49. package/dist/useBraintreeDropIn.d.ts +9 -9
  50. package/dist/useBraintreeDropIn.js +2 -2
  51. package/dist/validatePreCheckout.cjs +210 -0
  52. package/dist/validatePreCheckout.d.ts +22 -0
  53. package/dist/validatePreCheckout.js +13 -0
  54. package/package.json +2 -2
  55. package/dist/chunk-M4CJOCIQ.js +0 -26
  56. package/dist/chunk-NC7RAUNV.js +0 -66
package/dist/index.cjs CHANGED
@@ -30,27 +30,49 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  var src_exports = {};
31
31
  __export(src_exports, {
32
32
  ShopError: () => ShopError,
33
+ VerificationState: () => VerificationState,
34
+ applyKivaCredit: () => applyKivaCredit,
35
+ basketTotalsQuery: () => basketTotalsQuery,
36
+ callShopMutation: () => callShopMutation,
37
+ callShopQuery: () => callShopQuery,
33
38
  checkSubscriptionStatus: () => checkSubscriptionStatus,
34
39
  createBasket: () => createBasket,
35
40
  defaultPaymentTypes: () => defaultPaymentTypes,
36
41
  executeNewSubscriptionCheckout: () => executeNewSubscriptionCheckout,
37
42
  executeOneTimeCheckout: () => executeOneTimeCheckout,
38
43
  getBasketID: () => getBasketID,
44
+ getCheckoutStatus: () => getCheckoutStatus,
39
45
  getClientToken: () => getClientToken,
40
- getCookieValue: () => getCookieValue,
41
46
  hasBasketExpired: () => hasBasketExpired,
47
+ isBasketVerified: () => isBasketVerified,
42
48
  parseShopError: () => parseShopError,
49
+ pollForFinishedCheckout: () => pollForFinishedCheckout,
50
+ removeKivaCredit: () => removeKivaCredit,
43
51
  setBasketID: () => setBasketID,
44
- setCookieValue: () => setCookieValue,
45
52
  setTipDonation: () => setTipDonation,
46
53
  useBraintreeDropIn: () => useBraintreeDropIn,
47
- waitOnTransaction: () => waitOnTransaction
54
+ validatePreCheckout: () => validatePreCheckout,
55
+ validatePreCheckoutMutation: () => validatePreCheckoutMutation,
56
+ watchBasketTotals: () => watchBasketTotals,
57
+ watchShopQuery: () => watchShopQuery
48
58
  });
49
59
  module.exports = __toCommonJS(src_exports);
50
60
 
51
61
  // src/basket.ts
52
62
  var import_core = require("@apollo/client/core");
53
63
 
64
+ // src/util/cookie.ts
65
+ var getCookieValue = (name) => {
66
+ if (typeof document !== void 0) {
67
+ return decodeURIComponent(document.cookie.match(`(^|;)\\s*${name}\\s*=\\s*([^;]+)`)?.pop() || "");
68
+ }
69
+ };
70
+ var setCookieValue = (name, value, options = "") => {
71
+ if (typeof document !== void 0) {
72
+ document.cookie = `${name}=${encodeURIComponent(value)};${options}`;
73
+ }
74
+ };
75
+
54
76
  // src/shopError.ts
55
77
  var ShopError = class extends Error {
56
78
  constructor({ code, original }, ...params) {
@@ -62,8 +84,14 @@ var ShopError = class extends Error {
62
84
  this.code = code;
63
85
  this.original = original;
64
86
  }
87
+ aggregateErrors(errors) {
88
+ this.errors = errors;
89
+ }
65
90
  };
66
91
  function parseShopError(error) {
92
+ if (error instanceof ShopError) {
93
+ return error;
94
+ }
67
95
  const errorCode = error?.code ?? error?.extensions?.code ?? error?.name ?? "";
68
96
  const errorMessage = typeof error === "string" ? error : error?.message ?? "";
69
97
  if (errorCode === "invalidMethodParameter" && errorMessage.includes("paymentMethod.create")) {
@@ -72,6 +100,21 @@ function parseShopError(error) {
72
100
  original: error
73
101
  }, "There was a problem validating your payment information. Please double-check the details and try again.");
74
102
  }
103
+ if (errorMessage.includes("Invalid request: ")) {
104
+ const finalError = errorMessage.split("Invalid request: ")[1].split("., ").map((e) => e.matchAll(/[A-Z_]+: (.*)/g))[0];
105
+ const finalCode = finalError[1];
106
+ const finalMessage = finalError[2];
107
+ return new ShopError({
108
+ code: `paymentMethod.${finalCode}`,
109
+ original: error
110
+ }, finalMessage);
111
+ }
112
+ if (errorCode === "insufficientFunds" || errorMessage.includes("There is not enough credit")) {
113
+ return new ShopError({
114
+ code: "shop.insufficientFunds",
115
+ original: error
116
+ }, "There is not enough money to complete the checkout. Please double-check the details and try again.");
117
+ }
75
118
  if (errorCode === "shop.invalidBasketId" || errorCode === "shop.basketRequired" || errorCode === "shop.alreadyCheckedOut") {
76
119
  return new ShopError({
77
120
  code: errorCode,
@@ -91,21 +134,13 @@ function parseShopError(error) {
91
134
  }
92
135
 
93
136
  // src/basket.ts
94
- var getCookieValue = (name) => {
95
- if (typeof document !== void 0) {
96
- return decodeURIComponent(document.cookie.match(`(^|;)\\s*${name}\\s*=\\s*([^;]+)`)?.pop() || "");
97
- }
98
- };
99
- var setCookieValue = (name, value, options = "") => {
100
- document.cookie = `${name}=${encodeURIComponent(value)};${options}`;
101
- };
102
137
  function getBasketID() {
103
138
  return getCookieValue("kvbskt");
104
139
  }
105
140
  function setBasketID(basketId) {
106
141
  setCookieValue("kvbskt", basketId, "path=/;secure;");
107
142
  }
108
- async function createBasket(apollo) {
143
+ async function createBasketHelper(apollo) {
109
144
  try {
110
145
  return apollo.mutate({
111
146
  mutation: import_core.gql`mutation createNewBasketForUser { shop { id createBasket } }`
@@ -119,91 +154,472 @@ async function createBasket(apollo) {
119
154
  throw parseShopError(error);
120
155
  }
121
156
  }
157
+ var activeBasketCreationQuery = null;
158
+ async function createBasket(apollo) {
159
+ if (activeBasketCreationQuery) {
160
+ return activeBasketCreationQuery;
161
+ }
162
+ activeBasketCreationQuery = createBasketHelper(apollo);
163
+ return activeBasketCreationQuery;
164
+ }
122
165
  function hasBasketExpired(error) {
123
166
  const errorCode = error?.code ?? error?.extensions?.code ?? error?.name ?? "";
124
167
  return ["shop.invalidBasketId", "shop.basketRequired", "shop.alreadyCheckedOut"].includes(errorCode);
125
168
  }
126
169
 
127
- // src/basketItems.ts
170
+ // src/basketCredits.ts
128
171
  var import_core2 = require("@apollo/client/core");
129
- var import_numeral = __toESM(require("numeral"), 1);
130
- async function callShopMutation(apollo, mutation, variables, maxretries = 2) {
172
+
173
+ // src/shopQueries.ts
174
+ var watchQueries = /* @__PURE__ */ new Set();
175
+ async function callShopMutation(apollo, options, maxretries = 2) {
131
176
  try {
132
177
  const result = await apollo.mutate({
133
- mutation,
178
+ ...options,
134
179
  variables: {
135
- ...variables,
180
+ ...options.variables,
136
181
  basketId: getBasketID()
137
- }
182
+ },
183
+ refetchQueries: options.awaitRefetchQueries ? Array.from(watchQueries) : []
138
184
  });
139
185
  if (result?.errors?.length) {
140
186
  const basketErrors = result?.errors.filter((err) => hasBasketExpired(err));
141
187
  if (basketErrors.length) {
142
188
  if (maxretries > 0) {
143
189
  await createBasket(apollo);
144
- return callShopMutation(apollo, mutation, variables, maxretries - 1);
190
+ return callShopMutation(apollo, options, maxretries - 1);
145
191
  }
146
192
  throw basketErrors[0];
147
193
  }
148
- const otherErrors = result?.errors?.filter((err) => !hasBasketExpired(err));
149
- if (otherErrors.length) {
150
- throw otherErrors[0];
194
+ if (result?.errors?.length) {
195
+ throw result.errors[0];
151
196
  }
152
197
  }
153
198
  return result?.data;
154
199
  } catch (e) {
155
- if (e instanceof ShopError) {
156
- throw e;
200
+ throw parseShopError(e);
201
+ }
202
+ }
203
+ async function callShopQuery(apollo, options, maxretries = 2) {
204
+ try {
205
+ const result = await apollo.query({
206
+ ...options,
207
+ variables: {
208
+ ...options.variables,
209
+ basketId: getBasketID()
210
+ }
211
+ });
212
+ if (result?.errors?.length) {
213
+ const basketErrors = result?.errors.filter((err) => hasBasketExpired(err));
214
+ if (basketErrors.length) {
215
+ if (maxretries > 0) {
216
+ await createBasket(apollo);
217
+ return callShopQuery(apollo, options, maxretries - 1);
218
+ }
219
+ throw basketErrors[0];
220
+ }
221
+ if (result?.errors?.length) {
222
+ throw result.errors[0];
223
+ }
157
224
  }
225
+ return result?.data;
226
+ } catch (e) {
158
227
  throw parseShopError(e);
159
228
  }
160
229
  }
230
+ function watchShopQuery(apollo, options, maxretries = 2) {
231
+ let retries = 0;
232
+ watchQueries.add(options.query);
233
+ const observable = apollo.watchQuery({
234
+ ...options,
235
+ variables: {
236
+ ...options.variables,
237
+ basketId: getBasketID()
238
+ }
239
+ });
240
+ const oldSubscribe = observable.subscribe.bind(observable);
241
+ observable.subscribe = (...args) => {
242
+ let nextFn;
243
+ let errorFn;
244
+ let completeFn;
245
+ if (typeof args[0] === "function") {
246
+ [nextFn, errorFn, completeFn] = args;
247
+ } else {
248
+ nextFn = args[0]?.next;
249
+ errorFn = args[0]?.error;
250
+ completeFn = args[0]?.complete;
251
+ }
252
+ const newErrorFn = (err) => {
253
+ const basketErrors = err?.graphQLErrors?.filter((e) => hasBasketExpired(e));
254
+ if (basketErrors.length) {
255
+ if (retries < maxretries) {
256
+ createBasket(apollo).then(() => {
257
+ retries += 1;
258
+ observable.refetch({
259
+ ...observable.variables,
260
+ basketId: getBasketID()
261
+ });
262
+ });
263
+ } else {
264
+ errorFn(parseShopError(basketErrors[0]));
265
+ }
266
+ } else {
267
+ if (err?.graphQLErrors?.length) {
268
+ errorFn(parseShopError(err.graphQLErrors[0]));
269
+ }
270
+ if (err?.networkError) {
271
+ errorFn(parseShopError(err.networkError));
272
+ }
273
+ }
274
+ };
275
+ return oldSubscribe(nextFn, newErrorFn, completeFn);
276
+ };
277
+ return observable;
278
+ }
279
+
280
+ // src/basketCredits.ts
281
+ async function applyKivaCredit(apollo) {
282
+ const data = await callShopMutation(apollo, {
283
+ awaitRefetchQueries: true,
284
+ mutation: import_core2.gql`mutation applyKivaCredit($basketId: String) {
285
+ shop (basketId: $basketId) {
286
+ id
287
+ addCreditByType(creditType: kiva_credit)
288
+ }
289
+ }`
290
+ });
291
+ return !!data?.shop?.addCreditByType;
292
+ }
293
+ async function removeKivaCredit(apollo) {
294
+ const data = await callShopMutation(apollo, {
295
+ awaitRefetchQueries: true,
296
+ mutation: import_core2.gql`mutation removeKivaCredit($basketId: String) {
297
+ shop (basketId: $basketId) {
298
+ id
299
+ removeCreditByType(creditType: kiva_credit)
300
+ }
301
+ }`
302
+ });
303
+ return !!data?.shop?.removeCreditByType;
304
+ }
305
+
306
+ // src/basketItems.ts
307
+ var import_core3 = require("@apollo/client/core");
308
+ var import_numeral = __toESM(require("numeral"), 1);
161
309
  async function setTipDonation({ amount, apollo }) {
162
310
  const donationAmount = (0, import_numeral.default)(amount).format("0.00");
163
- const data = await callShopMutation(apollo, import_core2.gql`mutation setTipDonation($price: Money!, $basketId: String) {
164
- shop (basketId: $basketId) {
165
- id
166
- updateDonation (donation: {
167
- price: $price,
168
- isTip: true
169
- })
170
- {
311
+ const data = await callShopMutation(apollo, {
312
+ awaitRefetchQueries: true,
313
+ mutation: import_core3.gql`mutation setTipDonation($price: Money!, $basketId: String) {
314
+ shop (basketId: $basketId) {
171
315
  id
172
- price
173
- isTip
316
+ updateDonation (donation: {
317
+ price: $price,
318
+ isTip: true
319
+ })
320
+ {
321
+ id
322
+ price
323
+ isTip
324
+ }
174
325
  }
175
- }
176
- }`, { price: donationAmount });
326
+ }`,
327
+ variables: { price: donationAmount }
328
+ });
177
329
  return data?.shop?.updateDonation;
178
330
  }
179
331
 
180
- // src/oneTimeCheckout.ts
181
- var import_core3 = require("@apollo/client/core");
182
- async function executeOneTimeCheckout({ apollo }) {
332
+ // src/basketTotals.ts
333
+ var import_core4 = require("@apollo/client/core");
334
+ var basketTotalsQuery = import_core4.gql`query basketTotals($basketId: String) {
335
+ shop (basketId: $basketId) {
336
+ id
337
+ basket {
338
+ id
339
+ totals {
340
+ bonusAppliedTotal
341
+ bonusAvailableTotal
342
+ creditAmountNeeded
343
+ creditAppliedTotal
344
+ creditAvailableTotal
345
+ donationTotal
346
+ itemTotal
347
+ freeTrialAppliedTotal
348
+ freeTrialAvailableTotal
349
+ loanReservationTotal
350
+ kivaCardTotal
351
+ kivaCreditAppliedTotal
352
+ kivaCreditAvailableTotal
353
+ kivaCreditRemaining
354
+ kivaCreditToReapply
355
+ redemptionCodeAppliedTotal
356
+ redemptionCodeAvailableTotal
357
+ universalCodeAppliedTotal
358
+ universalCodeAvailableTotal
359
+ }
360
+ }
361
+ }
362
+ }`;
363
+ function watchBasketTotals(apollo) {
364
+ return watchShopQuery(apollo, {
365
+ query: basketTotalsQuery
366
+ });
367
+ }
368
+
369
+ // src/basketVerification.ts
370
+ var VerificationState = /* @__PURE__ */ ((VerificationState2) => {
371
+ VerificationState2["VERIFIED"] = "verified";
372
+ VerificationState2["PENDING"] = "pending";
373
+ VerificationState2["REQUIRED"] = "required";
374
+ VerificationState2["MAY_BE_NEEDED"] = "may_be_needed";
375
+ VerificationState2["NOT_NEEDED"] = "not_needed";
376
+ return VerificationState2;
377
+ })(VerificationState || {});
378
+ function isBasketVerified(state) {
379
+ return state === "verified" /* VERIFIED */ || state === "not_needed" /* NOT_NEEDED */;
380
+ }
381
+
382
+ // src/checkoutStatus.ts
383
+ var import_core5 = require("@apollo/client/core");
384
+
385
+ // src/util/poll.ts
386
+ function wait(ms) {
387
+ return new Promise((resolve) => setTimeout(resolve, ms));
388
+ }
389
+ async function poll(fn, fnCondition, interval, timeout) {
390
+ const endTime = Date.now() + timeout;
391
+ let result = await fn();
392
+ while (!fnCondition(result)) {
393
+ if (Date.now() > endTime) {
394
+ throw new Error("Polling timed out");
395
+ }
396
+ await wait(interval);
397
+ result = await fn();
398
+ }
399
+ return result;
183
400
  }
184
- async function waitOnTransaction({ apollo, transactionId }) {
185
- const result = await apollo.query({
186
- query: import_core3.gql`
187
- query checkoutStatus($transactionId: String!, $visitorId: string) {
401
+
402
+ // src/util/visitorId.ts
403
+ function getVisitorID() {
404
+ return getCookieValue("uiv");
405
+ }
406
+
407
+ // src/checkoutStatus.ts
408
+ async function getCheckoutStatus({ apollo, transactionSagaId }) {
409
+ return apollo.query({
410
+ query: import_core5.gql`
411
+ query checkoutStatus($transactionId: String!, $visitorId: String) {
188
412
  checkoutStatus(transactionId: $transactionId, visitorId: $visitorId) {
413
+ basketId
189
414
  errorCode
190
415
  errorMessage
416
+ receipt {
417
+ checkoutId
418
+ }
419
+ requestedAt
191
420
  status
192
421
  transactionId
422
+ updatedAt
193
423
  }
194
424
  }
195
425
  `,
196
426
  variables: {
197
- transactionId
427
+ transactionId: transactionSagaId,
428
+ visitorId: getVisitorID()
198
429
  }
199
430
  });
200
431
  }
432
+ async function pollForFinishedCheckout({
433
+ apollo,
434
+ transactionSagaId,
435
+ interval = 1e3,
436
+ timeout = 6e4
437
+ }) {
438
+ return poll(
439
+ // function to poll
440
+ () => getCheckoutStatus({
441
+ apollo,
442
+ transactionSagaId
443
+ }),
444
+ // function to check for completed status
445
+ (result) => {
446
+ const { status, errorCode, errorMessage } = result?.data?.checkoutStatus;
447
+ if (status === "COMPLETED" || errorCode || errorMessage) {
448
+ return true;
449
+ }
450
+ return false;
451
+ },
452
+ interval,
453
+ timeout
454
+ );
455
+ }
456
+
457
+ // src/oneTimeCheckout.ts
458
+ var import_core7 = require("@apollo/client/core");
459
+ var import_numeral2 = __toESM(require("numeral"), 1);
460
+
461
+ // src/validatePreCheckout.ts
462
+ var import_core6 = require("@apollo/client/core");
463
+ var validatePreCheckoutMutation = import_core6.gql`
464
+ mutation validatePreCheckout($basketId: String, $email: String, $visitorId: String, $emailOptIn: Boolean) {
465
+ shop (basketId: $basketId) {
466
+ id
467
+ validatePreCheckout (email: $email, visitorId: $visitorId, emailOptIn: $emailOptIn) {
468
+ error
469
+ success
470
+ value
471
+ }
472
+ }
473
+ }`;
474
+ async function validatePreCheckout({
475
+ apollo,
476
+ emailAddress,
477
+ emailOptIn
478
+ }) {
479
+ const data = await callShopMutation(apollo, {
480
+ mutation: validatePreCheckoutMutation,
481
+ variables: {
482
+ visitorId: getVisitorID(),
483
+ email: emailAddress,
484
+ emailOptIn
485
+ }
486
+ }, 0);
487
+ const results = data?.shop?.validatePreCheckout;
488
+ const errors = results.filter(({ success }) => !success).map((result) => parseShopError(result));
489
+ if (errors.length) {
490
+ const aggregate = new ShopError({ code: "shop.failedCheckoutValidation" });
491
+ aggregate.aggregateErrors(errors);
492
+ throw aggregate;
493
+ }
494
+ }
495
+
496
+ // src/oneTimeCheckout.ts
497
+ async function creditAmountNeeded(apollo) {
498
+ const data = await callShopQuery(apollo, {
499
+ query: import_core7.gql`
500
+ query creditAmountNeeded($basketId: String) {
501
+ shop (basketId: $basketId) {
502
+ id
503
+ basket {
504
+ id
505
+ totals {
506
+ creditAmountNeeded
507
+ }
508
+ }
509
+ }
510
+ }
511
+ `
512
+ }, 0);
513
+ return data?.shop?.basket?.totals?.creditAmountNeeded;
514
+ }
515
+ var creditCheckoutMutation = import_core7.gql`
516
+ mutation creditCheckout(
517
+ $basketId: String,
518
+ $visitorId: String
519
+ ) {
520
+ shop (basketId: $basketId) {
521
+ id
522
+ transactionId: checkoutAsync (visitorId: $visitorId)
523
+ }
524
+ }
525
+ `;
526
+ var depositCheckoutMutation = import_core7.gql`
527
+ mutation depositCheckout(
528
+ $basketId: String,
529
+ $amount: Money!,
530
+ $nonce: String!,
531
+ $savePaymentMethod: Boolean,
532
+ $deviceData: String,
533
+ $visitorId: String
534
+ ) {
535
+ shop (basketId: $basketId) {
536
+ id
537
+ transactionId: doNoncePaymentDepositAndCheckoutAsync(
538
+ amount: $amount,
539
+ nonce: $nonce,
540
+ savePaymentMethod: $savePaymentMethod,
541
+ deviceData: $deviceData,
542
+ visitorId: $visitorId
543
+ )
544
+ }
545
+ }
546
+ `;
547
+ function creditCheckout(apollo) {
548
+ return callShopMutation(apollo, {
549
+ mutation: creditCheckoutMutation,
550
+ variables: {
551
+ visitorId: getVisitorID()
552
+ }
553
+ }, 0);
554
+ }
555
+ async function depositCheckout({
556
+ apollo,
557
+ braintree,
558
+ amount
559
+ }) {
560
+ try {
561
+ const paymentMethod = await braintree.requestPaymentMethod();
562
+ if (!paymentMethod) {
563
+ throw new ShopError(
564
+ { code: "shop.dropinNoPaymentMethod" },
565
+ "No payment method returned from braintree dropin"
566
+ );
567
+ }
568
+ const { nonce, deviceData } = paymentMethod;
569
+ return callShopMutation(apollo, {
570
+ mutation: depositCheckoutMutation,
571
+ variables: {
572
+ nonce,
573
+ amount,
574
+ savePaymentMethod: false,
575
+ // save payment methods handled by braintree drop in UI
576
+ deviceData,
577
+ visitorId: getVisitorID()
578
+ }
579
+ }, 0);
580
+ } catch (e) {
581
+ throw parseShopError(e);
582
+ }
583
+ }
584
+ async function executeOneTimeCheckout({
585
+ apollo,
586
+ braintree,
587
+ emailAddress,
588
+ emailOptIn
589
+ }) {
590
+ await validatePreCheckout({
591
+ apollo,
592
+ emailAddress,
593
+ emailOptIn
594
+ });
595
+ const creditNeeded = await creditAmountNeeded(apollo);
596
+ const creditRequired = (0, import_numeral2.default)(creditNeeded).value() > 0;
597
+ if (creditRequired && !braintree) {
598
+ throw new ShopError({ code: "shop.dropinRequired" }, "Braintree dropin required for credit deposit checkout");
599
+ }
600
+ const data = creditRequired ? await depositCheckout({
601
+ apollo,
602
+ braintree,
603
+ amount: creditNeeded
604
+ }) : await creditCheckout(apollo);
605
+ const transactionId = data?.shop?.transactionId;
606
+ const result = await pollForFinishedCheckout({
607
+ apollo,
608
+ transactionSagaId: transactionId,
609
+ timeout: 3e5
610
+ // five minutes
611
+ });
612
+ if (result.errors?.length) {
613
+ throw parseShopError(result.errors[0]);
614
+ }
615
+ window.location.href = `/checkout/post-purchase?kiva_transaction_id=${transactionId}`;
616
+ }
201
617
 
202
618
  // src/subscriptionCheckout.ts
203
- var import_core4 = require("@apollo/client/core");
619
+ var import_core8 = require("@apollo/client/core");
204
620
  async function checkSubscriptionStatus(apollo) {
205
621
  const { data: subsData } = await apollo.query({
206
- query: import_core4.gql`query subscriptionStatus{
622
+ query: import_core8.gql`query subscriptionStatus{
207
623
  my {
208
624
  id
209
625
  subscriptions {
@@ -253,7 +669,7 @@ async function executeNewSubscriptionCheckout({
253
669
  donateAmount,
254
670
  dayOfMonth
255
671
  },
256
- mutation: import_core4.gql`mutation createAutoDepositSubscription(
672
+ mutation: import_core8.gql`mutation createAutoDepositSubscription(
257
673
  $nonce: String!,
258
674
  $deviceData: String,
259
675
  $amount: Money!,
@@ -297,13 +713,13 @@ async function executeNewSubscriptionCheckout({
297
713
  }
298
714
 
299
715
  // src/useBraintreeDropIn.ts
300
- var import_core5 = require("@apollo/client/core");
301
- var import_numeral2 = __toESM(require("numeral"), 1);
716
+ var import_core9 = require("@apollo/client/core");
717
+ var import_numeral3 = __toESM(require("numeral"), 1);
302
718
  var import_vue_demi = require("vue-demi");
303
719
  var defaultPaymentTypes = ["paypal", "card", "applePay", "googlePay"];
304
720
  async function getClientToken(apollo) {
305
721
  const { data, error, errors } = await apollo.query({
306
- query: import_core5.gql`query getClientToken {
722
+ query: import_core9.gql`query getClientToken {
307
723
  shop {
308
724
  id
309
725
  getClientToken(useCustomerId: true)
@@ -315,7 +731,7 @@ async function getClientToken(apollo) {
315
731
  }
316
732
  return data?.shop?.getClientToken;
317
733
  }
318
- function useBraintreeDropIn() {
734
+ function initBraintreeDropin() {
319
735
  let instance;
320
736
  let formattedAmount = "";
321
737
  const paymentMethodRequestable = (0, import_vue_demi.ref)(false);
@@ -360,7 +776,7 @@ function useBraintreeDropIn() {
360
776
  preselectVaultedPaymentMethod = true,
361
777
  paypalFlow = "checkout"
362
778
  }) {
363
- formattedAmount = (0, import_numeral2.default)(amount).format("0.00");
779
+ formattedAmount = (0, import_numeral3.default)(amount).format("0.00");
364
780
  const { default: DropIn } = await import("braintree-web-drop-in");
365
781
  try {
366
782
  instance = await DropIn.create({
@@ -430,7 +846,7 @@ function useBraintreeDropIn() {
430
846
  }
431
847
  }
432
848
  function updateAmount(amount) {
433
- const newAmount = (0, import_numeral2.default)(amount).format("0.00");
849
+ const newAmount = (0, import_numeral3.default)(amount).format("0.00");
434
850
  if (newAmount !== formattedAmount) {
435
851
  formattedAmount = newAmount;
436
852
  instance?.updateConfiguration("paypal", "amount", formattedAmount);
@@ -445,22 +861,39 @@ function useBraintreeDropIn() {
445
861
  updateAmount
446
862
  };
447
863
  }
864
+ var instances = {};
865
+ function useBraintreeDropIn(key = "default") {
866
+ if (!instances[key]) {
867
+ instances[key] = initBraintreeDropin();
868
+ }
869
+ return instances[key];
870
+ }
448
871
  // Annotate the CommonJS export names for ESM import in node:
449
872
  0 && (module.exports = {
450
873
  ShopError,
874
+ VerificationState,
875
+ applyKivaCredit,
876
+ basketTotalsQuery,
877
+ callShopMutation,
878
+ callShopQuery,
451
879
  checkSubscriptionStatus,
452
880
  createBasket,
453
881
  defaultPaymentTypes,
454
882
  executeNewSubscriptionCheckout,
455
883
  executeOneTimeCheckout,
456
884
  getBasketID,
885
+ getCheckoutStatus,
457
886
  getClientToken,
458
- getCookieValue,
459
887
  hasBasketExpired,
888
+ isBasketVerified,
460
889
  parseShopError,
890
+ pollForFinishedCheckout,
891
+ removeKivaCredit,
461
892
  setBasketID,
462
- setCookieValue,
463
893
  setTipDonation,
464
894
  useBraintreeDropIn,
465
- waitOnTransaction
895
+ validatePreCheckout,
896
+ validatePreCheckoutMutation,
897
+ watchBasketTotals,
898
+ watchShopQuery
466
899
  });