├── .gitignore
├── tests
└── react-midtrans.js
├── .prettierrc
├── lint-staged.config.js
├── src
├── index.js
└── react-midtrans.js
├── README.md
├── package.json
└── jest.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | config.json
3 | dist
4 | node_modules
5 | Services
6 | *.swp
7 | coverage
8 |
--------------------------------------------------------------------------------
/tests/react-midtrans.js:
--------------------------------------------------------------------------------
1 | describe('Test React-Midtrans', () => {
2 | test('Write Test Here', () => {
3 | //
4 | })
5 | })
6 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "jsxBracketSameLine": false,
3 | "printWidth": 80,
4 | "semi": false,
5 | "singleQuote": true,
6 | "tabWidth": 2,
7 | "trailingComma": "all",
8 | "useTabs": false
9 | }
10 |
--------------------------------------------------------------------------------
/lint-staged.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | linters: {
3 | '**/*.+(js|json|less|css|ts|tsx|md)': [
4 | 'prettier --write',
5 | 'yarn test --coverage --findRelatedTests',
6 | 'yarn docs',
7 | 'git add',
8 | ],
9 | },
10 | }
11 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import ReactMidtrans from './react-midtrans'
2 | /**
3 | * @name usage
4 | * @example
5 | *
6 | * import React from 'react'
7 | * import ReactDOM from 'react-dom'
8 | * import ReactMidtrans from 'react-midtrans'
9 | *
10 | * ReactDOM.render(
11 | *
12 | *
13 | *
14 | * ,document.getElementById('app')
15 | * )
16 | */
17 | export default ReactMidtrans
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-midtrans
2 |
3 | A Wrapper for Snap React Midtrans
4 |
5 | ## API
6 |
7 |
8 |
9 | #### Table of Contents
10 |
11 | - [usage](#usage)
12 | - [Examples](#examples)
13 | - [SnapMidtrans](#snapmidtrans)
14 | - [Parameters](#parameters)
15 | - [Properties](#properties)
16 |
17 | ### usage
18 |
19 | #### Examples
20 |
21 | ```javascript
22 | import React from 'react'
23 | import ReactDOM from 'react-dom'
24 | import ReactMidtrans from 'react-midtrans'
25 |
26 | ReactDOM.render(
27 |
28 |
29 |
30 | ,document.getElementById('app')
31 | )
32 | ```
33 |
34 | ###
35 |
36 | ### SnapMidtrans
37 |
38 | #### Parameters
39 |
40 | - `props` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**
41 |
42 | #### Properties
43 |
44 | - `children` **ReactElement** required
45 | - `token` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
46 | - `onSuccess` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)**
47 | - `onError` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)**
48 | - `onPending` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)**
49 | - `onClose` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)**
50 |
--------------------------------------------------------------------------------
/src/react-midtrans.js:
--------------------------------------------------------------------------------
1 | import { cloneElement, PureComponent } from 'react'
2 | import PropTypes from 'prop-types'
3 |
4 | const { oneOfType, arrayOf, node, func, string } = PropTypes
5 |
6 | export default class SnapMidtrans extends PureComponent {
7 | state = {
8 | children: null,
9 | token: '',
10 | }
11 |
12 | static getDerivedStateFromProps(nextProps, prevState) {
13 | return nextProps.token !== prevState.token
14 | ? { token: nextProps.token }
15 | : null
16 | }
17 |
18 | constructor(props) {
19 | super(props)
20 | const { NODE_ENV: ENV } = process.env
21 |
22 | // bind react-midtrans method
23 | this.mergeWithChildren = this.mergeWithChildren.bind(this)
24 | // backup currentview
25 | this.currentViewport = document
26 | .getElementsByTagName('meta')
27 | .hasOwnProperty('viewport')
28 | ? document.getElementsByTagName('meta').viewport
29 | : ''
30 | // create element for script
31 | this.snapScript = document.createElement('script')
32 |
33 | // checking environment mode
34 | this.snapScript.src =
35 | ENV === 'production'
36 | ? 'https://app.midtrans.com/snap/snap.js'
37 | : 'https://app.sandbox.midtrans.com/snap/snap.js'
38 |
39 | this.snapScript.type = 'text/javascript'
40 | this.snapScript.onload = this.onLoad.bind(this)
41 | this.snapScript.dataset.clientKey = props.clientKey
42 | }
43 |
44 | onLoad(e) {
45 | if ('snap' in window) {
46 | const { snap } = window
47 | this.setState({ snap })
48 | }
49 | }
50 |
51 | componentDidMount() {
52 | document.head.appendChild(this.snapScript)
53 | this.mergeWithChildren(this.props.children)
54 | }
55 |
56 | mergeWithChildren(children) {
57 | children = cloneElement(
58 | children,
59 | // Assign new Props
60 | {
61 | onClick: () => {
62 | // If Children have a onClick
63 | children.onClick && children.onClick()
64 | if (this.state.token && this.state.token !== '') {
65 | this.state.snap.pay(
66 | this.state.token,
67 | /** @todo options **/
68 | )
69 | }
70 | this.props.onClick && this.props.onClick()
71 | },
72 | },
73 | )
74 |
75 | this.setState({
76 | children,
77 | })
78 | }
79 |
80 | render() {
81 | return this.state.children
82 | }
83 | }
84 |
85 | /**
86 | * @module SnapMidtrans
87 | * @param {Object} props
88 | * @property {ReactElement} children - required
89 | * @property {String} token
90 | * @todo 4 callback
91 | * @property {Function} onSuccess
92 | * @property {Function} onError
93 | * @property {Function} onPending
94 | * @property {Function} onClose
95 | */
96 | SnapMidtrans.propTypes = {
97 | children: oneOfType([arrayOf(node), node]).isRequired,
98 | clientKey: string.isRequired,
99 | token: string,
100 |
101 | /* @see @link {https://snap-docs.midtrans.com/#snap-js|Midtrans API 4 Callback} */
102 | onSuccess: func,
103 | onPending: func,
104 | onError: func,
105 | onClose: func,
106 |
107 | /* Callback Or Custom onClick */
108 | onClick: func,
109 | }
110 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-midtrans",
3 | "version": "0.0.1",
4 | "description": "ReactJS Integration For Midtrans Payment Gateway Frontend Integration",
5 | "repository": "git@github.com:ri7nz/react-midtrans.git",
6 | "author": "ri7nz ",
7 | "license": "MIT",
8 | "source": "src/index.js",
9 | "main": "dist/react-midtrans.js",
10 | "module": "dist/react-midtrans.es.js",
11 | "umd:main": "dist/react-midtrans.umd.js",
12 | "files": [
13 | "src",
14 | "dist",
15 | "react-midtrns"
16 | ],
17 | "peerDependencies": {
18 | "react": "*"
19 | },
20 | "babel": {
21 | "presets": [
22 | [
23 | "@babel/preset-env",
24 | {
25 | "targets": {
26 | "node": true
27 | }
28 | }
29 | ]
30 | ],
31 | "plugins": [
32 | [
33 | "transform-react-jsx"
34 | ]
35 | ]
36 | },
37 | "devDependencies": {
38 | "@babel/core": "^7.3.3",
39 | "@babel/preset-env": "^7.3.1",
40 | "babel-eslint": "^10.0.1",
41 | "babel-jest": "^24.1.0",
42 | "babel-plugin-transform-react-jsx": "^6.24.1",
43 | "bundlesize": "^0.17.1",
44 | "documentation": "^9.2.0",
45 | "eslint": "^5.14.1",
46 | "eslint-config-prettier": "^3.3.0",
47 | "eslint-config-react-app": "^3.0.7",
48 | "eslint-plugin-flowtype": "^3.4.2",
49 | "eslint-plugin-import": "^2.16.0",
50 | "eslint-plugin-jest": "^22.3.0",
51 | "eslint-plugin-jsx-a11y": "^6.2.1",
52 | "eslint-plugin-prettier": "^3.0.1",
53 | "eslint-plugin-react": "^7.12.4",
54 | "gzip-size-cli": "^3.0.0",
55 | "husky": "^1.3.1",
56 | "jest": "^24.1.0",
57 | "lint-staged": "^8.1.4",
58 | "microbundle": "^0.10.1",
59 | "npm-run-all": "^4.1.5",
60 | "prettier": "^1.16.4",
61 | "prop-types": "^15.7.2",
62 | "react": "^16.8.3",
63 | "react-dom": "^16.8.3",
64 | "strip-json-comments-cli": "^1.0.1"
65 | },
66 | "eslintConfig": {
67 | "extends": "react-app"
68 | },
69 | "browserslist": [
70 | ">0.2%",
71 | "not dead",
72 | "not ie <= 11",
73 | "not op_mini all"
74 | ],
75 | "husky": {
76 | "hooks": {
77 | "pre-commit": "lint-staged"
78 | }
79 | },
80 | "bundlesize": [
81 | {
82 | "path": "./dist/*.js",
83 | "maxSize": "2 kB"
84 | }
85 | ],
86 | "scripts": {
87 | "dev": "microbundle watch",
88 | "build": "npm-run-all --silent -p build:main -s size docs",
89 | "build:main": "microbundle",
90 | "size": "strip-json-comments --no-whitespace dist/react-midtrans.js | gzip-size ",
91 | "docs": "documentation readme src/*.js -q --section API && yarn fixreadme",
92 | "lint": "eslint -c .eslintrc ./src --fix",
93 | "prepare": "rm -rf dist && yarn build",
94 | "test": "jest --config jest.config.js",
95 | "test:watch": "jest --watch",
96 | "test:size": "bundlesize",
97 | "fixreadme": "node -e 'var fs=require(\"fs\");fs.writeFileSync(\"README.md\", fs.readFileSync(\"README.md\", \"utf8\").replace(/^- /gm, \"- \"))'",
98 | "release": "yarn -s prepare && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish"
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | // For a detailed explanation regarding each configuration property, visit:
2 | // https://jestjs.io/docs/en/configuration.html
3 |
4 | module.exports = {
5 | // All imported modules in your tests should be mocked automatically
6 | // automock: false,
7 |
8 | // Stop running tests after the first failure
9 | // bail: false,
10 |
11 | // Respect "browser" field in package.json when resolving modules
12 | // browser: false,
13 |
14 | // The directory where Jest should store its cached dependency information
15 | // cacheDirectory: "/var/folders/_5/wdjqpts10qvgfhzhbk_3ty2m0000gn/T/jest_dx",
16 |
17 | // Automatically clear mock calls and instances between every test
18 | // clearMocks: false,
19 |
20 | // Indicates whether the coverage information should be collected while executing the test
21 | // collectCoverage: false,
22 |
23 | // An array of glob patterns indicating a set of files for which coverage information should be collected
24 | // collectCoverageFrom: null,
25 |
26 | // The directory where Jest should output its coverage files
27 | coverageDirectory: 'coverage',
28 |
29 | // An array of regexp pattern strings used to skip coverage collection
30 | // coveragePathIgnorePatterns: [
31 | // "/node_modules/"
32 | // ],
33 |
34 | // A list of reporter names that Jest uses when writing coverage reports
35 | // coverageReporters: [
36 | // "json",
37 | // "text",
38 | // "lcov",
39 | // "clover"
40 | // ],
41 |
42 | // An object that configures minimum threshold enforcement for coverage results
43 | // coverageThreshold: null,
44 |
45 | // Make calling deprecated APIs throw helpful error messages
46 | // errorOnDeprecated: false,
47 |
48 | // Force coverage collection from ignored files usin a array of glob patterns
49 | // forceCoverageMatch: [],
50 |
51 | // A path to a module which exports an async function that is triggered once before all test suites
52 | // globalSetup: null,
53 |
54 | // A path to a module which exports an async function that is triggered once after all test suites
55 | // globalTeardown: null,
56 |
57 | // A set of global variables that need to be available in all test environments
58 | // globals: {},
59 |
60 | // An array of directory names to be searched recursively up from the requiring module's location
61 | // moduleDirectories: [
62 | // "node_modules"
63 | // ],
64 |
65 | // An array of file extensions your modules use
66 | moduleFileExtensions: [
67 | 'js',
68 | // "json",
69 | // "jsx",
70 | // "node"
71 | ],
72 |
73 | // A map from regular expressions to module names that allow to stub out resources with a single module
74 | // moduleNameMapper: {},
75 |
76 | // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
77 | // modulePathIgnorePatterns: [],
78 |
79 | // Activates notifications for test results
80 | // notify: false,
81 |
82 | // An enum that specifies notification mode. Requires { notify: true }
83 | // notifyMode: "always",
84 |
85 | // A preset that is used as a base for Jest's configuration
86 | // preset: null,
87 |
88 | // Run tests from one or more projects
89 | // projects: null,
90 |
91 | // Use this configuration option to add custom reporters to Jest
92 | // reporters: undefined,
93 |
94 | // Automatically reset mock state between every test
95 | // resetMocks: false,
96 |
97 | // Reset the module registry before running each individual test
98 | // resetModules: false,
99 |
100 | // A path to a custom resolver
101 | // resolver: null,
102 |
103 | // Automatically restore mock state between every test
104 | // restoreMocks: false,
105 |
106 | // The root directory that Jest should scan for tests and modules within
107 | // rootDir: null,
108 |
109 | // A list of paths to directories that Jest should use to search for files in
110 | // roots: [
111 | // ""
112 | // ],
113 |
114 | // Allows you to use a custom runner instead of Jest's default test runner
115 | // runner: "jest-runner",
116 |
117 | // The paths to modules that run some code to configure or set up the testing environment before each test
118 | // setupFiles: [],
119 |
120 | // The path to a module that runs some code to configure or set up the testing framework before each test
121 | // setupTestFrameworkScriptFile: null,
122 |
123 | // A list of paths to snapshot serializer modules Jest should use for snapshot testing
124 | // snapshotSerializers: [],
125 |
126 | // The test environment that will be used for testing
127 | testEnvironment: 'jest-environment-jsdom',
128 |
129 | // Options that will be passed to the testEnvironment
130 | // testEnvironmentOptions: {},
131 |
132 | // Adds a location field to test results
133 | // testLocationInResults: false,
134 |
135 | // The glob patterns Jest uses to detect test files
136 | testMatch: ['**/tests/**/*.js?(x)'],
137 |
138 | // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
139 | testPathIgnorePatterns: ['/node_modules/'],
140 |
141 | // The regexp pattern Jest uses to detect test files
142 | // testRegex: '.*.test\\.js$',
143 |
144 | // This option allows the use of a custom results processor
145 | // testResultsProcessor: null,
146 |
147 | // This option allows use of a custom test runner
148 | // testRunner: "jasmine2",
149 |
150 | // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href
151 | // testURL: "http://localhost",
152 |
153 | // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout"
154 | // timers: "real",
155 |
156 | // A map from regular expressions to paths to transformers
157 | // transform: null,
158 |
159 | // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
160 | // transformIgnorePatterns: [
161 | // "/node_modules/"
162 | // ],
163 |
164 | // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
165 | // unmockedModulePathPatterns: undefined,
166 |
167 | // Indicates whether each individual test should be reported during the run
168 | verbose: true,
169 |
170 | // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
171 | // watchPathIgnorePatterns: [],
172 |
173 | // Whether to use watchman for file crawling
174 | // watchman: true,
175 | }
176 |
--------------------------------------------------------------------------------