diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 04921bcf77..1e46b60590 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -85,6 +85,7 @@ /packages/paypal-commerce-integration @bigcommerce/team-paypal /packages/paypal-commerce-utils @bigcommerce/team-paypal /packages/paypal-pro-integration @bigcommerce/team-paypal +/packages/paypal-utils @bigcommerce/team-paypal ## Shared diff --git a/packages/paypal-utils/.eslintrc.json b/packages/paypal-utils/.eslintrc.json new file mode 100644 index 0000000000..5626944bd1 --- /dev/null +++ b/packages/paypal-utils/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/packages/paypal-utils/README.md b/packages/paypal-utils/README.md new file mode 100644 index 0000000000..6806a33dc9 --- /dev/null +++ b/packages/paypal-utils/README.md @@ -0,0 +1,11 @@ +# paypal-utils + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test paypal-utils` to execute the unit tests via [Jest](https://jestjs.io). + +## Running lint + +Run `nx lint paypal-utils` to execute the lint via [ESLint](https://eslint.org/). diff --git a/packages/paypal-utils/jest.config.js b/packages/paypal-utils/jest.config.js new file mode 100644 index 0000000000..9988acb900 --- /dev/null +++ b/packages/paypal-utils/jest.config.js @@ -0,0 +1,14 @@ +module.exports = { + displayName: 'paypal-utils', + preset: '../../jest.preset.js', + globals: { + 'ts-jest': { + tsconfig: '/tsconfig.spec.json', + }, + }, + transform: { + '^.+\\.[tj]sx?$': 'ts-jest', + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], + coverageDirectory: '../../coverage/packages/paypal-utils', +}; diff --git a/packages/paypal-utils/project.json b/packages/paypal-utils/project.json new file mode 100644 index 0000000000..85d8e6b15f --- /dev/null +++ b/packages/paypal-utils/project.json @@ -0,0 +1,23 @@ +{ + "root": "packages/paypal-utils", + "sourceRoot": "packages/paypal-utils/src", + "projectType": "library", + "targets": { + "lint": { + "executor": "@nrwl/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["packages/paypal-utils/**/*.ts"] + } + }, + "test": { + "executor": "@nrwl/jest:jest", + "outputs": ["coverage/packages/paypal-utils"], + "options": { + "jestConfig": "packages/paypal-utils/jest.config.js", + "passWithNoTests": true + } + } + }, + "tags": [] +} diff --git a/packages/paypal-utils/src/index.ts b/packages/paypal-utils/src/index.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/paypal-utils/src/paypal-button.ts b/packages/paypal-utils/src/paypal-button.ts new file mode 100644 index 0000000000..116d1e50d2 --- /dev/null +++ b/packages/paypal-utils/src/paypal-button.ts @@ -0,0 +1,131 @@ +// Cart page / mini cart / add to cart modal -> default & payNowOptions +// PDP -> buyNowOptions & payNowOptions + + + +export default class PayPalButton { + renderOrThrow(options): Promise { + const { + containerId, + paymentMethodName, // (!) FundingSource + buttonStyles, // (?) + onEligibilityFailure, // (?) + onCancel, // (?) + onRenderButton, // (?) + buyNowOptions, // (?) + payNowOptions, // (?) -skip checkout + paypalSdk, // (!) + } = options; + + let paypalConfig = {}; + + /** + * + * Get mapped FundingSource based on payment provider name + * + */ + paypalConfig.fundingSource = this.getFundingSourceByPaymentMethodName(paymentMethodName); + + + /** + * + * Styles + * + * */ + if (buttonStyles) { + paypalConfig.style = this.getValidButtonStyle(paymentMethodName, buttonStyles); + } + + /** + * + * Get PayPal callbacks + * + * */ + + const paypalCallbacks = this.getButtonCallbacks(); + + Object.assign(paypalConfig, paypalCallbacks); + + + + + + // render wallet button based on config + + + + // get paypal sdk + // get default callbacks -> will be always provided + // get buy now callbacks -> buyNow config should be provided via render options + // get pay now callbacks -> payNow config should be provided via render options + // handle on eligibility failure -> should be provided via render options + + const paypalButton = paypal.Buttons(paypalConfig); + + if (paypalButton.isEligible()) { + paypalButton.render(`#${containerId}`); + } else { + console.log(`Button is not eligible to render. Payment method name is ${paymentMethodName}`); + + onEligibilityFailure(); + } + } + + /** + * + * Funding source mapper + * + */ + private getFundingSourceByPaymentMethodName(paymentMethodName: string): string { + // All mappings should be here + return ''; + } + + + /** + * + * Buttons styles + * + */ + private getValidButtonStyle(paymentMethodName: string, buttonStyles: object): object { + // All styles calculations should be here + return {}; + } + + + /** + * + * PayPal Config callbacks + * + * */ + private getButtonCallbacks() { + const callbacks = { + createOrder: () => {}, + onApprove: () => {}, + }; + + if (buyNowOptions) { + // Should buyNowInitializeOptions be validated on higher level? + + const buyNowCallbacks = { + onClick: () => {}, // only if buyNowInitializeOptions is provided + onCancel: () => {}, // load default checkout + }; + + Object.assign(callbacks, buyNowCallbacks); + } + + if (payNowOptions) { + const payNowCallbacks = { + onShippingAddressChange: () => {}, + onShippingOptionsChange: () => {}, + onApprove: () => {}, + }; + + Object.assign(callbacks, payNowCallbacks); + } + + return callbacks; + } + +} diff --git a/packages/paypal-utils/src/paypal-fastlane.ts b/packages/paypal-utils/src/paypal-fastlane.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/paypal-utils/src/paypal-hosted-fields.ts b/packages/paypal-utils/src/paypal-hosted-fields.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/paypal-utils/src/paypal-message.ts b/packages/paypal-utils/src/paypal-message.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/paypal-utils/src/paypal-sdk.ts b/packages/paypal-utils/src/paypal-sdk.ts new file mode 100644 index 0000000000..07331f32d2 --- /dev/null +++ b/packages/paypal-utils/src/paypal-sdk.ts @@ -0,0 +1,3 @@ +export default class PayPalSDK { + +} diff --git a/packages/paypal-utils/tsconfig.json b/packages/paypal-utils/tsconfig.json new file mode 100644 index 0000000000..d81bfb6464 --- /dev/null +++ b/packages/paypal-utils/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + } +} diff --git a/packages/paypal-utils/tsconfig.lib.json b/packages/paypal-utils/tsconfig.lib.json new file mode 100644 index 0000000000..ba5447ffb1 --- /dev/null +++ b/packages/paypal-utils/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "declaration": true, + "types": [] + }, + "include": ["**/*.ts"], + "exclude": ["**/*.spec.ts"] +} diff --git a/packages/paypal-utils/tsconfig.spec.json b/packages/paypal-utils/tsconfig.spec.json new file mode 100644 index 0000000000..2c1fb69d9f --- /dev/null +++ b/packages/paypal-utils/tsconfig.spec.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "**/*.test.ts", + "**/*.spec.ts", + "**/*.test.tsx", + "**/*.spec.tsx", + "**/*.test.js", + "**/*.spec.js", + "**/*.test.jsx", + "**/*.spec.jsx", + "**/*.d.ts" + ] +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 92d643e142..1dc0d14817 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -112,6 +112,7 @@ "@bigcommerce/checkout-sdk/paypal-pro-integration": [ "packages/paypal-pro-integration/src/index.ts" ], + "@bigcommerce/checkout-sdk/paypal-utils": ["packages/paypal-utils/src/index.ts"], "@bigcommerce/checkout-sdk/sagepay-integration": [ "packages/sagepay-integration/src/index.ts" ], diff --git a/workspace.json b/workspace.json index f9cffd7dd2..71bebe3148 100644 --- a/workspace.json +++ b/workspace.json @@ -36,6 +36,7 @@ "paypal-commerce-utils": "packages/paypal-commerce-utils", "paypal-express-integration": "packages/paypal-express-integration", "paypal-pro-integration": "packages/paypal-pro-integration", + "paypal-utils": "packages/paypal-utils", "sagepay-integration": "packages/sagepay-integration", "sezzle-integration": "packages/sezzle-integration", "squarev2-integration": "packages/squarev2-integration",