xcel-paygate-sdk 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 (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +225 -0
  3. package/dist/api/client.d.ts +19 -0
  4. package/dist/api/client.d.ts.map +1 -0
  5. package/dist/api/client.js +215 -0
  6. package/dist/components/XcelPaymentFlow.d.ts +50 -0
  7. package/dist/components/XcelPaymentFlow.d.ts.map +1 -0
  8. package/dist/components/XcelPaymentFlow.js +125 -0
  9. package/dist/components/XcelPaymentScreen.d.ts +67 -0
  10. package/dist/components/XcelPaymentScreen.d.ts.map +1 -0
  11. package/dist/components/XcelPaymentScreen.js +356 -0
  12. package/dist/components/XcelPaymentWebView.d.ts +76 -0
  13. package/dist/components/XcelPaymentWebView.d.ts.map +1 -0
  14. package/dist/components/XcelPaymentWebView.js +413 -0
  15. package/dist/components/index.d.ts +12 -0
  16. package/dist/components/index.d.ts.map +1 -0
  17. package/dist/components/index.js +14 -0
  18. package/dist/context/XcelPayGateProvider.d.ts +56 -0
  19. package/dist/context/XcelPayGateProvider.d.ts.map +1 -0
  20. package/dist/context/XcelPayGateProvider.js +107 -0
  21. package/dist/hooks/use-payment-completion.d.ts +75 -0
  22. package/dist/hooks/use-payment-completion.d.ts.map +1 -0
  23. package/dist/hooks/use-payment-completion.js +181 -0
  24. package/dist/hooks/use-xcel-paygate.d.ts +96 -0
  25. package/dist/hooks/use-xcel-paygate.d.ts.map +1 -0
  26. package/dist/hooks/use-xcel-paygate.js +279 -0
  27. package/dist/index.d.ts +14 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +65 -0
  30. package/dist/services/checkout.d.ts +32 -0
  31. package/dist/services/checkout.d.ts.map +1 -0
  32. package/dist/services/checkout.js +137 -0
  33. package/dist/services/xcel-wallet.d.ts +23 -0
  34. package/dist/services/xcel-wallet.d.ts.map +1 -0
  35. package/dist/services/xcel-wallet.js +107 -0
  36. package/dist/types/index.d.ts +373 -0
  37. package/dist/types/index.d.ts.map +1 -0
  38. package/dist/types/index.js +2 -0
  39. package/dist/utils/payment-completion.d.ts +87 -0
  40. package/dist/utils/payment-completion.d.ts.map +1 -0
  41. package/dist/utils/payment-completion.js +110 -0
  42. package/dist/utils/payment-helpers.d.ts +55 -0
  43. package/dist/utils/payment-helpers.d.ts.map +1 -0
  44. package/dist/utils/payment-helpers.js +261 -0
  45. package/package.json +51 -0
  46. package/src/api/client.ts +326 -0
  47. package/src/components/XcelPaymentFlow.tsx +154 -0
  48. package/src/components/XcelPaymentScreen.tsx +477 -0
  49. package/src/components/XcelPaymentWebView.tsx +533 -0
  50. package/src/components/index.ts +14 -0
  51. package/src/context/XcelPayGateProvider.tsx +98 -0
  52. package/src/hooks/use-payment-completion.ts +225 -0
  53. package/src/hooks/use-xcel-paygate.ts +363 -0
  54. package/src/index.ts +70 -0
  55. package/src/services/checkout.ts +165 -0
  56. package/src/services/xcel-wallet.ts +175 -0
  57. package/src/types/index.ts +407 -0
  58. package/src/utils/payment-completion.ts +144 -0
  59. package/src/utils/payment-helpers.ts +287 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 XCEL
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.
package/README.md ADDED
@@ -0,0 +1,225 @@
1
+ # XCEL PayGate SDK
2
+
3
+ Official React Native SDK for XCEL PayGate payment integration. Accept mobile money and card payments in your React Native apps with just a few lines of code.
4
+
5
+ [![npm version](https://badge.fury.io/js/@xcelapp%2Fpaygate-sdk.svg)](https://www.npmjs.com/package/@xcelapp/paygate-sdk)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Features
9
+
10
+ ✅ **Easy Integration** - Get started in 5 minutes with drop-in UI components
11
+ ✅ **Multiple Payment Methods** - Mobile Money, Cards, and more
12
+ ✅ **TypeScript Support** - Full type safety out of the box
13
+ ✅ **Customizable UI** - Pre-built components that match your brand
14
+ ✅ **Zero Native Code** - Pure JavaScript/TypeScript SDK
15
+ ✅ **Production Ready** - Built-in error handling and loading states
16
+
17
+ ## Supported Countries
18
+
19
+ 🇨🇲 Cameroon | 🇬🇭 Ghana | 🇰🇪 Kenya | 🇳🇬 Nigeria | And more across Africa
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install @xcelapp/paygate-sdk react-native-webview
25
+ ```
26
+
27
+ or with yarn:
28
+
29
+ ```bash
30
+ yarn add @xcelapp/paygate-sdk react-native-webview
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ ### Option 1: All-in-One Component (Easiest)
36
+
37
+ The quickest way to get started. This component handles everything:
38
+
39
+ ```tsx
40
+ import { XcelPaymentFlow } from '@xcelapp/paygate-sdk';
41
+
42
+ export default function PaymentScreen() {
43
+ return (
44
+ <XcelPaymentFlow
45
+ config={{
46
+ merchantId: 'YOUR_MERCHANT_ID',
47
+ publicKey: 'YOUR_PUBLIC_KEY',
48
+ }}
49
+ onPaymentComplete={(result) => {
50
+ if (result.status === 'SUCCESS') {
51
+ console.log('Payment successful!', result);
52
+ } else {
53
+ console.log('Payment failed', result);
54
+ }
55
+ }}
56
+ />
57
+ );
58
+ }
59
+ ```
60
+
61
+ ### Option 2: Individual Components (More Control)
62
+
63
+ For more control over the payment flow:
64
+
65
+ ```tsx
66
+ import { XcelPaymentScreen } from '@xcelapp/paygate-sdk';
67
+ import { useRouter } from 'expo-router';
68
+
69
+ export default function PaymentScreen() {
70
+ const router = useRouter();
71
+
72
+ return (
73
+ <XcelPaymentScreen
74
+ config={{
75
+ merchantId: 'YOUR_MERCHANT_ID',
76
+ publicKey: 'YOUR_PUBLIC_KEY',
77
+ }}
78
+ onPaymentLinkGenerated={(paymentLink, paymentCode) => {
79
+ router.push({
80
+ pathname: '/payment-webview',
81
+ params: { paymentLink, paymentCode },
82
+ });
83
+ }}
84
+ defaultValues={{
85
+ amount: '1000',
86
+ email: 'customer@example.com',
87
+ }}
88
+ />
89
+ );
90
+ }
91
+ ```
92
+
93
+ ### Option 3: Hooks Only (Maximum Control)
94
+
95
+ Use just the hooks for complete control over UI:
96
+
97
+ ```tsx
98
+ import { useCheckout } from '@xcelapp/paygate-sdk';
99
+
100
+ export default function PaymentScreen() {
101
+ const { initiatePayment, loading } = useCheckout({
102
+ merchantId: 'YOUR_MERCHANT_ID',
103
+ publicKey: 'YOUR_PUBLIC_KEY',
104
+ });
105
+
106
+ const handlePay = async () => {
107
+ const result = await initiatePayment({
108
+ amount: '1000',
109
+ currency: 'XAF',
110
+ customer_email: 'customer@example.com',
111
+ channel: 'WEB',
112
+ redirect_url: 'https://yourapp.com/callback',
113
+ });
114
+
115
+ console.log('Payment link:', result.data.payment_link);
116
+ };
117
+
118
+ return (
119
+ <Button title="Pay Now" onPress={handlePay} disabled={loading} />
120
+ );
121
+ }
122
+ ```
123
+
124
+ ## Get Your API Credentials
125
+
126
+ 1. Visit [XCEL Business Dashboard](https://business.xcelapp.com/)
127
+ 2. Sign up or log in
128
+ 3. Get your **Merchant ID** and **Public Key** from the dashboard
129
+
130
+ ## Configuration
131
+
132
+ ### Using Provider Pattern (Recommended for multiple screens)
133
+
134
+ Wrap your app with the provider to share config across all screens:
135
+
136
+ ```tsx
137
+ // app/_layout.tsx
138
+ import { XcelPayGateProvider } from '@xcelapp/paygate-sdk';
139
+
140
+ export default function RootLayout() {
141
+ return (
142
+ <XcelPayGateProvider
143
+ config={{
144
+ merchantId: process.env.EXPO_PUBLIC_XCEL_MERCHANT_ID,
145
+ publicKey: process.env.EXPO_PUBLIC_XCEL_PUBLIC_KEY,
146
+ }}
147
+ >
148
+ {/* Your app */}
149
+ </XcelPayGateProvider>
150
+ );
151
+ }
152
+
153
+ // app/payment.tsx
154
+ // No config needed - components use Provider context automatically!
155
+ import { XcelPaymentScreen } from '@xcelapp/paygate-sdk';
156
+
157
+ export default function Payment() {
158
+ return <XcelPaymentScreen />;
159
+ }
160
+ ```
161
+
162
+ ### Environment Variables
163
+
164
+ Create a `.env` file:
165
+
166
+ ```env
167
+ EXPO_PUBLIC_XCEL_MERCHANT_ID=your_merchant_id
168
+ EXPO_PUBLIC_XCEL_PUBLIC_KEY=your_public_key
169
+ ```
170
+
171
+ ## Documentation
172
+
173
+ - 📖 [Complete API Reference](./INTEGRATION_REFERENCE.md) - All endpoints and types
174
+ - 🎨 [Component Usage Guide](./COMPONENT_USAGE.md) - UI components documentation
175
+ - 🚀 [Quick Start Examples](./COMPONENT_USAGE.md#complete-examples)
176
+
177
+ ## Requirements
178
+
179
+ - React Native >= 0.60.0
180
+ - React >= 16.8.0
181
+ - react-native-webview (for UI components)
182
+
183
+ ## TypeScript Support
184
+
185
+ The SDK is written in TypeScript and includes full type definitions:
186
+
187
+ ```tsx
188
+ import type {
189
+ XcelPayGateConfig,
190
+ TransactionData,
191
+ PaymentRequest,
192
+ PaymentResult,
193
+ } from '@xcelapp/paygate-sdk';
194
+ ```
195
+
196
+ ## Supported Payment Methods
197
+
198
+ - 📱 Mobile Money (MTN, Orange, Moov, etc.)
199
+ - 💳 Card Payments (Visa, Mastercard)
200
+ - 🏦 Bank Transfers
201
+ - 💰 XCEL Wallet
202
+
203
+ ## Support
204
+
205
+ - 📧 Email: support@xcelapp.com
206
+ - 🐛 Issues: [GitHub Issues](https://github.com/xcelapp/xcel-paygate-sdk/issues)
207
+ - 📚 Docs: [GitHub Repository](https://github.com/xcelapp/xcel-paygate-sdk)
208
+
209
+ ## License
210
+
211
+ MIT © XCEL
212
+
213
+ ## Changelog
214
+
215
+ ### 1.0.0 (2025-01-13)
216
+
217
+ - Initial release
218
+ - Drop-in UI components
219
+ - TypeScript support
220
+ - Provider pattern
221
+ - Comprehensive documentation
222
+
223
+ ---
224
+
225
+ **Made with ❤️ by XCEL**
@@ -0,0 +1,19 @@
1
+ import type { CreateXcelTransactionRequest, GenerateDynamicLinkRequest, GenerateDynamicLinkResponse, GeneratePaymentLinkRequest, GeneratePaymentLinkResponse, MerchantDetails, MerchantFeesResponse, MerchantProductsResponse, TransactionDataResponse, XcelAccountVerificationResponse, XcelPayGateConfig, XcelTransactionResponse } from "../types";
2
+ export declare class XcelPayGateClient {
3
+ private config;
4
+ constructor(config: XcelPayGateConfig);
5
+ private getHeaders;
6
+ generatePaymentLink(request: GeneratePaymentLinkRequest): Promise<GeneratePaymentLinkResponse>;
7
+ getTransactionData(paymentCode: string): Promise<TransactionDataResponse>;
8
+ getMerchantDetails(merchantId?: string): Promise<MerchantDetails>;
9
+ getMerchantProducts(merchantId?: string): Promise<MerchantProductsResponse>;
10
+ getMerchantFees(merchantId?: string): Promise<MerchantFeesResponse>;
11
+ getMerchantAccounts(merchantId?: string): Promise<any>;
12
+ verifyXcelAccount(countryCode: string, phoneNumber: string): Promise<XcelAccountVerificationResponse>;
13
+ generateDynamicLink(request: GenerateDynamicLinkRequest): Promise<GenerateDynamicLinkResponse>;
14
+ createXcelTransaction(request: CreateXcelTransactionRequest): Promise<XcelTransactionResponse>;
15
+ getXcelTransactionStatus(merchantId: string, externalReference: string): Promise<XcelTransactionResponse>;
16
+ getCheckoutUrl(merchantId?: string): string;
17
+ getFullPaymentUrl(paymentCode: string, merchantId?: string): string;
18
+ }
19
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,eAAe,EACf,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,EACvB,+BAA+B,EAC/B,iBAAiB,EACjB,uBAAuB,EACxB,MAAM,UAAU,CAAC;AAKlB,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAA8B;gBAEhC,MAAM,EAAE,iBAAiB;IAOrC,OAAO,CAAC,UAAU;IAQZ,mBAAmB,CACvB,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,2BAA2B,CAAC;IAqDjC,kBAAkB,CACtB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,uBAAuB,CAAC;IAsB7B,kBAAkB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAuBjE,mBAAmB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAoC3E,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAqBnE,mBAAmB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAuBtD,iBAAiB,CACrB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,+BAA+B,CAAC;IAoBrC,mBAAmB,CACvB,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,2BAA2B,CAAC;IAuBjC,qBAAqB,CACzB,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,uBAAuB,CAAC;IAuB7B,wBAAwB,CAC5B,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,uBAAuB,CAAC;IAsBnC,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM;IAK3C,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM;CAIpE"}
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.XcelPayGateClient = void 0;
4
+ const DEFAULT_BASE_URL = "https://api.xcelapp.com";
5
+ const PAYGATE_BASE_URL = "https://paygate.xcelapp.com";
6
+ class XcelPayGateClient {
7
+ constructor(config) {
8
+ this.config = {
9
+ ...config,
10
+ baseUrl: config.baseUrl || DEFAULT_BASE_URL,
11
+ };
12
+ }
13
+ getHeaders() {
14
+ return {
15
+ "Content-Type": "application/json",
16
+ "x-merchant-id": this.config.merchantId,
17
+ "x-public-key": this.config.publicKey,
18
+ };
19
+ }
20
+ async generatePaymentLink(request) {
21
+ const headers = this.getHeaders();
22
+ const url = `${this.config.baseUrl}/transactions-service/paygate/generate-payment-link`;
23
+ console.log('=== [XcelPayGate] Generate Payment Link Request ===');
24
+ console.log('URL:', url);
25
+ console.log('Headers:', JSON.stringify(headers, null, 2));
26
+ console.log('Payload:', JSON.stringify(request, null, 2));
27
+ const response = await fetch(url, {
28
+ method: "POST",
29
+ headers,
30
+ body: JSON.stringify(request),
31
+ });
32
+ console.log('=== [XcelPayGate] Generate Payment Link Response ===');
33
+ console.log('Status Code:', response.status);
34
+ console.log('Status Text:', response.statusText);
35
+ console.log('Response Headers:', JSON.stringify(Object.fromEntries(response.headers.entries()), null, 2));
36
+ if (!response.ok) {
37
+ const errorText = await response.text();
38
+ console.log('Error Response Body:', errorText);
39
+ let errorMessage = `Failed to generate payment link: ${response.statusText}`;
40
+ try {
41
+ const errorData = JSON.parse(errorText);
42
+ console.log('Parsed Error Data:', JSON.stringify(errorData, null, 2));
43
+ errorMessage =
44
+ errorData.message || errorData.status_reason || errorMessage;
45
+ }
46
+ catch {
47
+ errorMessage = errorText || errorMessage;
48
+ }
49
+ throw new Error(errorMessage);
50
+ }
51
+ const responseData = await response.json();
52
+ console.log('Success Response Body:', JSON.stringify(responseData, null, 2));
53
+ if (responseData.data) {
54
+ console.log('--- Response Data Details ---');
55
+ console.log('Transaction ID:', responseData.data.transaction_id);
56
+ console.log('Payment Code:', responseData.data.payment_code);
57
+ console.log('Payment Link:', responseData.data.payment_link);
58
+ console.log('Amount:', responseData.data.amount);
59
+ console.log('Currency:', responseData.data.currency);
60
+ console.log('Expires At:', responseData.data.expires_at);
61
+ }
62
+ console.log('=== End Generate Payment Link Response ===\n');
63
+ return responseData;
64
+ }
65
+ async getTransactionData(paymentCode) {
66
+ const headers = this.getHeaders();
67
+ console.log('[XcelPayGate] Get Transaction Data - Headers:', JSON.stringify(headers, null, 2));
68
+ console.log('[XcelPayGate] Get Transaction Data - Payment Code:', paymentCode);
69
+ const response = await fetch(`${this.config.baseUrl}/transactions-service/paygate/get-transaction-data/${paymentCode}`, {
70
+ method: "GET",
71
+ headers,
72
+ });
73
+ if (!response.ok) {
74
+ throw new Error(`Failed to get transaction data: ${response.statusText}`);
75
+ }
76
+ const responseData = await response.json();
77
+ console.log('[XcelPayGate] Get Transaction Data - Response:', JSON.stringify(responseData, null, 2));
78
+ return responseData;
79
+ }
80
+ async getMerchantDetails(merchantId) {
81
+ const id = merchantId || this.config.merchantId;
82
+ const headers = this.getHeaders();
83
+ console.log('[XcelPayGate] Get Merchant Details - Headers:', JSON.stringify(headers, null, 2));
84
+ console.log('[XcelPayGate] Get Merchant Details - Merchant ID:', id);
85
+ const response = await fetch(`${this.config.baseUrl}/business-api/merchant/details/${id}`, {
86
+ method: "GET",
87
+ headers,
88
+ });
89
+ if (!response.ok) {
90
+ throw new Error(`Failed to get merchant details: ${response.statusText}`);
91
+ }
92
+ const responseData = await response.json();
93
+ console.log('[XcelPayGate] Get Merchant Details - Response:', JSON.stringify(responseData, null, 2));
94
+ return responseData;
95
+ }
96
+ async getMerchantProducts(merchantId) {
97
+ var _a;
98
+ const id = merchantId || this.config.merchantId;
99
+ const headers = this.getHeaders();
100
+ console.log('[XcelPayGate] Get Merchant Products - Headers:', JSON.stringify(headers, null, 2));
101
+ console.log('[XcelPayGate] Get Merchant Products - Merchant ID:', id);
102
+ const response = await fetch(`${this.config.baseUrl}/business-api/merchant/products/${id}`, {
103
+ method: "GET",
104
+ headers,
105
+ });
106
+ if (!response.ok) {
107
+ throw new Error(`Failed to get merchant products: ${response.statusText}`);
108
+ }
109
+ const responseData = await response.json();
110
+ console.log('[XcelPayGate] Get Merchant Products - Response:', JSON.stringify(responseData, null, 2));
111
+ if (((_a = responseData.data) === null || _a === void 0 ? void 0 : _a.data) && Array.isArray(responseData.data.data)) {
112
+ console.log('--- Merchant Products ---');
113
+ responseData.data.data.forEach((product, index) => {
114
+ console.log(`Product ${index + 1}:`);
115
+ console.log(' Product ID:', product.product_id);
116
+ console.log(' Product Name:', product.name);
117
+ console.log(' Active:', product.active.status);
118
+ console.log(' Web Enabled:', product.web);
119
+ console.log(' Payment Code:', product.payment_code);
120
+ });
121
+ }
122
+ return responseData;
123
+ }
124
+ async getMerchantFees(merchantId) {
125
+ const id = merchantId || this.config.merchantId;
126
+ const headers = this.getHeaders();
127
+ console.log('[XcelPayGate] Get Merchant Fees - Headers:', JSON.stringify(headers, null, 2));
128
+ console.log('[XcelPayGate] Get Merchant Fees - Merchant ID:', id);
129
+ const response = await fetch(`${this.config.baseUrl}/transactions-service/merchant/charge-customer/${id}`, {
130
+ method: "GET",
131
+ headers,
132
+ });
133
+ if (!response.ok) {
134
+ throw new Error(`Failed to get merchant fees: ${response.statusText}`);
135
+ }
136
+ return response.json();
137
+ }
138
+ async getMerchantAccounts(merchantId) {
139
+ const id = merchantId || this.config.merchantId;
140
+ const headers = this.getHeaders();
141
+ console.log('[XcelPayGate] Get Merchant Accounts - Headers:', JSON.stringify(headers, null, 2));
142
+ console.log('[XcelPayGate] Get Merchant Accounts - Merchant ID:', id);
143
+ const response = await fetch(`${this.config.baseUrl}/business-api/merchant/pos/${id}`, {
144
+ method: "GET",
145
+ headers,
146
+ });
147
+ if (!response.ok) {
148
+ throw new Error(`Failed to get merchant accounts: ${response.statusText}`);
149
+ }
150
+ return response.json();
151
+ }
152
+ async verifyXcelAccount(countryCode, phoneNumber) {
153
+ const headers = this.getHeaders();
154
+ console.log('[XcelPayGate] Verify Xcel Account - Headers:', JSON.stringify(headers, null, 2));
155
+ console.log('[XcelPayGate] Verify Xcel Account - Country Code:', countryCode, 'Phone Number:', phoneNumber);
156
+ const response = await fetch(`${this.config.baseUrl}/xas/v1/accounts/users/${countryCode}/${phoneNumber}`, {
157
+ method: "GET",
158
+ headers,
159
+ });
160
+ if (!response.ok) {
161
+ throw new Error(`Failed to verify XCEL account: ${response.statusText}`);
162
+ }
163
+ return response.json();
164
+ }
165
+ async generateDynamicLink(request) {
166
+ const headers = this.getHeaders();
167
+ console.log('[XcelPayGate] Generate Dynamic Link - Headers:', JSON.stringify(headers, null, 2));
168
+ console.log('[XcelPayGate] Generate Dynamic Link - Payload:', JSON.stringify(request, null, 2));
169
+ const response = await fetch(`${this.config.baseUrl}/esa/otp/generate/dynamic-link`, {
170
+ method: "POST",
171
+ headers,
172
+ body: JSON.stringify(request),
173
+ });
174
+ if (!response.ok) {
175
+ throw new Error(`Failed to generate dynamic link: ${response.statusText}`);
176
+ }
177
+ return response.json();
178
+ }
179
+ async createXcelTransaction(request) {
180
+ const headers = this.getHeaders();
181
+ console.log('[XcelPayGate] Create Xcel Transaction - Headers:', JSON.stringify(headers, null, 2));
182
+ console.log('[XcelPayGate] Create Xcel Transaction - Payload:', JSON.stringify(request, null, 2));
183
+ const response = await fetch(`${this.config.baseUrl}/xas/v1/pos/create_transaction`, {
184
+ method: "POST",
185
+ headers,
186
+ body: JSON.stringify(request),
187
+ });
188
+ if (!response.ok) {
189
+ throw new Error(`Failed to create XCEL transaction: ${response.statusText}`);
190
+ }
191
+ return response.json();
192
+ }
193
+ async getXcelTransactionStatus(merchantId, externalReference) {
194
+ const headers = this.getHeaders();
195
+ console.log('[XcelPayGate] Get Xcel Transaction Status - Headers:', JSON.stringify(headers, null, 2));
196
+ console.log('[XcelPayGate] Get Xcel Transaction Status - Merchant ID:', merchantId, 'External Reference:', externalReference);
197
+ const response = await fetch(`${this.config.baseUrl}/xas/v1/pos/transaction/${merchantId}/${externalReference}`, {
198
+ method: "GET",
199
+ headers,
200
+ });
201
+ if (!response.ok) {
202
+ throw new Error(`Failed to get transaction status: ${response.statusText}`);
203
+ }
204
+ return response.json();
205
+ }
206
+ getCheckoutUrl(merchantId) {
207
+ const id = merchantId || this.config.merchantId;
208
+ return `${PAYGATE_BASE_URL}/pay/${id}`;
209
+ }
210
+ getFullPaymentUrl(paymentCode, merchantId) {
211
+ const checkoutUrl = this.getCheckoutUrl(merchantId);
212
+ return `${checkoutUrl}?code=${paymentCode}`;
213
+ }
214
+ }
215
+ exports.XcelPayGateClient = XcelPayGateClient;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * XcelPaymentFlow - Complete Payment Flow Component
3
+ *
4
+ * All-in-one component that handles:
5
+ * - Payment form UI
6
+ * - WebView navigation
7
+ * - Payment completion
8
+ * - Receipt display
9
+ *
10
+ * Just drop this in your app and you're done!
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * import { XcelPaymentFlow } from '@xcelapp/paygate-sdk';
15
+ *
16
+ * export default function App() {
17
+ * return (
18
+ * <XcelPaymentFlow
19
+ * config={{
20
+ * merchantId: 'your-merchant-id',
21
+ * publicKey: 'your-public-key',
22
+ * }}
23
+ * onPaymentComplete={(result) => {
24
+ * console.log('Payment done!', result);
25
+ * }}
26
+ * />
27
+ * );
28
+ * }
29
+ * ```
30
+ */
31
+ import React from 'react';
32
+ import { XcelPaymentScreenProps } from './XcelPaymentScreen';
33
+ import { PaymentResult } from './XcelPaymentWebView';
34
+ import type { XcelPayGateConfig } from '../types';
35
+ export interface XcelPaymentFlowProps {
36
+ /** SDK Configuration */
37
+ config?: XcelPayGateConfig;
38
+ /** Called when payment completes (success/fail) */
39
+ onPaymentComplete?: (result: PaymentResult) => void;
40
+ /** Called when payment is cancelled */
41
+ onCancel?: () => void;
42
+ /** Pass through props to XcelPaymentScreen */
43
+ screenProps?: Partial<XcelPaymentScreenProps>;
44
+ /** Show receipt screen (implement your own or use default) */
45
+ renderReceipt?: (result: PaymentResult) => React.ReactNode;
46
+ /** Use modal for WebView (default: true) */
47
+ useModal?: boolean;
48
+ }
49
+ export declare function XcelPaymentFlow({ config, onPaymentComplete, onCancel, screenProps, renderReceipt, useModal, }: XcelPaymentFlowProps): React.JSX.Element;
50
+ //# sourceMappingURL=XcelPaymentFlow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"XcelPaymentFlow.d.ts","sourceRoot":"","sources":["../../src/components/XcelPaymentFlow.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,EAAqB,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAsB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,MAAM,WAAW,oBAAoB;IACnC,wBAAwB;IACxB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAE3B,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IAEpD,uCAAuC;IACvC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAE9C,8DAA8D;IAC9D,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,KAAK,CAAC,SAAS,CAAC;IAE3D,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,iBAAiB,EACjB,QAAQ,EACR,WAAgB,EAChB,aAAa,EACb,QAAe,GAChB,EAAE,oBAAoB,qBA+EtB"}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ /**
3
+ * XcelPaymentFlow - Complete Payment Flow Component
4
+ *
5
+ * All-in-one component that handles:
6
+ * - Payment form UI
7
+ * - WebView navigation
8
+ * - Payment completion
9
+ * - Receipt display
10
+ *
11
+ * Just drop this in your app and you're done!
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * import { XcelPaymentFlow } from '@xcelapp/paygate-sdk';
16
+ *
17
+ * export default function App() {
18
+ * return (
19
+ * <XcelPaymentFlow
20
+ * config={{
21
+ * merchantId: 'your-merchant-id',
22
+ * publicKey: 'your-public-key',
23
+ * }}
24
+ * onPaymentComplete={(result) => {
25
+ * console.log('Payment done!', result);
26
+ * }}
27
+ * />
28
+ * );
29
+ * }
30
+ * ```
31
+ */
32
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
33
+ if (k2 === undefined) k2 = k;
34
+ var desc = Object.getOwnPropertyDescriptor(m, k);
35
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
36
+ desc = { enumerable: true, get: function() { return m[k]; } };
37
+ }
38
+ Object.defineProperty(o, k2, desc);
39
+ }) : (function(o, m, k, k2) {
40
+ if (k2 === undefined) k2 = k;
41
+ o[k2] = m[k];
42
+ }));
43
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
44
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
45
+ }) : function(o, v) {
46
+ o["default"] = v;
47
+ });
48
+ var __importStar = (this && this.__importStar) || (function () {
49
+ var ownKeys = function(o) {
50
+ ownKeys = Object.getOwnPropertyNames || function (o) {
51
+ var ar = [];
52
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
53
+ return ar;
54
+ };
55
+ return ownKeys(o);
56
+ };
57
+ return function (mod) {
58
+ if (mod && mod.__esModule) return mod;
59
+ var result = {};
60
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
61
+ __setModuleDefault(result, mod);
62
+ return result;
63
+ };
64
+ })();
65
+ Object.defineProperty(exports, "__esModule", { value: true });
66
+ exports.XcelPaymentFlow = XcelPaymentFlow;
67
+ const react_1 = __importStar(require("react"));
68
+ const react_native_1 = require("react-native");
69
+ const XcelPaymentScreen_1 = require("./XcelPaymentScreen");
70
+ const XcelPaymentWebView_1 = require("./XcelPaymentWebView");
71
+ function XcelPaymentFlow({ config, onPaymentComplete, onCancel, screenProps = {}, renderReceipt, useModal = true, }) {
72
+ const [paymentLink, setPaymentLink] = (0, react_1.useState)(null);
73
+ const [paymentCode, setPaymentCode] = (0, react_1.useState)(null);
74
+ const [showWebView, setShowWebView] = (0, react_1.useState)(false);
75
+ const [paymentResult, setPaymentResult] = (0, react_1.useState)(null);
76
+ const handlePaymentLinkGenerated = (link, code) => {
77
+ setPaymentLink(link);
78
+ setPaymentCode(code);
79
+ setShowWebView(true);
80
+ };
81
+ const handleSuccess = (result) => {
82
+ setPaymentResult(result);
83
+ setShowWebView(false);
84
+ onPaymentComplete === null || onPaymentComplete === void 0 ? void 0 : onPaymentComplete(result);
85
+ };
86
+ const handleFailure = (result) => {
87
+ setPaymentResult(result);
88
+ setShowWebView(false);
89
+ onPaymentComplete === null || onPaymentComplete === void 0 ? void 0 : onPaymentComplete(result);
90
+ };
91
+ const handlePending = (result) => {
92
+ setPaymentResult(result);
93
+ setShowWebView(false);
94
+ onPaymentComplete === null || onPaymentComplete === void 0 ? void 0 : onPaymentComplete(result);
95
+ };
96
+ const handleCancelWebView = () => {
97
+ setShowWebView(false);
98
+ onCancel === null || onCancel === void 0 ? void 0 : onCancel();
99
+ };
100
+ // Show receipt if available
101
+ if (paymentResult && renderReceipt) {
102
+ return <>{renderReceipt(paymentResult)}</>;
103
+ }
104
+ const webViewContent = paymentLink && (<XcelPaymentWebView_1.XcelPaymentWebView paymentLink={paymentLink} paymentCode={paymentCode || undefined} onSuccess={handleSuccess} onFailure={handleFailure} onPending={handlePending} onCancel={handleCancelWebView}/>);
105
+ return (<react_native_1.View style={styles.container}>
106
+ {/* Payment Form */}
107
+ <XcelPaymentScreen_1.XcelPaymentScreen config={config} onPaymentLinkGenerated={handlePaymentLinkGenerated} {...screenProps}/>
108
+
109
+ {/* WebView Modal or Inline */}
110
+ {showWebView && (useModal ? (<react_native_1.Modal visible={showWebView} animationType="slide" presentationStyle="fullScreen" onRequestClose={handleCancelWebView}>
111
+ <react_native_1.SafeAreaView style={styles.modalContainer}>
112
+ {webViewContent}
113
+ </react_native_1.SafeAreaView>
114
+ </react_native_1.Modal>) : (webViewContent))}
115
+ </react_native_1.View>);
116
+ }
117
+ const styles = react_native_1.StyleSheet.create({
118
+ container: {
119
+ flex: 1,
120
+ },
121
+ modalContainer: {
122
+ flex: 1,
123
+ backgroundColor: '#fff',
124
+ },
125
+ });