@rebilly/framepay-react 2.0.1 → 2.1.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 (79) hide show
  1. package/.env.example +2 -0
  2. package/CHANGELOG.md +7 -0
  3. package/env.js +7 -0
  4. package/package.json +10 -2
  5. package/src/index.spec.ts +19 -0
  6. package/src/index.ts +42 -0
  7. package/src/lib/components/elements/applepay-element.tsx +36 -0
  8. package/src/lib/components/elements/bank-element.spec.tsx +119 -0
  9. package/src/lib/components/elements/bank-element.tsx +74 -0
  10. package/src/lib/components/elements/base-element.tsx +100 -0
  11. package/src/lib/components/elements/card-element.spec.tsx +113 -0
  12. package/src/lib/components/elements/card-element.tsx +73 -0
  13. package/src/lib/components/elements/googlepay-element.tsx +36 -0
  14. package/src/lib/components/elements/iban-element.spec.tsx +104 -0
  15. package/src/lib/components/elements/iban-element.tsx +75 -0
  16. package/src/lib/components/elements/paypal-element.tsx +36 -0
  17. package/src/lib/components/injector.spec.tsx +162 -0
  18. package/src/lib/components/injector.tsx +495 -0
  19. package/src/lib/components/provider.spec.tsx +98 -0
  20. package/src/lib/components/provider.tsx +111 -0
  21. package/src/lib/constants.ts +43 -0
  22. package/src/lib/context.ts +24 -0
  23. package/src/lib/dom-util.ts +35 -0
  24. package/src/lib/framepay-error.ts +59 -0
  25. package/src/lib/get-rebilly-api.ts +11 -0
  26. package/test/e2e/assets/prop-types.js +849 -0
  27. package/test/e2e/assets/react-0.14.0.js +18759 -0
  28. package/test/e2e/assets/react-15.0.0.js +19309 -0
  29. package/test/e2e/assets/react-16.js +3318 -0
  30. package/test/e2e/assets/react-17.js +3357 -0
  31. package/test/e2e/assets/react-18.js +3342 -0
  32. package/test/e2e/assets/react-dom-0.14.0.js +42 -0
  33. package/test/e2e/assets/react-dom-15.0.0.js +42 -0
  34. package/test/e2e/assets/react-dom-16.js +25147 -0
  35. package/test/e2e/assets/react-dom-17.js +26292 -0
  36. package/test/e2e/assets/react-dom-18.js +29869 -0
  37. package/test/e2e/cypress-support.js +2 -0
  38. package/test/e2e/cypress.d.ts +1 -0
  39. package/test/e2e/fixtures/apple-pay.html +15 -0
  40. package/test/e2e/fixtures/apple-pay.js +63 -0
  41. package/test/e2e/fixtures/bank-separate.html +12 -0
  42. package/test/e2e/fixtures/bank-separate.js +323 -0
  43. package/test/e2e/fixtures/card-separate-brands.html +12 -0
  44. package/test/e2e/fixtures/card-separate-brands.js +260 -0
  45. package/test/e2e/fixtures/card-separate-rebilly-fields.html +12 -0
  46. package/test/e2e/fixtures/card-separate-rebilly-fields.js +281 -0
  47. package/test/e2e/fixtures/card-separate.html +12 -0
  48. package/test/e2e/fixtures/card-separate.js +227 -0
  49. package/test/e2e/fixtures/checkout-combined.html +12 -0
  50. package/test/e2e/fixtures/checkout-combined.js +199 -0
  51. package/test/e2e/fixtures/google-pay.html +15 -0
  52. package/test/e2e/fixtures/google-pay.js +63 -0
  53. package/test/e2e/fixtures/iban.html +12 -0
  54. package/test/e2e/fixtures/iban.js +239 -0
  55. package/test/e2e/fixtures/multiple-methods.html +12 -0
  56. package/test/e2e/fixtures/multiple-methods.js +470 -0
  57. package/test/e2e/fixtures/nav.js +20 -0
  58. package/test/e2e/fixtures/paypal.html +15 -0
  59. package/test/e2e/fixtures/paypal.js +62 -0
  60. package/test/e2e/fixtures/style.css +55 -0
  61. package/test/e2e/fixtures/util.js +71 -0
  62. package/test/e2e/local-server.mjs +12 -0
  63. package/test/e2e/server.mjs +43 -0
  64. package/test/e2e/specs/bank-separate.cy.ts +27 -0
  65. package/test/e2e/specs/card-separate-brands.cy.ts +70 -0
  66. package/test/e2e/specs/card-separate.cy.ts +27 -0
  67. package/test/e2e/specs/checkout-combined.cy.ts +24 -0
  68. package/test/e2e/specs/google-pay.cy.ts +13 -0
  69. package/test/e2e/specs/iban.cy.ts +17 -0
  70. package/test/e2e/specs/multiple-methods.cy.ts +130 -0
  71. package/test/e2e/specs/paypal.cy.ts +13 -0
  72. package/test/e2e/specs/react-version.cy.ts +12 -0
  73. package/test/e2e/switch-react-version.js +42 -0
  74. package/test/e2e/tsconfig.json +8 -0
  75. package/test/unit/jest.config.js +29 -0
  76. package/test/unit/specs/declaration-mock.spec.tsx +143 -0
  77. package/tsconfig.json +31 -0
  78. package/tsconfig.spec.json +13 -0
  79. package/tslint.json +36 -0
@@ -0,0 +1,495 @@
1
+ // tslint:disable:max-classes-per-file
2
+
3
+ import * as React from 'react';
4
+ import { ContextConsumer } from '../context';
5
+ import ApplePayElementComponent from './elements/applepay-element';
6
+ import BankElementComponent from './elements/bank-element';
7
+ import CardElementComponent from './elements/card-element';
8
+ import GooglePayElementComponent from './elements/googlepay-element';
9
+ import IBANElementComponent from './elements/iban-element';
10
+ import PaypalElementComponent from './elements/paypal-element';
11
+
12
+ import {
13
+ FramePayApplePayProps,
14
+ FramePayBankProps,
15
+ FramePayCardProps,
16
+ FramePayComponentProps,
17
+ FramePayGooglePayProps,
18
+ FramePayIBANProps,
19
+ FramePayPaypalProps
20
+ } from '../../../types/injector';
21
+
22
+ const makeRebillyProps = (data: FramePayContext): RebillyProps =>
23
+ Object.assign(Object.create(data.api || {}), {
24
+ error: data.error,
25
+ ready: data.ready
26
+ }) as RebillyProps;
27
+
28
+ function Hoc<P extends object>(
29
+ name: string,
30
+ WrappedComponent: React.ComponentType<P>,
31
+ provider: (data: FramePayContext) => object
32
+ ) {
33
+ return class extends React.Component<P, {}> {
34
+ static readonly displayName = `withFramePay${name}(${WrappedComponent.displayName ||
35
+ WrappedComponent.name ||
36
+ 'Component'})`;
37
+
38
+ render() {
39
+ return (
40
+ <ContextConsumer>
41
+ {(data: FramePayContext) => {
42
+ const provided = provider(data);
43
+ return (
44
+ <WrappedComponent
45
+ {...{ ...this.props, ...provided }}
46
+ />
47
+ );
48
+ }}
49
+ </ContextConsumer>
50
+ );
51
+ }
52
+ };
53
+ }
54
+
55
+ /**
56
+ * Returns the PaymentElementWrapper elements.
57
+ *
58
+ * @param type {string} PaymentElements
59
+ */
60
+ const elementsFabric = (type: PaymentElements): object => {
61
+ if (type === 'iban') {
62
+ /**
63
+ * IBAN
64
+ */
65
+
66
+ /**
67
+ * IBAN number element
68
+ */
69
+ const IBANElement = Hoc(
70
+ 'IBANElement',
71
+ IBANElementComponent,
72
+ (data: FramePayContext) =>
73
+ ({
74
+ Rebilly: makeRebillyProps(data),
75
+ elementType: 'iban'
76
+ } as IBANProps)
77
+ );
78
+
79
+ return {
80
+ IBANElement
81
+ };
82
+ }
83
+
84
+ if (type === 'bankAccount') {
85
+ /**
86
+ * BankAccount
87
+ * @see https://rebilly.github.io/framepay-docs/reference/rebilly.html#rebilly-bankaccount-mount
88
+ */
89
+
90
+ /**
91
+ * Bank AccountType Element
92
+ */
93
+ const BankAccountTypeElement = Hoc(
94
+ 'BankAccountTypeElement',
95
+ BankElementComponent,
96
+ (data: FramePayContext) =>
97
+ ({
98
+ Rebilly: makeRebillyProps(data),
99
+ elementType: 'bankAccountType'
100
+ } as BankProps)
101
+ );
102
+
103
+ /**
104
+ * BankRoutingNumber Element
105
+ */
106
+ const BankRoutingNumberElement = Hoc(
107
+ 'BankRoutingNumberElement',
108
+ BankElementComponent,
109
+ (data: FramePayContext) =>
110
+ ({
111
+ Rebilly: makeRebillyProps(data),
112
+ elementType: 'bankRoutingNumber'
113
+ } as BankProps)
114
+ );
115
+
116
+ /**
117
+ * Bank AccountNumber Element
118
+ */
119
+ const BankAccountNumberElement = Hoc(
120
+ 'BankAccountNumberElement',
121
+ BankElementComponent,
122
+ (data: FramePayContext) =>
123
+ ({
124
+ Rebilly: makeRebillyProps(data),
125
+ elementType: 'bankAccountNumber'
126
+ } as BankProps)
127
+ );
128
+
129
+ return {
130
+ BankAccountNumberElement,
131
+ BankAccountTypeElement,
132
+ BankRoutingNumberElement
133
+ };
134
+ }
135
+
136
+ if (type === 'card') {
137
+ /**
138
+ * Default Card Element
139
+ * @see https://rebilly.github.io/framepay-docs/reference/rebilly.html#rebilly-card-mount
140
+ */
141
+ const CardElement = Hoc(
142
+ 'CardElement',
143
+ CardElementComponent,
144
+ (data: FramePayContext) =>
145
+ ({
146
+ Rebilly: makeRebillyProps(data)
147
+ } as CardProps)
148
+ );
149
+
150
+ /**
151
+ * Card CVV Element
152
+ */
153
+ const CardCvvElement = Hoc(
154
+ 'CardCvvElement',
155
+ CardElementComponent,
156
+ (data: FramePayContext) =>
157
+ ({
158
+ Rebilly: makeRebillyProps(data),
159
+ elementType: 'cardCvv'
160
+ } as CardProps)
161
+ );
162
+
163
+ /**
164
+ * Card Expiry Element
165
+ */
166
+ const CardExpiryElement = Hoc(
167
+ 'CardExpiryElement',
168
+ CardElementComponent,
169
+ (data: FramePayContext) =>
170
+ ({
171
+ Rebilly: makeRebillyProps(data),
172
+ elementType: 'cardExpiry'
173
+ } as CardProps)
174
+ );
175
+
176
+ /**
177
+ * Card Number Element
178
+ */
179
+ const CardNumberElement = Hoc(
180
+ 'CardNumberElement',
181
+ CardElementComponent,
182
+ (data: FramePayContext) =>
183
+ ({
184
+ Rebilly: makeRebillyProps(data),
185
+ elementType: 'cardNumber'
186
+ } as CardProps)
187
+ );
188
+
189
+ return {
190
+ CardCvvElement,
191
+ CardElement,
192
+ CardExpiryElement,
193
+ CardNumberElement
194
+ };
195
+ }
196
+
197
+ if (type === 'applePay') {
198
+ /**
199
+ * Apple Pay
200
+ */
201
+
202
+ const ApplePayElement = Hoc(
203
+ 'ApplePayElement',
204
+ ApplePayElementComponent,
205
+ (data: FramePayContext) =>
206
+ ({
207
+ Rebilly: makeRebillyProps(data)
208
+ } as ApplePayProps)
209
+ );
210
+
211
+ return {
212
+ ApplePayElement
213
+ };
214
+ }
215
+
216
+ if (type === 'googlePay') {
217
+ /**
218
+ * Google Pay
219
+ */
220
+
221
+ const GooglePayElement = Hoc(
222
+ 'GooglePayElement',
223
+ GooglePayElementComponent,
224
+ (data: FramePayContext) =>
225
+ ({
226
+ Rebilly: makeRebillyProps(data)
227
+ } as GooglePayProps)
228
+ );
229
+
230
+ return {
231
+ GooglePayElement
232
+ };
233
+ }
234
+
235
+ if (type === 'paypal') {
236
+ /**
237
+ * Paypal
238
+ */
239
+
240
+ const PaypalElement = Hoc(
241
+ 'PaypalElement',
242
+ PaypalElementComponent,
243
+ (data: FramePayContext) =>
244
+ ({
245
+ Rebilly: makeRebillyProps(data)
246
+ } as PaypalProps)
247
+ );
248
+
249
+ return {
250
+ PaypalElement
251
+ };
252
+ }
253
+
254
+ /**
255
+ * Throw the error by default.
256
+ */
257
+ throw new Error(
258
+ `Invalid PaymentMethod type, see PaymentMethodTypes declaration`
259
+ );
260
+ };
261
+
262
+ export function withFramePay<OriginalProps extends object>(
263
+ WrappedComponent: React.ComponentType<
264
+ OriginalProps & FramePayComponentProps
265
+ >
266
+ ) {
267
+ const elements = {
268
+ ...elementsFabric('card'),
269
+ ...elementsFabric('bankAccount'),
270
+ ...elementsFabric('iban'),
271
+ ...elementsFabric('applePay'),
272
+ ...elementsFabric('googlePay'),
273
+ ...elementsFabric('paypal')
274
+ };
275
+ return class extends React.Component<
276
+ OriginalProps & FramePayComponentProps,
277
+ {}
278
+ > {
279
+ static readonly displayName = `withFramePay${name}(${WrappedComponent.displayName ||
280
+ WrappedComponent.name ||
281
+ 'Component'})`;
282
+
283
+ render() {
284
+ return (
285
+ <ContextConsumer>
286
+ {(data: FramePayContext) => {
287
+ return (
288
+ <WrappedComponent
289
+ {...{
290
+ ...this.props,
291
+ ...elements,
292
+ Rebilly: makeRebillyProps(data)
293
+ }}
294
+ />
295
+ );
296
+ }}
297
+ </ContextConsumer>
298
+ );
299
+ }
300
+ };
301
+ }
302
+
303
+ export function withFramePayCardComponent<OriginalProps extends object>(
304
+ WrappedComponent: React.ComponentType<OriginalProps & FramePayCardProps>
305
+ ) {
306
+ const elements = elementsFabric('card');
307
+ return class extends React.Component<
308
+ OriginalProps & FramePayCardProps,
309
+ {}
310
+ > {
311
+ static readonly displayName = `withFramePayCardComponent${name}(${WrappedComponent.displayName ||
312
+ WrappedComponent.name ||
313
+ 'Component'})`;
314
+
315
+ render() {
316
+ return (
317
+ <ContextConsumer>
318
+ {(data: FramePayContext) => {
319
+ return (
320
+ <WrappedComponent
321
+ {...{
322
+ ...this.props,
323
+ ...elements,
324
+ Rebilly: makeRebillyProps(data)
325
+ }}
326
+ />
327
+ );
328
+ }}
329
+ </ContextConsumer>
330
+ );
331
+ }
332
+ };
333
+ }
334
+
335
+ export function withFramePayBankComponent<OriginalProps extends object>(
336
+ WrappedComponent: React.ComponentType<OriginalProps & FramePayBankProps>
337
+ ) {
338
+ const elements = elementsFabric('bankAccount');
339
+ return class extends React.Component<
340
+ OriginalProps & FramePayBankProps,
341
+ {}
342
+ > {
343
+ static readonly displayName = `withFramePayBankComponent${name}(${WrappedComponent.displayName ||
344
+ WrappedComponent.name ||
345
+ 'Component'})`;
346
+
347
+ render() {
348
+ return (
349
+ <ContextConsumer>
350
+ {(data: FramePayContext) => {
351
+ return (
352
+ <WrappedComponent
353
+ {...{
354
+ ...this.props,
355
+ ...elements,
356
+ Rebilly: makeRebillyProps(data)
357
+ }}
358
+ />
359
+ );
360
+ }}
361
+ </ContextConsumer>
362
+ );
363
+ }
364
+ };
365
+ }
366
+
367
+ export function withFramePayIBANComponent<OriginalProps extends object>(
368
+ WrappedComponent: React.ComponentType<OriginalProps & FramePayIBANProps>
369
+ ) {
370
+ const elements = elementsFabric('iban');
371
+ return class extends React.Component<
372
+ OriginalProps & FramePayIBANProps,
373
+ {}
374
+ > {
375
+ static readonly displayName = `withFramePayIBANComponent${name}(${WrappedComponent.displayName ||
376
+ WrappedComponent.name ||
377
+ 'Component'})`;
378
+
379
+ render() {
380
+ return (
381
+ <ContextConsumer>
382
+ {(data: FramePayContext) => {
383
+ return (
384
+ <WrappedComponent
385
+ {...{
386
+ ...this.props,
387
+ ...elements,
388
+ Rebilly: makeRebillyProps(data)
389
+ }}
390
+ />
391
+ );
392
+ }}
393
+ </ContextConsumer>
394
+ );
395
+ }
396
+ };
397
+ }
398
+
399
+ export function withFramePayApplePayComponent<OriginalProps extends object>(
400
+ WrappedComponent: React.ComponentType<OriginalProps & FramePayApplePayProps>
401
+ ) {
402
+ const elements = elementsFabric('applePay');
403
+ return class extends React.Component<
404
+ OriginalProps & FramePayApplePayProps,
405
+ {}
406
+ > {
407
+ static readonly displayName = `withFramePayApplePayComponent${name}(${WrappedComponent.displayName ||
408
+ WrappedComponent.name ||
409
+ 'Component'})`;
410
+
411
+ render() {
412
+ return (
413
+ <ContextConsumer>
414
+ {(data: FramePayContext) => {
415
+ return (
416
+ <WrappedComponent
417
+ {...{
418
+ ...this.props,
419
+ ...elements,
420
+ Rebilly: makeRebillyProps(data)
421
+ }}
422
+ />
423
+ );
424
+ }}
425
+ </ContextConsumer>
426
+ );
427
+ }
428
+ };
429
+ }
430
+
431
+ export function withFramePayGooglePayComponent<OriginalProps extends object>(
432
+ WrappedComponent: React.ComponentType<
433
+ OriginalProps & FramePayGooglePayProps
434
+ >
435
+ ) {
436
+ const elements = elementsFabric('googlePay');
437
+ return class extends React.Component<
438
+ OriginalProps & FramePayGooglePayProps,
439
+ {}
440
+ > {
441
+ static readonly displayName = `withFramePayGooglePayComponent${name}(${WrappedComponent.displayName ||
442
+ WrappedComponent.name ||
443
+ 'Component'})`;
444
+
445
+ render() {
446
+ return (
447
+ <ContextConsumer>
448
+ {(data: FramePayContext) => {
449
+ return (
450
+ <WrappedComponent
451
+ {...{
452
+ ...this.props,
453
+ ...elements,
454
+ Rebilly: makeRebillyProps(data)
455
+ }}
456
+ />
457
+ );
458
+ }}
459
+ </ContextConsumer>
460
+ );
461
+ }
462
+ };
463
+ }
464
+
465
+ export function withFramePayPaypalComponent<OriginalProps extends object>(
466
+ WrappedComponent: React.ComponentType<OriginalProps & FramePayPaypalProps>
467
+ ) {
468
+ const elements = elementsFabric('paypal');
469
+ return class extends React.Component<
470
+ OriginalProps & FramePayPaypalProps,
471
+ {}
472
+ > {
473
+ static readonly displayName = `withFramePayPaypalComponent${name}(${WrappedComponent.displayName ||
474
+ WrappedComponent.name ||
475
+ 'Component'})`;
476
+
477
+ render() {
478
+ return (
479
+ <ContextConsumer>
480
+ {(data: FramePayContext) => {
481
+ return (
482
+ <WrappedComponent
483
+ {...{
484
+ ...this.props,
485
+ ...elements,
486
+ Rebilly: makeRebillyProps(data)
487
+ }}
488
+ />
489
+ );
490
+ }}
491
+ </ContextConsumer>
492
+ );
493
+ }
494
+ };
495
+ }
@@ -0,0 +1,98 @@
1
+ // tslint:disable:max-classes-per-file
2
+
3
+ import { render } from '@testing-library/react';
4
+ import * as React from 'react';
5
+ import { FRAMEPAY_SCRIPT_LINK, FRAMEPAY_STYLE_LINK } from '../constants';
6
+ import Provider from './provider';
7
+
8
+ describe('Provider', () => {
9
+ it('should add the FramePay script on the page', () => {
10
+ const props = { publishableKey: 'pk_sandbox_1234567890' };
11
+
12
+ class ChildComponent extends React.Component {
13
+ render() {
14
+ return <div>child</div>;
15
+ }
16
+ }
17
+
18
+ expect(document.head.innerHTML).not.toContain(FRAMEPAY_SCRIPT_LINK);
19
+
20
+ render(
21
+ <Provider {...props}>
22
+ <ChildComponent />
23
+ </Provider>
24
+ );
25
+ expect(document.head.innerHTML).toContain(FRAMEPAY_SCRIPT_LINK);
26
+ });
27
+
28
+ it('should add the FramePay styles on the page', () => {
29
+ const props = {
30
+ injectStyle: true,
31
+ publishableKey: 'pk_sandbox_1234567890'
32
+ };
33
+
34
+ class ChildComponent extends React.Component {
35
+ render() {
36
+ return <div>child</div>;
37
+ }
38
+ }
39
+
40
+ expect(document.head.innerHTML).not.toContain(FRAMEPAY_STYLE_LINK);
41
+ render(
42
+ <Provider {...props}>
43
+ <ChildComponent />
44
+ </Provider>
45
+ );
46
+ expect(document.head.innerHTML).toContain(FRAMEPAY_STYLE_LINK);
47
+ });
48
+
49
+ it('should render with single child component', () => {
50
+ const props = { publishableKey: 'pk_sandbox_1234567890' };
51
+
52
+ class ChildComponent extends React.Component {
53
+ render() {
54
+ return <div>child</div>;
55
+ }
56
+ }
57
+
58
+ const { container } = render(
59
+ <Provider {...props}>
60
+ <ChildComponent />
61
+ </Provider>
62
+ );
63
+ expect(container.firstChild).toMatchInlineSnapshot(`
64
+ <div>
65
+ child
66
+ </div>
67
+ `);
68
+ });
69
+
70
+ it('should render with multiple child components', () => {
71
+ const props = { publishableKey: 'pk_sandbox_1234567890' };
72
+
73
+ class ChildComponent extends React.Component<{
74
+ readonly title: string;
75
+ }> {
76
+ render() {
77
+ return <div>{this.props.title}</div>;
78
+ }
79
+ }
80
+
81
+ const { container } = render(
82
+ <Provider {...props}>
83
+ <ChildComponent title="child-1" />
84
+ <ChildComponent title="child-2" />
85
+ </Provider>
86
+ );
87
+ expect(container).toMatchInlineSnapshot(`
88
+ <div>
89
+ <div>
90
+ child-1
91
+ </div>
92
+ <div>
93
+ child-2
94
+ </div>
95
+ </div>
96
+ `);
97
+ });
98
+ });
@@ -0,0 +1,111 @@
1
+ import * as React from 'react';
2
+ import { FRAMEPAY_SCRIPT_LINK } from '../constants';
3
+ import { ContextProvider } from '../context';
4
+ import { injectScript, injectStyle } from '../dom-util';
5
+ import FramePayError from '../framepay-error';
6
+ import getRebillyApi from '../get-rebilly-api';
7
+
8
+ export default class Provider extends React.Component<
9
+ ProviderProps,
10
+ FramePayContext
11
+ > {
12
+ static readonly defaultProps = {
13
+ injectScript: true,
14
+ injectStyle: false,
15
+ onError: () => ({}),
16
+ onReady: () => ({}),
17
+ onTokenReady: () => ({})
18
+ };
19
+
20
+ readonly state: FramePayContext = {
21
+ api: getRebillyApi(),
22
+ error: null,
23
+ ready: false
24
+ };
25
+
26
+ componentDidMount() {
27
+ if (this.props.injectScript) {
28
+ injectScript({
29
+ onError: () => this.onApiError(),
30
+ onReady: () => this.onApiReady()
31
+ });
32
+ }
33
+ if (this.props.injectStyle) {
34
+ injectStyle();
35
+ }
36
+ }
37
+
38
+ onApiError() {
39
+ return this.setState(
40
+ {
41
+ error: FramePayError.codes.remoteScriptError,
42
+ ready: false
43
+ },
44
+ () => {
45
+ const error = FramePayError({
46
+ code: FramePayError.codes.remoteScriptError,
47
+ details: `Remote CDN link "${FRAMEPAY_SCRIPT_LINK}"`
48
+ });
49
+ throw error;
50
+ }
51
+ );
52
+ }
53
+
54
+ async onApiReady() {
55
+ const api = getRebillyApi();
56
+ try {
57
+ // tslint:disable:no-shadowed-variable
58
+ const { injectStyle, children, ...settings } = this.props;
59
+ // tslint:enable:no-shadowed-variable
60
+ api.initialize(settings);
61
+ api.on('ready', () => {
62
+ this.setState({ ready: true, api, error: null });
63
+
64
+ // call onReady callback
65
+ if (this.props.onReady) {
66
+ this.props.onReady();
67
+ }
68
+ });
69
+ api.on('error', error => {
70
+ this.setState({
71
+ api,
72
+ error: (error as any).code,
73
+ ready: false
74
+ });
75
+
76
+ // call error callback
77
+ if (this.props.onError) {
78
+ // @ts-ignore
79
+ this.props.onError(error);
80
+ }
81
+ });
82
+ api.on('token-ready', token => {
83
+ if (this.props.onTokenReady) {
84
+ this.props.onTokenReady(token);
85
+ }
86
+ });
87
+ } catch (e) {
88
+ return this.setState(
89
+ {
90
+ error: FramePayError.codes.initializeError,
91
+ ready: false
92
+ },
93
+ () => {
94
+ throw FramePayError({
95
+ code: FramePayError.codes.initializeError,
96
+ details: 'Api initialize error',
97
+ trace: e
98
+ });
99
+ }
100
+ );
101
+ }
102
+ }
103
+
104
+ render() {
105
+ return (
106
+ <ContextProvider value={this.state}>
107
+ {this.props.children}
108
+ </ContextProvider>
109
+ );
110
+ }
111
+ }