Skip to content

Commit

Permalink
Merge pull request #254 from hyva-themes/custom-payment-renderers-imp…
Browse files Browse the repository at this point in the history
…rovement

Custom payment renderers integration improvement
  • Loading branch information
rajeev-k-tomy committed Jan 14, 2022
2 parents 648eba8 + 447e9c9 commit c589f8b
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 133 deletions.
93 changes: 35 additions & 58 deletions src/reactapp/scripts/configurePaymentMethods.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,7 @@
const util = require('util');
const exec = util.promisify(require('child_process').exec);
const fs = require('fs');
const util = require('./utility');

const paymentMethodDir = 'src/paymentMethods';

async function installRepo(directory, repoUri) {
console.log(`installing ${directory}: ${repoUri}`);
const { stdout, stderr } = await exec(
`cd ${paymentMethodDir} && git clone ${repoUri} ${directory} && cd .. && cd ..`
);
console.log(`${directory} payment method added successfully.`);
}

function collectPaymentMethodReposFromEnv() {
const { env } = process;
const paymentRepoConfigPrefix = 'npm_package_config_paymentMethodsRepo_';
const paymentRepos = {};

Object.keys(env).forEach(envProp => {
if (envProp.startsWith(paymentRepoConfigPrefix)) {
const paymentCode = envProp.replace(paymentRepoConfigPrefix, '');
if (paymentCode) {
paymentRepos[paymentCode] = env[envProp];
}
}
});

return paymentRepos;
}

async function cloneAndConfigurePaymentRepos(paymentRepos) {
const paymentMethodList = Object.keys(paymentRepos);

await Promise.all(
paymentMethodList.map(async paymentMethod => {
if (!fs.existsSync(`${paymentMethodDir}/${paymentMethod}`)) {
await installRepo(paymentMethod, paymentRepos[paymentMethod]);
}
return 'success';
})
);
}
const paymentDirectoryPath = './src/paymentMethods/';

/**
* Setting up custom payment methods into the react app section
Expand All @@ -49,28 +10,44 @@ async function cloneAndConfigurePaymentRepos(paymentRepos) {
* `config.paymentMethodsRepo` section in package.json file into the
* `src/paymentMethods`
*
* It will also populate `src/paymentMethods/paymentConfig.json` file with the
* available payment methods details. This will be used by the react app to
* correctly configure the custom payment methods into the app.
* It will also populate `src/paymentMethods/customRenderers.js` which can be
* used to port custom payment renderers into the react app.
*/
module.exports = (async () => {
if (!fs.existsSync(paymentMethodDir)) {
console.warn(
`${paymentMethodDir} directory is not present. Cannot proceed with payment methods setup`
);
return;
}

const paymentRepos = collectPaymentMethodReposFromEnv();
const paymentRepos = util.collectConfiguredReposFromEnv('paymentMethodsRepo');
const paymentMethodList = Object.keys(paymentRepos);

await cloneAndConfigurePaymentRepos(paymentRepos);

// write down available payment methods into `src/paymentMethods/paymentConfig.json`
fs.writeFileSync(
`${paymentMethodDir}/paymentConfig.json`,
JSON.stringify({ availablePaymentMethods: paymentMethodList })
await util.cloneAndConfigureRepos(
paymentRepos,
paymentDirectoryPath,
'payment method'
);

if (paymentMethodList.length) {
let content = `/**
* 📢 📢 📢 This file is autogenerated and may be overwritten. Handle with care. 🙅🏽 🙅🏽 🙅🏽
*
* When you have custom payment repo integration, then the content of this file
* will be overwritten during performing "npm install". So, in most of the cases,
* you don't need to alter the content of this file.
*
* But, if you have your own custom payment methods locally, then you need to
* include them here as well. That is the only time you need to touch this file.
*/\n\n`;
content += paymentMethodList
.map(
(method) => `import ${method}Renderers from './${method}/renderers';\n`
)
.join('');
content += '\n';
content += `export default {\n`;
content += paymentMethodList
.map((method) => ` ...${method}Renderers,\n`)
.join('');
content += '};\n';

fs.writeFileSync(`${paymentDirectoryPath}customRenderers.js`, content);
}

console.log('Payment methods successfully added');
})();
46 changes: 46 additions & 0 deletions src/reactapp/scripts/utility/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const fs = require('fs');
const util = require('util');
const exec = util.promisify(require('child_process').exec);

module.exports = {
async installRepo(path, directory, repoUri, repoType) {
console.log(`Installing ${directory}: ${repoUri}`);
await exec(`git clone ${repoUri} ${path}${directory}`);
console.log(`${directory} ${repoType} added successfully.`);
},

collectConfiguredReposFromEnv(configKey) {
const { env } = process;
const configPrefix = `npm_package_config_${configKey}_`;
const repos = {};

Object.keys(env).forEach((envProp) => {
if (envProp.startsWith(configPrefix)) {
const paymentCode = envProp.replace(configPrefix, '');
if (paymentCode) {
repos[paymentCode] = env[envProp];
}
}
});

return repos;
},

async cloneAndConfigureRepos(repoList, installationPath, repoType) {
const paymentMethodList = Object.keys(repoList);

await Promise.all(
paymentMethodList.map(async (repo) => {
if (!fs.existsSync(`${installationPath}${repo}`)) {
await this.installRepo(
installationPath,
repo,
repoList[repo],
repoType
);
}
return 'success';
})
);
},
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React from 'react';

import Card from '../common/Card';
import ToggleBox from '../common/ToggleBox';
Expand All @@ -7,27 +7,18 @@ import NoPaymentMethodInfoBox from './components/NoPaymentMethodInfoBox';
import PaymentMethodFormManager from './components/PaymentMethodFormManager';
import { __ } from '../../i18n';
import { formikDataShape } from '../../utils/propTypes';
import getCustomRenderers from '../../paymentMethods/customRenderers';
import customRenderers from '../../paymentMethods/customRenderers';
import usePaymentMethodCartContext from './hooks/usePaymentMethodCartContext';

const PaymentMethodMemorized = React.memo(({ formikData }) => {
const [renderers, setRenderers] = useState({});
const { isPaymentAvailable } = usePaymentMethodCartContext();

// collect custom renderers from the custom payment methods installed.
useEffect(() => {
(async () => {
const availableRenderers = await getCustomRenderers();
setRenderers(availableRenderers);
})();
}, []);

return (
<PaymentMethodFormManager formikData={formikData}>
<Card classes={isPaymentAvailable ? '' : 'opacity-75'}>
<ToggleBox show title={__('Payment Methods')}>
{isPaymentAvailable ? (
<PaymentMethodList methodRenderers={renderers} />
<PaymentMethodList methodRenderers={customRenderers} />
) : (
<NoPaymentMethodInfoBox />
)}
Expand Down
23 changes: 7 additions & 16 deletions src/reactapp/src/paymentMethods/customRenderers.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import { paymentFetcher } from './utility';

/**
* Preparing custom renderers from the available payment methods configured
* into this directory.
* 📢 📢 📢 This file is autogenerated and may be overwritten. Handle with care. 🙅🏽 🙅🏽 🙅🏽
*
* Available payment methods are available in `paymentConfig.json`.
* When you have custom payment repo integration, then the content of this file
* will be overwritten during performing "npm install". So, in most of the cases,
* you don't need to alter the content of this file.
*
* Each payment methods will posses `renderers.js` file which will defines the
* custom payment method renderers. This will collect all the renderers provide
* it into the PaymentMethods component.
* But, if you have your own custom payment methods locally, then you need to
* include them here as well. That is the only time you need to touch this file.
*/
export default async function getCustomRenderers() {
const paymentMethodRenderers =
await paymentFetcher.fetchDataFromPaymentMethods('renderers.js', []);

return paymentMethodRenderers.reduce(
(renderers, item) => ({ ...renderers, ...item }),
{}
);
}
export default {};
1 change: 0 additions & 1 deletion src/reactapp/src/paymentMethods/paymentConfig.json

This file was deleted.

46 changes: 0 additions & 46 deletions src/reactapp/src/paymentMethods/utility/index.js

This file was deleted.

0 comments on commit c589f8b

Please sign in to comment.