@internetarchive/donation-form 1.0.3-alpha-webdev7960.0 → 1.0.3-webdev-8122.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/LICENSE +661 -661
  2. package/README.md +115 -115
  3. package/dist/demo/braintree-endpoint-manager.js.map +1 -1
  4. package/dist/demo/demo-analytics-handler.js.map +1 -1
  5. package/dist/demo/submit-form-with.js.map +1 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/src/braintree-manager/braintree-interfaces.js.map +1 -1
  8. package/dist/src/braintree-manager/braintree-manager.js.map +1 -1
  9. package/dist/src/braintree-manager/payment-clients.js.map +1 -1
  10. package/dist/src/braintree-manager/payment-providers/apple-pay/apple-pay-interface.js.map +1 -1
  11. package/dist/src/braintree-manager/payment-providers/apple-pay/apple-pay-session-datasource-delegate.js.map +1 -1
  12. package/dist/src/braintree-manager/payment-providers/apple-pay/apple-pay-session-datasource-interface.js.map +1 -1
  13. package/dist/src/braintree-manager/payment-providers/apple-pay/apple-pay-session-datasource.js.map +1 -1
  14. package/dist/src/braintree-manager/payment-providers/apple-pay/apple-pay-session-manager.js.map +1 -1
  15. package/dist/src/braintree-manager/payment-providers/apple-pay/apple-pay.js.map +1 -1
  16. package/dist/src/braintree-manager/payment-providers/credit-card/credit-card-interface.js.map +1 -1
  17. package/dist/src/braintree-manager/payment-providers/credit-card/credit-card.js.map +1 -1
  18. package/dist/src/braintree-manager/payment-providers/credit-card/hosted-field-configuration.js.map +1 -1
  19. package/dist/src/braintree-manager/payment-providers/credit-card/hosted-field-container.js.map +1 -1
  20. package/dist/src/braintree-manager/payment-providers/google-pay-interface.js.map +1 -1
  21. package/dist/src/braintree-manager/payment-providers/google-pay.js.map +1 -1
  22. package/dist/src/braintree-manager/payment-providers/paypal/paypal-button-datasource.js.map +1 -1
  23. package/dist/src/braintree-manager/payment-providers/paypal/paypal-interface.js.map +1 -1
  24. package/dist/src/braintree-manager/payment-providers/paypal/paypal.js.map +1 -1
  25. package/dist/src/braintree-manager/payment-providers/venmo-interface.js.map +1 -1
  26. package/dist/src/braintree-manager/payment-providers/venmo.js.map +1 -1
  27. package/dist/src/braintree-manager/payment-providers-interface.js.map +1 -1
  28. package/dist/src/braintree-manager/payment-providers.js.map +1 -1
  29. package/dist/src/donation-form-controller.js +123 -123
  30. package/dist/src/donation-form-controller.js.map +1 -1
  31. package/dist/src/donation-form-error.js.map +1 -1
  32. package/dist/src/donation-form.js +107 -107
  33. package/dist/src/donation-form.js.map +1 -1
  34. package/dist/src/form-elements/badged-input.js +47 -47
  35. package/dist/src/form-elements/badged-input.js.map +1 -1
  36. package/dist/src/form-elements/contact-form/autocomplete-field-options.js.map +1 -1
  37. package/dist/src/form-elements/contact-form/contact-form.js +159 -157
  38. package/dist/src/form-elements/contact-form/contact-form.js.map +1 -1
  39. package/dist/src/form-elements/contact-form/countries.js.map +1 -1
  40. package/dist/src/form-elements/header/donation-form-header.js +14 -14
  41. package/dist/src/form-elements/header/donation-form-header.js.map +1 -1
  42. package/dist/src/form-elements/header/donation-summary.js +15 -15
  43. package/dist/src/form-elements/header/donation-summary.js.map +1 -1
  44. package/dist/src/form-elements/payment-selector.js +164 -164
  45. package/dist/src/form-elements/payment-selector.js.map +1 -1
  46. package/dist/src/form-elements/total-amount.js +16 -16
  47. package/dist/src/form-elements/total-amount.js.map +1 -1
  48. package/dist/src/modals/confirm-donation-modal-content.js +51 -51
  49. package/dist/src/modals/confirm-donation-modal-content.js.map +1 -1
  50. package/dist/src/modals/error-modal-content.js +22 -22
  51. package/dist/src/modals/error-modal-content.js.map +1 -1
  52. package/dist/src/modals/upsell-modal-content.js +182 -182
  53. package/dist/src/modals/upsell-modal-content.js.map +1 -1
  54. package/dist/src/payment-flow-handlers/donation-flow-modal-manager.js +20 -20
  55. package/dist/src/payment-flow-handlers/donation-flow-modal-manager.js.map +1 -1
  56. package/dist/src/payment-flow-handlers/handlers/applepay-flow-handler.js.map +1 -1
  57. package/dist/src/payment-flow-handlers/handlers/creditcard-flow-handler.js.map +1 -1
  58. package/dist/src/payment-flow-handlers/handlers/googlepay-flow-handler.js +2 -0
  59. package/dist/src/payment-flow-handlers/handlers/googlepay-flow-handler.js.map +1 -1
  60. package/dist/src/payment-flow-handlers/handlers/paypal-flow-handler.js +2 -0
  61. package/dist/src/payment-flow-handlers/handlers/paypal-flow-handler.js.map +1 -1
  62. package/dist/src/payment-flow-handlers/handlers/venmo-flow-handler.js.map +1 -1
  63. package/dist/src/payment-flow-handlers/handlers/venmo-restoration-state-handler.js.map +1 -1
  64. package/dist/src/payment-flow-handlers/payment-flow-handlers.js.map +1 -1
  65. package/dist/src/recaptcha-manager/recaptcha-manager.js.map +1 -1
  66. package/dist/src/util/promisedSleep.js.map +1 -1
  67. package/dist/test/helpers/fillInContactForm.js.map +1 -1
  68. package/dist/test/mocks/flow-handlers/individual-handlers/mock-applepay-flow-handler.js.map +1 -1
  69. package/dist/test/mocks/flow-handlers/individual-handlers/mock-creditcard-flow-handler.js.map +1 -1
  70. package/dist/test/mocks/flow-handlers/individual-handlers/mock-googlepay-flow-handler.js.map +1 -1
  71. package/dist/test/mocks/flow-handlers/individual-handlers/mock-paypal-flow-handler.js.map +1 -1
  72. package/dist/test/mocks/flow-handlers/individual-handlers/mock-venmo-flow-handler.js.map +1 -1
  73. package/dist/test/mocks/flow-handlers/mock-payment-flow-handlers.js.map +1 -1
  74. package/dist/test/mocks/mock-braintree-manager.js.map +1 -1
  75. package/dist/test/mocks/mock-donation-info.js.map +1 -1
  76. package/dist/test/mocks/mock-endpoint-manager.js.map +1 -1
  77. package/dist/test/mocks/mock-hosted-fields-config.js.map +1 -1
  78. package/dist/test/mocks/mock-hosted-fields-container.js.map +1 -1
  79. package/dist/test/mocks/mock-lazy-loader.js.map +1 -1
  80. package/dist/test/mocks/mock-modal-manager.js.map +1 -1
  81. package/dist/test/mocks/mock-payment-clients.js.map +1 -1
  82. package/dist/test/mocks/mock-paypal-button-renderer.js.map +1 -1
  83. package/dist/test/mocks/mock-recaptcha-manager.js.map +1 -1
  84. package/dist/test/mocks/models/mock-billing-info.js +2 -0
  85. package/dist/test/mocks/models/mock-billing-info.js.map +1 -1
  86. package/dist/test/mocks/models/mock-custom-fields.js.map +1 -1
  87. package/dist/test/mocks/models/mock-customer-info.js.map +1 -1
  88. package/dist/test/mocks/models/mock-donation-request.js.map +1 -1
  89. package/dist/test/mocks/models/mock-success-response.js.map +1 -1
  90. package/dist/test/mocks/payment-clients/mock-applepay-client.js.map +1 -1
  91. package/dist/test/mocks/payment-clients/mock-applepay-payment.js.map +1 -1
  92. package/dist/test/mocks/payment-clients/mock-applepay-paymentauthorizedevent.js.map +1 -1
  93. package/dist/test/mocks/payment-clients/mock-applepay-session.js.map +1 -1
  94. package/dist/test/mocks/payment-clients/mock-applepay-sessionmanager.js.map +1 -1
  95. package/dist/test/mocks/payment-clients/mock-applepay-validatemerchantevent.js.map +1 -1
  96. package/dist/test/mocks/payment-clients/mock-braintree-client.js.map +1 -1
  97. package/dist/test/mocks/payment-clients/mock-data-collector.js.map +1 -1
  98. package/dist/test/mocks/payment-clients/mock-googlepay-client.js.map +1 -1
  99. package/dist/test/mocks/payment-clients/mock-googlepay-library.js.map +1 -1
  100. package/dist/test/mocks/payment-clients/mock-grecaptcha.js.map +1 -1
  101. package/dist/test/mocks/payment-clients/mock-hostedfields-client.js.map +1 -1
  102. package/dist/test/mocks/payment-clients/mock-hostedfieldstateobject-generator.js.map +1 -1
  103. package/dist/test/mocks/payment-clients/mock-hostedfieldtokenizepayload.js.map +1 -1
  104. package/dist/test/mocks/payment-clients/mock-paypal-client.js.map +1 -1
  105. package/dist/test/mocks/payment-clients/mock-paypal-library.js.map +1 -1
  106. package/dist/test/mocks/payment-clients/mock-venmo-client.js.map +1 -1
  107. package/dist/test/mocks/payment-providers/individual-providers/mock-applepay-datasource-delegate.js.map +1 -1
  108. package/dist/test/mocks/payment-providers/individual-providers/mock-applepay-handler.js.map +1 -1
  109. package/dist/test/mocks/payment-providers/individual-providers/mock-creditcard-handler.js.map +1 -1
  110. package/dist/test/mocks/payment-providers/individual-providers/mock-googlepay-handler.js.map +1 -1
  111. package/dist/test/mocks/payment-providers/individual-providers/mock-paypal-button-datasource-delegate.js.map +1 -1
  112. package/dist/test/mocks/payment-providers/individual-providers/mock-paypal-button-datasource.js.map +1 -1
  113. package/dist/test/mocks/payment-providers/individual-providers/mock-paypal-handler.js.map +1 -1
  114. package/dist/test/mocks/payment-providers/individual-providers/mock-venmo-handler.js.map +1 -1
  115. package/dist/test/mocks/payment-providers/mock-payment-providers.js.map +1 -1
  116. package/dist/test/tests/braintree-manager.test.js.map +1 -1
  117. package/dist/test/tests/donation-form-controller.test.js +39 -39
  118. package/dist/test/tests/donation-form-controller.test.js.map +1 -1
  119. package/dist/test/tests/donation-form.test.js +4 -4
  120. package/dist/test/tests/donation-form.test.js.map +1 -1
  121. package/dist/test/tests/flow-handlers/donation-flow-modal-manager.test.js +16 -14
  122. package/dist/test/tests/flow-handlers/donation-flow-modal-manager.test.js.map +1 -1
  123. package/dist/test/tests/form-elements/donation-summary.test.js.map +1 -1
  124. package/dist/test/tests/form-elements/payment-selector.test.js.map +1 -1
  125. package/dist/test/tests/modals/error-modal-content.test.js +2 -2
  126. package/dist/test/tests/modals/error-modal-content.test.js.map +1 -1
  127. package/dist/test/tests/modals/upsell-modal-content.test.js +31 -31
  128. package/dist/test/tests/modals/upsell-modal-content.test.js.map +1 -1
  129. package/dist/test/tests/models/donation-payment-info.test.js.map +1 -1
  130. package/dist/test/tests/payment-clients.test.js.map +1 -1
  131. package/dist/test/tests/payment-providers/applepay-sessiondatasource.test.js.map +1 -1
  132. package/dist/test/tests/payment-providers/applepay-sessionmanager.test.js.map +1 -1
  133. package/dist/test/tests/payment-providers/applepay.test.js.map +1 -1
  134. package/dist/test/tests/payment-providers/creditcard.test.js.map +1 -1
  135. package/dist/test/tests/payment-providers/googlepay.test.js.map +1 -1
  136. package/dist/test/tests/payment-providers/payment-providers.test.js.map +1 -1
  137. package/dist/test/tests/payment-providers/paypal-button-datasource.test.js.map +1 -1
  138. package/dist/test/tests/payment-providers/paypal.test.js.map +1 -1
  139. package/dist/test/tests/payment-providers/venmo.test.js.map +1 -1
  140. package/dist/test/tests/recaptcha-manager.test.js.map +1 -1
  141. package/package.json +107 -107
  142. package/src/@types/analytics-handler/index.d.ts +8 -8
  143. package/src/@types/braintree-web/LICENSE +21 -21
  144. package/src/@types/braintree-web/index.d.ts +93 -93
  145. package/src/@types/braintree-web/modules/american-express.d.ts +50 -50
  146. package/src/@types/braintree-web/modules/apple-pay.d.ts +213 -213
  147. package/src/@types/braintree-web/modules/client.d.ts +103 -103
  148. package/src/@types/braintree-web/modules/core.d.ts +34 -34
  149. package/src/@types/braintree-web/modules/data-collector.d.ts +13 -13
  150. package/src/@types/braintree-web/modules/google-payment.d.ts +269 -269
  151. package/src/@types/braintree-web/modules/hosted-fields.d.ts +366 -366
  152. package/src/@types/braintree-web/modules/paypal-checkout.d.ts +262 -262
  153. package/src/@types/braintree-web/modules/paypal.d.ts +177 -177
  154. package/src/@types/braintree-web/modules/three-d-secure.d.ts +141 -141
  155. package/src/@types/braintree-web/modules/unionpay.d.ts +224 -224
  156. package/src/@types/braintree-web/modules/us-bank-account.d.ts +81 -81
  157. package/src/@types/braintree-web/modules/venmo.d.ts +110 -110
  158. package/src/@types/braintree-web/package.json +64 -64
  159. package/src/@types/paypal-checkout-components/LICENSE +21 -21
  160. package/src/@types/paypal-checkout-components/index.d.ts +67 -67
  161. package/src/@types/paypal-checkout-components/modules/button.d.ts +50 -50
  162. package/src/@types/paypal-checkout-components/modules/callback-data.d.ts +244 -244
  163. package/src/@types/paypal-checkout-components/modules/configuration.d.ts +114 -114
  164. package/src/@types/paypal-checkout-components/package.json +58 -58
  165. package/src/braintree-manager/braintree-interfaces.ts +172 -172
  166. package/src/braintree-manager/braintree-manager.ts +281 -281
  167. package/src/braintree-manager/payment-clients.ts +146 -146
  168. package/src/braintree-manager/payment-providers/apple-pay/apple-pay-interface.ts +13 -13
  169. package/src/braintree-manager/payment-providers/apple-pay/apple-pay-session-datasource-delegate.ts +8 -8
  170. package/src/braintree-manager/payment-providers/apple-pay/apple-pay-session-datasource-interface.ts +10 -10
  171. package/src/braintree-manager/payment-providers/apple-pay/apple-pay-session-datasource.ts +119 -119
  172. package/src/braintree-manager/payment-providers/apple-pay/apple-pay-session-manager.ts +21 -21
  173. package/src/braintree-manager/payment-providers/apple-pay/apple-pay.ts +97 -97
  174. package/src/braintree-manager/payment-providers/credit-card/credit-card-interface.ts +21 -21
  175. package/src/braintree-manager/payment-providers/credit-card/credit-card.ts +130 -130
  176. package/src/braintree-manager/payment-providers/credit-card/hosted-field-configuration.ts +19 -19
  177. package/src/braintree-manager/payment-providers/credit-card/hosted-field-container.ts +85 -85
  178. package/src/braintree-manager/payment-providers/google-pay-interface.ts +8 -8
  179. package/src/braintree-manager/payment-providers/google-pay.ts +59 -59
  180. package/src/braintree-manager/payment-providers/paypal/paypal-button-datasource.ts +218 -218
  181. package/src/braintree-manager/payment-providers/paypal/paypal-interface.ts +13 -13
  182. package/src/braintree-manager/payment-providers/paypal/paypal.ts +78 -78
  183. package/src/braintree-manager/payment-providers/venmo-interface.ts +8 -8
  184. package/src/braintree-manager/payment-providers/venmo.ts +67 -67
  185. package/src/braintree-manager/payment-providers-interface.ts +25 -25
  186. package/src/braintree-manager/payment-providers.ts +147 -147
  187. package/src/donation-form-controller.ts +623 -623
  188. package/src/donation-form-error.ts +6 -6
  189. package/src/donation-form.ts +576 -576
  190. package/src/form-elements/badged-input.ts +109 -109
  191. package/src/form-elements/contact-form/autocomplete-field-options.ts +63 -63
  192. package/src/form-elements/contact-form/contact-form.ts +436 -434
  193. package/src/form-elements/contact-form/countries.ts +252 -252
  194. package/src/form-elements/header/donation-form-header.ts +98 -98
  195. package/src/form-elements/header/donation-summary.ts +61 -61
  196. package/src/form-elements/payment-selector.ts +365 -365
  197. package/src/form-elements/total-amount.ts +46 -46
  198. package/src/modals/confirm-donation-modal-content.ts +168 -168
  199. package/src/modals/error-modal-content.ts +48 -48
  200. package/src/modals/upsell-modal-content.ts +284 -284
  201. package/src/payment-flow-handlers/donation-flow-modal-manager.ts +439 -439
  202. package/src/payment-flow-handlers/handlers/applepay-flow-handler.ts +109 -109
  203. package/src/payment-flow-handlers/handlers/creditcard-flow-handler.ts +232 -232
  204. package/src/payment-flow-handlers/handlers/googlepay-flow-handler.ts +113 -111
  205. package/src/payment-flow-handlers/handlers/paypal-flow-handler.ts +333 -331
  206. package/src/payment-flow-handlers/handlers/venmo-flow-handler.ts +119 -119
  207. package/src/payment-flow-handlers/handlers/venmo-restoration-state-handler.ts +127 -127
  208. package/src/payment-flow-handlers/payment-flow-handlers.ts +218 -218
  209. package/src/recaptcha-manager/recaptcha-manager.ts +123 -123
  210. package/src/util/promisedSleep.ts +3 -3
@@ -1,281 +1,281 @@
1
- import {
2
- DonationResponse,
3
- DonationRequest,
4
- DonationRequestCustomFields,
5
- DonationType,
6
- CustomerInfo,
7
- BillingInfo,
8
- DonationPaymentInfo,
9
- PaymentProvider,
10
- SuccessResponse,
11
- } from '@internetarchive/donation-form-data-models';
12
-
13
- import { PaymentProviders } from './payment-providers';
14
- import { PaymentClientsInterface } from './payment-clients';
15
- import {
16
- BraintreeManagerInterface,
17
- BraintreeEndpointManagerInterface,
18
- HostingEnvironment,
19
- BraintreeManagerEvents,
20
- } from './braintree-interfaces';
21
- import { HostedFieldConfiguration } from './payment-providers/credit-card/hosted-field-configuration';
22
- import { PromisedSingleton } from '@internetarchive/promised-singleton';
23
- import { PaymentProvidersInterface } from './payment-providers-interface';
24
- import { createNanoEvents, Unsubscribe } from 'nanoevents';
25
-
26
- /** @inheritdoc */
27
- export class BraintreeManager implements BraintreeManagerInterface {
28
- private referrer?: string;
29
-
30
- /**
31
- * The origin is made up of campaign / ABTest information that the user originated from.
32
- *
33
- * The field is a freeform string so it can be anything, but make sure it's something
34
- * identifiable so it can be queried in CiviCRM.
35
- *
36
- * For instance, we use this format for the Donation Banner:
37
- * - `{Source}-{Test Name}-{Variant Name}`, eg:
38
- * - `DonateBanner-Campaign Start 2020-IADefault`
39
- * - `DonateBanner-Mid Campaign-IAThermometer`
40
- *
41
- * For additional specificity, you could add additional info, ie.
42
- * - `DonateBanner-MidJuly2020 Campaign-VariantA-Button1`
43
- *
44
- * @private
45
- * @type {string}
46
- * @memberof BraintreeManager
47
- */
48
- private origin?: string;
49
-
50
- private loggedInUser?: string;
51
-
52
- /**
53
- * The Device Data token generated by the DataCollector.
54
- *
55
- * This gets submitted for several of the payment providers as an anti-fraud mechanism.
56
- *
57
- * @private
58
- * @type {string}
59
- * @memberof BraintreeManager
60
- */
61
- private deviceData?: string;
62
-
63
- private emitter = createNanoEvents<BraintreeManagerEvents>();
64
-
65
- on<E extends keyof BraintreeManagerEvents>(
66
- event: E,
67
- callback: BraintreeManagerEvents[E],
68
- ): Unsubscribe {
69
- return this.emitter.on(event, callback);
70
- }
71
-
72
- /** @inheritdoc */
73
- paymentProviders: PaymentProvidersInterface;
74
-
75
- /** @inheritdoc */
76
- async startup(): Promise<void> {
77
- return this.collectDeviceData();
78
- }
79
-
80
- /** @inheritdoc */
81
- instance = new PromisedSingleton<braintree.Client>({
82
- generator: async (): Promise<braintree.Client> => {
83
- const client = await this.paymentClients.braintreeClient.get();
84
- return client?.create({ authorization: this.authorizationToken });
85
- },
86
- });
87
-
88
- /** @inheritdoc */
89
- async submitDonation(options: {
90
- nonce: string;
91
- paymentProvider: PaymentProvider;
92
- donationInfo: DonationPaymentInfo;
93
- billingInfo: BillingInfo;
94
- customerInfo: CustomerInfo;
95
- upsellOnetimeTransactionId?: string;
96
- customerId?: string;
97
- recaptchaToken?: string;
98
- bin?: string; // first 6 digits of CC
99
- binName?: string; // credit card bank name
100
- }): Promise<DonationResponse> {
101
- const customFields = new DonationRequestCustomFields();
102
- customFields.fee_amount_covered = options.donationInfo.feeAmountCovered;
103
- customFields.logged_in_user = this.loggedInUser;
104
- customFields.referrer = this.referrer;
105
- customFields.origin = this.origin;
106
-
107
- // This is interesting and applies only to Venmo, but will work for other providers as well.
108
- // In Safari, `donationInfo` actually comes through as a DonationPaymentInfo object,
109
- // but in Chrome, it comes through as a plain object so you can't call `.total()` on it to
110
- // get the total amount and instead have to calculate the total
111
- const total = DonationPaymentInfo.calculateTotal(
112
- options.donationInfo.amount,
113
- options.donationInfo.coverFees,
114
- );
115
-
116
- const donationRequest = new DonationRequest({
117
- deviceData: this.deviceData,
118
- paymentProvider: options.paymentProvider,
119
- paymentMethodNonce: options.nonce,
120
- amount: total,
121
- donationType: options.donationInfo.donationType,
122
- customer: options.customerInfo,
123
- billing: options.billingInfo,
124
- customFields: customFields,
125
- upsellOnetimeTransactionId: options.upsellOnetimeTransactionId,
126
- customerId: options.customerId,
127
- recaptchaToken: options.recaptchaToken,
128
- bin: options.bin,
129
- binName: options.binName,
130
- });
131
-
132
- const jsonResponse = await this.endpointManager.submitData(donationRequest);
133
- const modeledResponse = new DonationResponse(jsonResponse);
134
- return modeledResponse;
135
- }
136
-
137
- /** @inheritdoc */
138
- async submitUpsellDonation(options: {
139
- oneTimeDonationResponse: SuccessResponse;
140
- amount: number;
141
- }): Promise<DonationResponse> {
142
- const response = options.oneTimeDonationResponse;
143
-
144
- const donationInfo = new DonationPaymentInfo({
145
- amount: options.amount,
146
- donationType: DonationType.Upsell,
147
- coverFees: false,
148
- });
149
-
150
- return this.submitDonation({
151
- nonce: response.paymentMethodNonce,
152
- paymentProvider: response.paymentProvider,
153
- customerId: response.customer_id,
154
- donationInfo: donationInfo,
155
- customerInfo: response.customer,
156
- billingInfo: response.billing,
157
- upsellOnetimeTransactionId: response.transaction_id,
158
- });
159
- }
160
-
161
- /** @inheritdoc */
162
- donationSuccessful(options: {
163
- successResponse: SuccessResponse;
164
- upsellSuccessResponse?: SuccessResponse;
165
- }): void {
166
- this.endpointManager.donationSuccessful(options);
167
- }
168
-
169
- private deviceDataCollectionStarted = false;
170
-
171
- /**
172
- * Collect Braintree device data. This is used to help fraud detection.
173
- *
174
- * @private
175
- * @returns {Promise<void>}
176
- * @memberof BraintreeManager
177
- */
178
- private async collectDeviceData(): Promise<void> {
179
- if (this.deviceDataCollectionStarted) {
180
- return;
181
- }
182
- this.deviceDataCollectionStarted = true;
183
-
184
- const instance = await this.instance.get();
185
- if (!instance) {
186
- return;
187
- }
188
-
189
- return this.paymentClients.dataCollector
190
- .get()
191
- .then((collector?: braintree.DataCollector) => {
192
- return collector?.create({ client: instance, kount: false, paypal: true });
193
- })
194
- .then(instance => {
195
- this.deviceData = instance?.deviceData;
196
- });
197
- }
198
-
199
- /**
200
- * Braintree Authorization Token
201
- *
202
- * @private
203
- * @type {string}
204
- * @memberof BraintreeManager
205
- */
206
- private authorizationToken: string;
207
-
208
- /**
209
- * The endpoint manager for network communications
210
- *
211
- * @private
212
- * @type {BraintreeEndpointManagerInterface}
213
- * @memberof BraintreeManager
214
- */
215
- private endpointManager: BraintreeEndpointManagerInterface;
216
-
217
- /**
218
- * The payment clients container containing the braintree, paypal, and google clients
219
- *
220
- * @private
221
- * @type {PaymentClientsInterface}
222
- * @memberof BraintreeManager
223
- */
224
- private paymentClients: PaymentClientsInterface;
225
-
226
- private hostingEnvironment: HostingEnvironment = HostingEnvironment.Development;
227
-
228
- constructor(options: {
229
- authorizationToken: string;
230
- paymentClients: PaymentClientsInterface;
231
- endpointManager: BraintreeEndpointManagerInterface;
232
- hostedFieldConfig: HostedFieldConfiguration;
233
- hostingEnvironment: HostingEnvironment;
234
- venmoProfileId?: string;
235
- googlePayMerchantId?: string;
236
- referrer?: string;
237
- loggedInUser?: string;
238
- origin?: string;
239
- }) {
240
- this.authorizationToken = options.authorizationToken;
241
- this.endpointManager = options.endpointManager;
242
- this.hostingEnvironment = options.hostingEnvironment;
243
- this.paymentClients = options.paymentClients;
244
-
245
- this.referrer = options.referrer;
246
- this.loggedInUser = options.loggedInUser;
247
- this.origin = options.origin;
248
-
249
- this.paymentProviders = new PaymentProviders({
250
- braintreeManager: this,
251
- paymentClients: this.paymentClients,
252
- venmoProfileId: options.venmoProfileId,
253
- googlePayMerchantId: options.googlePayMerchantId,
254
- hostingEnvironment: options.hostingEnvironment,
255
- hostedFieldConfig: options.hostedFieldConfig,
256
- });
257
-
258
- this.paymentProviders.on('hostedFieldsRetry', (retryNumber: number) => {
259
- this.emitter.emit('paymentProvidersHostedFieldsRetry', retryNumber);
260
- });
261
-
262
- this.paymentProviders.on('hostedFieldsFailed', (error: unknown) => {
263
- this.emitter.emit('paymentProvidersHostedFieldsFailed', error);
264
- });
265
- }
266
-
267
- /** @inheritdoc */
268
- setReferrer(referrer: string): void {
269
- this.referrer = referrer;
270
- }
271
-
272
- /** @inheritdoc */
273
- setLoggedInUser(loggedInUser: string): void {
274
- this.loggedInUser = loggedInUser;
275
- }
276
-
277
- /** @inheritdoc */
278
- setOrigin(origin: string): void {
279
- this.origin = origin;
280
- }
281
- }
1
+ import {
2
+ DonationResponse,
3
+ DonationRequest,
4
+ DonationRequestCustomFields,
5
+ DonationType,
6
+ CustomerInfo,
7
+ BillingInfo,
8
+ DonationPaymentInfo,
9
+ PaymentProvider,
10
+ SuccessResponse,
11
+ } from '@internetarchive/donation-form-data-models';
12
+
13
+ import { PaymentProviders } from './payment-providers';
14
+ import { PaymentClientsInterface } from './payment-clients';
15
+ import {
16
+ BraintreeManagerInterface,
17
+ BraintreeEndpointManagerInterface,
18
+ HostingEnvironment,
19
+ BraintreeManagerEvents,
20
+ } from './braintree-interfaces';
21
+ import { HostedFieldConfiguration } from './payment-providers/credit-card/hosted-field-configuration';
22
+ import { PromisedSingleton } from '@internetarchive/promised-singleton';
23
+ import { PaymentProvidersInterface } from './payment-providers-interface';
24
+ import { createNanoEvents, Unsubscribe } from 'nanoevents';
25
+
26
+ /** @inheritdoc */
27
+ export class BraintreeManager implements BraintreeManagerInterface {
28
+ private referrer?: string;
29
+
30
+ /**
31
+ * The origin is made up of campaign / ABTest information that the user originated from.
32
+ *
33
+ * The field is a freeform string so it can be anything, but make sure it's something
34
+ * identifiable so it can be queried in CiviCRM.
35
+ *
36
+ * For instance, we use this format for the Donation Banner:
37
+ * - `{Source}-{Test Name}-{Variant Name}`, eg:
38
+ * - `DonateBanner-Campaign Start 2020-IADefault`
39
+ * - `DonateBanner-Mid Campaign-IAThermometer`
40
+ *
41
+ * For additional specificity, you could add additional info, ie.
42
+ * - `DonateBanner-MidJuly2020 Campaign-VariantA-Button1`
43
+ *
44
+ * @private
45
+ * @type {string}
46
+ * @memberof BraintreeManager
47
+ */
48
+ private origin?: string;
49
+
50
+ private loggedInUser?: string;
51
+
52
+ /**
53
+ * The Device Data token generated by the DataCollector.
54
+ *
55
+ * This gets submitted for several of the payment providers as an anti-fraud mechanism.
56
+ *
57
+ * @private
58
+ * @type {string}
59
+ * @memberof BraintreeManager
60
+ */
61
+ private deviceData?: string;
62
+
63
+ private emitter = createNanoEvents<BraintreeManagerEvents>();
64
+
65
+ on<E extends keyof BraintreeManagerEvents>(
66
+ event: E,
67
+ callback: BraintreeManagerEvents[E],
68
+ ): Unsubscribe {
69
+ return this.emitter.on(event, callback);
70
+ }
71
+
72
+ /** @inheritdoc */
73
+ paymentProviders: PaymentProvidersInterface;
74
+
75
+ /** @inheritdoc */
76
+ async startup(): Promise<void> {
77
+ return this.collectDeviceData();
78
+ }
79
+
80
+ /** @inheritdoc */
81
+ instance = new PromisedSingleton<braintree.Client>({
82
+ generator: async (): Promise<braintree.Client> => {
83
+ const client = await this.paymentClients.braintreeClient.get();
84
+ return client?.create({ authorization: this.authorizationToken });
85
+ },
86
+ });
87
+
88
+ /** @inheritdoc */
89
+ async submitDonation(options: {
90
+ nonce: string;
91
+ paymentProvider: PaymentProvider;
92
+ donationInfo: DonationPaymentInfo;
93
+ billingInfo: BillingInfo;
94
+ customerInfo: CustomerInfo;
95
+ upsellOnetimeTransactionId?: string;
96
+ customerId?: string;
97
+ recaptchaToken?: string;
98
+ bin?: string; // first 6 digits of CC
99
+ binName?: string; // credit card bank name
100
+ }): Promise<DonationResponse> {
101
+ const customFields = new DonationRequestCustomFields();
102
+ customFields.fee_amount_covered = options.donationInfo.feeAmountCovered;
103
+ customFields.logged_in_user = this.loggedInUser;
104
+ customFields.referrer = this.referrer;
105
+ customFields.origin = this.origin;
106
+
107
+ // This is interesting and applies only to Venmo, but will work for other providers as well.
108
+ // In Safari, `donationInfo` actually comes through as a DonationPaymentInfo object,
109
+ // but in Chrome, it comes through as a plain object so you can't call `.total()` on it to
110
+ // get the total amount and instead have to calculate the total
111
+ const total = DonationPaymentInfo.calculateTotal(
112
+ options.donationInfo.amount,
113
+ options.donationInfo.coverFees,
114
+ );
115
+
116
+ const donationRequest = new DonationRequest({
117
+ deviceData: this.deviceData,
118
+ paymentProvider: options.paymentProvider,
119
+ paymentMethodNonce: options.nonce,
120
+ amount: total,
121
+ donationType: options.donationInfo.donationType,
122
+ customer: options.customerInfo,
123
+ billing: options.billingInfo,
124
+ customFields: customFields,
125
+ upsellOnetimeTransactionId: options.upsellOnetimeTransactionId,
126
+ customerId: options.customerId,
127
+ recaptchaToken: options.recaptchaToken,
128
+ bin: options.bin,
129
+ binName: options.binName,
130
+ });
131
+
132
+ const jsonResponse = await this.endpointManager.submitData(donationRequest);
133
+ const modeledResponse = new DonationResponse(jsonResponse);
134
+ return modeledResponse;
135
+ }
136
+
137
+ /** @inheritdoc */
138
+ async submitUpsellDonation(options: {
139
+ oneTimeDonationResponse: SuccessResponse;
140
+ amount: number;
141
+ }): Promise<DonationResponse> {
142
+ const response = options.oneTimeDonationResponse;
143
+
144
+ const donationInfo = new DonationPaymentInfo({
145
+ amount: options.amount,
146
+ donationType: DonationType.Upsell,
147
+ coverFees: false,
148
+ });
149
+
150
+ return this.submitDonation({
151
+ nonce: response.paymentMethodNonce,
152
+ paymentProvider: response.paymentProvider,
153
+ customerId: response.customer_id,
154
+ donationInfo: donationInfo,
155
+ customerInfo: response.customer,
156
+ billingInfo: response.billing,
157
+ upsellOnetimeTransactionId: response.transaction_id,
158
+ });
159
+ }
160
+
161
+ /** @inheritdoc */
162
+ donationSuccessful(options: {
163
+ successResponse: SuccessResponse;
164
+ upsellSuccessResponse?: SuccessResponse;
165
+ }): void {
166
+ this.endpointManager.donationSuccessful(options);
167
+ }
168
+
169
+ private deviceDataCollectionStarted = false;
170
+
171
+ /**
172
+ * Collect Braintree device data. This is used to help fraud detection.
173
+ *
174
+ * @private
175
+ * @returns {Promise<void>}
176
+ * @memberof BraintreeManager
177
+ */
178
+ private async collectDeviceData(): Promise<void> {
179
+ if (this.deviceDataCollectionStarted) {
180
+ return;
181
+ }
182
+ this.deviceDataCollectionStarted = true;
183
+
184
+ const instance = await this.instance.get();
185
+ if (!instance) {
186
+ return;
187
+ }
188
+
189
+ return this.paymentClients.dataCollector
190
+ .get()
191
+ .then((collector?: braintree.DataCollector) => {
192
+ return collector?.create({ client: instance, kount: false, paypal: true });
193
+ })
194
+ .then(instance => {
195
+ this.deviceData = instance?.deviceData;
196
+ });
197
+ }
198
+
199
+ /**
200
+ * Braintree Authorization Token
201
+ *
202
+ * @private
203
+ * @type {string}
204
+ * @memberof BraintreeManager
205
+ */
206
+ private authorizationToken: string;
207
+
208
+ /**
209
+ * The endpoint manager for network communications
210
+ *
211
+ * @private
212
+ * @type {BraintreeEndpointManagerInterface}
213
+ * @memberof BraintreeManager
214
+ */
215
+ private endpointManager: BraintreeEndpointManagerInterface;
216
+
217
+ /**
218
+ * The payment clients container containing the braintree, paypal, and google clients
219
+ *
220
+ * @private
221
+ * @type {PaymentClientsInterface}
222
+ * @memberof BraintreeManager
223
+ */
224
+ private paymentClients: PaymentClientsInterface;
225
+
226
+ private hostingEnvironment: HostingEnvironment = HostingEnvironment.Development;
227
+
228
+ constructor(options: {
229
+ authorizationToken: string;
230
+ paymentClients: PaymentClientsInterface;
231
+ endpointManager: BraintreeEndpointManagerInterface;
232
+ hostedFieldConfig: HostedFieldConfiguration;
233
+ hostingEnvironment: HostingEnvironment;
234
+ venmoProfileId?: string;
235
+ googlePayMerchantId?: string;
236
+ referrer?: string;
237
+ loggedInUser?: string;
238
+ origin?: string;
239
+ }) {
240
+ this.authorizationToken = options.authorizationToken;
241
+ this.endpointManager = options.endpointManager;
242
+ this.hostingEnvironment = options.hostingEnvironment;
243
+ this.paymentClients = options.paymentClients;
244
+
245
+ this.referrer = options.referrer;
246
+ this.loggedInUser = options.loggedInUser;
247
+ this.origin = options.origin;
248
+
249
+ this.paymentProviders = new PaymentProviders({
250
+ braintreeManager: this,
251
+ paymentClients: this.paymentClients,
252
+ venmoProfileId: options.venmoProfileId,
253
+ googlePayMerchantId: options.googlePayMerchantId,
254
+ hostingEnvironment: options.hostingEnvironment,
255
+ hostedFieldConfig: options.hostedFieldConfig,
256
+ });
257
+
258
+ this.paymentProviders.on('hostedFieldsRetry', (retryNumber: number) => {
259
+ this.emitter.emit('paymentProvidersHostedFieldsRetry', retryNumber);
260
+ });
261
+
262
+ this.paymentProviders.on('hostedFieldsFailed', (error: unknown) => {
263
+ this.emitter.emit('paymentProvidersHostedFieldsFailed', error);
264
+ });
265
+ }
266
+
267
+ /** @inheritdoc */
268
+ setReferrer(referrer: string): void {
269
+ this.referrer = referrer;
270
+ }
271
+
272
+ /** @inheritdoc */
273
+ setLoggedInUser(loggedInUser: string): void {
274
+ this.loggedInUser = loggedInUser;
275
+ }
276
+
277
+ /** @inheritdoc */
278
+ setOrigin(origin: string): void {
279
+ this.origin = origin;
280
+ }
281
+ }