@internetarchive/donation-monthly-portal 7.7.0 → 7.7.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 (38) hide show
  1. package/dist/src/edit-plan-form.d.ts +2 -0
  2. package/dist/src/edit-plan-form.js +4 -0
  3. package/dist/src/edit-plan-form.js.map +1 -1
  4. package/dist/src/form-sections/parts/braintree-manager.d.ts +4 -0
  5. package/dist/src/form-sections/parts/braintree-manager.js +101 -1
  6. package/dist/src/form-sections/parts/braintree-manager.js.map +1 -1
  7. package/dist/src/form-sections/payment-method.d.ts +7 -0
  8. package/dist/src/form-sections/payment-method.js +102 -12
  9. package/dist/src/form-sections/payment-method.js.map +1 -1
  10. package/dist/src/models/plan.d.ts +1 -1
  11. package/dist/src/models/plan.js +4 -4
  12. package/dist/src/models/plan.js.map +1 -1
  13. package/dist/src/monthly-giving-circle.d.ts +2 -0
  14. package/dist/src/monthly-giving-circle.js +6 -0
  15. package/dist/src/monthly-giving-circle.js.map +1 -1
  16. package/dist/src/utils/venmo-pending-storage.d.ts +23 -0
  17. package/dist/src/utils/venmo-pending-storage.js +74 -0
  18. package/dist/src/utils/venmo-pending-storage.js.map +1 -0
  19. package/dist/test/edit-plan-flow-payment-method.test.js +410 -0
  20. package/dist/test/edit-plan-flow-payment-method.test.js.map +1 -1
  21. package/dist/test/form-sections/braintree-manager.test.d.ts +1 -0
  22. package/dist/test/form-sections/braintree-manager.test.js +376 -0
  23. package/dist/test/form-sections/braintree-manager.test.js.map +1 -0
  24. package/dist/test/helpers/mock-storage.d.ts +9 -0
  25. package/dist/test/helpers/mock-storage.js +26 -0
  26. package/dist/test/helpers/mock-storage.js.map +1 -0
  27. package/dist/test/models/plan.test.js +2 -1
  28. package/dist/test/models/plan.test.js.map +1 -1
  29. package/dist/test/utils/venmo-pending-storage.test.d.ts +1 -0
  30. package/dist/test/utils/venmo-pending-storage.test.js +121 -0
  31. package/dist/test/utils/venmo-pending-storage.test.js.map +1 -0
  32. package/package.json +1 -1
  33. package/src/edit-plan-form.ts +4 -0
  34. package/src/form-sections/parts/braintree-manager.ts +108 -0
  35. package/src/form-sections/payment-method.ts +113 -8
  36. package/src/models/plan.ts +3 -3
  37. package/src/monthly-giving-circle.ts +5 -0
  38. package/src/utils/venmo-pending-storage.ts +80 -0
@@ -2,6 +2,7 @@ import { LitElement } from 'lit';
2
2
  import '@internetarchive/donation-form/dist/src/form-elements/badged-input';
3
3
  import type { PaymentConfig } from './form-sections/parts/braintree-manager';
4
4
  import type { MonthlyPlan } from './models/plan';
5
+ import type { VenmoPendingStorage } from './utils/venmo-pending-storage';
5
6
  import './form-sections/amount';
6
7
  import './form-sections/date';
7
8
  import './form-sections/cancel';
@@ -16,6 +17,7 @@ export declare class IauxEditPlanForm extends LitElement {
16
17
  coverFees: boolean;
17
18
  feeCovered: number;
18
19
  }) => void;
20
+ venmoPendingStorage?: VenmoPendingStorage;
19
21
  paymentConfig: PaymentConfig;
20
22
  braintreeNumberInput: HTMLDivElement;
21
23
  braintreeExpirationDateInput: HTMLDivElement;
@@ -63,6 +63,7 @@ let IauxEditPlanForm = class IauxEditPlanForm extends LitElement {
63
63
  .plan=${this.plan}
64
64
  .patronEmail=${this.patronEmail}
65
65
  .paymentConfig=${this.paymentConfig}
66
+ .venmoPendingStorage=${this.venmoPendingStorage}
66
67
  @UpdatePaymentMethod=${(e) => {
67
68
  const { newPaymentMethodRequest } = e.detail;
68
69
  if (this.plan) {
@@ -118,6 +119,9 @@ __decorate([
118
119
  __decorate([
119
120
  property({ type: Object })
120
121
  ], IauxEditPlanForm.prototype, "updateAmountHandler", void 0);
122
+ __decorate([
123
+ property({ type: Object })
124
+ ], IauxEditPlanForm.prototype, "venmoPendingStorage", void 0);
121
125
  __decorate([
122
126
  property({ type: Object })
123
127
  ], IauxEditPlanForm.prototype, "paymentConfig", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"edit-plan-form.js","sourceRoot":"","sources":["../../src/edit-plan-form.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\n\nimport '@internetarchive/donation-form/dist/src/form-elements/badged-input';\n\nimport { HostingEnvironment } from '@internetarchive/donation-form';\nimport type { PaymentConfig } from './form-sections/parts/braintree-manager';\nimport type { MonthlyPlan } from './models/plan';\nimport './form-sections/amount';\nimport './form-sections/date';\nimport './form-sections/cancel';\nimport './form-sections/payment-method';\nimport type { MGCEditPlanAmount } from './form-sections/amount';\nimport type { MGCEditPlanDate } from './form-sections/date';\nimport type { MGCEditPaymentMethod } from './form-sections/payment-method';\n\n@customElement('ia-mgc-edit-plan')\nexport class IauxEditPlanForm extends LitElement {\n @property({ type: Object }) plan?: MonthlyPlan;\n\n @property({ type: String }) patronEmail: string = '';\n\n @property({ type: Boolean }) canEditPaymentMethod: boolean = false;\n\n @property({ type: Object }) updateAmountHandler?: (\n plan: MonthlyPlan,\n amountUpdates: {\n amount: number;\n baseAmount: number;\n coverFees: boolean;\n feeCovered: number;\n },\n ) => void;\n\n @property({ type: Object }) paymentConfig: PaymentConfig = {\n referrer: '',\n origin: '',\n braintreeAuthToken: '',\n venmoProfileId: '',\n googlePayMerchantId: '',\n environment: HostingEnvironment.Development,\n paymentClients: undefined,\n endpointManager: undefined,\n };\n\n @query('#braintree-creditcard') braintreeNumberInput!: HTMLDivElement;\n\n @query('#braintree-expiration') braintreeExpirationDateInput!: HTMLDivElement;\n\n @query('#braintree-cvv') braintreeCVVInput!: HTMLDivElement;\n\n @query('#braintree-error-message') braintreeErrorMessage!: HTMLDivElement;\n\n createRenderRoot() {\n return this;\n }\n\n paymentMethodUpdates(status: 'success' | 'fail') {\n const paymentMethodForm = this.querySelector(\n 'ia-mgc-edit-payment-method',\n ) as MGCEditPaymentMethod;\n paymentMethodForm!.paymentMethodUpdated(status);\n }\n\n amountUpdates(status: 'success' | 'fail') {\n const amountForm = this.querySelector(\n 'ia-mgc-edit-plan-amount',\n ) as MGCEditPlanAmount;\n amountForm!.amountUpdated(status);\n }\n\n dateUpdates(status: 'success' | 'fail') {\n const dateForm = this.querySelector('ia-mgc-edit-date') as MGCEditPlanDate;\n dateForm!.dateUpdated(status);\n }\n\n render() {\n return html`\n <section class=\"mgc-edit-plan\">\n <ia-mgc-edit-plan-amount\n .plan=${this.plan}\n @updateAmount=${(e: CustomEvent) => {\n const { amount, baseAmount, coverFees, feeCovered } = e.detail;\n if (this.plan) {\n this.updateAmountHandler?.(this.plan, {\n amount,\n baseAmount,\n coverFees,\n feeCovered,\n });\n }\n }}\n ></ia-mgc-edit-plan-amount>\n ${this.canEditPaymentMethod\n ? html`\n <hr />\n <ia-mgc-edit-payment-method\n .plan=${this.plan}\n .patronEmail=${this.patronEmail}\n .paymentConfig=${this.paymentConfig}\n @UpdatePaymentMethod=${(e: CustomEvent) => {\n const { newPaymentMethodRequest } = e.detail;\n if (this.plan) {\n this.dispatchEvent(\n new CustomEvent('UpdatePaymentMethod', {\n detail: { plan: this.plan, newPaymentMethodRequest },\n }),\n );\n }\n }}\n >\n </ia-mgc-edit-payment-method>\n `\n : ''}\n <hr />\n <ia-mgc-edit-date\n @updateDate=${(e: CustomEvent) => {\n const { newDate } = e.detail;\n if (this.plan) {\n this.dispatchEvent(\n new CustomEvent('updateDate', {\n detail: { plan: this.plan, newDate },\n }),\n );\n }\n }}\n .plan=${this.plan}\n ></ia-mgc-edit-date>\n <hr />\n <ia-mgc-cancel-plan\n .plan=${this.plan}\n @cancelPlan=${() => {\n this.dispatchEvent(new Event('cancelPlan'));\n }}\n ></ia-mgc-cancel-plan>\n <hr />\n <p class=\"email-edit-plan\">\n Need to update your plan further? Please email us at\n <a href=${this.mailToText()}>donations@archive.org</a>.\n </p>\n </section>\n `;\n }\n\n mailToText(): string {\n return `mailto:donations@archive.org?subject=I'd like to update my monthly donation`;\n }\n}\n"]}
1
+ {"version":3,"file":"edit-plan-form.js","sourceRoot":"","sources":["../../src/edit-plan-form.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\n\nimport '@internetarchive/donation-form/dist/src/form-elements/badged-input';\n\nimport { HostingEnvironment } from '@internetarchive/donation-form';\nimport type { PaymentConfig } from './form-sections/parts/braintree-manager';\nimport type { MonthlyPlan } from './models/plan';\nimport type { VenmoPendingStorage } from './utils/venmo-pending-storage';\nimport './form-sections/amount';\nimport './form-sections/date';\nimport './form-sections/cancel';\nimport './form-sections/payment-method';\nimport type { MGCEditPlanAmount } from './form-sections/amount';\nimport type { MGCEditPlanDate } from './form-sections/date';\nimport type { MGCEditPaymentMethod } from './form-sections/payment-method';\n\n@customElement('ia-mgc-edit-plan')\nexport class IauxEditPlanForm extends LitElement {\n @property({ type: Object }) plan?: MonthlyPlan;\n\n @property({ type: String }) patronEmail: string = '';\n\n @property({ type: Boolean }) canEditPaymentMethod: boolean = false;\n\n @property({ type: Object }) updateAmountHandler?: (\n plan: MonthlyPlan,\n amountUpdates: {\n amount: number;\n baseAmount: number;\n coverFees: boolean;\n feeCovered: number;\n },\n ) => void;\n\n @property({ type: Object }) venmoPendingStorage?: VenmoPendingStorage;\n\n @property({ type: Object }) paymentConfig: PaymentConfig = {\n referrer: '',\n origin: '',\n braintreeAuthToken: '',\n venmoProfileId: '',\n googlePayMerchantId: '',\n environment: HostingEnvironment.Development,\n paymentClients: undefined,\n endpointManager: undefined,\n };\n\n @query('#braintree-creditcard') braintreeNumberInput!: HTMLDivElement;\n\n @query('#braintree-expiration') braintreeExpirationDateInput!: HTMLDivElement;\n\n @query('#braintree-cvv') braintreeCVVInput!: HTMLDivElement;\n\n @query('#braintree-error-message') braintreeErrorMessage!: HTMLDivElement;\n\n createRenderRoot() {\n return this;\n }\n\n paymentMethodUpdates(status: 'success' | 'fail') {\n const paymentMethodForm = this.querySelector(\n 'ia-mgc-edit-payment-method',\n ) as MGCEditPaymentMethod;\n paymentMethodForm!.paymentMethodUpdated(status);\n }\n\n amountUpdates(status: 'success' | 'fail') {\n const amountForm = this.querySelector(\n 'ia-mgc-edit-plan-amount',\n ) as MGCEditPlanAmount;\n amountForm!.amountUpdated(status);\n }\n\n dateUpdates(status: 'success' | 'fail') {\n const dateForm = this.querySelector('ia-mgc-edit-date') as MGCEditPlanDate;\n dateForm!.dateUpdated(status);\n }\n\n render() {\n return html`\n <section class=\"mgc-edit-plan\">\n <ia-mgc-edit-plan-amount\n .plan=${this.plan}\n @updateAmount=${(e: CustomEvent) => {\n const { amount, baseAmount, coverFees, feeCovered } = e.detail;\n if (this.plan) {\n this.updateAmountHandler?.(this.plan, {\n amount,\n baseAmount,\n coverFees,\n feeCovered,\n });\n }\n }}\n ></ia-mgc-edit-plan-amount>\n ${this.canEditPaymentMethod\n ? html`\n <hr />\n <ia-mgc-edit-payment-method\n .plan=${this.plan}\n .patronEmail=${this.patronEmail}\n .paymentConfig=${this.paymentConfig}\n .venmoPendingStorage=${this.venmoPendingStorage}\n @UpdatePaymentMethod=${(e: CustomEvent) => {\n const { newPaymentMethodRequest } = e.detail;\n if (this.plan) {\n this.dispatchEvent(\n new CustomEvent('UpdatePaymentMethod', {\n detail: { plan: this.plan, newPaymentMethodRequest },\n }),\n );\n }\n }}\n >\n </ia-mgc-edit-payment-method>\n `\n : ''}\n <hr />\n <ia-mgc-edit-date\n @updateDate=${(e: CustomEvent) => {\n const { newDate } = e.detail;\n if (this.plan) {\n this.dispatchEvent(\n new CustomEvent('updateDate', {\n detail: { plan: this.plan, newDate },\n }),\n );\n }\n }}\n .plan=${this.plan}\n ></ia-mgc-edit-date>\n <hr />\n <ia-mgc-cancel-plan\n .plan=${this.plan}\n @cancelPlan=${() => {\n this.dispatchEvent(new Event('cancelPlan'));\n }}\n ></ia-mgc-cancel-plan>\n <hr />\n <p class=\"email-edit-plan\">\n Need to update your plan further? Please email us at\n <a href=${this.mailToText()}>donations@archive.org</a>.\n </p>\n </section>\n `;\n }\n\n mailToText(): string {\n return `mailto:donations@archive.org?subject=I'd like to update my monthly donation`;\n }\n}\n"]}
@@ -2,6 +2,7 @@ import { LitElement, CSSResult, PropertyValueMap } from 'lit';
2
2
  import { BraintreeManagerInterface, HostingEnvironment } from '@internetarchive/donation-form';
3
3
  import type { BraintreeEndpointManagerInterface } from '@internetarchive/donation-form/dist/src/braintree-manager/braintree-interfaces.js';
4
4
  import type { PaymentClientsInterface } from '@internetarchive/donation-form/dist/src/braintree-manager/payment-clients.js';
5
+ import { VenmoPendingStorage } from '../../utils/venmo-pending-storage';
5
6
  import type { MonthlyPlan } from '../../models/plan';
6
7
  export type PaymentConfig = {
7
8
  braintreeAuthToken?: string;
@@ -20,6 +21,7 @@ export declare class MGCBraintreeManager extends LitElement {
20
21
  paymentConfig?: PaymentConfig;
21
22
  braintreeManager?: BraintreeManagerInterface;
22
23
  private elementConnected;
24
+ venmoPendingStorage?: VenmoPendingStorage;
23
25
  get braintreeInputs(): {
24
26
  errorMessage: HTMLDivElement | null;
25
27
  number: HTMLDivElement | null;
@@ -37,6 +39,8 @@ export declare class MGCBraintreeManager extends LitElement {
37
39
  get creditCardTemplate(): import("lit").TemplateResult<1>;
38
40
  renderPayPalVaultButton(): Promise<void>;
39
41
  private handlePayPalAuthorized;
42
+ startVenmoPayment(): Promise<void>;
43
+ private checkVenmoRestoration;
40
44
  private setupBraintreeManager;
41
45
  get contactForm(): HTMLFormElement | null;
42
46
  }
@@ -233,8 +233,90 @@ let MGCBraintreeManager = class MGCBraintreeManager extends LitElement {
233
233
  },
234
234
  }));
235
235
  }
236
+ async startVenmoPayment() {
237
+ var _a, _b, _c, _d, _e, _f, _g;
238
+ const handler = await ((_a = this.braintreeManager) === null || _a === void 0 ? void 0 : _a.paymentProviders.venmoHandler.get());
239
+ if (!handler)
240
+ return;
241
+ if ((_b = this.plan) === null || _b === void 0 ? void 0 : _b.id)
242
+ (_c = this.venmoPendingStorage) === null || _c === void 0 ? void 0 : _c.setPending(this.plan.id);
243
+ try {
244
+ const payload = await handler.startPayment();
245
+ if ((_d = this.plan) === null || _d === void 0 ? void 0 : _d.id)
246
+ (_e = this.venmoPendingStorage) === null || _e === void 0 ? void 0 : _e.clearPending(this.plan.id);
247
+ this.dispatchEvent(new CustomEvent('VenmoAuthorized', {
248
+ detail: {
249
+ paymentMethodInfo: {
250
+ description: `Venmo - ${payload.details.username}`,
251
+ nonce: payload.nonce,
252
+ type: payload.type,
253
+ details: { username: payload.details.username },
254
+ },
255
+ },
256
+ }));
257
+ }
258
+ catch (e) {
259
+ if ((_f = this.plan) === null || _f === void 0 ? void 0 : _f.id)
260
+ (_g = this.venmoPendingStorage) === null || _g === void 0 ? void 0 : _g.clearPending(this.plan.id);
261
+ const code = e === null || e === void 0 ? void 0 : e.code;
262
+ if (code === 'VENMO_APP_CANCELED' || code === 'VENMO_CANCELED') {
263
+ console.log('Venmo payment cancelled');
264
+ }
265
+ else {
266
+ console.error('Venmo payment error:', e);
267
+ this.dispatchEvent(new CustomEvent('VenmoError', { detail: { error: e } }));
268
+ }
269
+ }
270
+ }
271
+ async checkVenmoRestoration() {
272
+ var _a, _b, _c, _d, _e, _f, _g;
273
+ const planId = (_a = this.plan) === null || _a === void 0 ? void 0 : _a.id;
274
+ if (!planId)
275
+ return;
276
+ const pending = (_b = this.venmoPendingStorage) === null || _b === void 0 ? void 0 : _b.getPending(planId);
277
+ if (!pending)
278
+ return;
279
+ try {
280
+ const handler = await ((_c = this.braintreeManager) === null || _c === void 0 ? void 0 : _c.paymentProviders.venmoHandler.get());
281
+ if (!handler) {
282
+ (_d = this.venmoPendingStorage) === null || _d === void 0 ? void 0 : _d.clearPending(planId);
283
+ return;
284
+ }
285
+ const instance = await handler.instance.get();
286
+ if (!instance) {
287
+ (_e = this.venmoPendingStorage) === null || _e === void 0 ? void 0 : _e.clearPending(planId);
288
+ return;
289
+ }
290
+ // Clear before tokenizing to prevent retry loops on failure
291
+ (_f = this.venmoPendingStorage) === null || _f === void 0 ? void 0 : _f.clearPending(planId);
292
+ if (!instance.hasTokenizationResult())
293
+ return;
294
+ // startPayment() re-checks hasTokenizationResult() internally and
295
+ // calls instance.tokenize() on the cached result — it does NOT launch
296
+ // a new Venmo redirect when a tokenization result is already present.
297
+ const payload = await handler.startPayment();
298
+ this.dispatchEvent(new CustomEvent('VenmoAuthorized', {
299
+ detail: {
300
+ paymentMethodInfo: {
301
+ description: `Venmo - ${payload.details.username}`,
302
+ nonce: payload.nonce,
303
+ type: payload.type,
304
+ details: { username: payload.details.username },
305
+ },
306
+ },
307
+ }));
308
+ }
309
+ catch (e) {
310
+ (_g = this.venmoPendingStorage) === null || _g === void 0 ? void 0 : _g.clearPending(planId);
311
+ const code = e === null || e === void 0 ? void 0 : e.code;
312
+ if (code !== 'VENMO_APP_CANCELED' && code !== 'VENMO_CANCELED') {
313
+ console.error('Venmo restoration error:', e);
314
+ this.dispatchEvent(new CustomEvent('VenmoError', { detail: { error: e } }));
315
+ }
316
+ }
317
+ }
236
318
  async setupBraintreeManager() {
237
- var _a, _b, _c, _d, _e, _f, _g, _h;
319
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
238
320
  this.braintreeManager = new BraintreeManager({
239
321
  paymentClients: (_b = (_a = this.paymentConfig) === null || _a === void 0 ? void 0 : _a.paymentClients) !== null && _b !== void 0 ? _b : {},
240
322
  endpointManager: (_c = this.paymentConfig) === null || _c === void 0 ? void 0 : _c.endpointManager,
@@ -281,6 +363,21 @@ let MGCBraintreeManager = class MGCBraintreeManager extends LitElement {
281
363
  });
282
364
  this.dispatchEvent(event);
283
365
  });
366
+ // BraintreeManager (@internetarchive/donation-form) has no config option to
367
+ // suppress Google Pay, so we replace the handler directly. The upstream path
368
+ // is `BraintreeManager.paymentProviders.googlePayHandler` — if that changes
369
+ // this cast will silently stop working and the button may reappear.
370
+ if (!((_j = this.paymentConfig) === null || _j === void 0 ? void 0 : _j.googlePayMerchantId) && this.braintreeManager) {
371
+ // BraintreeManager has no config option to suppress Google Pay, so we
372
+ // replace the handler directly. Casting only paymentProviders (not the
373
+ // whole manager) keeps the access chain type-checked — if upstream
374
+ // renames paymentProviders or googlePayHandler, TypeScript will catch it.
375
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
376
+ this.braintreeManager.paymentProviders.googlePayHandler = {
377
+ get: async () => null,
378
+ };
379
+ }
380
+ await this.checkVenmoRestoration();
284
381
  this.dispatchEvent(new Event('BraintreeManagerSetupComplete'));
285
382
  }
286
383
  get contactForm() {
@@ -305,6 +402,9 @@ __decorate([
305
402
  __decorate([
306
403
  state()
307
404
  ], MGCBraintreeManager.prototype, "elementConnected", void 0);
405
+ __decorate([
406
+ property({ type: Object })
407
+ ], MGCBraintreeManager.prototype, "venmoPendingStorage", void 0);
308
408
  MGCBraintreeManager = __decorate([
309
409
  customElement('ia-mgc-braintree-manager')
310
410
  ], MGCBraintreeManager);
@@ -1 +1 @@
1
- {"version":3,"file":"braintree-manager.js","sourceRoot":"","sources":["../../../../src/form-sections/parts/braintree-manager.ts"],"names":[],"mappings":";AAAA,+BAA+B;AAC/B,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAA+B,MAAM,KAAK,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAEnE,OAAO,EACL,oBAAoB,EACpB,eAAe,GAChB,MAAM,gHAAgH,CAAC;AACxH,OAAO,EACL,gBAAgB,GAGjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,mBAAmB,EACnB,YAAY,GACb,MAAM,4CAA4C,CAAC;AAIpD,OAAO,aAAa,MAAM,4CAA4C,CAAC;AACvE,OAAO,WAAW,MAAM,yCAAyC,CAAC;AAClE,OAAO,OAAO,MAAM,qCAAqC,CAAC;AAgBnD,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,UAAU;IAA5C;;QAGuC,sBAAiB,GAC3D,KAAK,CAAC;QAEoB,gBAAW,GAAW,EAAE,CAAC;QAMpC,qBAAgB,GAAY,KAAK,CAAC;IAiVrD,CAAC;IA/UC,IAAI,eAAe;QAMjB,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,aAAa,CAC9B,0BAA0B,CACF;YAC1B,MAAM,EAAE,IAAI,CAAC,aAAa,CACxB,uBAAuB,CACC;YAC1B,GAAG,EAAE,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAA0B;YAClE,cAAc,EAAE,IAAI,CAAC,aAAa,CAChC,uBAAuB,CACC;SAC3B,CAAC;IACJ,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,oBAAoB;QAClB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAChC,CAAC;IAED,iBAAiB;QACf,+CAA+C;QAC/C,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAE1B,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;QAExE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAC/B,CAAC;IAES,OAAO,CACf,OAA0D;QAE1D,MAAM,wBAAwB,GAC5B,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC;QAC3D,IAAI,wBAAwB,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvB,MAAM,EACJ,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,WAAW,GACZ,GAAG,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC;gBAE7B,MAAM,qBAAqB,GACzB,CAAC,IAAI,CAAC,gBAAgB;oBACtB,kBAAkB;oBAClB,eAAe;oBACf,cAAc;oBACd,WAAW,CAAC;gBACd,IAAI,qBAAqB,EAAE,CAAC;oBAC1B,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC/B,CAAC;YACH,CAAC;QACH,CAAC;QAED,IACE,IAAI,CAAC,gBAAgB;YACrB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;YAChC,IAAI,CAAC,iBAAiB,EACtB,CAAC;YACD,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,wBAAwB;;QAC5B,MAAM,OAAO,GACX,MAAM,CAAA,MAAA,IAAI,CAAC,gBAAgB,0CAAE,gBAAgB,CAAC,iBAAiB,CAAC,GAAG,EAAE,CAAA,CAAC;QACxE,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,IAAI,oBAAoB,GAAG,IAAI,CAAC;QAChC,IAAI,CAAC;YACH,oBAAoB,GAAG,MAAM,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB,EAAE,CAAA,CAAC;YAC7D,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,KAAK,GAAG,CAAmB,CAAC;YAElC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,gBAAgB,EAAE,CAAC;YAE5B,yCAAyC;YACzC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnB,KAAK,4BAA4B;oBAC/B,+CAA+C;oBAC/C,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,eAAe,CAAC;wBACvB,eAAe,CAAC,MAAM;wBACtB,eAAe,CAAC,GAAG;wBACnB,eAAe,CAAC,cAAc;qBAC/B,CAAC,CAAC;oBACH,MAAM;gBACR,KAAK,8BAA8B;oBACjC,kEAAkE;oBAClE,uDAAuD;oBACvD,wDAAwD;oBACxD,MAAM;oBACN,MAAM;gBACR,KAAK,8CAA8C;oBACjD,eAAe;oBACf,mEAAmE;oBACnE,kEAAkE;oBAClE,4BAA4B;oBAC5B,+EAA+E;oBAC/E,MAAM;gBACR,KAAK,oDAAoD;oBACvD,eAAe;oBACf,mEAAmE;oBACnE,mEAAmE;oBACnE,uEAAuE;oBACvE,oBAAoB;oBACpB,wCAAwC;oBACxC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,eAAe,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;oBAChD,MAAM;gBACR,KAAK,mCAAmC;oBACtC,wDAAwD;oBACxD,MAAM;gBACR,KAAK,0CAA0C;oBAC7C,wDAAwD;oBACxD,MAAM;gBACR;oBACE,0BAA0B;oBAC1B,MAAM;YACV,CAAC;QACH,CAAC;QAED,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,sBAAsB;;QAC1B,kCAAkC;QAClC,MAAM,OAAO,GACX,MAAM,CAAA,MAAA,IAAI,CAAC,gBAAgB,0CAAE,gBAAgB,CAAC,iBAAiB,CAAC,GAAG,EAAE,CAAA,CAAC;QACxE,IAAI,CAAC;YACH,MAAM,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB,EAAE,CAAA,CAAC;QACxC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,yDAAyD;QAC3D,CAAC;QAED,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,iBAAiB,CAAC;YACzB,eAAe,CAAC,MAAM;YACtB,eAAe,CAAC,GAAG;YACnB,eAAe,CAAC,cAAc;SAC/B,CAAC,CAAC;IACL,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA,SAAS,IAAI,CAAC,kBAAkB,SAAS,CAAC;IACvD,CAAC;IAED,WAAW;QACT,OAAO,GAAG,CAAA;;;;;;;;;;;KAWT,CAAC;IACJ,CAAC;IAED,IAAI,kBAAkB;QACpB,OAAO,IAAI,CAAA;;;YAGH,IAAI,CAAC,WAAW,EAAE;;;;;oBAKV,aAAa;wBACT,IAAI;;;;;;;;oBAQR,WAAW;wBACP,IAAI;;;;;gCAKI,OAAO,cAAc,IAAI;;;;;KAKpD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,uBAAuB;;QAC3B,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QAEvD,MAAM,OAAO,GACX,MAAM,CAAA,MAAA,IAAI,CAAC,gBAAgB,0CAAE,gBAAgB,CAAC,aAAa,CAAC,GAAG,EAAE,CAAA,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,uBAAuB,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,SAAS,CAAC,CAAC;QAEtD,MAAM,YAAY,GAAG,IAAI,mBAAmB,CAAC;YAC3C,YAAY,EAAE,YAAY,CAAC,OAAO;YAClC,MAAM,EAAE,MAAA,MAAA,IAAI,CAAC,IAAI,0CAAE,MAAM,mCAAI,CAAC;YAC9B,SAAS,EAAE,KAAK;SACjB,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,kBAAkB,CAAC;YAClD,QAAQ,EAAE,uBAAuB;YACjC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;YACvD,YAAY;SACb,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,UAAU,CAAC,CAAC;QAEhD,IAAI,CAAC,UAAU;YAAE,OAAO;QAExB,UAAU,CAAC,QAAQ,GAAG;YACpB,oBAAoB,EAAE,KAAK,IAAI,EAAE;gBAC/B,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;YACxC,CAAC;YACD,uBAAuB,EAAE,KAAK,EAAE,GAAQ,EAAE,OAAY,EAAE,EAAE;gBACxD,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;YACvC,CAAC;YACD,sBAAsB,EAAE,KAAK,EAAE,GAAQ,EAAE,OAAY,EAAE,EAAE;gBACvD,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;YACvC,CAAC;YACD,sBAAsB,EAAE,KAAK,IAAI,EAAE;gBACjC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;YAC1C,CAAC;YACD,kBAAkB,EAAE,KAAK,EAAE,GAAQ,EAAE,KAAc,EAAE,EAAE;gBACrD,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;gBAC5C,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,kBAAkB,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAC3D,CAAC;YACJ,CAAC;SACF,CAAC;IACJ,CAAC;IAEO,sBAAsB,CAAC,OAI9B;QACC,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,uBAAuB,EAAE;YACvC,MAAM,EAAE;gBACN,iBAAiB,EAAE;oBACjB,WAAW,EAAE,YAAY,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE;oBAChD,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE;iBAC1C;aACF;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,qBAAqB;;QACjC,IAAI,CAAC,gBAAgB,GAAG,IAAI,gBAAgB,CAAC;YAC3C,cAAc,EACZ,MAAA,MAAA,IAAI,CAAC,aAAa,0CAAE,cAAc,mCAAK,EAA8B;YACvE,eAAe,EAAE,MAAA,IAAI,CAAC,aAAa,0CAC/B,eAAoD;YACxD,kBAAkB,EAAE,MAAA,MAAA,IAAI,CAAC,aAAa,0CAAE,kBAAkB,mCAAI,EAAE;YAChE,cAAc,EAAE,MAAA,IAAI,CAAC,aAAa,0CAAE,cAAc;YAClD,mBAAmB,EAAE,MAAA,IAAI,CAAC,aAAa,0CAAE,mBAAmB;YAC5D,iBAAiB,EAAE;gBACjB,gBAAgB,EAAE,EAAE,EAAE,wCAAwC;gBAC9D,uBAAuB,EAAE;oBACvB,MAAM,EAAE;wBACN,QAAQ,EAAE,uBAAuB;wBACjC,WAAW,EAAE,aAAa;qBAC3B;oBACD,GAAG,EAAE;wBACH,QAAQ,EAAE,gBAAgB;wBAC1B,WAAW,EAAE,KAAK;qBACnB;oBACD,cAAc,EAAE;wBACd,QAAQ,EAAE,uBAAuB;wBACjC,WAAW,EAAE,SAAS;qBACvB;iBACF,EAAE,yCAAyC;gBAC5C,oBAAoB,EAAE,IAAI,oBAAoB,CAAC;oBAC7C,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,MAAwB;oBACrD,GAAG,EAAE,IAAI,CAAC,eAAe,CAAC,GAAqB;oBAC/C,cAAc,EAAE,IAAI,CAAC,eAAe,CAAC,cAAgC;oBACrE,cAAc,EAAE,IAAI,CAAC,eAAe,CAAC,YAA8B;iBACpE,CAAC;aACH;YACD,kBAAkB,EAAE,MAAA,IAAI,CAAC,aAAa,0CAAE,WAAiC;YACzE,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;YAC9B,YAAY,EAAE,IAAI,CAAC,WAAW;YAC9B,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;SAC/B,CAAC,CAAC;QAEH,IAAI,CAAC,gBAAgB,CAAC,EAAE,CACtB,mCAAmC,EACnC,CAAC,WAAmB,EAAE,EAAE;YACtB,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,mCAAmC,EAAE;gBACjE,MAAM,EAAE,EAAE,WAAW,EAAE;aACxB,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC,CACF,CAAC;QAEF,IAAI,CAAC,gBAAgB,CAAC,EAAE,CACtB,oCAAoC,EACpC,CAAC,KAAc,EAAE,EAAE;YACjB,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,oCAAoC,EAAE;gBAClE,MAAM,EAAE,EAAE,KAAK,EAAE;aAClB,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC,CACF,CAAC;QAEF,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,aAAa,CAAC,2BAA2B,CAAC,CAAC;IACzD,CAAC;CACF,CAAA;AA5V6B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iDAAoB;AAEH;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;8DACnC;AAEoB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;wDAA0B;AAEzB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0DAA+B;AAE9B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;6DAA8C;AAExD;IAAhB,KAAK,EAAE;6DAA2C;AAZxC,mBAAmB;IAD/B,aAAa,CAAC,0BAA0B,CAAC;GAC7B,mBAAmB,CA6V/B","sourcesContent":["/* eslint-disable no-console */\nimport { LitElement, html, css, CSSResult, PropertyValueMap } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport {\n HostedFieldContainer,\n HostedFieldName,\n} from '@internetarchive/donation-form/dist/src/braintree-manager/payment-providers/credit-card/hosted-field-container';\nimport {\n BraintreeManager,\n BraintreeManagerInterface,\n HostingEnvironment,\n} from '@internetarchive/donation-form';\nimport {\n DonationPaymentInfo,\n DonationType,\n} from '@internetarchive/donation-form-data-models';\nimport type { BraintreeEndpointManagerInterface } from '@internetarchive/donation-form/dist/src/braintree-manager/braintree-interfaces.js';\nimport type { PaymentClientsInterface } from '@internetarchive/donation-form/dist/src/braintree-manager/payment-clients.js';\n\nimport creditCardImg from '@internetarchive/icon-credit-card/index.js';\nimport calendarImg from '@internetarchive/icon-calendar/index.js';\nimport lockImg from '@internetarchive/icon-lock/index.js';\n\nimport type { MonthlyPlan } from '../../models/plan';\n\nexport type PaymentConfig = {\n braintreeAuthToken?: string;\n endpointManager?: BraintreeEndpointManagerInterface;\n paymentClients?: PaymentClientsInterface;\n environment?: HostingEnvironment;\n venmoProfileId?: string;\n googlePayMerchantId?: string;\n referrer: string;\n origin: string;\n};\n\n@customElement('ia-mgc-braintree-manager')\nexport class MGCBraintreeManager extends LitElement {\n @property({ type: Object }) plan?: MonthlyPlan;\n\n @property({ type: Boolean, reflect: true }) displayCreditCard: boolean =\n false;\n\n @property({ type: String }) patronEmail: string = '';\n\n @property({ type: Object }) paymentConfig?: PaymentConfig;\n\n @property({ type: Object }) braintreeManager?: BraintreeManagerInterface;\n\n @state() private elementConnected: boolean = false;\n\n get braintreeInputs(): {\n errorMessage: HTMLDivElement | null;\n number: HTMLDivElement | null;\n cvv: HTMLDivElement | null;\n expirationDate: HTMLDivElement | null;\n } {\n return {\n errorMessage: this.querySelector(\n '#braintree-error-message',\n ) as HTMLDivElement | null,\n number: this.querySelector(\n '#braintree-creditcard',\n ) as HTMLDivElement | null,\n cvv: this.querySelector('#braintree-cvv') as HTMLDivElement | null,\n expirationDate: this.querySelector(\n '#braintree-expiration',\n ) as HTMLDivElement | null,\n };\n }\n\n createRenderRoot() {\n return this;\n }\n\n disconnectedCallback(): void {\n this.elementConnected = false;\n }\n\n connectedCallback(): void {\n // eslint-disable-next-line wc/guard-super-call\n super.connectedCallback();\n\n console.log('connectedCallback', { paymentConfig: this.paymentConfig });\n\n this.elementConnected = true;\n }\n\n protected updated(\n changed: PropertyValueMap<any> | Map<PropertyKey, unknown>,\n ): void {\n const elementHasConnectedToDOM =\n changed.has('elementConnected') && this.elementConnected;\n if (elementHasConnectedToDOM) {\n if (this.paymentConfig) {\n const {\n braintreeAuthToken,\n endpointManager,\n paymentClients,\n environment,\n } = this.paymentConfig || {};\n\n const needsBraintreeManager =\n !this.braintreeManager &&\n braintreeAuthToken &&\n endpointManager &&\n paymentClients &&\n environment;\n if (needsBraintreeManager) {\n this.setupBraintreeManager();\n }\n }\n }\n\n if (\n this.braintreeManager &&\n changed.has('displayCreditCard') &&\n this.displayCreditCard\n ) {\n this.setupCreditCardHandler();\n }\n }\n\n async validateCreditCardFields() {\n const handler =\n await this.braintreeManager?.paymentProviders.creditCardHandler.get();\n let tokenized = false;\n let hostedFieldsResponse = null;\n try {\n hostedFieldsResponse = await handler?.tokenizeHostedFields();\n tokenized = true;\n } catch (e) {\n const error = e as unknown as any;\n\n handler?.showErrorMessage();\n\n // todo: move these codes to an enum/type\n switch (error.code) {\n case 'HOSTED_FIELDS_FIELDS_EMPTY':\n // occurs when none of the fields are filled in\n handler?.markFieldErrors([\n HostedFieldName.Number,\n HostedFieldName.CVV,\n HostedFieldName.ExpirationDate,\n ]);\n break;\n case 'HOSTED_FIELDS_FIELDS_INVALID':\n // occurs when certain fields do not pass client side validationto\n // Object.keys(.details.invalidFields).forEach(key => {\n // handler?.markFieldErrors([key as HostedFieldName]);\n // });\n break;\n case 'HOSTED_FIELDS_TOKENIZATION_FAIL_ON_DUPLICATE':\n // occurs when:\n // * the client token used for client authorization was generated\n // with a customer ID and the fail on duplicate payment method\n // option is set to true\n // * the card being tokenized has previously been vaulted (with any customer)\n break;\n case 'HOSTED_FIELDS_TOKENIZATION_CVV_VERIFICATION_FAILED':\n // occurs when:\n // * the client token used for client authorization was generated\n // with a customer ID and the verify card option is set to true\n // and you have credit card verification turned on in the Braintree\n // control panel\n // * the cvv does not pass verfication\n handler?.markFieldErrors([HostedFieldName.CVV]);\n break;\n case 'HOSTED_FIELDS_FAILED_TOKENIZATION':\n // occurs for any other tokenization error on the server\n break;\n case 'HOSTED_FIELDS_TOKENIZATION_NETWORK_ERROR':\n // occurs when the Braintree gateway cannot be contacted\n break;\n default:\n // something else happened\n break;\n }\n }\n\n if (!tokenized) {\n return false;\n }\n\n return hostedFieldsResponse;\n }\n\n async setupCreditCardHandler() {\n // braintree turn on hosted fields\n const handler =\n await this.braintreeManager?.paymentProviders.creditCardHandler.get();\n try {\n await handler?.tokenizeHostedFields();\n } catch (e) {\n // todo: show error message only about fields not loading\n }\n\n handler?.removeFieldErrors([\n HostedFieldName.Number,\n HostedFieldName.CVV,\n HostedFieldName.ExpirationDate,\n ]);\n }\n\n render() {\n return html` <div>${this.creditCardTemplate}</div> `;\n }\n\n lightDomCSS(): CSSResult {\n return css`\n contact-form form badged-input {\n width: 100%;\n }\n\n #ia-mgc-cc-area .braintree-input {\n width: 100%;\n display: block;\n height: stretch;\n height: -webkit-fill-available;\n }\n `;\n }\n\n get creditCardTemplate() {\n return html`\n <div id=\"ia-mgc-cc-area\" style=\"border: 1px sold red;\">\n <style>\n ${this.lightDomCSS()}\n </style>\n <div id=\"braintree-error-message\"></div>\n <div class=\"braintree-row\">\n <badged-input\n .icon=${creditCardImg}\n ?required=${true}\n class=\"creditcard\"\n >\n <div class=\"braintree-input\" id=\"braintree-creditcard\"></div>\n </badged-input>\n </div>\n <div class=\"braintree-row\">\n <badged-input\n .icon=${calendarImg}\n ?required=${true}\n class=\"expiration\"\n >\n <div class=\"braintree-input\" id=\"braintree-expiration\"></div>\n </badged-input>\n <badged-input .icon=${lockImg} ?required=${true} class=\"cvv\">\n <div class=\"braintree-input\" id=\"braintree-cvv\"></div>\n </badged-input>\n </div>\n </div>\n `;\n }\n\n async renderPayPalVaultButton(): Promise<void> {\n console.log('[PayPal] renderPayPalVaultButton called');\n\n const handler =\n await this.braintreeManager?.paymentProviders.paypalHandler.get();\n console.log('[PayPal] handler:', handler);\n if (!handler) return;\n\n const container = document.querySelector('#ia-mgc-paypal-button');\n console.log('[PayPal] container element:', container);\n\n const donationInfo = new DonationPaymentInfo({\n donationType: DonationType.Monthly,\n amount: this.plan?.amount ?? 0,\n coverFees: false,\n });\n\n const dataSource = await handler.renderPayPalButton({\n selector: '#ia-mgc-paypal-button',\n style: { color: 'blue', shape: 'rect', size: 'medium' },\n donationInfo,\n });\n console.log('[PayPal] dataSource:', dataSource);\n\n if (!dataSource) return;\n\n dataSource.delegate = {\n payPalPaymentStarted: async () => {\n console.log('PayPal payment started');\n },\n payPalPaymentAuthorized: async (_ds: any, payload: any) => {\n this.handlePayPalAuthorized(payload);\n },\n payPalPaymentConfirmed: async (_ds: any, payload: any) => {\n this.handlePayPalAuthorized(payload);\n },\n payPalPaymentCancelled: async () => {\n console.log('PayPal payment cancelled');\n },\n payPalPaymentError: async (_ds: any, error: unknown) => {\n console.error('PayPal vault error:', error);\n this.dispatchEvent(\n new CustomEvent('PayPalVaultError', { detail: { error } }),\n );\n },\n };\n }\n\n private handlePayPalAuthorized(payload: {\n nonce: string;\n type: string;\n details: { email: string };\n }): void {\n this.dispatchEvent(\n new CustomEvent('PayPalVaultAuthorized', {\n detail: {\n paymentMethodInfo: {\n description: `PayPal - ${payload.details.email}`,\n nonce: payload.nonce,\n type: payload.type,\n details: { email: payload.details.email },\n },\n },\n }),\n );\n }\n\n private async setupBraintreeManager(): Promise<void> {\n this.braintreeManager = new BraintreeManager({\n paymentClients:\n this.paymentConfig?.paymentClients ?? ({} as PaymentClientsInterface),\n endpointManager: this.paymentConfig\n ?.endpointManager as BraintreeEndpointManagerInterface,\n authorizationToken: this.paymentConfig?.braintreeAuthToken ?? '',\n venmoProfileId: this.paymentConfig?.venmoProfileId,\n googlePayMerchantId: this.paymentConfig?.googlePayMerchantId,\n hostedFieldConfig: {\n hostedFieldStyle: {}, // Provide your custom style object here\n hostedFieldFieldOptions: {\n number: {\n selector: '#braintree-creditcard',\n placeholder: 'Card number',\n },\n cvv: {\n selector: '#braintree-cvv',\n placeholder: 'CVC',\n },\n expirationDate: {\n selector: '#braintree-expiration',\n placeholder: 'MM / YY',\n },\n }, // Provide your custom field options here\n hostedFieldContainer: new HostedFieldContainer({\n number: this.braintreeInputs.number as HTMLDivElement,\n cvv: this.braintreeInputs.cvv as HTMLDivElement,\n expirationDate: this.braintreeInputs.expirationDate as HTMLDivElement,\n errorContainer: this.braintreeInputs.errorMessage as HTMLDivElement,\n }),\n },\n hostingEnvironment: this.paymentConfig?.environment as HostingEnvironment,\n referrer: window.location.href,\n loggedInUser: this.patronEmail,\n origin: window.location.origin,\n });\n\n this.braintreeManager.on(\n 'paymentProvidersHostedFieldsRetry',\n (retryNumber: number) => {\n const event = new CustomEvent('paymentProvidersHostedFieldsRetry', {\n detail: { retryNumber },\n });\n this.dispatchEvent(event);\n },\n );\n\n this.braintreeManager.on(\n 'paymentProvidersHostedFieldsFailed',\n (error: unknown) => {\n const event = new CustomEvent('paymentProvidersHostedFieldsFailed', {\n detail: { error },\n });\n this.dispatchEvent(event);\n },\n );\n\n this.dispatchEvent(new Event('BraintreeManagerSetupComplete'));\n }\n\n get contactForm(): HTMLFormElement | null {\n return this.querySelector('form[name=\"contact-form\"]');\n }\n}\n"]}
1
+ {"version":3,"file":"braintree-manager.js","sourceRoot":"","sources":["../../../../src/form-sections/parts/braintree-manager.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\nimport { LitElement, html, css, CSSResult, PropertyValueMap } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport {\n HostedFieldContainer,\n HostedFieldName,\n} from '@internetarchive/donation-form/dist/src/braintree-manager/payment-providers/credit-card/hosted-field-container';\nimport {\n BraintreeManager,\n BraintreeManagerInterface,\n HostingEnvironment,\n} from '@internetarchive/donation-form';\nimport {\n DonationPaymentInfo,\n DonationType,\n} from '@internetarchive/donation-form-data-models';\nimport type { BraintreeEndpointManagerInterface } from '@internetarchive/donation-form/dist/src/braintree-manager/braintree-interfaces.js';\nimport type { PaymentClientsInterface } from '@internetarchive/donation-form/dist/src/braintree-manager/payment-clients.js';\n\nimport creditCardImg from '@internetarchive/icon-credit-card/index.js';\nimport calendarImg from '@internetarchive/icon-calendar/index.js';\nimport lockImg from '@internetarchive/icon-lock/index.js';\nimport { VenmoPendingStorage } from '../../utils/venmo-pending-storage';\n\nimport type { MonthlyPlan } from '../../models/plan';\n\nexport type PaymentConfig = {\n braintreeAuthToken?: string;\n endpointManager?: BraintreeEndpointManagerInterface;\n paymentClients?: PaymentClientsInterface;\n environment?: HostingEnvironment;\n venmoProfileId?: string;\n googlePayMerchantId?: string;\n referrer: string;\n origin: string;\n};\n\n@customElement('ia-mgc-braintree-manager')\nexport class MGCBraintreeManager extends LitElement {\n @property({ type: Object }) plan?: MonthlyPlan;\n\n @property({ type: Boolean, reflect: true }) displayCreditCard: boolean =\n false;\n\n @property({ type: String }) patronEmail: string = '';\n\n @property({ type: Object }) paymentConfig?: PaymentConfig;\n\n @property({ type: Object }) braintreeManager?: BraintreeManagerInterface;\n\n @state() private elementConnected: boolean = false;\n\n @property({ type: Object }) venmoPendingStorage?: VenmoPendingStorage;\n\n get braintreeInputs(): {\n errorMessage: HTMLDivElement | null;\n number: HTMLDivElement | null;\n cvv: HTMLDivElement | null;\n expirationDate: HTMLDivElement | null;\n } {\n return {\n errorMessage: this.querySelector(\n '#braintree-error-message',\n ) as HTMLDivElement | null,\n number: this.querySelector(\n '#braintree-creditcard',\n ) as HTMLDivElement | null,\n cvv: this.querySelector('#braintree-cvv') as HTMLDivElement | null,\n expirationDate: this.querySelector(\n '#braintree-expiration',\n ) as HTMLDivElement | null,\n };\n }\n\n createRenderRoot() {\n return this;\n }\n\n disconnectedCallback(): void {\n this.elementConnected = false;\n }\n\n connectedCallback(): void {\n // eslint-disable-next-line wc/guard-super-call\n super.connectedCallback();\n\n console.log('connectedCallback', { paymentConfig: this.paymentConfig });\n\n this.elementConnected = true;\n }\n\n protected updated(\n changed: PropertyValueMap<any> | Map<PropertyKey, unknown>,\n ): void {\n const elementHasConnectedToDOM =\n changed.has('elementConnected') && this.elementConnected;\n if (elementHasConnectedToDOM) {\n if (this.paymentConfig) {\n const {\n braintreeAuthToken,\n endpointManager,\n paymentClients,\n environment,\n } = this.paymentConfig || {};\n\n const needsBraintreeManager =\n !this.braintreeManager &&\n braintreeAuthToken &&\n endpointManager &&\n paymentClients &&\n environment;\n if (needsBraintreeManager) {\n this.setupBraintreeManager();\n }\n }\n }\n\n if (\n this.braintreeManager &&\n changed.has('displayCreditCard') &&\n this.displayCreditCard\n ) {\n this.setupCreditCardHandler();\n }\n }\n\n async validateCreditCardFields() {\n const handler =\n await this.braintreeManager?.paymentProviders.creditCardHandler.get();\n let tokenized = false;\n let hostedFieldsResponse = null;\n try {\n hostedFieldsResponse = await handler?.tokenizeHostedFields();\n tokenized = true;\n } catch (e) {\n const error = e as unknown as any;\n\n handler?.showErrorMessage();\n\n // todo: move these codes to an enum/type\n switch (error.code) {\n case 'HOSTED_FIELDS_FIELDS_EMPTY':\n // occurs when none of the fields are filled in\n handler?.markFieldErrors([\n HostedFieldName.Number,\n HostedFieldName.CVV,\n HostedFieldName.ExpirationDate,\n ]);\n break;\n case 'HOSTED_FIELDS_FIELDS_INVALID':\n // occurs when certain fields do not pass client side validationto\n // Object.keys(.details.invalidFields).forEach(key => {\n // handler?.markFieldErrors([key as HostedFieldName]);\n // });\n break;\n case 'HOSTED_FIELDS_TOKENIZATION_FAIL_ON_DUPLICATE':\n // occurs when:\n // * the client token used for client authorization was generated\n // with a customer ID and the fail on duplicate payment method\n // option is set to true\n // * the card being tokenized has previously been vaulted (with any customer)\n break;\n case 'HOSTED_FIELDS_TOKENIZATION_CVV_VERIFICATION_FAILED':\n // occurs when:\n // * the client token used for client authorization was generated\n // with a customer ID and the verify card option is set to true\n // and you have credit card verification turned on in the Braintree\n // control panel\n // * the cvv does not pass verfication\n handler?.markFieldErrors([HostedFieldName.CVV]);\n break;\n case 'HOSTED_FIELDS_FAILED_TOKENIZATION':\n // occurs for any other tokenization error on the server\n break;\n case 'HOSTED_FIELDS_TOKENIZATION_NETWORK_ERROR':\n // occurs when the Braintree gateway cannot be contacted\n break;\n default:\n // something else happened\n break;\n }\n }\n\n if (!tokenized) {\n return false;\n }\n\n return hostedFieldsResponse;\n }\n\n async setupCreditCardHandler() {\n // braintree turn on hosted fields\n const handler =\n await this.braintreeManager?.paymentProviders.creditCardHandler.get();\n try {\n await handler?.tokenizeHostedFields();\n } catch (e) {\n // todo: show error message only about fields not loading\n }\n\n handler?.removeFieldErrors([\n HostedFieldName.Number,\n HostedFieldName.CVV,\n HostedFieldName.ExpirationDate,\n ]);\n }\n\n render() {\n return html` <div>${this.creditCardTemplate}</div> `;\n }\n\n lightDomCSS(): CSSResult {\n return css`\n contact-form form badged-input {\n width: 100%;\n }\n\n #ia-mgc-cc-area .braintree-input {\n width: 100%;\n display: block;\n height: stretch;\n height: -webkit-fill-available;\n }\n `;\n }\n\n get creditCardTemplate() {\n return html`\n <div id=\"ia-mgc-cc-area\" style=\"border: 1px sold red;\">\n <style>\n ${this.lightDomCSS()}\n </style>\n <div id=\"braintree-error-message\"></div>\n <div class=\"braintree-row\">\n <badged-input\n .icon=${creditCardImg}\n ?required=${true}\n class=\"creditcard\"\n >\n <div class=\"braintree-input\" id=\"braintree-creditcard\"></div>\n </badged-input>\n </div>\n <div class=\"braintree-row\">\n <badged-input\n .icon=${calendarImg}\n ?required=${true}\n class=\"expiration\"\n >\n <div class=\"braintree-input\" id=\"braintree-expiration\"></div>\n </badged-input>\n <badged-input .icon=${lockImg} ?required=${true} class=\"cvv\">\n <div class=\"braintree-input\" id=\"braintree-cvv\"></div>\n </badged-input>\n </div>\n </div>\n `;\n }\n\n async renderPayPalVaultButton(): Promise<void> {\n console.log('[PayPal] renderPayPalVaultButton called');\n\n const handler =\n await this.braintreeManager?.paymentProviders.paypalHandler.get();\n console.log('[PayPal] handler:', handler);\n if (!handler) return;\n\n const container = document.querySelector('#ia-mgc-paypal-button');\n console.log('[PayPal] container element:', container);\n\n const donationInfo = new DonationPaymentInfo({\n donationType: DonationType.Monthly,\n amount: this.plan?.amount ?? 0,\n coverFees: false,\n });\n\n const dataSource = await handler.renderPayPalButton({\n selector: '#ia-mgc-paypal-button',\n style: { color: 'blue', shape: 'rect', size: 'medium' },\n donationInfo,\n });\n console.log('[PayPal] dataSource:', dataSource);\n\n if (!dataSource) return;\n\n dataSource.delegate = {\n payPalPaymentStarted: async () => {\n console.log('PayPal payment started');\n },\n payPalPaymentAuthorized: async (_ds: any, payload: any) => {\n this.handlePayPalAuthorized(payload);\n },\n payPalPaymentConfirmed: async (_ds: any, payload: any) => {\n this.handlePayPalAuthorized(payload);\n },\n payPalPaymentCancelled: async () => {\n console.log('PayPal payment cancelled');\n },\n payPalPaymentError: async (_ds: any, error: unknown) => {\n console.error('PayPal vault error:', error);\n this.dispatchEvent(\n new CustomEvent('PayPalVaultError', { detail: { error } }),\n );\n },\n };\n }\n\n private handlePayPalAuthorized(payload: {\n nonce: string;\n type: string;\n details: { email: string };\n }): void {\n this.dispatchEvent(\n new CustomEvent('PayPalVaultAuthorized', {\n detail: {\n paymentMethodInfo: {\n description: `PayPal - ${payload.details.email}`,\n nonce: payload.nonce,\n type: payload.type,\n details: { email: payload.details.email },\n },\n },\n }),\n );\n }\n\n async startVenmoPayment(): Promise<void> {\n const handler =\n await this.braintreeManager?.paymentProviders.venmoHandler.get();\n if (!handler) return;\n\n if (this.plan?.id) this.venmoPendingStorage?.setPending(this.plan.id);\n\n try {\n const payload = await handler.startPayment();\n if (this.plan?.id) this.venmoPendingStorage?.clearPending(this.plan.id);\n this.dispatchEvent(\n new CustomEvent('VenmoAuthorized', {\n detail: {\n paymentMethodInfo: {\n description: `Venmo - ${payload.details.username}`,\n nonce: payload.nonce,\n type: payload.type,\n details: { username: payload.details.username },\n },\n },\n }),\n );\n } catch (e: unknown) {\n if (this.plan?.id) this.venmoPendingStorage?.clearPending(this.plan.id);\n const code = (e as { code?: string })?.code;\n if (code === 'VENMO_APP_CANCELED' || code === 'VENMO_CANCELED') {\n console.log('Venmo payment cancelled');\n } else {\n console.error('Venmo payment error:', e);\n this.dispatchEvent(\n new CustomEvent('VenmoError', { detail: { error: e } }),\n );\n }\n }\n }\n\n private async checkVenmoRestoration(): Promise<void> {\n const planId = this.plan?.id;\n if (!planId) return;\n const pending = this.venmoPendingStorage?.getPending(planId);\n if (!pending) return;\n\n try {\n const handler =\n await this.braintreeManager?.paymentProviders.venmoHandler.get();\n if (!handler) {\n this.venmoPendingStorage?.clearPending(planId);\n return;\n }\n\n const instance = await handler.instance.get();\n if (!instance) {\n this.venmoPendingStorage?.clearPending(planId);\n return;\n }\n\n // Clear before tokenizing to prevent retry loops on failure\n this.venmoPendingStorage?.clearPending(planId);\n\n if (!instance.hasTokenizationResult()) return;\n\n // startPayment() re-checks hasTokenizationResult() internally and\n // calls instance.tokenize() on the cached result — it does NOT launch\n // a new Venmo redirect when a tokenization result is already present.\n const payload = await handler.startPayment();\n this.dispatchEvent(\n new CustomEvent('VenmoAuthorized', {\n detail: {\n paymentMethodInfo: {\n description: `Venmo - ${payload.details.username}`,\n nonce: payload.nonce,\n type: payload.type,\n details: { username: payload.details.username },\n },\n },\n }),\n );\n } catch (e: unknown) {\n this.venmoPendingStorage?.clearPending(planId);\n const code = (e as { code?: string })?.code;\n if (code !== 'VENMO_APP_CANCELED' && code !== 'VENMO_CANCELED') {\n console.error('Venmo restoration error:', e);\n this.dispatchEvent(\n new CustomEvent('VenmoError', { detail: { error: e } }),\n );\n }\n }\n }\n\n private async setupBraintreeManager(): Promise<void> {\n this.braintreeManager = new BraintreeManager({\n paymentClients:\n this.paymentConfig?.paymentClients ?? ({} as PaymentClientsInterface),\n endpointManager: this.paymentConfig\n ?.endpointManager as BraintreeEndpointManagerInterface,\n authorizationToken: this.paymentConfig?.braintreeAuthToken ?? '',\n venmoProfileId: this.paymentConfig?.venmoProfileId,\n googlePayMerchantId: this.paymentConfig?.googlePayMerchantId,\n hostedFieldConfig: {\n hostedFieldStyle: {}, // Provide your custom style object here\n hostedFieldFieldOptions: {\n number: {\n selector: '#braintree-creditcard',\n placeholder: 'Card number',\n },\n cvv: {\n selector: '#braintree-cvv',\n placeholder: 'CVC',\n },\n expirationDate: {\n selector: '#braintree-expiration',\n placeholder: 'MM / YY',\n },\n }, // Provide your custom field options here\n hostedFieldContainer: new HostedFieldContainer({\n number: this.braintreeInputs.number as HTMLDivElement,\n cvv: this.braintreeInputs.cvv as HTMLDivElement,\n expirationDate: this.braintreeInputs.expirationDate as HTMLDivElement,\n errorContainer: this.braintreeInputs.errorMessage as HTMLDivElement,\n }),\n },\n hostingEnvironment: this.paymentConfig?.environment as HostingEnvironment,\n referrer: window.location.href,\n loggedInUser: this.patronEmail,\n origin: window.location.origin,\n });\n\n this.braintreeManager.on(\n 'paymentProvidersHostedFieldsRetry',\n (retryNumber: number) => {\n const event = new CustomEvent('paymentProvidersHostedFieldsRetry', {\n detail: { retryNumber },\n });\n this.dispatchEvent(event);\n },\n );\n\n this.braintreeManager.on(\n 'paymentProvidersHostedFieldsFailed',\n (error: unknown) => {\n const event = new CustomEvent('paymentProvidersHostedFieldsFailed', {\n detail: { error },\n });\n this.dispatchEvent(event);\n },\n );\n\n // BraintreeManager (@internetarchive/donation-form) has no config option to\n // suppress Google Pay, so we replace the handler directly. The upstream path\n // is `BraintreeManager.paymentProviders.googlePayHandler` — if that changes\n // this cast will silently stop working and the button may reappear.\n if (!this.paymentConfig?.googlePayMerchantId && this.braintreeManager) {\n // BraintreeManager has no config option to suppress Google Pay, so we\n // replace the handler directly. Casting only paymentProviders (not the\n // whole manager) keeps the access chain type-checked — if upstream\n // renames paymentProviders or googlePayHandler, TypeScript will catch it.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this.braintreeManager.paymentProviders as any).googlePayHandler = {\n get: async () => null,\n };\n }\n\n await this.checkVenmoRestoration();\n this.dispatchEvent(new Event('BraintreeManagerSetupComplete'));\n }\n\n get contactForm(): HTMLFormElement | null {\n return this.querySelector('form[name=\"contact-form\"]');\n }\n}\n"]}
@@ -11,6 +11,7 @@ import '../presentational/mgc-button';
11
11
  import type { MGCButton } from '../presentational/mgc-button';
12
12
  import '../presentational/mgc-update-status';
13
13
  import type { MGCBraintreeManager, PaymentConfig } from '../form-sections/parts/braintree-manager';
14
+ import { VenmoPendingStorage } from '../utils/venmo-pending-storage';
14
15
  /**
15
16
  * <ia-mgc-edit-payment-method>
16
17
  * - collecting the data to send to the service
@@ -32,7 +33,10 @@ export declare class MGCEditPaymentMethod extends LitElement {
32
33
  paymentSelectorFirstUpdated: boolean;
33
34
  updateMessage: string;
34
35
  updateStatus: 'success' | 'fail' | '';
36
+ venmoPendingStorage?: VenmoPendingStorage;
35
37
  createRenderRoot(): this;
38
+ firstUpdated(): void;
39
+ private checkAndRestoreVenmoState;
36
40
  submitPaymentMethodChange(e: Event): void;
37
41
  clearStatusMessaging(): void;
38
42
  paymentMethodUpdated(status: 'success' | 'fail'): Promise<void>;
@@ -42,7 +46,10 @@ export declare class MGCEditPaymentMethod extends LitElement {
42
46
  get paymentFormSection(): TemplateResult | typeof nothing;
43
47
  get creditCardElement(): ContactForm | null;
44
48
  get braintreeManagerElement(): MGCBraintreeManager | null;
49
+ get paymentMethodDetail(): string;
45
50
  render(): TemplateResult<1>;
51
+ showVenmoError(message?: string): void;
52
+ private handleVenmoAuthorized;
46
53
  private handlePayPalVaultAuthorized;
47
54
  get styles(): import("lit").CSSResult;
48
55
  }
@@ -12,6 +12,9 @@ import '../presentational/donation-section-info';
12
12
  import '../presentational/mgc-button';
13
13
  import '../presentational/mgc-update-status';
14
14
  import { PaymentMethodRequest } from '../models/payment-method-request';
15
+ // Braintree's paymentMethodType for credit card ('creditCard') differs from
16
+ // PaymentProvider.CreditCard ('Credit Card'), so we define it explicitly here.
17
+ const BRAINTREE_CREDITCARD_TYPE = 'creditCard';
15
18
  /**
16
19
  * <ia-mgc-edit-payment-method>
17
20
  * - collecting the data to send to the service
@@ -46,6 +49,18 @@ let MGCEditPaymentMethod = class MGCEditPaymentMethod extends LitElement {
46
49
  createRenderRoot() {
47
50
  return this;
48
51
  }
52
+ firstUpdated() {
53
+ this.checkAndRestoreVenmoState();
54
+ }
55
+ checkAndRestoreVenmoState() {
56
+ var _a, _b;
57
+ if (!((_a = this.plan) === null || _a === void 0 ? void 0 : _a.id))
58
+ return;
59
+ if ((_b = this.venmoPendingStorage) === null || _b === void 0 ? void 0 : _b.getPending(this.plan.id)) {
60
+ this.currentlyEditing = true;
61
+ this.selectedPaymentProvider = PaymentProvider.Venmo;
62
+ }
63
+ }
49
64
  submitPaymentMethodChange(e) {
50
65
  e.preventDefault();
51
66
  }
@@ -104,13 +119,23 @@ let MGCEditPaymentMethod = class MGCEditPaymentMethod extends LitElement {
104
119
  get braintreeManagerElement() {
105
120
  return this.querySelector('ia-mgc-braintree-manager');
106
121
  }
122
+ get paymentMethodDetail() {
123
+ var _a, _b;
124
+ const { paymentMethodType, paypalEmail, venmoUsername, cardType, last4 } = (_b = (_a = this.plan) === null || _a === void 0 ? void 0 : _a.payment) !== null && _b !== void 0 ? _b : {};
125
+ if (paymentMethodType === PaymentProvider.PayPal)
126
+ return paypalEmail !== null && paypalEmail !== void 0 ? paypalEmail : '';
127
+ if (paymentMethodType === PaymentProvider.Venmo)
128
+ return venmoUsername !== null && venmoUsername !== void 0 ? venmoUsername : '';
129
+ return `${cardType} - ${last4}`;
130
+ }
107
131
  render() {
108
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
132
+ var _a, _b, _c, _d, _e;
109
133
  const displayContactForm = this.selectedPaymentProvider === PaymentProvider.CreditCard ||
110
134
  this.selectedPaymentProvider === PaymentProvider.Venmo;
111
135
  const displayCCFields = this.selectedPaymentProvider === PaymentProvider.CreditCard;
112
136
  const displayBraintreeManager = this.selectedPaymentProvider === PaymentProvider.CreditCard ||
113
- this.selectedPaymentProvider === PaymentProvider.PayPal;
137
+ this.selectedPaymentProvider === PaymentProvider.PayPal ||
138
+ this.selectedPaymentProvider === PaymentProvider.Venmo;
114
139
  return html `
115
140
  <style>
116
141
  ${this.styles}
@@ -123,13 +148,11 @@ let MGCEditPaymentMethod = class MGCEditPaymentMethod extends LitElement {
123
148
  this.clearStatusMessaging();
124
149
  }}
125
150
  ><span>
126
- ${((_b = (_a = this.plan) === null || _a === void 0 ? void 0 : _a.payment) === null || _b === void 0 ? void 0 : _b.paymentMethodType) === 'creditCard'
151
+ ${((_b = (_a = this.plan) === null || _a === void 0 ? void 0 : _a.payment) === null || _b === void 0 ? void 0 : _b.paymentMethodType) ===
152
+ BRAINTREE_CREDITCARD_TYPE
127
153
  ? 'Credit Card'
128
154
  : (_d = (_c = this.plan) === null || _c === void 0 ? void 0 : _c.payment) === null || _d === void 0 ? void 0 : _d.paymentMethodType}:
129
- ${((_f = (_e = this.plan) === null || _e === void 0 ? void 0 : _e.payment) === null || _f === void 0 ? void 0 : _f.paymentMethodType) ===
130
- PaymentProvider.PayPal
131
- ? (_h = (_g = this.plan) === null || _g === void 0 ? void 0 : _g.payment) === null || _h === void 0 ? void 0 : _h.paypalEmail
132
- : `${(_k = (_j = this.plan) === null || _j === void 0 ? void 0 : _j.payment) === null || _k === void 0 ? void 0 : _k.cardType} - ${(_m = (_l = this.plan) === null || _l === void 0 ? void 0 : _l.payment) === null || _m === void 0 ? void 0 : _m.last4}`}
155
+ ${this.paymentMethodDetail}
133
156
  </span></ia-mgc-form-section-info
134
157
  >`
135
158
  : nothing}
@@ -137,7 +160,7 @@ let MGCEditPaymentMethod = class MGCEditPaymentMethod extends LitElement {
137
160
  ? html `
138
161
  <form id="edit-plan-payment-method" @submit=${this.submitPaymentMethodChange}>
139
162
  <payment-selector
140
- .paymentProviders=${(_o = this.braintreeManager) === null || _o === void 0 ? void 0 : _o.paymentProviders}
163
+ .paymentProviders=${(_e = this.braintreeManager) === null || _e === void 0 ? void 0 : _e.paymentProviders}
141
164
  @firstUpdated=${(e) => {
142
165
  var _a;
143
166
  this.paymentSelectorFirstUpdated = true;
@@ -177,9 +200,12 @@ let MGCEditPaymentMethod = class MGCEditPaymentMethod extends LitElement {
177
200
  .displayCreditCard=${displayCCFields}
178
201
  .plan=${this.plan}
179
202
  .paymentConfig=${this.paymentConfig}
203
+ .venmoPendingStorage=${this.venmoPendingStorage}
180
204
  @BraintreeManagerSetupComplete=${() => {
181
- var _a;
182
- (_a = this.braintreeManagerElement) === null || _a === void 0 ? void 0 : _a.renderPayPalVaultButton();
205
+ var _a, _b;
206
+ this.braintreeManager =
207
+ (_a = this.braintreeManagerElement) === null || _a === void 0 ? void 0 : _a.braintreeManager;
208
+ (_b = this.braintreeManagerElement) === null || _b === void 0 ? void 0 : _b.renderPayPalVaultButton();
183
209
  }}
184
210
  @PayPalVaultAuthorized=${(e) => {
185
211
  this.handlePayPalVaultAuthorized(e);
@@ -187,6 +213,18 @@ let MGCEditPaymentMethod = class MGCEditPaymentMethod extends LitElement {
187
213
  @PayPalVaultError=${() => {
188
214
  this.updateStatus = 'fail';
189
215
  this.updateMessage = 'PayPal error, please try again';
216
+ }}
217
+ @VenmoAuthorized=${(e) => {
218
+ this.handleVenmoAuthorized(e);
219
+ }}
220
+ @VenmoError=${() => {
221
+ this.showVenmoError('Venmo error, please try again');
222
+ // Re-dispatch with bubbles so ancestor components can react
223
+ // (e.g. close a loading/redirect modal).
224
+ this.dispatchEvent(new CustomEvent('VenmoError', {
225
+ bubbles: true,
226
+ composed: true,
227
+ }));
190
228
  }}
191
229
  ></ia-mgc-braintree-manager>
192
230
 
@@ -194,13 +232,19 @@ let MGCEditPaymentMethod = class MGCEditPaymentMethod extends LitElement {
194
232
  id="edit-plan-payment-method-cancel"
195
233
  class="secondary"
196
234
  .clickHandler=${() => {
235
+ var _a, _b;
236
+ if (this.selectedPaymentProvider === PaymentProvider.Venmo &&
237
+ ((_a = this.plan) === null || _a === void 0 ? void 0 : _a.id)) {
238
+ (_b = this.venmoPendingStorage) === null || _b === void 0 ? void 0 : _b.clearPending(this.plan.id);
239
+ }
197
240
  this.currentlyEditing = false;
198
241
  this.selectedPaymentProvider = '';
199
242
  this.clearStatusMessaging();
200
243
  }}
201
244
  >Cancel</ia-mgc-button
202
245
  >
203
- ${this.selectedPaymentProvider !== PaymentProvider.PayPal
246
+ ${this.selectedPaymentProvider !== PaymentProvider.PayPal &&
247
+ this.selectedPaymentProvider !== PaymentProvider.Venmo
204
248
  ? html `<ia-mgc-button
205
249
  id="edit-plan-payment-method-submit"
206
250
  class="primary"
@@ -233,6 +277,29 @@ let MGCEditPaymentMethod = class MGCEditPaymentMethod extends LitElement {
233
277
  >Update payment method</ia-mgc-button
234
278
  >`
235
279
  : nothing}
280
+ ${this.selectedPaymentProvider === PaymentProvider.Venmo
281
+ ? html `<ia-mgc-button
282
+ id="edit-plan-payment-method-venmo-submit"
283
+ class="primary"
284
+ .clickHandler=${async (_event, iaButton) => {
285
+ var _a, _b;
286
+ const button = iaButton;
287
+ button.isDisabled = true;
288
+ const isContactFormValid = (_a = this.contactFormElement) === null || _a === void 0 ? void 0 : _a.reportValidity();
289
+ if (!isContactFormValid) {
290
+ button.isDisabled = false;
291
+ return;
292
+ }
293
+ this.dispatchEvent(new CustomEvent('VenmoRedirectStarted', {
294
+ bubbles: true,
295
+ composed: true,
296
+ }));
297
+ await ((_b = this.braintreeManagerElement) === null || _b === void 0 ? void 0 : _b.startVenmoPayment());
298
+ button.isDisabled = false;
299
+ }}
300
+ >Pay with Venmo</ia-mgc-button
301
+ >`
302
+ : nothing}
236
303
  <ia-mgc-update-status .status=${this.updateStatus}
237
304
  >${this.updateMessage}</ia-mgc-update-status
238
305
  ></ia-mgc-form-section-info>
@@ -245,12 +312,32 @@ let MGCEditPaymentMethod = class MGCEditPaymentMethod extends LitElement {
245
312
  </donation-form-section>
246
313
  `;
247
314
  }
248
- handlePayPalVaultAuthorized(e) {
315
+ showVenmoError(message = 'Venmo payment cancelled, please try again.') {
316
+ this.updateStatus = 'fail';
317
+ this.updateMessage = message;
318
+ }
319
+ handleVenmoAuthorized(e) {
249
320
  var _a, _b;
250
321
  const { paymentMethodInfo } = e.detail;
251
322
  const newPaymentMethodRequest = new PaymentMethodRequest({
252
323
  paymentMethodInfo,
253
324
  donorContactInfo: (_b = (_a = this.contactFormElement) === null || _a === void 0 ? void 0 : _a.donorContactInfo) !== null && _b !== void 0 ? _b : {},
325
+ paymentProvider: PaymentProvider.Venmo,
326
+ });
327
+ this.dispatchEvent(new CustomEvent('UpdatePaymentMethod', {
328
+ detail: { newPaymentMethodRequest },
329
+ }));
330
+ }
331
+ handlePayPalVaultAuthorized(e) {
332
+ var _a, _b, _c, _d;
333
+ const { paymentMethodInfo } = e.detail;
334
+ const paypalEmail = (_b = (_a = paymentMethodInfo === null || paymentMethodInfo === void 0 ? void 0 : paymentMethodInfo.details) === null || _a === void 0 ? void 0 : _a.email) !== null && _b !== void 0 ? _b : '';
335
+ const donorContactInfo = (_d = (_c = this.contactFormElement) === null || _c === void 0 ? void 0 : _c.donorContactInfo) !== null && _d !== void 0 ? _d : {
336
+ customer: { email: paypalEmail },
337
+ };
338
+ const newPaymentMethodRequest = new PaymentMethodRequest({
339
+ paymentMethodInfo,
340
+ donorContactInfo,
254
341
  paymentProvider: PaymentProvider.PayPal,
255
342
  });
256
343
  this.dispatchEvent(new CustomEvent('UpdatePaymentMethod', {
@@ -330,6 +417,9 @@ __decorate([
330
417
  __decorate([
331
418
  property({ type: String })
332
419
  ], MGCEditPaymentMethod.prototype, "updateStatus", void 0);
420
+ __decorate([
421
+ property({ type: Object })
422
+ ], MGCEditPaymentMethod.prototype, "venmoPendingStorage", void 0);
333
423
  MGCEditPaymentMethod = __decorate([
334
424
  customElement('ia-mgc-edit-payment-method')
335
425
  ], MGCEditPaymentMethod);