@rebilly/instruments 3.25.1-beta.0 → 3.26.1-beta.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rebilly/instruments",
3
- "version": "3.25.1-beta.0",
3
+ "version": "3.26.1-beta.0",
4
4
  "author": "Rebilly",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -99,8 +99,8 @@ export async function makePurchase({ payload }) {
99
99
  export function handleApprovalUrl({fields, payload}) {
100
100
  if (payload.redirectUrl || !fields.transaction?.approvalUrl) {
101
101
  const { paymentMethodsUrl } = state.options._computed;
102
-
103
102
  const modelSafeFields = JSON.parse(JSON.stringify(fields));
103
+
104
104
  const model = {};
105
105
  if (state.data.isPayment) {
106
106
  model.payment = modelSafeFields;
@@ -5,6 +5,57 @@ import { Endpoint } from './index';
5
5
  import state from '../state';
6
6
  import { mapItemsQuantities } from '../utils/quantity';
7
7
 
8
+ export function filterReadyToPay(readyToPay) {
9
+ const paymentMethodsMetadata = [...paymentMethodsFile];
10
+ const EXPRESS_METHODS = [
11
+ 'Google Pay',
12
+ 'Apple Pay',
13
+ 'paypal',
14
+ ];
15
+ const BLOCKED_METHODS = [
16
+ // account number, routing number, and account type required
17
+ 'echeck',
18
+
19
+ // payment instrument is required
20
+ // card number is required
21
+ // card cvv is required
22
+ // expiration month is required
23
+ // expiration year is required
24
+ 'Khelocard',
25
+
26
+ // Klarna authorization token is required
27
+ // Klarna session ID is required
28
+ 'Klarna',
29
+ ];
30
+ const isExpressMethod = ({ method, feature }) => (
31
+ EXPRESS_METHODS.includes(method) ||
32
+ EXPRESS_METHODS.includes(feature?.name)
33
+ );
34
+ return readyToPay
35
+ .filter(readyData => {
36
+ // Remove result for "old" paypal method
37
+ const isOldPayPal = readyData.method === 'paypal' && !readyData.feature;
38
+ // Remove result for plaid method
39
+ const isPlaid = readyData.method === 'ach' && readyData.feature;
40
+ // Remove result for blocked method
41
+ const isBlocked = BLOCKED_METHODS.includes(readyData.method)
42
+
43
+ return !isOldPayPal && !isPlaid && !isBlocked
44
+ })
45
+ .map((fields, index) => {
46
+ const metadata = paymentMethodsMetadata
47
+ .find(methodMetadata => methodMetadata.apiName === fields.method) || {};
48
+ metadata.isExpressMethod = isExpressMethod(fields);
49
+
50
+ return new ReadyToPayModel({
51
+ index,
52
+ metadata,
53
+ ...fields
54
+ });
55
+ })
56
+ .filter(({metadata}) => metadata.storefrontEnabled);
57
+ }
58
+
8
59
  export async function fetchReadyToPay({
9
60
  riskMetadata = null,
10
61
  }) {
@@ -36,22 +87,7 @@ export async function fetchReadyToPay({
36
87
 
37
88
  const { fields: readyToPayFields } = await state.storefront.purchase.readyToPay({ data });
38
89
  const readyToPay = Object.values(readyToPayFields);
39
- const paymentMethodsMetadata = [...paymentMethodsFile];
40
-
41
- return readyToPay
42
- // Remove result for "old" paypal method
43
- .filter((fields) => !(fields.method === 'paypal' && !fields.feature))
44
- // Remove Plaid payment method
45
- .filter((fields) => !(fields.method === 'ach' && fields.feature))
46
- .map((fields, index) => {
47
- const metadata = paymentMethodsMetadata
48
- .find(methodMetadata => methodMetadata.apiName === fields.method);
49
-
50
- return new ReadyToPayModel({
51
- index,
52
- metadata,
53
- ...fields
54
- });
55
- });
90
+
91
+ return filterReadyToPay(readyToPay);
56
92
  });
57
93
  }
@@ -1,6 +1,4 @@
1
1
  import Postmate from 'popostmate';
2
- import { SUPPORTED_METHODS } from '../../method-selector/get-payment-methods';
3
- import { basicLoaderHTML } from '../../../loader';
4
2
 
5
3
  export default class BaseIframe {
6
4
  constructor({
@@ -48,10 +46,6 @@ export default class BaseIframe {
48
46
  },
49
47
  };
50
48
 
51
- if (SUPPORTED_METHODS.includes(this.name)) {
52
- this.container.insertAdjacentHTML('beforeend', basicLoaderHTML);
53
- }
54
-
55
49
  const component = await new Postmate({
56
50
  name: this.name,
57
51
  url: this.url,
@@ -60,6 +60,7 @@ export function clearError() {
60
60
  }
61
61
 
62
62
  export function showError(error) {
63
+ if (!error) return;
63
64
  const errorContainer = document.querySelector('#rebilly-instruments-error');
64
65
  if (!errorContainer) return ;
65
66
 
@@ -1,28 +1,5 @@
1
1
  import state from '../../state';
2
2
 
3
- // TODO: Express methods should be filtered from RTP some how
4
- export const SUPPORTED_EXPRESS_METHODS = [
5
- 'Google Pay',
6
- 'Apple Pay',
7
- 'paypal',
8
- ];
9
-
10
- // TODO: Supported methods should be aimed to be not needed
11
- // eventually moving to a BLOCKED_METHODS
12
- export const SUPPORTED_METHODS = [
13
- 'payment-card',
14
- 'ach',
15
- 'cryptocurrency',
16
- 'bitcoin'
17
- ];
18
-
19
- const isExpressMethod = ({ method, feature }) => (
20
- SUPPORTED_EXPRESS_METHODS.includes(method) ||
21
- SUPPORTED_EXPRESS_METHODS.includes(feature?.name)
22
- );
23
-
24
- const isSupportedMethod = ({ method }) => SUPPORTED_METHODS.includes(method);
25
-
26
3
  export function getPaymentMethods() {
27
4
  const result = {
28
5
  EXPRESS_METHODS: [],
@@ -30,9 +7,9 @@ export function getPaymentMethods() {
30
7
  };
31
8
 
32
9
  state.data.readyToPay?.forEach((method) => {
33
- if (isExpressMethod(method)) {
10
+ if (method.metadata.isExpressMethod) {
34
11
  result.EXPRESS_METHODS.push(method);
35
- } else if (isSupportedMethod(method)) {
12
+ } else {
36
13
  result.METHODS.push(method);
37
14
  }
38
15
  });
@@ -1,31 +1,35 @@
1
+ import { StorefontTestingInstance } from 'tests/mocks/storefront-mock';
1
2
  import { getPaymentMethods } from './get-payment-methods';
2
- import ReadyToPayModel from '@/storefront/models/ready-to-pay-model';
3
+ import { ok, post } from 'msw-when-then';
4
+ import { when } from 'tests/msw/server';
5
+ import { storefrontURL } from 'tests/mocks/storefront-api-mock';
6
+ import { fetchReadyToPay } from '../../storefront/ready-to-pay';
3
7
  import state from 'src/state';
4
8
 
5
- it('should only return the allowed methods', () => {
6
- state.data = {
7
- readyToPay: [
8
- new ReadyToPayModel({
9
- method: 'payment-card',
10
- feature: {
11
- name: 'Google Pay',
12
- merchantName: 'google-pay-merchant-name',
13
- merchantOrigin: 'google-pay-merchant-origin'
14
- },
15
- brands: ['Visa'],
16
- filters: []
17
- }),
18
- new ReadyToPayModel({
19
- method: 'fake-method',
20
- filters: []
21
- }),
22
- new ReadyToPayModel({
23
- method: 'payment-card',
24
- brands: ['Visa'],
25
- filters: []
26
- })
27
- ]
28
- }
9
+ it('should only return the allowed methods', async () => {
10
+ StorefontTestingInstance();
11
+ when(
12
+ post(`${storefrontURL}/ready-to-pay`)
13
+ ).thenReturn(
14
+ ok([{
15
+ method: 'payment-card',
16
+ feature: {
17
+ name: 'Google Pay',
18
+ merchantName: 'google-pay-merchant-name',
19
+ merchantOrigin: 'google-pay-merchant-origin'
20
+ },
21
+ brands: ['Visa'],
22
+ filters: []
23
+ }, {
24
+ method: 'fake-method',
25
+ filters: []
26
+ }, {
27
+ method: 'payment-card',
28
+ brands: ['Visa'],
29
+ filters: []
30
+ }])
31
+ );
32
+ state.data.readyToPay = await fetchReadyToPay({});
29
33
 
30
34
  const results = getPaymentMethods();
31
35
  expect(results.hasOwnProperty('EXPRESS_METHODS')).toEqual(true);
@@ -113,6 +113,7 @@ export async function mountMethodSelector() {
113
113
 
114
114
  iframes.form = iframe;
115
115
  } else {
116
+ state.loader.stopLoading({id: 'rebilly-instruments-form'});
116
117
  METHODS_CONTAINER.style.display = 'none';
117
118
  document.querySelectorAll('[data-rebilly-instruments="divider"]')
118
119
  .forEach(el => { el.style.display = 'none' });