├── .DS_Store ├── .all-contributorsrc ├── .eslintrc.js ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md ├── pull_request_template.md └── workflows │ ├── pr-test.yml │ └── release.yml ├── .gitignore ├── .husky ├── .gitignore └── pre-commit ├── .prettierrc ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── __tests__ └── index.test.tsx ├── _config.yml ├── babel.config.js ├── development ├── PaystackProvider.tsx ├── index.tsx ├── styles.ts ├── types.ts ├── usePaystack.tsx └── utils.ts ├── package.json ├── release.config.cjs ├── tsconfig.json └── yarn.lock /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/just1and0/React-Native-Paystack-WebView/c41258d5f3a722827cd46434d2a3fb1e061faeae/.DS_Store -------------------------------------------------------------------------------- /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "contributors": [ 8 | { 9 | "login": "just1and0", 10 | "name": "Oluwatobi Shokunbi ", 11 | "avatar_url": "https://avatars3.githubusercontent.com/u/17249207?v=4", 12 | "profile": "https://linksnest.com/just1and0", 13 | "contributions": [ 14 | "code", 15 | "doc" 16 | ] 17 | }, 18 | { 19 | "login": "mosoakinyemi", 20 | "name": "Akinyemi Mosolasi", 21 | "avatar_url": "https://avatars2.githubusercontent.com/u/41248079?v=4", 22 | "profile": "https://github.com/mosoakinyemi", 23 | "contributions": [ 24 | "doc", 25 | "code" 26 | ] 27 | }, 28 | { 29 | "login": "okechukwu0127", 30 | "name": "okechukwu0127", 31 | "avatar_url": "https://avatars0.githubusercontent.com/u/23473673?v=4", 32 | "profile": "https://github.com/okechukwu0127", 33 | "contributions": [ 34 | "code", 35 | "bug" 36 | ] 37 | }, 38 | { 39 | "login": "johneyo", 40 | "name": "Johney", 41 | "avatar_url": "https://avatars2.githubusercontent.com/u/36991140?v=4", 42 | "profile": "https://github.com/johneyo", 43 | "contributions": [ 44 | "code" 45 | ] 46 | }, 47 | { 48 | "login": "samie820", 49 | "name": "sammy", 50 | "avatar_url": "https://avatars2.githubusercontent.com/u/27306463?v=4", 51 | "profile": "https://twitter.com/AjeboDeveloper", 52 | "contributions": [ 53 | "code" 54 | ] 55 | }, 56 | { 57 | "login": "walexanderos", 58 | "name": "Jimoh Jamiu", 59 | "avatar_url": "https://avatars0.githubusercontent.com/u/36700043?v=4", 60 | "profile": "https://github.com/walexanderos", 61 | "contributions": [ 62 | "bug", 63 | "doc", 64 | "code" 65 | ] 66 | }, 67 | { 68 | "login": "cahakgeorge", 69 | "name": "Cahak George", 70 | "avatar_url": "https://avatars3.githubusercontent.com/u/8522701?v=4", 71 | "profile": "https://medium.com/@cahakgeorge", 72 | "contributions": [ 73 | "code" 74 | ] 75 | }, 76 | { 77 | "login": "johnayeni", 78 | "name": "John Ayeni", 79 | "avatar_url": "https://avatars0.githubusercontent.com/u/22295092?v=4", 80 | "profile": "https://johnayeni.xyz", 81 | "contributions": [ 82 | "doc" 83 | ] 84 | }, 85 | { 86 | "login": "majirieyowel", 87 | "name": "majirieyowel", 88 | "avatar_url": "https://avatars.githubusercontent.com/u/30162976?v=4", 89 | "profile": "https://github.com/majirieyowel", 90 | "contributions": [ 91 | "code" 92 | ] 93 | }, 94 | { 95 | "login": "Zeusmist", 96 | "name": "David Erinayo Obidu", 97 | "avatar_url": "https://avatars.githubusercontent.com/u/51177741?v=4", 98 | "profile": "https://github.com/Zeusmist", 99 | "contributions": [ 100 | "bug" 101 | ] 102 | }, 103 | { 104 | "login": "surafelbm", 105 | "name": "surafelbm", 106 | "avatar_url": "https://avatars.githubusercontent.com/u/11531221?v=4", 107 | "profile": "https://github.com/surafelbm", 108 | "contributions": [ 109 | "bug" 110 | ] 111 | }, 112 | { 113 | "login": "omivrex", 114 | "name": "Rex Omiv", 115 | "avatar_url": "https://avatars.githubusercontent.com/u/42608841?v=4", 116 | "profile": "https://github.com/omivrex", 117 | "contributions": [ 118 | "bug" 119 | ] 120 | }, 121 | { 122 | "login": "ossyfizy1", 123 | "name": "Osagie Osaigbovo Charles", 124 | "avatar_url": "https://avatars.githubusercontent.com/u/18512476?v=4", 125 | "profile": "https://github.com/ossyfizy1", 126 | "contributions": [ 127 | "bug" 128 | ] 129 | }, 130 | { 131 | "login": "Ujjalcha1", 132 | "name": "Ujjalcha1", 133 | "avatar_url": "https://avatars.githubusercontent.com/u/40722840?v=4", 134 | "profile": "https://github.com/Ujjalcha1", 135 | "contributions": [ 136 | "bug" 137 | ] 138 | }, 139 | { 140 | "login": "Blac-Panda", 141 | "name": "Oyefeso Oluwatunmise", 142 | "avatar_url": "https://avatars.githubusercontent.com/u/23406970?v=4", 143 | "profile": "http://codexplorer.me", 144 | "contributions": [ 145 | "bug" 146 | ] 147 | }, 148 | { 149 | "login": "fuadop", 150 | "name": "Fuad Olatunji", 151 | "avatar_url": "https://avatars.githubusercontent.com/u/65264054?v=4", 152 | "profile": "http://fuadolatunji.me", 153 | "contributions": [ 154 | "doc" 155 | ] 156 | }, 157 | { 158 | "login": "erasmuswill", 159 | "name": "Wilhelm Erasmus", 160 | "avatar_url": "https://avatars.githubusercontent.com/u/15966713?v=4", 161 | "profile": "https://erasmuswill.dev", 162 | "contributions": [ 163 | "code" 164 | ] 165 | }, 166 | { 167 | "login": "opmat", 168 | "name": "Matiluko Opeyemi Emmanuel", 169 | "avatar_url": "https://avatars.githubusercontent.com/u/2133903?v=4", 170 | "profile": "https://github.com/opmat", 171 | "contributions": [ 172 | "code", 173 | "doc" 174 | ] 175 | }, 176 | { 177 | "login": "mureyvenom", 178 | "name": "Oluwamurewa Alao", 179 | "avatar_url": "https://avatars.githubusercontent.com/u/47125673?v=4", 180 | "profile": "https://mureyfolio.com.ng/", 181 | "contributions": [ 182 | "code" 183 | ] 184 | }, 185 | { 186 | "login": "El-Nazy", 187 | "name": "Emmanuel Ngene", 188 | "avatar_url": "https://avatars.githubusercontent.com/u/48170272?v=4", 189 | "profile": "https://github.com/El-Nazy", 190 | "contributions": [ 191 | "code" 192 | ] 193 | }, 194 | { 195 | "login": "maukoese", 196 | "name": "Mauko", 197 | "avatar_url": "https://avatars.githubusercontent.com/u/14233942?v=4", 198 | "profile": "https://osen.co.ke", 199 | "contributions": [ 200 | "doc" 201 | ] 202 | }, 203 | { 204 | "login": "quartusk", 205 | "name": "Quartus Kok", 206 | "avatar_url": "https://avatars.githubusercontent.com/u/39792290?v=4", 207 | "profile": "https://github.com/quartusk", 208 | "contributions": [ 209 | "code" 210 | ] 211 | }, 212 | { 213 | "login": "tolu-paystack", 214 | "name": "Tolu Kalejaiye", 215 | "avatar_url": "https://avatars.githubusercontent.com/u/60101507?v=4", 216 | "profile": "https://github.com/tolu-paystack", 217 | "contributions": [ 218 | "code", 219 | "bug" 220 | ] 221 | } 222 | ], 223 | "contributorsPerLine": 7, 224 | "projectName": "React-Native-Paystack-WebView", 225 | "projectOwner": "just1and0", 226 | "repoType": "github", 227 | "repoHost": "https://github.com", 228 | "skipCi": true, 229 | "commitType": "docs", 230 | "commitConvention": "angular" 231 | } 232 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | const IGNORE = 0; 2 | const WARN = 1; 3 | const ERROR = 2; 4 | 5 | module.exports = { 6 | env: { 7 | browser: true, 8 | node: true, 9 | jest: true, 10 | es6: true, 11 | }, 12 | extends: [ 13 | 'plugin:react/recommended', 14 | 'airbnb', 15 | 'plugin:import/warnings', 16 | 'plugin:import/typescript', 17 | 'plugin:import/errors', 18 | ], 19 | parser: '@typescript-eslint/parser', 20 | parserOptions: { 21 | ecmaVersion: 6, 22 | sourceType: 'module', 23 | ecmaFeatures: { 24 | modules: true, 25 | }, 26 | }, 27 | plugins: ['react', 'react-native', '@typescript-eslint', 'import'], 28 | rules: { 29 | // Allow imports from dev and peer dependencies 30 | 'import/no-extraneous-dependencies': [ERROR, { devDependencies: true, peerDependencies: true }], 31 | 'no-unused-vars': WARN, 32 | 'no-shadow': IGNORE, 33 | 'import/no-unresolved': IGNORE, 34 | 'import/extensions': [ 35 | ERROR, 36 | 'ignorePackages', 37 | { 38 | js: 'never', 39 | jsx: 'never', 40 | ts: 'never', 41 | tsx: 'never', 42 | }, 43 | ], 44 | 'react/prop-types': IGNORE, 45 | 'no-use-before-define': IGNORE, 46 | 'react/jsx-filename-extension': IGNORE, 47 | 'no-case-declarations': IGNORE, 48 | 'no-unused-expressions': IGNORE, 49 | 'object-curly-newline': IGNORE, 50 | 'prefer-template': IGNORE, 51 | }, 52 | }; 53 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [just1and0] 4 | patreon: just1and0 5 | ko_fi: just1and0 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when I setup the package in my React Native JS project, it seem the project has an issue with imported types in javascript. 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | 4 | ## Issue URL 5 | 6 | 7 | ## Before and After 8 | Add Image/video/gifs of changes 9 | 10 | | Before | After | 11 | | --- | --- | 12 | | **Visual:** | **Visual:** | 13 | | **Functionality:** | **Functionality:** | 14 | -------------------------------------------------------------------------------- /.github/workflows/pr-test.yml: -------------------------------------------------------------------------------- 1 | name: Run Build and Tests on Pull Request 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - reopened 8 | - synchronize 9 | 10 | jobs: 11 | test-build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: actions/setup-node@v4 16 | with: 17 | node-version: "lts/*" 18 | - run: npm install --legacy-peer-deps 19 | - name: Run Tests 20 | run: | 21 | npx jest --ci --coverage --maxWorkers=2 22 | continue-on-error: false 23 | - name: TypeScript Check 24 | run: yarn tsc 25 | - run: yarn build 26 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: NEW RELEASE 🥳 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - next 8 | 9 | permissions: 10 | contents: write 11 | issues: write 12 | pull-requests: write 13 | 14 | jobs: 15 | release: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: actions/setup-node@v4 20 | with: 21 | node-version: "lts/*" 22 | - run: npm install --legacy-peer-deps 23 | - name: Run Tests 24 | run: | 25 | npx jest --ci --coverage --maxWorkers=2 26 | continue-on-error: false 27 | - name: TypeScript Check 28 | run: yarn tsc 29 | - run: yarn build 30 | - name: Release 31 | env: 32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 33 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 34 | run: npx semantic-release 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IJ 26 | # 27 | *.iml 28 | .idea 29 | .gradle 30 | local.properties 31 | 32 | # node.js 33 | # 34 | node_modules/ 35 | npm-debug.log 36 | 37 | production/ 38 | # yarn 39 | yarn-error.log 40 | 41 | # BUCK 42 | buck-out/ 43 | \.buckd/ 44 | android/app/libs 45 | android/keystores/debug.keystore 46 | package-json.lock 47 | 48 | # vscode 49 | .vscode 50 | examples/mlkit/android/app/google-services.json 51 | examples/mlkit/ios/Pods 52 | examples/mlkit/ios/mlkit/GoogleService-Info.plist 53 | 54 | !debug.keystore 55 | /ios/Pods/ 56 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "printWidth": 120 5 | } 6 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | We’re excited to have you contribute! Here’s how to get started: 4 | 5 | ## Steps to Contribute 6 | 7 | - Fork the Project: Start by forking this repository to your own GitHub account. 8 | - Create a New Branch: For each new feature or change, create a new branch from the `main` branch. 9 | - Make Your Changes. 10 | - Submit a Pull Request (PR): Once you’re satisfied with your changes, submit a PR. Be sure to provide a clear description of what your PR does and the problem it solves. 11 | - Add @just1and0 as a reviewer. 12 | 13 | ## Important Notes 14 | - All commit titles must begin with either; 15 | - fix(RNPSW): : this is a fix PR 16 | - feat(RNPSW): : this is a new feature PR 17 | - perf(RNPSW): : this is a performance PR 18 | - BREAKING CHANGE: : this is a breaking change 19 | - No Build Attempts in PRs: Please do not try to build the project within your PR; our Continuous Integration (CI) system will handle that for you. 20 | - Contributor Recognition: You do not need to add yourself as a contributor; the CI will automatically recognize and credit you once your PR is merged. 21 | 22 | Thank you for helping us make this project even better! We appreciate your contributions! 23 | 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Oluwatobi Shokunbi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |

React Native Paystack WebView (v5)

5 | 6 |

7 | Modern, hook-based, Paystack-powered payments in React Native apps using WebViews — now streamlined with Provider architecture & fully customizable. 8 |

9 | 10 | Endorsed by Paystack, so you know you’re in good hands. Payment processing has never been this easy! 11 | 12 | All Contributors 13 | 14 | 15 |
16 | 17 |
18 | Screenshot of library in action 19 |
20 | 21 | --- 22 | 23 | 24 | ## 🚀 Installation 25 | 26 | ```bash 27 | npm install react-native-paystack-webview 28 | # or 29 | yarn add react-native-paystack-webview 30 | ``` 31 | 32 | ### 📦 Peer Dependency 33 | 34 | ```bash 35 | yarn add react-native-webview 36 | 37 | # iOS 38 | cd ios && pod install 39 | 40 | # Expo 41 | npx expo install react-native-webview 42 | ``` 43 | 44 | --- 45 | 46 | ## ⚡ Quick Start 47 | 48 | ### Wrap your app with the Provider 49 | 50 | ```tsx 51 | import { PaystackProvider } from 'react-native-paystack-webview'; 52 | 53 | 54 | 55 | 56 | ``` 57 | 58 | ### Use in a component 59 | 60 | ```tsx 61 | import React from 'react'; 62 | import { Button } from 'react-native'; 63 | import { usePaystack } from 'react-native-paystack-webview'; 64 | 65 | const Checkout = () => { 66 | const { popup } = usePaystack(); 67 | 68 | const payNow = () => { 69 | popup.checkout({ 70 | email: 'jane.doe@example.com', 71 | amount: 5000, 72 | reference: 'TXN_123456', 73 | plan: 'PLN_example123', 74 | invoice_limit: 3, 75 | subaccount: 'SUB_abc123', 76 | split_code: 'SPL_def456', 77 | split: { 78 | type: 'percentage', 79 | bearer_type: 'account', 80 | subaccounts: [ 81 | { subaccount: 'ACCT_abc', share: 60 }, 82 | { subaccount: 'ACCT_xyz', share: 40 } 83 | ] 84 | }, 85 | metadata: { 86 | custom_fields: [ 87 | { 88 | display_name: 'Order ID', 89 | variable_name: 'order_id', 90 | value: 'OID1234' 91 | } 92 | ] 93 | }, 94 | onSuccess: (res) => console.log('Success:', res), 95 | onCancel: () => console.log('User cancelled'), 96 | onLoad: (res) => console.log('WebView Loaded:', res), 97 | onError: (err) => console.log('WebView Error:', err) 98 | }); 99 | }; 100 | 101 | return