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.
- package/LICENSE +21 -0
- package/README.md +225 -0
- package/dist/api/client.d.ts +19 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +215 -0
- package/dist/components/XcelPaymentFlow.d.ts +50 -0
- package/dist/components/XcelPaymentFlow.d.ts.map +1 -0
- package/dist/components/XcelPaymentFlow.js +125 -0
- package/dist/components/XcelPaymentScreen.d.ts +67 -0
- package/dist/components/XcelPaymentScreen.d.ts.map +1 -0
- package/dist/components/XcelPaymentScreen.js +356 -0
- package/dist/components/XcelPaymentWebView.d.ts +76 -0
- package/dist/components/XcelPaymentWebView.d.ts.map +1 -0
- package/dist/components/XcelPaymentWebView.js +413 -0
- package/dist/components/index.d.ts +12 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +14 -0
- package/dist/context/XcelPayGateProvider.d.ts +56 -0
- package/dist/context/XcelPayGateProvider.d.ts.map +1 -0
- package/dist/context/XcelPayGateProvider.js +107 -0
- package/dist/hooks/use-payment-completion.d.ts +75 -0
- package/dist/hooks/use-payment-completion.d.ts.map +1 -0
- package/dist/hooks/use-payment-completion.js +181 -0
- package/dist/hooks/use-xcel-paygate.d.ts +96 -0
- package/dist/hooks/use-xcel-paygate.d.ts.map +1 -0
- package/dist/hooks/use-xcel-paygate.js +279 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +65 -0
- package/dist/services/checkout.d.ts +32 -0
- package/dist/services/checkout.d.ts.map +1 -0
- package/dist/services/checkout.js +137 -0
- package/dist/services/xcel-wallet.d.ts +23 -0
- package/dist/services/xcel-wallet.d.ts.map +1 -0
- package/dist/services/xcel-wallet.js +107 -0
- package/dist/types/index.d.ts +373 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/payment-completion.d.ts +87 -0
- package/dist/utils/payment-completion.d.ts.map +1 -0
- package/dist/utils/payment-completion.js +110 -0
- package/dist/utils/payment-helpers.d.ts +55 -0
- package/dist/utils/payment-helpers.d.ts.map +1 -0
- package/dist/utils/payment-helpers.js +261 -0
- package/package.json +51 -0
- package/src/api/client.ts +326 -0
- package/src/components/XcelPaymentFlow.tsx +154 -0
- package/src/components/XcelPaymentScreen.tsx +477 -0
- package/src/components/XcelPaymentWebView.tsx +533 -0
- package/src/components/index.ts +14 -0
- package/src/context/XcelPayGateProvider.tsx +98 -0
- package/src/hooks/use-payment-completion.ts +225 -0
- package/src/hooks/use-xcel-paygate.ts +363 -0
- package/src/index.ts +70 -0
- package/src/services/checkout.ts +165 -0
- package/src/services/xcel-wallet.ts +175 -0
- package/src/types/index.ts +407 -0
- package/src/utils/payment-completion.ts +144 -0
- 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
|
+
[](https://www.npmjs.com/package/@xcelapp/paygate-sdk)
|
|
6
|
+
[](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
|
+
});
|