@kiva/kv-shop 2.1.2 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/_virtual/_commonjs-dynamic-modules.js +6 -0
  2. package/dist/_virtual/_commonjsHelpers.js +8 -0
  3. package/dist/_virtual/_plugin-vue_export-helper.js +9 -0
  4. package/dist/_virtual/dropin.js +11 -0
  5. package/dist/_virtual/dropin2.js +4 -0
  6. package/dist/basket.js +35 -12
  7. package/dist/basketCredits.js +78 -14
  8. package/dist/basketItems.js +27 -8
  9. package/dist/basketTotals.js +38 -10
  10. package/dist/basketVerification.js +6 -6
  11. package/dist/checkoutStatus.js +52 -8
  12. package/dist/components/KvPaymentSelect.css +1 -0
  13. package/dist/components/KvPaymentSelect.js +23 -0
  14. package/dist/components/KvPaymentSelect2.js +110 -0
  15. package/dist/index.d.ts +321 -20
  16. package/dist/index.js +49 -96
  17. package/dist/managedAccount.js +62 -8
  18. package/dist/oneTimeCheckout.js +156 -12
  19. package/dist/receipt.js +143 -12
  20. package/dist/shopError.js +41 -6
  21. package/dist/shopQueries.js +82 -11
  22. package/dist/subscriptionCheckout.js +88 -7
  23. package/dist/useBraintreeDropIn.js +145 -9
  24. package/dist/util/cookie.js +11 -0
  25. package/dist/util/poll.js +17 -0
  26. package/dist/util/redirect.js +8 -0
  27. package/dist/util/visitorId.js +7 -0
  28. package/dist/validatePreCheckout.js +44 -11
  29. package/dist/vendor/braintree-web-drop-in/dist/browser/dropin.js +12223 -0
  30. package/package.json +28 -26
  31. package/dist/basket.cjs +0 -141
  32. package/dist/basket.d.ts +0 -8
  33. package/dist/basketCredits.cjs +0 -250
  34. package/dist/basketCredits.d.ts +0 -32
  35. package/dist/basketItems.cjs +0 -205
  36. package/dist/basketItems.d.ts +0 -26
  37. package/dist/basketTotals.cjs +0 -228
  38. package/dist/basketTotals.d.ts +0 -37
  39. package/dist/basketVerification.cjs +0 -41
  40. package/dist/basketVerification.d.ts +0 -10
  41. package/dist/checkoutStatus.cjs +0 -111
  42. package/dist/checkoutStatus.d.ts +0 -20
  43. package/dist/chunk-4ODZGLWK.js +0 -64
  44. package/dist/chunk-ASZJVUQ7.js +0 -72
  45. package/dist/chunk-FBF4WMN6.js +0 -49
  46. package/dist/chunk-FC4QW6QA.js +0 -106
  47. package/dist/chunk-FCAOCO7O.js +0 -17
  48. package/dist/chunk-GVVI7X2R.js +0 -196
  49. package/dist/chunk-IIN37LC7.js +0 -45
  50. package/dist/chunk-IOZ5ERDX.js +0 -121
  51. package/dist/chunk-KCUOMCSN.js +0 -58
  52. package/dist/chunk-LZ4UMRCV.js +0 -16
  53. package/dist/chunk-RQNRQ2E5.js +0 -155
  54. package/dist/chunk-SRGYGDAX.js +0 -80
  55. package/dist/chunk-TPJPGUO7.js +0 -12
  56. package/dist/chunk-UJXHTR43.js +0 -86
  57. package/dist/chunk-VZ3VDRRP.js +0 -167
  58. package/dist/chunk-Z7JRY3QE.js +0 -34
  59. package/dist/components/KvPaymentSelect.vue +0 -380
  60. package/dist/index.cjs +0 -1227
  61. package/dist/managedAccount.cjs +0 -231
  62. package/dist/managedAccount.d.ts +0 -59
  63. package/dist/oneTimeCheckout.cjs +0 -636
  64. package/dist/oneTimeCheckout.d.ts +0 -21
  65. package/dist/receipt.cjs +0 -191
  66. package/dist/receipt.d.ts +0 -16
  67. package/dist/shopError.cjs +0 -88
  68. package/dist/shopError.d.ts +0 -14
  69. package/dist/shopQueries.cjs +0 -248
  70. package/dist/shopQueries.d.ts +0 -8
  71. package/dist/subscriptionCheckout.cjs +0 -187
  72. package/dist/subscriptionCheckout.d.ts +0 -13
  73. package/dist/useBraintreeDropIn.cjs +0 -258
  74. package/dist/useBraintreeDropIn.d.ts +0 -25
  75. package/dist/validatePreCheckout.cjs +0 -218
  76. package/dist/validatePreCheckout.d.ts +0 -28
package/dist/index.cjs DELETED
@@ -1,1227 +0,0 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
27
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
-
29
- // src/index.ts
30
- var src_exports = {};
31
- __export(src_exports, {
32
- ShopError: () => ShopError,
33
- VerificationState: () => VerificationState,
34
- applyKivaCredit: () => applyKivaCredit,
35
- applyPromoCredit: () => applyPromoCredit,
36
- basketTotalsQuery: () => basketTotalsQuery,
37
- callShopMutation: () => callShopMutation,
38
- callShopQuery: () => callShopQuery,
39
- checkSubscriptionStatus: () => checkSubscriptionStatus,
40
- createBasket: () => createBasket,
41
- defaultPaymentTypes: () => defaultPaymentTypes,
42
- executeNewSubscriptionCheckout: () => executeNewSubscriptionCheckout,
43
- executeOneTimeCheckout: () => executeOneTimeCheckout,
44
- getBasketID: () => getBasketID,
45
- getCheckoutStatus: () => getCheckoutStatus,
46
- getCheckoutTrackingData: () => getCheckoutTrackingData,
47
- getClientToken: () => getClientToken,
48
- getFTDStatus: () => getFTDStatus,
49
- getPromoFromBasket: () => getPromoFromBasket,
50
- getReceiptItems: () => getReceiptItems,
51
- getReceiptTotals: () => getReceiptTotals,
52
- hasBasketExpired: () => hasBasketExpired,
53
- isBasketVerified: () => isBasketVerified,
54
- parseShopError: () => parseShopError,
55
- pollForFinishedCheckout: () => pollForFinishedCheckout,
56
- removeKivaCredit: () => removeKivaCredit,
57
- removePromoCredit: () => removePromoCredit,
58
- setBasketID: () => setBasketID,
59
- setTipDonation: () => setTipDonation,
60
- useBraintreeDropIn: () => useBraintreeDropIn,
61
- validatePreCheckout: () => validatePreCheckout,
62
- validatePreCheckoutMutation: () => validatePreCheckoutMutation,
63
- watchBasketTotals: () => watchBasketTotals,
64
- watchShopQuery: () => watchShopQuery
65
- });
66
- module.exports = __toCommonJS(src_exports);
67
-
68
- // src/basket.ts
69
- var import_core = require("@apollo/client/core/core.cjs");
70
-
71
- // src/util/cookie.ts
72
- var getCookieValue = (name) => {
73
- if (typeof document !== void 0) {
74
- return decodeURIComponent(document.cookie.match(`(^|;)\\s*${name}\\s*=\\s*([^;]+)`)?.pop() || "");
75
- }
76
- };
77
- var setCookieValue = (name, value, options = "") => {
78
- if (typeof document !== void 0) {
79
- document.cookie = `${name}=${encodeURIComponent(value)};${options}`;
80
- }
81
- };
82
-
83
- // src/shopError.ts
84
- var ShopError = class extends Error {
85
- constructor({ code, original }, ...params) {
86
- super(...params);
87
- if (Error.captureStackTrace) {
88
- Error.captureStackTrace(this, ShopError);
89
- }
90
- this.name = "ShopError";
91
- this.code = code;
92
- this.original = original;
93
- }
94
- aggregateErrors(errors) {
95
- this.errors = errors;
96
- }
97
- };
98
- function parseShopError(error) {
99
- if (error instanceof ShopError) {
100
- return error;
101
- }
102
- const errorCode = error?.code ?? error?.extensions?.code ?? error?.name ?? "";
103
- const errorMessage = typeof error === "string" ? error : error?.message ?? "";
104
- if (errorCode === "invalidMethodParameter" && errorMessage.includes("paymentMethod.create")) {
105
- return new ShopError({
106
- code: "paymentMethod.create.invalidMethodParameter",
107
- original: error
108
- }, "There was a problem validating your payment information. Please double-check the details and try again.");
109
- }
110
- if (errorMessage.includes("Invalid request: ")) {
111
- const finalError = errorMessage.split("Invalid request: ")[1].split("., ").map((e) => e.matchAll(/[A-Z_]+: (.*)/g))[0];
112
- const finalCode = finalError[1];
113
- const finalMessage = finalError[2];
114
- return new ShopError({
115
- code: `paymentMethod.${finalCode}`,
116
- original: error
117
- }, finalMessage);
118
- }
119
- if (errorCode === "insufficientFunds" || errorMessage.includes("There is not enough credit")) {
120
- return new ShopError({
121
- code: "shop.insufficientFunds",
122
- original: error
123
- }, "There is not enough money to complete the checkout. Please double-check the details and try again.");
124
- }
125
- if (errorCode === "shop.invalidBasketId" || errorCode === "shop.basketRequired" || errorCode === "shop.alreadyCheckedOut") {
126
- return new ShopError({
127
- code: errorCode,
128
- original: error
129
- }, "There was a problem with your basket. Please, refresh the page and try again.");
130
- }
131
- if (errorCode === "donationAmountTooLarge") {
132
- return new ShopError({
133
- code: errorCode,
134
- original: error
135
- }, errorMessage);
136
- }
137
- return new ShopError({
138
- code: "shop.unknown",
139
- original: error
140
- }, "An unknown error occurred.");
141
- }
142
-
143
- // src/basket.ts
144
- function getBasketID() {
145
- return getCookieValue("kvbskt");
146
- }
147
- function setBasketID(basketId) {
148
- setCookieValue("kvbskt", basketId, "path=/;secure;");
149
- }
150
- async function createBasketHelper(apollo) {
151
- try {
152
- return apollo.mutate({
153
- mutation: import_core.gql`mutation createNewBasketForUser { shop { id createBasket } }`
154
- }).then(({ data }) => {
155
- const newBasketId = data.shop?.createBasket ?? null;
156
- if (newBasketId) {
157
- setBasketID(newBasketId);
158
- }
159
- });
160
- } catch (error) {
161
- throw parseShopError(error);
162
- }
163
- }
164
- var activeBasketCreationQuery = null;
165
- async function createBasket(apollo) {
166
- if (activeBasketCreationQuery) {
167
- return activeBasketCreationQuery;
168
- }
169
- activeBasketCreationQuery = createBasketHelper(apollo);
170
- return activeBasketCreationQuery;
171
- }
172
- function hasBasketExpired(error) {
173
- const errorCode = error?.code ?? error?.extensions?.code ?? error?.name ?? "";
174
- return ["shop.invalidBasketId", "shop.basketRequired", "shop.alreadyCheckedOut"].includes(errorCode);
175
- }
176
-
177
- // src/basketCredits.ts
178
- var import_core2 = require("@apollo/client/core/core.cjs");
179
-
180
- // src/shopQueries.ts
181
- var watchQueries = /* @__PURE__ */ new Set();
182
- async function callShopMutation(apollo, options, maxretries = 2) {
183
- try {
184
- const result = await apollo.mutate({
185
- ...options,
186
- variables: {
187
- ...options.variables,
188
- basketId: getBasketID()
189
- },
190
- refetchQueries: options.awaitRefetchQueries ? Array.from(watchQueries) : []
191
- });
192
- if (result?.errors?.length) {
193
- const basketErrors = result?.errors.filter((err) => hasBasketExpired(err));
194
- if (basketErrors.length) {
195
- if (maxretries > 0) {
196
- await createBasket(apollo);
197
- return callShopMutation(apollo, options, maxretries - 1);
198
- }
199
- throw basketErrors[0];
200
- }
201
- if (result?.errors?.length) {
202
- throw result.errors[0];
203
- }
204
- }
205
- return result?.data;
206
- } catch (e) {
207
- throw parseShopError(e);
208
- }
209
- }
210
- async function callShopQuery(apollo, options, maxretries = 2) {
211
- try {
212
- const result = await apollo.query({
213
- ...options,
214
- variables: {
215
- ...options.variables,
216
- basketId: getBasketID()
217
- }
218
- });
219
- if (result?.errors?.length) {
220
- const basketErrors = result?.errors.filter((err) => hasBasketExpired(err));
221
- if (basketErrors.length) {
222
- if (maxretries > 0) {
223
- await createBasket(apollo);
224
- return callShopQuery(apollo, options, maxretries - 1);
225
- }
226
- throw basketErrors[0];
227
- }
228
- if (result?.errors?.length) {
229
- throw result.errors[0];
230
- }
231
- }
232
- return result?.data;
233
- } catch (e) {
234
- throw parseShopError(e);
235
- }
236
- }
237
- function watchShopQuery(apollo, options, maxretries = 2) {
238
- let retries = 0;
239
- watchQueries.add(options.query);
240
- const observable = apollo.watchQuery({
241
- ...options,
242
- variables: {
243
- ...options.variables,
244
- basketId: getBasketID()
245
- }
246
- });
247
- const oldSubscribe = observable.subscribe.bind(observable);
248
- observable.subscribe = (...args) => {
249
- let nextFn;
250
- let errorFn;
251
- let completeFn;
252
- if (typeof args[0] === "function") {
253
- [nextFn, errorFn, completeFn] = args;
254
- } else {
255
- nextFn = args[0]?.next;
256
- errorFn = args[0]?.error;
257
- completeFn = args[0]?.complete;
258
- }
259
- const newErrorFn = (err) => {
260
- const basketErrors = err?.graphQLErrors?.filter((e) => hasBasketExpired(e));
261
- if (basketErrors.length) {
262
- if (retries < maxretries) {
263
- createBasket(apollo).then(() => {
264
- retries += 1;
265
- observable.refetch({
266
- ...observable.variables,
267
- basketId: getBasketID()
268
- });
269
- });
270
- } else {
271
- errorFn(parseShopError(basketErrors[0]));
272
- }
273
- } else {
274
- if (err?.graphQLErrors?.length) {
275
- errorFn(parseShopError(err.graphQLErrors[0]));
276
- }
277
- if (err?.networkError) {
278
- errorFn(parseShopError(err.networkError));
279
- }
280
- }
281
- };
282
- return oldSubscribe(nextFn, newErrorFn, completeFn);
283
- };
284
- return observable;
285
- }
286
-
287
- // src/basketCredits.ts
288
- async function applyKivaCredit(apollo) {
289
- const data = await callShopMutation(apollo, {
290
- awaitRefetchQueries: true,
291
- mutation: import_core2.gql`mutation applyKivaCredit($basketId: String) {
292
- shop (basketId: $basketId) {
293
- id
294
- addCreditByType(creditType: kiva_credit)
295
- }
296
- }`
297
- });
298
- return !!data?.shop?.addCreditByType;
299
- }
300
- async function removeKivaCredit(apollo) {
301
- const data = await callShopMutation(apollo, {
302
- awaitRefetchQueries: true,
303
- mutation: import_core2.gql`mutation removeKivaCredit($basketId: String) {
304
- shop (basketId: $basketId) {
305
- id
306
- removeCreditByType(creditType: kiva_credit)
307
- }
308
- }`
309
- });
310
- return !!data?.shop?.removeCreditByType;
311
- }
312
- async function applyPromoCredit(apollo, options) {
313
- if (!options?.variables?.creditType || !options?.variables?.redemptionCode) {
314
- return Promise.resolve({
315
- errors: [
316
- {
317
- message: "Missing required parameter.",
318
- extensions: { code: "upc.missing_parameter" }
319
- }
320
- ]
321
- });
322
- }
323
- const data = await callShopMutation(apollo, {
324
- awaitRefetchQueries: true,
325
- fetchPolicy: options?.fetchPolicy ?? "network-only",
326
- mutation: import_core2.gql`mutation applyPromoCredit(
327
- $basketId: String,
328
- $creditType: CreditTypeEnum!,
329
- $redemptionCode: String
330
- ) {
331
- shop (basketId: $basketId) {
332
- id
333
- addCreditByType(creditType: $creditType, redemptionCode: $redemptionCode)
334
- }
335
- }`,
336
- variables: { ...options?.variables }
337
- });
338
- return data;
339
- }
340
- async function removePromoCredit(apollo, options) {
341
- if (!options?.variables?.creditType && !options?.variables?.redemptionCode) {
342
- return Promise.resolve(false);
343
- }
344
- const data = await callShopMutation(apollo, {
345
- awaitRefetchQueries: true,
346
- fetchPolicy: options?.fetchPolicy ?? "network-only",
347
- mutation: import_core2.gql`mutation removePromoCredit(
348
- $basketId: String,
349
- $creditType: CreditTypeEnum!,
350
- $redemptionCode: String
351
- ) {
352
- shop (basketId: $basketId) {
353
- id
354
- removeCreditByType(creditType: $creditType, redemptionCode: $redemptionCode)
355
- }
356
- }`,
357
- variables: { ...options?.variables }
358
- });
359
- return !!data?.shop?.removeCreditByType;
360
- }
361
-
362
- // src/basketItems.ts
363
- var import_core3 = require("@apollo/client/core/core.cjs");
364
- var import_numeral = __toESM(require("numeral"), 1);
365
- async function setTipDonation({ amount, apollo, metadata }) {
366
- const donationAmount = (0, import_numeral.default)(amount).format("0.00");
367
- const data = await callShopMutation(apollo, {
368
- awaitRefetchQueries: true,
369
- mutation: import_core3.gql`mutation setTipDonation($price: Money!, $basketId: String, $metadata: String) {
370
- shop (basketId: $basketId) {
371
- id
372
- updateDonation (donation: {
373
- price: $price,
374
- isTip: true,
375
- metadata: $metadata,
376
- })
377
- {
378
- id
379
- price
380
- isTip
381
- }
382
- }
383
- }`,
384
- variables: { price: donationAmount, metadata }
385
- });
386
- return data?.shop?.updateDonation;
387
- }
388
-
389
- // src/basketTotals.ts
390
- var import_core4 = require("@apollo/client/core/core.cjs");
391
- var basketTotalsQuery = import_core4.gql`query basketTotals($basketId: String) {
392
- shop (basketId: $basketId) {
393
- id
394
- basket {
395
- id
396
- totals {
397
- bonusAppliedTotal
398
- bonusAvailableTotal
399
- creditAmountNeeded
400
- creditAppliedTotal
401
- creditAvailableTotal
402
- donationTotal
403
- itemTotal
404
- freeTrialAppliedTotal
405
- freeTrialAvailableTotal
406
- loanReservationTotal
407
- kivaCardTotal
408
- kivaCreditAppliedTotal
409
- kivaCreditAvailableTotal
410
- kivaCreditRemaining
411
- kivaCreditToReapply
412
- redemptionCodeAppliedTotal
413
- redemptionCodeAvailableTotal
414
- universalCodeAppliedTotal
415
- universalCodeAvailableTotal
416
- }
417
- }
418
- }
419
- }`;
420
- function watchBasketTotals(apollo) {
421
- return watchShopQuery(apollo, {
422
- query: basketTotalsQuery
423
- });
424
- }
425
-
426
- // src/basketVerification.ts
427
- var VerificationState = /* @__PURE__ */ ((VerificationState2) => {
428
- VerificationState2["VERIFIED"] = "verified";
429
- VerificationState2["PENDING"] = "pending";
430
- VerificationState2["REQUIRED"] = "required";
431
- VerificationState2["MAY_BE_NEEDED"] = "may_be_needed";
432
- VerificationState2["NOT_NEEDED"] = "not_needed";
433
- return VerificationState2;
434
- })(VerificationState || {});
435
- function isBasketVerified(state) {
436
- return state === "verified" /* VERIFIED */ || state === "not_needed" /* NOT_NEEDED */;
437
- }
438
-
439
- // src/checkoutStatus.ts
440
- var import_core5 = require("@apollo/client/core/core.cjs");
441
-
442
- // src/util/poll.ts
443
- function wait(ms) {
444
- return new Promise((resolve) => setTimeout(resolve, ms));
445
- }
446
- async function poll(fn, fnCondition, interval, timeout) {
447
- const endTime = Date.now() + timeout;
448
- let result = await fn();
449
- while (!fnCondition(result)) {
450
- if (Date.now() > endTime) {
451
- throw new Error("Polling timed out");
452
- }
453
- await wait(interval);
454
- result = await fn();
455
- }
456
- return result;
457
- }
458
-
459
- // src/util/visitorId.ts
460
- function getVisitorID() {
461
- return getCookieValue("uiv");
462
- }
463
-
464
- // src/checkoutStatus.ts
465
- async function getCheckoutStatus({ apollo, transactionSagaId }) {
466
- return apollo.query({
467
- query: import_core5.gql`
468
- query checkoutStatus($transactionId: String!, $visitorId: String) {
469
- checkoutStatus(transactionId: $transactionId, visitorId: $visitorId) {
470
- basketId
471
- errorCode
472
- errorMessage
473
- receipt {
474
- checkoutId
475
- }
476
- requestedAt
477
- status
478
- transactionId
479
- updatedAt
480
- }
481
- }
482
- `,
483
- variables: {
484
- transactionId: transactionSagaId,
485
- visitorId: getVisitorID()
486
- },
487
- fetchPolicy: "network-only"
488
- });
489
- }
490
- async function pollForFinishedCheckout({
491
- apollo,
492
- transactionSagaId,
493
- interval = 1e3,
494
- timeout = 6e4
495
- }) {
496
- return poll(
497
- // function to poll
498
- () => getCheckoutStatus({
499
- apollo,
500
- transactionSagaId
501
- }),
502
- // function to check for completed status
503
- (result) => {
504
- const { status, errorCode, errorMessage } = result?.data?.checkoutStatus;
505
- if (status === "COMPLETED" || errorCode || errorMessage) {
506
- return true;
507
- }
508
- return false;
509
- },
510
- interval,
511
- timeout
512
- );
513
- }
514
-
515
- // src/managedAccount.ts
516
- var import_core6 = require("@apollo/client/core/core.cjs");
517
- async function getPromoFromBasket(apollo, options) {
518
- if (!options?.variables?.promoFundId && !options?.variables?.basketId) {
519
- return Promise.resolve({ error: "promoFundId or basketId variable required" });
520
- }
521
- const data = await callShopQuery(apollo, {
522
- variables: { ...options?.variables },
523
- query: import_core6.gql`
524
- query promoCampaign($basketId: String, $promoFundId: String) {
525
- shop (basketId: $basketId) {
526
- id
527
- promoCampaign (promoFundId: $promoFundId) {
528
- promoFund {
529
- id
530
- displayName
531
- displayDescription
532
- promoPrice
533
- }
534
- promoGroup {
535
- id
536
- type
537
- teamId
538
- }
539
- managedAccount {
540
- managementType
541
- audience
542
- allowDonations
543
- sendKivaNewsletter
544
- id
545
- isEmployee
546
- formId
547
- pageId
548
- loanSearchCriteria {
549
- filters {
550
- cityState
551
- country
552
- currencyLossPossible
553
- dafEligible
554
- distributionModel
555
- status
556
- excludeNonRated
557
- expiringSoon
558
- gender
559
- hasResearchScore
560
- isGroup
561
- lenderFavorite
562
- loanLimit
563
- isMatched
564
- sector
565
- loanTags
566
- theme
567
- }
568
- sortBy
569
- }
570
- }
571
- }
572
- }
573
- }
574
- `,
575
- fetchPolicy: options?.fetchPolicy ?? "network-only"
576
- }, 0);
577
- return data;
578
- }
579
-
580
- // src/oneTimeCheckout.ts
581
- var import_core9 = require("@apollo/client/core/core.cjs");
582
- var import_kv_analytics = require("@kiva/kv-analytics");
583
- var import_numeral2 = __toESM(require("numeral"), 1);
584
-
585
- // src/validatePreCheckout.ts
586
- var import_core7 = require("@apollo/client/core/core.cjs");
587
- var validatePreCheckoutMutation = import_core7.gql`
588
- mutation validatePreCheckout(
589
- $basketId: String,
590
- $email: String,
591
- $visitorId: String,
592
- $emailOptIn: Boolean,
593
- $inviter: InviterInput
594
- ) {
595
- shop (basketId: $basketId) {
596
- id
597
- validatePreCheckout (email: $email, visitorId: $visitorId, emailOptIn: $emailOptIn, inviter: $inviter) {
598
- error
599
- success
600
- value
601
- }
602
- }
603
- }`;
604
- async function validatePreCheckout({
605
- apollo,
606
- emailAddress,
607
- emailOptIn,
608
- valetInviter
609
- }) {
610
- const data = await callShopMutation(apollo, {
611
- mutation: validatePreCheckoutMutation,
612
- variables: {
613
- visitorId: getVisitorID(),
614
- email: emailAddress,
615
- emailOptIn,
616
- inviter: valetInviter
617
- }
618
- }, 0);
619
- const results = data?.shop?.validatePreCheckout;
620
- const errors = results.filter(({ success }) => !success).map((result) => parseShopError(result));
621
- if (errors.length) {
622
- const aggregate = new ShopError({ code: "shop.failedCheckoutValidation" });
623
- aggregate.aggregateErrors(errors);
624
- throw aggregate;
625
- }
626
- }
627
-
628
- // src/util/redirect.ts
629
- function redirectTo(href) {
630
- return new Promise(() => {
631
- window.location.href = href;
632
- });
633
- }
634
-
635
- // src/receipt.ts
636
- var import_core8 = require("@apollo/client/core/core.cjs");
637
- async function getFTDStatus(apollo) {
638
- const result = await apollo.query({
639
- query: import_core8.gql`
640
- query ftdStatus {
641
- my {
642
- id
643
- userAccount {
644
- id
645
- isFirstTimeDepositor
646
- }
647
- }
648
- }
649
- `
650
- });
651
- return result.data?.my?.userAccount?.isFirstTimeDepositor ?? false;
652
- }
653
- async function getReceiptItems(apollo, checkoutId) {
654
- return new Promise((resolve, reject) => {
655
- const limit = 100;
656
- let offset = 0;
657
- const observer = apollo.watchQuery({
658
- query: import_core8.gql`
659
- query receiptItems($checkoutId: Int, $visitorId: String, $limit: Int, $offset: Int) {
660
- shop {
661
- id
662
- receipt(checkoutId: $checkoutId, visitorId: $visitorId) {
663
- id
664
- items(limit: $limit, offset: $offset) {
665
- totalCount
666
- values {
667
- id
668
- price
669
- __typename
670
-
671
- ... on Donation {
672
- id
673
- isTip
674
- isUserEdited
675
- }
676
- }
677
- }
678
- }
679
- }
680
- }
681
- `,
682
- variables: {
683
- checkoutId,
684
- visitorId: getVisitorID(),
685
- limit,
686
- offset
687
- }
688
- });
689
- let items = [];
690
- const handleResult = async (result) => {
691
- const total = result.data?.shop?.receipt?.items?.totalCount;
692
- items = items.concat(result.data?.shop?.receipt?.items?.values);
693
- if (total > offset + limit) {
694
- offset += limit;
695
- const nextResult = await observer.fetchMore({
696
- variables: {
697
- offset
698
- }
699
- });
700
- try {
701
- handleResult(nextResult);
702
- } catch (e) {
703
- reject(e);
704
- }
705
- } else {
706
- resolve(items);
707
- }
708
- };
709
- observer.subscribe({
710
- next: handleResult,
711
- error: (error) => {
712
- reject(error);
713
- }
714
- });
715
- });
716
- }
717
- async function getReceiptTotals(apollo, checkoutId) {
718
- const result = await apollo.query({
719
- query: import_core8.gql`
720
- query receiptTotals($checkoutId: Int, $visitorId: String) {
721
- shop {
722
- id
723
- receipt(checkoutId: $checkoutId, visitorId: $visitorId) {
724
- id
725
- totals {
726
- loanReservationTotal
727
- donationTotal
728
- kivaCardTotal
729
- itemTotal
730
- kivaCreditAppliedTotal
731
- depositTotals {
732
- depositTotal
733
- }
734
- }
735
- }
736
- }
737
- }
738
- `,
739
- variables: {
740
- checkoutId,
741
- visitorId: getVisitorID()
742
- }
743
- });
744
- return result.data?.shop?.receipt?.totals;
745
- }
746
- async function getCheckoutTrackingData(apollo, checkoutId, paymentType) {
747
- const checkoutIdInt = parseInt(checkoutId, 10);
748
- const [isFTD, items, totals] = await Promise.all([
749
- getFTDStatus(apollo),
750
- getReceiptItems(apollo, checkoutIdInt),
751
- getReceiptTotals(apollo, checkoutIdInt)
752
- ]);
753
- const loans = items.filter((item) => item.__typename === "LoanReservation");
754
- const donations = items.filter((item) => item.__typename === "Donation");
755
- const kivaCards = items.filter((item) => item.__typename === "KivaCard");
756
- return {
757
- transactionId: checkoutId,
758
- itemTotal: totals.itemTotal,
759
- // Loan reservations
760
- loans,
761
- loanCount: loans.length,
762
- loanTotal: totals.loanReservationTotal,
763
- // Donations
764
- donations: donations.map(({ id, price, __typename }) => ({ id, price, __typename })),
765
- donationTotal: totals.donationTotal,
766
- isTip: donations.every((donation) => donation.isTip),
767
- isUserEdited: donations.some((donation) => donation.isUserEdited),
768
- // Kiva Cards
769
- kivaCards,
770
- kivaCardCount: kivaCards.length,
771
- kivaCardTotal: totals.kivaCardTotal,
772
- // Credit & deposit
773
- kivaCreditAppliedTotal: totals.kivaCreditAppliedTotal,
774
- depositTotal: totals.depositTotals?.depositTotal ?? "0.00",
775
- paymentType,
776
- isFTD
777
- };
778
- }
779
-
780
- // src/oneTimeCheckout.ts
781
- async function creditAmountNeeded(apollo) {
782
- const data = await callShopQuery(apollo, {
783
- query: import_core9.gql`
784
- query creditAmountNeeded($basketId: String) {
785
- shop (basketId: $basketId) {
786
- id
787
- basket {
788
- id
789
- totals {
790
- creditAmountNeeded
791
- }
792
- }
793
- }
794
- }
795
- `,
796
- fetchPolicy: "network-only"
797
- }, 0);
798
- return data?.shop?.basket?.totals?.creditAmountNeeded;
799
- }
800
- var creditCheckoutMutation = import_core9.gql`
801
- mutation creditCheckout(
802
- $basketId: String,
803
- $visitorId: String
804
- ) {
805
- shop (basketId: $basketId) {
806
- id
807
- transactionId: checkoutAsync (visitorId: $visitorId)
808
- }
809
- }
810
- `;
811
- var depositCheckoutMutation = import_core9.gql`
812
- mutation depositCheckout(
813
- $basketId: String,
814
- $amount: Money!,
815
- $nonce: String!,
816
- $savePaymentMethod: Boolean,
817
- $deviceData: String,
818
- $visitorId: String
819
- ) {
820
- shop (basketId: $basketId) {
821
- id
822
- transactionId: doNoncePaymentDepositAndCheckoutAsync(
823
- amount: $amount,
824
- nonce: $nonce,
825
- savePaymentMethod: $savePaymentMethod,
826
- deviceData: $deviceData,
827
- visitorId: $visitorId
828
- )
829
- }
830
- }
831
- `;
832
- function creditCheckout(apollo) {
833
- return callShopMutation(apollo, {
834
- mutation: creditCheckoutMutation,
835
- variables: {
836
- visitorId: getVisitorID()
837
- }
838
- }, 0);
839
- }
840
- async function depositCheckout({
841
- apollo,
842
- braintree,
843
- amount
844
- }) {
845
- try {
846
- const paymentMethod = await braintree.requestPaymentMethod();
847
- if (!paymentMethod) {
848
- throw new ShopError(
849
- { code: "shop.dropinNoPaymentMethod" },
850
- "No payment method returned from braintree dropin"
851
- );
852
- }
853
- const { nonce, deviceData, type } = paymentMethod;
854
- return {
855
- paymentType: type,
856
- mutation: callShopMutation(apollo, {
857
- mutation: depositCheckoutMutation,
858
- variables: {
859
- nonce,
860
- amount,
861
- savePaymentMethod: false,
862
- // save payment methods handled by braintree drop in UI
863
- deviceData,
864
- visitorId: getVisitorID()
865
- }
866
- }, 0)
867
- };
868
- } catch (e) {
869
- throw parseShopError(e);
870
- }
871
- }
872
- async function trackSuccess(apollo, checkoutId, paymentType) {
873
- try {
874
- const transactionData = await getCheckoutTrackingData(
875
- apollo,
876
- checkoutId,
877
- paymentType
878
- );
879
- (0, import_kv_analytics.trackTransaction)(transactionData);
880
- await wait(800);
881
- } catch (e) {
882
- console.error("Error tracking transaction", e);
883
- }
884
- }
885
- async function executeOneTimeCheckout({
886
- apollo,
887
- braintree,
888
- emailAddress,
889
- emailOptIn,
890
- valetInviter,
891
- deactivateRedirect
892
- }) {
893
- await validatePreCheckout({
894
- apollo,
895
- emailAddress,
896
- emailOptIn,
897
- valetInviter
898
- });
899
- const creditNeeded = await creditAmountNeeded(apollo);
900
- const creditRequired = (0, import_numeral2.default)(creditNeeded).value() > 0;
901
- if (creditRequired && !braintree) {
902
- throw new ShopError({ code: "shop.dropinRequired" }, "Braintree dropin required for credit deposit checkout");
903
- }
904
- let data;
905
- let paymentType = "";
906
- if (creditRequired) {
907
- const checkoutResult = await depositCheckout({
908
- apollo,
909
- braintree,
910
- amount: creditNeeded
911
- });
912
- paymentType = checkoutResult.paymentType;
913
- data = await checkoutResult.mutation;
914
- } else {
915
- data = await creditCheckout(apollo);
916
- }
917
- const transactionId = data?.shop?.transactionId;
918
- const result = await pollForFinishedCheckout({
919
- apollo,
920
- transactionSagaId: transactionId,
921
- timeout: 3e5
922
- // five minutes
923
- });
924
- if (result.errors?.length) {
925
- throw parseShopError(result.errors[0]);
926
- }
927
- const checkoutId = result.data?.checkoutStatus?.receipt?.checkoutId;
928
- await trackSuccess(apollo, checkoutId, paymentType);
929
- if (deactivateRedirect) {
930
- return result;
931
- }
932
- let redirectUrl = `/checkout/post-purchase?kiva_transaction_id=${checkoutId}`;
933
- if (valetInviter?.inviterId) {
934
- redirectUrl += `&valet_inviter=${valetInviter.inviterId}`;
935
- }
936
- await redirectTo(redirectUrl);
937
- }
938
-
939
- // src/subscriptionCheckout.ts
940
- var import_core10 = require("@apollo/client/core/core.cjs");
941
- async function checkSubscriptionStatus(apollo) {
942
- const { data: subsData } = await apollo.query({
943
- query: import_core10.gql`query subscriptionStatus{
944
- my {
945
- id
946
- subscriptions {
947
- totalCount
948
- }
949
- autoDeposit {
950
- id
951
- isSubscriber
952
- }
953
- }
954
- }`
955
- });
956
- if (!subsData?.my?.id) {
957
- throw new ShopError({ code: "api.authenticationRequired" }, "You must be logged in to continue.");
958
- }
959
- if ((subsData?.my?.subscriptions?.totalCount ?? 0) > 0 || subsData?.my?.autoDeposit?.isSubscriber) {
960
- throw new ShopError({ code: "shop.subscriptionExists" }, "You already have an existing Monthly Good subscription. Changes can be made in your subscription settings.");
961
- }
962
- if (subsData?.my?.autoDeposit?.id) {
963
- throw new ShopError({ code: "shop.autoDepositExists" }, "You already have existing Auto Deposit settings. Changes can be made in your subscription settings.");
964
- }
965
- return true;
966
- }
967
- async function executeNewSubscriptionCheckout({
968
- amount,
969
- apollo,
970
- dayOfMonth = (/* @__PURE__ */ new Date()).getDate(),
971
- donateAmount,
972
- paymentMethod
973
- }) {
974
- const amountRegex = new RegExp(/^\d+\.\d{2}$/);
975
- if (!amountRegex.test(amount) || !amountRegex.test(donateAmount)) {
976
- throw new ShopError({
977
- code: "api.invalidMethodParameter"
978
- }, "Please check that the amount is correct and try again.");
979
- }
980
- await checkSubscriptionStatus(apollo);
981
- const { deviceData, nonce } = paymentMethod;
982
- let data;
983
- let error;
984
- try {
985
- const result = await apollo.mutate({
986
- variables: {
987
- nonce,
988
- deviceData,
989
- amount,
990
- donateAmount,
991
- dayOfMonth
992
- },
993
- mutation: import_core10.gql`mutation createAutoDepositSubscription(
994
- $nonce: String!,
995
- $deviceData: String,
996
- $amount: Money!,
997
- $donateAmount: Money!,
998
- $dayOfMonth: Int!
999
- ) {
1000
- my {
1001
- createAutoDeposit (
1002
- autoDeposit: {
1003
- amount: $amount,
1004
- donateAmount: $donateAmount,
1005
- dayOfMonth: $dayOfMonth,
1006
- },
1007
- deviceData: $deviceData,
1008
- paymentMethodNonce: $nonce
1009
- ) {
1010
- id amount donateAmount dayOfMonth status
1011
- }
1012
- }
1013
- }`
1014
- });
1015
- if (result?.error || result?.errors?.length) {
1016
- error = result?.error ?? result?.errors?.[0];
1017
- } else {
1018
- data = result?.data;
1019
- }
1020
- } catch (e) {
1021
- error = e;
1022
- }
1023
- if (error) {
1024
- const parsed = parseShopError(error);
1025
- if (parsed?.code === "shop.unknown") {
1026
- throw new ShopError({
1027
- code: "shop.createAutoDepositError",
1028
- original: parsed
1029
- }, "There was a problem trying to setup your monthly deposit.");
1030
- }
1031
- throw parsed;
1032
- }
1033
- return data?.my?.createAutoDeposit;
1034
- }
1035
-
1036
- // src/useBraintreeDropIn.ts
1037
- var import_core11 = require("@apollo/client/core/core.cjs");
1038
- var import_numeral3 = __toESM(require("numeral"), 1);
1039
- var import_vue_demi = require("vue-demi");
1040
- var defaultPaymentTypes = ["paypal", "card", "applePay", "googlePay"];
1041
- async function getClientToken(apollo) {
1042
- const { data, error, errors } = await apollo.query({
1043
- query: import_core11.gql`query getClientToken {
1044
- shop {
1045
- id
1046
- getClientToken(useCustomerId: true)
1047
- }
1048
- }`
1049
- });
1050
- if (error || errors?.length) {
1051
- throw parseShopError(error ?? errors?.[0]);
1052
- }
1053
- return data?.shop?.getClientToken;
1054
- }
1055
- function initBraintreeDropin() {
1056
- let instance;
1057
- let formattedAmount = "";
1058
- const paymentMethodRequestable = (0, import_vue_demi.ref)(false);
1059
- function getApplePaymentRequest(amount) {
1060
- return {
1061
- countryCode: "US",
1062
- currencyCode: "USD",
1063
- // merchantCapabilities: ['supports3DS'], // TODO: confirm/update
1064
- requiredBillingContactFields: ["postalAddress"],
1065
- // supportedNetworks: ['amex', 'discover', 'interac', 'jcb', 'masterCard', 'visa'], // TODO: confirm/update
1066
- total: {
1067
- label: "Kiva",
1068
- amount
1069
- }
1070
- };
1071
- }
1072
- function getGoogleTransactionInfo(amount) {
1073
- return {
1074
- totalPriceStatus: "FINAL",
1075
- totalPrice: amount,
1076
- currencyCode: "USD",
1077
- countryCode: "US"
1078
- };
1079
- }
1080
- function initDropInActions() {
1081
- if (instance.isPaymentMethodRequestable()) {
1082
- paymentMethodRequestable.value = true;
1083
- }
1084
- instance.on("paymentMethodRequestable", (event) => {
1085
- paymentMethodRequestable.value = true;
1086
- });
1087
- instance.on("noPaymentMethodRequestable", () => {
1088
- paymentMethodRequestable.value = false;
1089
- });
1090
- }
1091
- async function initDropIn({
1092
- amount,
1093
- authToken,
1094
- container,
1095
- googlePayMerchantId,
1096
- paymentTypes = [...defaultPaymentTypes],
1097
- preselectVaultedPaymentMethod = true,
1098
- paypalFlow = "checkout"
1099
- }) {
1100
- formattedAmount = (0, import_numeral3.default)(amount).format("0.00");
1101
- const { default: DropIn } = await import("braintree-web-drop-in");
1102
- try {
1103
- instance = await DropIn.create({
1104
- authorization: authToken,
1105
- container,
1106
- dataCollector: {
1107
- kount: true
1108
- // Required if Kount fraud data collection is enabled
1109
- },
1110
- // vaultManager: true, - Useful for testing and removing payment methods easily.
1111
- paymentOptionPriority: paymentTypes,
1112
- preselectVaultedPaymentMethod,
1113
- card: {
1114
- vault: {
1115
- allowVaultCardOverride: true
1116
- }
1117
- },
1118
- paypal: {
1119
- flow: paypalFlow,
1120
- amount: formattedAmount,
1121
- currency: "USD",
1122
- buttonStyle: {
1123
- // @ts-ignore
1124
- color: "gold",
1125
- // @ts-ignore
1126
- shape: "rect",
1127
- // @ts-ignore
1128
- size: "responsive"
1129
- }
1130
- },
1131
- googlePay: {
1132
- googlePayVersion: 2,
1133
- merchantId: googlePayMerchantId,
1134
- transactionInfo: getGoogleTransactionInfo(formattedAmount),
1135
- button: {
1136
- allowedPaymentMethods: [{
1137
- type: "CARD",
1138
- // @ts-ignore
1139
- parameters: {
1140
- // allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'], // TODO: confirm/update
1141
- // allowedCardNetworks: ['AMEX', 'DISCOVER', 'INTERAC', 'JCB', 'MASTERCARD', 'VISA'], // TODO: confirm/update
1142
- billingAddressRequired: true,
1143
- billingAddressParameters: {
1144
- format: "FULL"
1145
- }
1146
- }
1147
- }]
1148
- }
1149
- },
1150
- applePay: {
1151
- displayName: "Kiva",
1152
- paymentRequest: getApplePaymentRequest(formattedAmount)
1153
- }
1154
- });
1155
- initDropInActions();
1156
- } catch (e) {
1157
- throw new ShopError({
1158
- code: "shop.braintreeDropinInitError",
1159
- original: e
1160
- }, "An Error has occured. Please refresh the page and try again.");
1161
- }
1162
- return instance;
1163
- }
1164
- async function requestPaymentMethod() {
1165
- if (instance.isPaymentMethodRequestable()) {
1166
- return instance.requestPaymentMethod();
1167
- }
1168
- }
1169
- function updateAmount(amount) {
1170
- const newAmount = (0, import_numeral3.default)(amount).format("0.00");
1171
- if (newAmount !== formattedAmount) {
1172
- formattedAmount = newAmount;
1173
- instance?.updateConfiguration("paypal", "amount", formattedAmount);
1174
- instance?.updateConfiguration("googlePay", "transactionInfo", getGoogleTransactionInfo(formattedAmount));
1175
- instance?.updateConfiguration?.("applePay", "paymentRequest", getApplePaymentRequest(formattedAmount));
1176
- }
1177
- }
1178
- return {
1179
- initDropIn,
1180
- paymentMethodRequestable,
1181
- requestPaymentMethod,
1182
- updateAmount
1183
- };
1184
- }
1185
- var instances = {};
1186
- function useBraintreeDropIn(key = "default") {
1187
- if (!instances[key]) {
1188
- instances[key] = initBraintreeDropin();
1189
- }
1190
- return instances[key];
1191
- }
1192
- // Annotate the CommonJS export names for ESM import in node:
1193
- 0 && (module.exports = {
1194
- ShopError,
1195
- VerificationState,
1196
- applyKivaCredit,
1197
- applyPromoCredit,
1198
- basketTotalsQuery,
1199
- callShopMutation,
1200
- callShopQuery,
1201
- checkSubscriptionStatus,
1202
- createBasket,
1203
- defaultPaymentTypes,
1204
- executeNewSubscriptionCheckout,
1205
- executeOneTimeCheckout,
1206
- getBasketID,
1207
- getCheckoutStatus,
1208
- getCheckoutTrackingData,
1209
- getClientToken,
1210
- getFTDStatus,
1211
- getPromoFromBasket,
1212
- getReceiptItems,
1213
- getReceiptTotals,
1214
- hasBasketExpired,
1215
- isBasketVerified,
1216
- parseShopError,
1217
- pollForFinishedCheckout,
1218
- removeKivaCredit,
1219
- removePromoCredit,
1220
- setBasketID,
1221
- setTipDonation,
1222
- useBraintreeDropIn,
1223
- validatePreCheckout,
1224
- validatePreCheckoutMutation,
1225
- watchBasketTotals,
1226
- watchShopQuery
1227
- });