@zezosoft/react-native-zezopay 1.0.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.
Files changed (78) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +150 -0
  3. package/lib/module/ZezoPay/Payments/Providers/PaymentGateways.types.d.js +2 -0
  4. package/lib/module/ZezoPay/Payments/Providers/PaymentGateways.types.d.js.map +1 -0
  5. package/lib/module/ZezoPay/Payments/Providers/Razorpay/Razorpay.js +39 -0
  6. package/lib/module/ZezoPay/Payments/Providers/Razorpay/Razorpay.js.map +1 -0
  7. package/lib/module/ZezoPay/Payments/Providers/index.js +10 -0
  8. package/lib/module/ZezoPay/Payments/Providers/index.js.map +1 -0
  9. package/lib/module/ZezoPay/ZezoPay.js +176 -0
  10. package/lib/module/ZezoPay/ZezoPay.js.map +1 -0
  11. package/lib/module/ZezoPay/components/Header.js +97 -0
  12. package/lib/module/ZezoPay/components/Header.js.map +1 -0
  13. package/lib/module/ZezoPay/components/PayButton.js +143 -0
  14. package/lib/module/ZezoPay/components/PayButton.js.map +1 -0
  15. package/lib/module/ZezoPay/components/PaymentMethod.js +250 -0
  16. package/lib/module/ZezoPay/components/PaymentMethod.js.map +1 -0
  17. package/lib/module/ZezoPay/components/Summary.js +184 -0
  18. package/lib/module/ZezoPay/components/Summary.js.map +1 -0
  19. package/lib/module/ZezoPay/components/VoucherBox.js +124 -0
  20. package/lib/module/ZezoPay/components/VoucherBox.js.map +1 -0
  21. package/lib/module/ZezoPay/index.js +5 -0
  22. package/lib/module/ZezoPay/index.js.map +1 -0
  23. package/lib/module/ZezoPay/types/index.js +4 -0
  24. package/lib/module/ZezoPay/types/index.js.map +1 -0
  25. package/lib/module/ZezoPay/utils/hooks/useAsync.js +32 -0
  26. package/lib/module/ZezoPay/utils/hooks/useAsync.js.map +1 -0
  27. package/lib/module/ZezoPay/utils/hooks/useZezoPay.js +270 -0
  28. package/lib/module/ZezoPay/utils/hooks/useZezoPay.js.map +1 -0
  29. package/lib/module/ZezoPay/utils/index.js +15 -0
  30. package/lib/module/ZezoPay/utils/index.js.map +1 -0
  31. package/lib/module/index.js +4 -0
  32. package/lib/module/index.js.map +1 -0
  33. package/lib/module/package.json +1 -0
  34. package/lib/typescript/package.json +1 -0
  35. package/lib/typescript/src/ZezoPay/Payments/Providers/Razorpay/Razorpay.d.ts +7 -0
  36. package/lib/typescript/src/ZezoPay/Payments/Providers/Razorpay/Razorpay.d.ts.map +1 -0
  37. package/lib/typescript/src/ZezoPay/Payments/Providers/index.d.ts +7 -0
  38. package/lib/typescript/src/ZezoPay/Payments/Providers/index.d.ts.map +1 -0
  39. package/lib/typescript/src/ZezoPay/ZezoPay.d.ts +5 -0
  40. package/lib/typescript/src/ZezoPay/ZezoPay.d.ts.map +1 -0
  41. package/lib/typescript/src/ZezoPay/components/Header.d.ts +12 -0
  42. package/lib/typescript/src/ZezoPay/components/Header.d.ts.map +1 -0
  43. package/lib/typescript/src/ZezoPay/components/PayButton.d.ts +12 -0
  44. package/lib/typescript/src/ZezoPay/components/PayButton.d.ts.map +1 -0
  45. package/lib/typescript/src/ZezoPay/components/PaymentMethod.d.ts +12 -0
  46. package/lib/typescript/src/ZezoPay/components/PaymentMethod.d.ts.map +1 -0
  47. package/lib/typescript/src/ZezoPay/components/Summary.d.ts +7 -0
  48. package/lib/typescript/src/ZezoPay/components/Summary.d.ts.map +1 -0
  49. package/lib/typescript/src/ZezoPay/components/VoucherBox.d.ts +9 -0
  50. package/lib/typescript/src/ZezoPay/components/VoucherBox.d.ts.map +1 -0
  51. package/lib/typescript/src/ZezoPay/index.d.ts +3 -0
  52. package/lib/typescript/src/ZezoPay/index.d.ts.map +1 -0
  53. package/lib/typescript/src/ZezoPay/types/index.d.ts +65 -0
  54. package/lib/typescript/src/ZezoPay/types/index.d.ts.map +1 -0
  55. package/lib/typescript/src/ZezoPay/utils/hooks/useAsync.d.ts +6 -0
  56. package/lib/typescript/src/ZezoPay/utils/hooks/useAsync.d.ts.map +1 -0
  57. package/lib/typescript/src/ZezoPay/utils/hooks/useZezoPay.d.ts +46 -0
  58. package/lib/typescript/src/ZezoPay/utils/hooks/useZezoPay.d.ts.map +1 -0
  59. package/lib/typescript/src/ZezoPay/utils/index.d.ts +6 -0
  60. package/lib/typescript/src/ZezoPay/utils/index.d.ts.map +1 -0
  61. package/lib/typescript/src/index.d.ts +2 -0
  62. package/lib/typescript/src/index.d.ts.map +1 -0
  63. package/package.json +181 -0
  64. package/src/ZezoPay/Payments/Providers/PaymentGateways.types.d.ts +48 -0
  65. package/src/ZezoPay/Payments/Providers/Razorpay/Razorpay.ts +46 -0
  66. package/src/ZezoPay/Payments/Providers/index.ts +8 -0
  67. package/src/ZezoPay/ZezoPay.tsx +174 -0
  68. package/src/ZezoPay/components/Header.tsx +107 -0
  69. package/src/ZezoPay/components/PayButton.tsx +132 -0
  70. package/src/ZezoPay/components/PaymentMethod.tsx +259 -0
  71. package/src/ZezoPay/components/Summary.tsx +188 -0
  72. package/src/ZezoPay/components/VoucherBox.tsx +133 -0
  73. package/src/ZezoPay/index.ts +2 -0
  74. package/src/ZezoPay/types/index.ts +69 -0
  75. package/src/ZezoPay/utils/hooks/useAsync.ts +38 -0
  76. package/src/ZezoPay/utils/hooks/useZezoPay.ts +325 -0
  77. package/src/ZezoPay/utils/index.ts +16 -0
  78. package/src/index.tsx +1 -0
package/package.json ADDED
@@ -0,0 +1,181 @@
1
+ {
2
+ "name": "@zezosoft/react-native-zezopay",
3
+ "version": "1.0.0",
4
+ "description": "A React Native library for integrating ZezoPay payment gateway seamlessly in iOS and Android apps.",
5
+ "main": "./lib/module/index.js",
6
+ "types": "./lib/typescript/src/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "source": "./src/index.tsx",
10
+ "types": "./lib/typescript/src/index.d.ts",
11
+ "default": "./lib/module/index.js"
12
+ },
13
+ "./package.json": "./package.json"
14
+ },
15
+ "files": [
16
+ "src",
17
+ "lib",
18
+ "android",
19
+ "ios",
20
+ "cpp",
21
+ "*.podspec",
22
+ "react-native.config.js",
23
+ "!ios/build",
24
+ "!android/build",
25
+ "!android/gradle",
26
+ "!android/gradlew",
27
+ "!android/gradlew.bat",
28
+ "!android/local.properties",
29
+ "!**/__tests__",
30
+ "!**/__fixtures__",
31
+ "!**/__mocks__",
32
+ "!**/.*"
33
+ ],
34
+ "scripts": {
35
+ "example": "yarn workspace @zezosoft/react-native-zezopay-example",
36
+ "test": "jest",
37
+ "typecheck": "tsc",
38
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
39
+ "lint:fix": "eslint \"**/*.{js,ts,tsx}\" --fix",
40
+ "clean": "del-cli lib",
41
+ "prepare": "bob build",
42
+ "release": "release-it --only-version",
43
+ "build": "bob build",
44
+ "watch": "nodemon --watch src --ext ts,tsx,js --delay 500ms --exec \"yarn clean && yarn build && yalc push\""
45
+ },
46
+ "keywords": [
47
+ "react-native",
48
+ "zezopay",
49
+ "payment",
50
+ "payment-gateway",
51
+ "ios",
52
+ "android",
53
+ "upi",
54
+ "razorpay",
55
+ "library"
56
+ ],
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "git+https://github.com/Zezo-Soft/react-native-zezopay.git"
60
+ },
61
+ "author": "Naresh Dhamu <narsadhamu@gmail.com> (https://github.com/naresh-dhamu)",
62
+ "license": "MIT",
63
+ "bugs": {
64
+ "url": "https://github.com/Zezo-Soft/react-native-zezopay/issues"
65
+ },
66
+ "homepage": "https://github.com/Zezo-Soft/react-native-zezopay#readme",
67
+ "publishConfig": {
68
+ "registry": "https://registry.npmjs.org/"
69
+ },
70
+ "devDependencies": {
71
+ "@commitlint/config-conventional": "^19.6.0",
72
+ "@eslint/compat": "^1.2.7",
73
+ "@eslint/eslintrc": "^3.3.0",
74
+ "@eslint/js": "^9.22.0",
75
+ "@evilmartians/lefthook": "^1.5.0",
76
+ "@react-native/babel-preset": "0.78.2",
77
+ "@react-native/eslint-config": "^0.78.0",
78
+ "@release-it/conventional-changelog": "^9.0.2",
79
+ "@types/axios": "^0.14.4",
80
+ "@types/jest": "^29.5.5",
81
+ "@types/react": "^19.0.12",
82
+ "@types/react-native-razorpay": "^2.2.6",
83
+ "commitlint": "^19.6.1",
84
+ "del-cli": "^6.0.0",
85
+ "eslint": "^9.22.0",
86
+ "eslint-config-prettier": "^10.1.1",
87
+ "eslint-plugin-prettier": "^5.2.3",
88
+ "jest": "^29.7.0",
89
+ "nodemon": "^3.1.10",
90
+ "prettier": "^3.0.3",
91
+ "react": "19.0.0",
92
+ "react-native": "0.79.5",
93
+ "react-native-builder-bob": "^0.40.13",
94
+ "react-native-linear-gradient": "^2.8.3",
95
+ "react-native-safe-area-context": "^5.6.1",
96
+ "react-native-svg": "^15.13.0",
97
+ "release-it": "^17.10.0",
98
+ "typescript": "5.4.4",
99
+ "yalc": "^1.0.0-pre.53"
100
+ },
101
+ "peerDependencies": {
102
+ "react": "*",
103
+ "react-native": "*",
104
+ "react-native-linear-gradient": "*",
105
+ "react-native-safe-area-context": "*"
106
+ },
107
+ "workspaces": [
108
+ "example"
109
+ ],
110
+ "packageManager": "yarn@3.6.1",
111
+ "jest": {
112
+ "preset": "react-native",
113
+ "modulePathIgnorePatterns": [
114
+ "<rootDir>/example/node_modules",
115
+ "<rootDir>/lib/"
116
+ ]
117
+ },
118
+ "commitlint": {
119
+ "extends": [
120
+ "@commitlint/config-conventional"
121
+ ]
122
+ },
123
+ "release-it": {
124
+ "git": {
125
+ "commitMessage": "chore: release ${version}",
126
+ "tagName": "v${version}"
127
+ },
128
+ "npm": {
129
+ "publish": true
130
+ },
131
+ "github": {
132
+ "release": true
133
+ },
134
+ "plugins": {
135
+ "@release-it/conventional-changelog": {
136
+ "preset": {
137
+ "name": "angular"
138
+ }
139
+ }
140
+ }
141
+ },
142
+ "prettier": {
143
+ "quoteProps": "consistent",
144
+ "singleQuote": true,
145
+ "tabWidth": 2,
146
+ "trailingComma": "es5",
147
+ "useTabs": false
148
+ },
149
+ "react-native-builder-bob": {
150
+ "source": "src",
151
+ "output": "lib",
152
+ "targets": [
153
+ [
154
+ "module",
155
+ {
156
+ "esm": true
157
+ }
158
+ ],
159
+ [
160
+ "typescript",
161
+ {
162
+ "project": "tsconfig.build.json"
163
+ }
164
+ ]
165
+ ]
166
+ },
167
+ "create-react-native-library": {
168
+ "languages": "js",
169
+ "type": "library",
170
+ "version": "0.52.1"
171
+ },
172
+ "dependencies": {
173
+ "@zezosoft/zezopay-client": "^1.0.1",
174
+ "axios": "^1.11.0",
175
+ "lucide-react-native": "^0.542.0",
176
+ "qs": "^6.14.0",
177
+ "react-native-keyboard-aware-scroll-view": "^0.9.5",
178
+ "react-native-razorpay": "^2.3.0",
179
+ "react-native-size-matters": "^0.4.2"
180
+ }
181
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @author Naresh Dhamu
3
+ * @lastModified Thu 25 Sep 2025 at 11:35 AM
4
+ */
5
+
6
+ declare interface IPaymentGateway {
7
+ init(): void;
8
+ open(options: IPaymentGatewayOpenOptions): void;
9
+ }
10
+
11
+ declare interface IPaymentGatewayOpenOptions {
12
+ publicKey: string;
13
+ amount: number;
14
+ currency: string;
15
+ order_id: string;
16
+ redirect_url?: string;
17
+ name?: string;
18
+ description?: string;
19
+ mode?: 'live' | 'test';
20
+ image?: string;
21
+ handler?: (response: {
22
+ razorpay_order_id: string;
23
+ razorpay_signature?: string;
24
+ razorpay_payment_id?: string;
25
+ }) => void;
26
+ OnError?: (error?: any) => void;
27
+ prefill?: {
28
+ user_name?: string;
29
+ user_email?: string;
30
+ user_phone?: string;
31
+ };
32
+ theme?: {
33
+ color?: string;
34
+ };
35
+ extraData?: {
36
+ merchantId: string;
37
+ merchantTransactionId: string;
38
+ body: string;
39
+ checksum: string;
40
+ instrumentResponse?: {
41
+ type: string;
42
+ redirectInfo: {
43
+ url: string;
44
+ method: string;
45
+ };
46
+ };
47
+ };
48
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @author Naresh Dhamu
3
+ * @lastModified Thu 25 Sep 2025 at 11:34 AM
4
+ */
5
+ import RazorpayCheckout from 'react-native-razorpay';
6
+
7
+ class Razorpay implements IPaymentGateway {
8
+ constructor() {
9
+ // init Razorpay
10
+ this.init();
11
+ }
12
+
13
+ init() {
14
+ // check if Razorpay already initialized
15
+ }
16
+
17
+ async open(options: IPaymentGatewayOpenOptions) {
18
+ RazorpayCheckout.open({
19
+ key: options.publicKey,
20
+ amount: options.amount,
21
+ currency: options.currency,
22
+ name: options.name || '',
23
+ description: options.description
24
+ ? options.description?.length > 255
25
+ ? options.description.slice(0, 255)
26
+ : options.description
27
+ : '',
28
+ order_id: options.order_id,
29
+ image: options.image,
30
+ prefill: {
31
+ name: options?.prefill?.user_name || '',
32
+ email: options?.prefill?.user_email || '',
33
+ contact: options?.prefill?.user_phone || '',
34
+ },
35
+ theme: options.theme,
36
+ })
37
+ .then((response) => {
38
+ options.handler?.(response);
39
+ })
40
+ .catch((error) => {
41
+ options.OnError?.(error);
42
+ });
43
+ }
44
+ }
45
+
46
+ export default Razorpay;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @author Naresh Dhamu
3
+ * @lastModified Thu 25 Sep 2025 at 11:37 AM
4
+ */
5
+
6
+ import Razorpay from './Razorpay/Razorpay';
7
+
8
+ export { Razorpay };
@@ -0,0 +1,174 @@
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ StyleSheet,
5
+ Keyboard,
6
+ TouchableWithoutFeedback,
7
+ StatusBar,
8
+ Text,
9
+ } from 'react-native';
10
+ import { ArrowLeft } from 'lucide-react-native';
11
+ import { scale, verticalScale, moderateScale } from 'react-native-size-matters';
12
+ import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
13
+ import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
14
+ import Header from './components/Header';
15
+ import type { ZezoPayProps } from './types';
16
+ import PaymentMethod from './components/PaymentMethod';
17
+ import { Summary } from './components/Summary';
18
+ import PayButton from './components/PayButton';
19
+ import { useZezoPay } from './utils/hooks/useZezoPay';
20
+ import { formatCurrency } from './utils';
21
+
22
+ const ZezoPay: React.FC<ZezoPayProps> = ({
23
+ title = 'Payments',
24
+ summaryItems,
25
+ onBack,
26
+ userInfo,
27
+ publicKey,
28
+ digitalProductId,
29
+ subscriptionId,
30
+ callback,
31
+ }) => {
32
+ const {
33
+ selectedPayment,
34
+ setSelectedPayment,
35
+ summaryItems: items,
36
+ totalPrice,
37
+ isSuccess,
38
+ error,
39
+ isProcessing,
40
+ providers,
41
+ loading,
42
+ providerError,
43
+ removeItem,
44
+ handlePayNow,
45
+ } = useZezoPay({
46
+ publicKey: publicKey,
47
+ userInfo: {
48
+ _id: userInfo._id,
49
+ name: userInfo?.name || '',
50
+ email: userInfo?.email || '',
51
+ },
52
+ subscriptionId: subscriptionId,
53
+ digitalProductId: digitalProductId,
54
+ summaryItems: summaryItems || [],
55
+ callback,
56
+ });
57
+
58
+ return (
59
+ <SafeAreaProvider>
60
+ <SafeAreaView style={styles.safeArea} edges={['bottom', 'left', 'right']}>
61
+ <StatusBar
62
+ barStyle="dark-content"
63
+ backgroundColor={styles.safeArea.backgroundColor}
64
+ />
65
+ <SafeAreaView style={styles.headerSafeArea} edges={['top']}>
66
+ <View style={styles.headerWrapper}>
67
+ <Header
68
+ title={title}
69
+ onBack={onBack}
70
+ leftIcon={<ArrowLeft size={moderateScale(24)} color="#000" />}
71
+ />
72
+ </View>
73
+ </SafeAreaView>
74
+
75
+ <TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
76
+ <View style={styles.container}>
77
+ <KeyboardAwareScrollView
78
+ style={styles.scrollView}
79
+ contentContainerStyle={styles.scrollContent}
80
+ keyboardShouldPersistTaps="handled"
81
+ enableOnAndroid
82
+ extraScrollHeight={verticalScale(20)}
83
+ showsVerticalScrollIndicator={false}
84
+ contentInsetAdjustmentBehavior="never"
85
+ >
86
+ <View style={styles.content}>
87
+ <PaymentMethod
88
+ providers={providers || []}
89
+ onProviderChange={setSelectedPayment}
90
+ selectedProvider={selectedPayment}
91
+ isLoading={loading}
92
+ error={providerError?.message}
93
+ />
94
+
95
+ <Summary items={items} onRemoveItem={removeItem} />
96
+ </View>
97
+ </KeyboardAwareScrollView>
98
+
99
+ {/* Bottom container for error + PayButton */}
100
+ <View style={styles.bottomContainer}>
101
+ {error ? (
102
+ <View style={styles.errorWrapper}>
103
+ <Text style={styles.errorText}>{error}</Text>
104
+ </View>
105
+ ) : null}
106
+
107
+ <PayButton
108
+ onPaymentInitiate={handlePayNow}
109
+ status={
110
+ isSuccess
111
+ ? 'success'
112
+ : isProcessing
113
+ ? 'processing'
114
+ : !selectedPayment || totalPrice === 0
115
+ ? 'disabled'
116
+ : 'idle'
117
+ }
118
+ paymentButtonText={`Pay ${formatCurrency({
119
+ amount: totalPrice,
120
+ minimumFractionDigits: 0,
121
+ })}`}
122
+ noteText="Powered by Zezo Pay"
123
+ />
124
+ </View>
125
+ </View>
126
+ </TouchableWithoutFeedback>
127
+ </SafeAreaView>
128
+ </SafeAreaProvider>
129
+ );
130
+ };
131
+
132
+ const styles = StyleSheet.create({
133
+ safeArea: { flex: 1, backgroundColor: '#FFFFFF' },
134
+ headerSafeArea: { backgroundColor: '#FFFFFF' },
135
+ headerWrapper: {
136
+ borderBottomWidth: 1,
137
+ borderBottomColor: '#E5E7EB',
138
+ zIndex: 10,
139
+ },
140
+ container: { flex: 1, position: 'relative' },
141
+ scrollView: { flex: 1, paddingBottom: verticalScale(80) },
142
+ scrollContent: {
143
+ flexGrow: 1,
144
+ paddingTop: verticalScale(10),
145
+ paddingBottom: verticalScale(80),
146
+ },
147
+ content: { paddingHorizontal: scale(16) },
148
+ bottomContainer: {
149
+ position: 'absolute',
150
+ bottom: 0,
151
+ left: 0,
152
+ right: 0,
153
+ paddingHorizontal: scale(16),
154
+ paddingVertical: verticalScale(16),
155
+ backgroundColor: '#FFFFFF',
156
+ borderTopWidth: 1,
157
+ borderTopColor: '#E5E7EB',
158
+ alignItems: 'center',
159
+ zIndex: 5,
160
+ },
161
+ errorWrapper: {
162
+ marginBottom: verticalScale(8),
163
+ width: '100%',
164
+ alignItems: 'center',
165
+ },
166
+ errorText: {
167
+ color: '#DC2626',
168
+ fontSize: moderateScale(14),
169
+ fontWeight: '500',
170
+ textAlign: 'center',
171
+ },
172
+ });
173
+
174
+ export default ZezoPay;
@@ -0,0 +1,107 @@
1
+ import React from 'react';
2
+ import { View, Text, Pressable, StyleSheet, Platform } from 'react-native';
3
+ import type { ViewStyle, TextStyle } from 'react-native';
4
+ import { ArrowLeft } from 'lucide-react-native';
5
+ import { scale, moderateScale } from 'react-native-size-matters';
6
+
7
+ export interface HeaderProps {
8
+ title: string;
9
+ titleStyle?: TextStyle;
10
+ containerStyle?: ViewStyle;
11
+ leftIcon?: React.ReactNode;
12
+ onBack?: () => void;
13
+ }
14
+
15
+ const Header: React.FC<HeaderProps> = ({
16
+ title,
17
+ titleStyle,
18
+ containerStyle,
19
+ leftIcon,
20
+ onBack,
21
+ }) => {
22
+ return (
23
+ <View style={[styles.header, containerStyle]}>
24
+ {/* Left Button Container */}
25
+ <View style={styles.gridItemLeft}>
26
+ <View style={styles.backBtnContainer}>
27
+ <Pressable
28
+ onPress={onBack}
29
+ android_ripple={{
30
+ color: 'rgba(0,0,0,0.1)',
31
+ borderless: false,
32
+ radius: scale(100),
33
+ }}
34
+ style={({ pressed }) => [
35
+ styles.backBtnWrapper,
36
+ pressed && Platform.OS === 'ios' && styles.backBtnPressed,
37
+ ]}
38
+ hitSlop={10}
39
+ >
40
+ <View style={styles.backBtn}>
41
+ {leftIcon ? (
42
+ leftIcon
43
+ ) : (
44
+ <ArrowLeft size={moderateScale(20)} color="#000" />
45
+ )}
46
+ </View>
47
+ </Pressable>
48
+ </View>
49
+ </View>
50
+
51
+ {/* Title */}
52
+ <View style={styles.gridItem}>
53
+ <Text style={[styles.title, titleStyle]} numberOfLines={1}>
54
+ {title}
55
+ </Text>
56
+ </View>
57
+
58
+ <View style={styles.gridItem} />
59
+ </View>
60
+ );
61
+ };
62
+
63
+ const styles = StyleSheet.create({
64
+ header: {
65
+ flexDirection: 'row',
66
+ alignItems: 'center',
67
+ width: '100%',
68
+ height: scale(44),
69
+ paddingHorizontal: scale(16),
70
+ justifyContent: 'space-between',
71
+ },
72
+ gridItem: {
73
+ flex: 1,
74
+ alignItems: 'center',
75
+ justifyContent: 'center',
76
+ },
77
+ gridItemLeft: {
78
+ flex: 1,
79
+ alignItems: 'flex-start',
80
+ justifyContent: 'center',
81
+ },
82
+ backBtnContainer: {
83
+ borderRadius: scale(100),
84
+ overflow: 'hidden', // crucial for Android ripple
85
+ },
86
+ backBtnWrapper: {
87
+ borderRadius: scale(100),
88
+ },
89
+ backBtn: {
90
+ justifyContent: 'center',
91
+ alignItems: 'center',
92
+ padding: scale(10),
93
+ width: scale(35),
94
+ height: scale(35),
95
+ },
96
+ backBtnPressed: {
97
+ backgroundColor: 'rgba(0,0,0,0.1)', // iOS pressed effect
98
+ },
99
+ title: {
100
+ fontSize: moderateScale(18),
101
+ fontWeight: '700',
102
+ color: '#000',
103
+ textAlign: 'center',
104
+ },
105
+ });
106
+
107
+ export default Header;
@@ -0,0 +1,132 @@
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ Pressable,
6
+ StyleSheet,
7
+ ActivityIndicator,
8
+ } from 'react-native';
9
+ import { scale, verticalScale, moderateScale } from 'react-native-size-matters';
10
+ import LinearGradient from 'react-native-linear-gradient';
11
+ import { Check } from 'lucide-react-native';
12
+
13
+ interface PayButtonProps {
14
+ onPaymentInitiate: () => void;
15
+ status?: 'idle' | 'processing' | 'success' | 'disabled';
16
+ paymentButtonText?: string;
17
+ paymentProcessingText?: string;
18
+ paymentSuccessText?: string;
19
+ noteText?: string;
20
+ }
21
+
22
+ const PayButton: React.FC<PayButtonProps> = ({
23
+ onPaymentInitiate,
24
+ status = 'idle',
25
+ paymentButtonText = 'Pay Now',
26
+ paymentProcessingText = 'Processing...',
27
+ paymentSuccessText = 'Payment Successful',
28
+ noteText = 'Powered by Zezo Pay',
29
+ }) => {
30
+ const colorsMap = {
31
+ idle: ['#0251ca', '#063482'],
32
+ processing: ['#0a84ff', '#1784e6'],
33
+ success: ['#28a745', '#1c7c31'],
34
+ disabled: ['#556fadff', '#3d71e9ff'],
35
+ };
36
+
37
+ return (
38
+ <View style={styles.container}>
39
+ {status === 'success' ? (
40
+ <View style={styles.shadowWrapper}>
41
+ <LinearGradient
42
+ colors={colorsMap.success}
43
+ start={{ x: 0, y: 0 }}
44
+ end={{ x: 1, y: 0 }}
45
+ style={styles.paymentButton}
46
+ >
47
+ <Check size={20} color="#fff" />
48
+ <Text style={[styles.successText, { marginLeft: scale(8) }]}>
49
+ {paymentSuccessText}
50
+ </Text>
51
+ </LinearGradient>
52
+ </View>
53
+ ) : (
54
+ <Pressable
55
+ onPress={onPaymentInitiate}
56
+ disabled={status === 'processing' || status === 'disabled'}
57
+ style={({ pressed }) => [
58
+ { opacity: pressed ? 0.85 : 1, width: '100%' },
59
+ ]}
60
+ >
61
+ <View style={styles.shadowWrapper}>
62
+ <LinearGradient
63
+ colors={colorsMap[status]}
64
+ start={{ x: 0, y: 0 }}
65
+ end={{ x: 1, y: 0 }}
66
+ style={styles.paymentButton}
67
+ >
68
+ {status === 'processing' ? (
69
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
70
+ <ActivityIndicator
71
+ color="#fff"
72
+ style={{ marginRight: scale(8) }}
73
+ />
74
+ <Text style={styles.paymentText}>
75
+ {paymentProcessingText}
76
+ </Text>
77
+ </View>
78
+ ) : (
79
+ <Text style={styles.paymentText}>{paymentButtonText}</Text>
80
+ )}
81
+ </LinearGradient>
82
+ </View>
83
+ </Pressable>
84
+ )}
85
+
86
+ {noteText && <Text style={styles.noteText}>{noteText}</Text>}
87
+ </View>
88
+ );
89
+ };
90
+
91
+ const styles = StyleSheet.create({
92
+ container: { width: '100%', alignItems: 'center' },
93
+ shadowWrapper: {
94
+ width: '100%',
95
+ height: verticalScale(50),
96
+ borderRadius: scale(12),
97
+ shadowColor: '#000',
98
+ shadowOffset: { width: 0, height: 3 },
99
+ shadowOpacity: 0.2,
100
+ shadowRadius: 4,
101
+ elevation: 3,
102
+ backgroundColor: '#0000',
103
+ justifyContent: 'center',
104
+ },
105
+ paymentButton: {
106
+ width: '100%',
107
+ height: '100%',
108
+ borderRadius: scale(12),
109
+ justifyContent: 'center',
110
+ alignItems: 'center',
111
+ flexDirection: 'row',
112
+ },
113
+ paymentText: {
114
+ color: '#fff',
115
+ fontSize: moderateScale(18),
116
+ fontWeight: '700',
117
+ },
118
+ successText: {
119
+ color: '#fff',
120
+ fontSize: moderateScale(18),
121
+ fontWeight: '700',
122
+ },
123
+ noteText: {
124
+ marginTop: verticalScale(10),
125
+ fontSize: moderateScale(13),
126
+ fontWeight: '600',
127
+ color: '#FF7847',
128
+ textAlign: 'center',
129
+ },
130
+ });
131
+
132
+ export default PayButton;