react-native-payvessel 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.
- package/LICENSE +21 -0
- package/README.md +243 -0
- package/lib/PayvesselCheckout.d.ts +30 -0
- package/lib/PayvesselCheckout.d.ts.map +1 -0
- package/lib/PayvesselCheckout.js +387 -0
- package/lib/PayvesselCheckout.js.map +1 -0
- package/lib/index.d.ts +14 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +29 -0
- package/lib/index.js.map +1 -0
- package/lib/types.d.ts +168 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +22 -0
- package/lib/types.js.map +1 -0
- package/lib/usePayvessel.d.ts +74 -0
- package/lib/usePayvessel.d.ts.map +1 -0
- package/lib/usePayvessel.js +97 -0
- package/lib/usePayvessel.js.map +1 -0
- package/package.json +55 -0
- package/src/PayvesselCheckout.tsx +507 -0
- package/src/index.ts +50 -0
- package/src/types.ts +200 -0
- package/src/usePayvessel.ts +156 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment status enum
|
|
3
|
+
*/
|
|
4
|
+
export enum PaymentStatus {
|
|
5
|
+
SUCCESS = 'success',
|
|
6
|
+
FAILED = 'failed',
|
|
7
|
+
CANCELLED = 'cancelled',
|
|
8
|
+
PENDING = 'pending',
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Payment channels supported by Payvessel
|
|
13
|
+
*/
|
|
14
|
+
export enum PaymentChannel {
|
|
15
|
+
BANK_TRANSFER = 'BANK_TRANSFER',
|
|
16
|
+
CARD = 'CARD',
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Checkout configuration
|
|
21
|
+
*/
|
|
22
|
+
export interface CheckoutConfig {
|
|
23
|
+
/** Your Payvessel API key */
|
|
24
|
+
apiKey: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Customer information for checkout
|
|
29
|
+
*/
|
|
30
|
+
export interface CustomerInfo {
|
|
31
|
+
/** Customer's email address */
|
|
32
|
+
email: string;
|
|
33
|
+
/** Customer's phone number */
|
|
34
|
+
phoneNumber?: string;
|
|
35
|
+
/** Customer's full name */
|
|
36
|
+
name: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Payment information
|
|
41
|
+
*/
|
|
42
|
+
export interface PaymentInfo {
|
|
43
|
+
/** Amount to charge (as string or number) */
|
|
44
|
+
amount: string | number;
|
|
45
|
+
/** Currency code (default: NGN) */
|
|
46
|
+
currency?: string;
|
|
47
|
+
/** Payment channels to enable */
|
|
48
|
+
channels?: PaymentChannel[];
|
|
49
|
+
/** Custom metadata */
|
|
50
|
+
metadata?: Record<string, unknown>;
|
|
51
|
+
/** Unique transaction reference */
|
|
52
|
+
reference?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Checkout parameters combining customer and payment info
|
|
57
|
+
*/
|
|
58
|
+
export interface CheckoutParams extends CustomerInfo, PaymentInfo {}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Transaction data returned from initialization
|
|
62
|
+
*/
|
|
63
|
+
export interface TransactionData {
|
|
64
|
+
id: string;
|
|
65
|
+
reference: string;
|
|
66
|
+
access_code: string;
|
|
67
|
+
amount: number;
|
|
68
|
+
currency: string;
|
|
69
|
+
customer_email: string;
|
|
70
|
+
customer_name: string;
|
|
71
|
+
status: string;
|
|
72
|
+
[key: string]: unknown;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Success response from checkout
|
|
77
|
+
*/
|
|
78
|
+
export interface PayvesselSuccessResponse {
|
|
79
|
+
status: PaymentStatus.SUCCESS;
|
|
80
|
+
reference?: string;
|
|
81
|
+
transactionId?: string;
|
|
82
|
+
accessCode?: string;
|
|
83
|
+
paymentId?: string;
|
|
84
|
+
data?: TransactionData | Record<string, unknown>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Error response from checkout
|
|
89
|
+
*/
|
|
90
|
+
export interface PayvesselErrorResponse {
|
|
91
|
+
status: PaymentStatus.FAILED;
|
|
92
|
+
message: string;
|
|
93
|
+
code?: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Close response
|
|
98
|
+
*/
|
|
99
|
+
export interface PayvesselCloseResponse {
|
|
100
|
+
status: PaymentStatus.CANCELLED;
|
|
101
|
+
reference?: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Combined response type
|
|
106
|
+
*/
|
|
107
|
+
export type PayvesselResponse =
|
|
108
|
+
| PayvesselSuccessResponse
|
|
109
|
+
| PayvesselErrorResponse
|
|
110
|
+
| PayvesselCloseResponse;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Callback types
|
|
114
|
+
*/
|
|
115
|
+
export type OnSuccessCallback = (response: PayvesselSuccessResponse) => void;
|
|
116
|
+
export type OnErrorCallback = (error: PayvesselErrorResponse) => void;
|
|
117
|
+
export type OnCloseCallback = () => void;
|
|
118
|
+
export type OnSuccessfulOrderCallback = (response: PayvesselSuccessResponse) => void;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Props for PayvesselCheckout component
|
|
122
|
+
*/
|
|
123
|
+
export interface PayvesselCheckoutProps {
|
|
124
|
+
/** Whether the checkout modal is visible */
|
|
125
|
+
visible: boolean;
|
|
126
|
+
|
|
127
|
+
/** Your Payvessel API key */
|
|
128
|
+
apiKey: string;
|
|
129
|
+
|
|
130
|
+
/** Customer's email address */
|
|
131
|
+
customerEmail: string;
|
|
132
|
+
|
|
133
|
+
/** Customer's phone number */
|
|
134
|
+
customerPhoneNumber?: string;
|
|
135
|
+
|
|
136
|
+
/** Amount to charge */
|
|
137
|
+
amount: string | number;
|
|
138
|
+
|
|
139
|
+
/** Currency code (default: NGN) */
|
|
140
|
+
currency?: string;
|
|
141
|
+
|
|
142
|
+
/** Customer's full name */
|
|
143
|
+
customerName: string;
|
|
144
|
+
|
|
145
|
+
/** Payment channels to enable (default: ['BANK_TRANSFER']) */
|
|
146
|
+
channels?: PaymentChannel[] | string[];
|
|
147
|
+
|
|
148
|
+
/** Custom metadata */
|
|
149
|
+
metadata?: Record<string, unknown>;
|
|
150
|
+
|
|
151
|
+
/** Unique transaction reference */
|
|
152
|
+
reference?: string;
|
|
153
|
+
|
|
154
|
+
/** Called when transaction is initialized successfully */
|
|
155
|
+
onSuccess?: OnSuccessCallback;
|
|
156
|
+
|
|
157
|
+
/** Called when an error occurs */
|
|
158
|
+
onError?: OnErrorCallback;
|
|
159
|
+
|
|
160
|
+
/** Called when checkout is closed */
|
|
161
|
+
onClose?: OnCloseCallback;
|
|
162
|
+
|
|
163
|
+
/** Called when payment is confirmed successful */
|
|
164
|
+
onSuccessfulOrder?: OnSuccessfulOrderCallback;
|
|
165
|
+
|
|
166
|
+
/** Show close button (default: true) */
|
|
167
|
+
showCloseButton?: boolean;
|
|
168
|
+
|
|
169
|
+
/** Close button text (default: '✕') */
|
|
170
|
+
closeButtonText?: string;
|
|
171
|
+
|
|
172
|
+
/** Loading text (default: 'Initializing checkout...') */
|
|
173
|
+
loadingText?: string;
|
|
174
|
+
|
|
175
|
+
/** Header title (default: 'Checkout') */
|
|
176
|
+
headerTitle?: string;
|
|
177
|
+
|
|
178
|
+
/** Show header (default: true) */
|
|
179
|
+
showHeader?: boolean;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Hook return type
|
|
184
|
+
*/
|
|
185
|
+
export interface UsePayvesselReturn {
|
|
186
|
+
/** Whether checkout is visible */
|
|
187
|
+
isVisible: boolean;
|
|
188
|
+
/** Whether checkout is loading */
|
|
189
|
+
isLoading: boolean;
|
|
190
|
+
/** Current error message */
|
|
191
|
+
error: string | null;
|
|
192
|
+
/** Transaction data */
|
|
193
|
+
transactionData: TransactionData | null;
|
|
194
|
+
/** Open the checkout */
|
|
195
|
+
openCheckout: (params: CheckoutParams) => void;
|
|
196
|
+
/** Close the checkout */
|
|
197
|
+
closeCheckout: () => void;
|
|
198
|
+
/** The checkout component to render */
|
|
199
|
+
CheckoutModal: React.FC;
|
|
200
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* usePayvessel Hook
|
|
3
|
+
*
|
|
4
|
+
* A React Hook for programmatically controlling the Payvessel checkout.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState, useCallback } from 'react';
|
|
8
|
+
import type {
|
|
9
|
+
CheckoutParams,
|
|
10
|
+
TransactionData,
|
|
11
|
+
PayvesselSuccessResponse,
|
|
12
|
+
PayvesselErrorResponse,
|
|
13
|
+
} from './types';
|
|
14
|
+
import { PaymentStatus } from './types';
|
|
15
|
+
|
|
16
|
+
export interface UsePayvesselOptions {
|
|
17
|
+
/** Your Payvessel API key */
|
|
18
|
+
apiKey: string;
|
|
19
|
+
/** Called when payment is successful */
|
|
20
|
+
onSuccess?: (response: PayvesselSuccessResponse) => void;
|
|
21
|
+
/** Called when payment fails */
|
|
22
|
+
onError?: (error: PayvesselErrorResponse) => void;
|
|
23
|
+
/** Called when checkout is closed */
|
|
24
|
+
onClose?: () => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface UsePayvesselReturn {
|
|
28
|
+
/** Whether the checkout is currently visible */
|
|
29
|
+
isVisible: boolean;
|
|
30
|
+
/** Whether the checkout is loading */
|
|
31
|
+
isLoading: boolean;
|
|
32
|
+
/** Current error message, if any */
|
|
33
|
+
error: string | null;
|
|
34
|
+
/** Transaction data from initialization */
|
|
35
|
+
transactionData: TransactionData | null;
|
|
36
|
+
/** Open the checkout with given parameters */
|
|
37
|
+
openCheckout: (params: CheckoutParams) => void;
|
|
38
|
+
/** Close the checkout */
|
|
39
|
+
closeCheckout: () => void;
|
|
40
|
+
/** Reset any error state */
|
|
41
|
+
resetError: () => void;
|
|
42
|
+
/** Props to spread on PayvesselCheckout component */
|
|
43
|
+
checkoutProps: {
|
|
44
|
+
visible: boolean;
|
|
45
|
+
apiKey: string;
|
|
46
|
+
customerEmail: string;
|
|
47
|
+
customerPhoneNumber?: string;
|
|
48
|
+
customerName: string;
|
|
49
|
+
amount: string | number;
|
|
50
|
+
currency?: string;
|
|
51
|
+
channels?: string[];
|
|
52
|
+
metadata?: Record<string, unknown>;
|
|
53
|
+
reference?: string;
|
|
54
|
+
onSuccess?: (response: PayvesselSuccessResponse) => void;
|
|
55
|
+
onError?: (error: PayvesselErrorResponse) => void;
|
|
56
|
+
onClose?: () => void;
|
|
57
|
+
} | null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Hook for managing Payvessel checkout state
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```tsx
|
|
65
|
+
* const { openCheckout, closeCheckout, checkoutProps } = usePayvessel({
|
|
66
|
+
* apiKey: 'YOUR_API_KEY',
|
|
67
|
+
* onSuccess: (response) => console.log('Payment successful', response),
|
|
68
|
+
* onError: (error) => console.log('Payment failed', error),
|
|
69
|
+
* onClose: () => console.log('Checkout closed'),
|
|
70
|
+
* });
|
|
71
|
+
*
|
|
72
|
+
* // Open checkout
|
|
73
|
+
* openCheckout({
|
|
74
|
+
* email: 'customer@example.com',
|
|
75
|
+
* name: 'John Doe',
|
|
76
|
+
* amount: 1000,
|
|
77
|
+
* });
|
|
78
|
+
*
|
|
79
|
+
* // In your JSX
|
|
80
|
+
* {checkoutProps && <PayvesselCheckout {...checkoutProps} />}
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export function usePayvessel(options: UsePayvesselOptions): UsePayvesselReturn {
|
|
84
|
+
const { apiKey, onSuccess, onError, onClose } = options;
|
|
85
|
+
|
|
86
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
87
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
88
|
+
const [error, setError] = useState<string | null>(null);
|
|
89
|
+
const [transactionData, setTransactionData] = useState<TransactionData | null>(null);
|
|
90
|
+
const [checkoutParams, setCheckoutParams] = useState<CheckoutParams | null>(null);
|
|
91
|
+
|
|
92
|
+
const openCheckout = useCallback((params: CheckoutParams) => {
|
|
93
|
+
setCheckoutParams(params);
|
|
94
|
+
setIsVisible(true);
|
|
95
|
+
setIsLoading(true);
|
|
96
|
+
setError(null);
|
|
97
|
+
}, []);
|
|
98
|
+
|
|
99
|
+
const closeCheckout = useCallback(() => {
|
|
100
|
+
setIsVisible(false);
|
|
101
|
+
setIsLoading(false);
|
|
102
|
+
setCheckoutParams(null);
|
|
103
|
+
setTransactionData(null);
|
|
104
|
+
onClose?.();
|
|
105
|
+
}, [onClose]);
|
|
106
|
+
|
|
107
|
+
const resetError = useCallback(() => {
|
|
108
|
+
setError(null);
|
|
109
|
+
}, []);
|
|
110
|
+
|
|
111
|
+
const handleSuccess = useCallback((response: PayvesselSuccessResponse) => {
|
|
112
|
+
setIsLoading(false);
|
|
113
|
+
setTransactionData(response.data as TransactionData || null);
|
|
114
|
+
onSuccess?.(response);
|
|
115
|
+
closeCheckout();
|
|
116
|
+
}, [onSuccess, closeCheckout]);
|
|
117
|
+
|
|
118
|
+
const handleError = useCallback((errorResponse: PayvesselErrorResponse) => {
|
|
119
|
+
setIsLoading(false);
|
|
120
|
+
setError(errorResponse.message);
|
|
121
|
+
onError?.(errorResponse);
|
|
122
|
+
}, [onError]);
|
|
123
|
+
|
|
124
|
+
const handleClose = useCallback(() => {
|
|
125
|
+
closeCheckout();
|
|
126
|
+
}, [closeCheckout]);
|
|
127
|
+
|
|
128
|
+
const checkoutProps = checkoutParams ? {
|
|
129
|
+
visible: isVisible,
|
|
130
|
+
apiKey,
|
|
131
|
+
customerEmail: checkoutParams.email,
|
|
132
|
+
customerPhoneNumber: checkoutParams.phoneNumber,
|
|
133
|
+
customerName: checkoutParams.name,
|
|
134
|
+
amount: checkoutParams.amount,
|
|
135
|
+
currency: checkoutParams.currency,
|
|
136
|
+
channels: checkoutParams.channels,
|
|
137
|
+
metadata: checkoutParams.metadata,
|
|
138
|
+
reference: checkoutParams.reference,
|
|
139
|
+
onSuccess: handleSuccess,
|
|
140
|
+
onError: handleError,
|
|
141
|
+
onClose: handleClose,
|
|
142
|
+
} : null;
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
isVisible,
|
|
146
|
+
isLoading,
|
|
147
|
+
error,
|
|
148
|
+
transactionData,
|
|
149
|
+
openCheckout,
|
|
150
|
+
closeCheckout,
|
|
151
|
+
resetError,
|
|
152
|
+
checkoutProps,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export default usePayvessel;
|