@moipayway/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/README.md ADDED
@@ -0,0 +1,253 @@
1
+ # MoiPayWay Checkout SDK
2
+
3
+ Official MoiPayWay Payment SDK. Accept payments via **Card**, **Bank Transfer**, **USSD**, **Mobile Money**, **Pay by Bank**, **Crypto**, and more.
4
+
5
+ ## Installation
6
+
7
+ ### NPM / Yarn
8
+
9
+ ```bash
10
+ npm install @moipayway/sdk
11
+ # or
12
+ yarn add @moipayway/sdk
13
+ ```
14
+
15
+ ### CDN (Vanilla JS)
16
+
17
+ ```html
18
+ <script src="https://checkout.moipayway.com/sdk/v1/checkout.js"></script>
19
+ ```
20
+
21
+ Or host `checkout.js` on your own server.
22
+
23
+ ---
24
+
25
+ ## Quick Start
26
+
27
+ ### React / TypeScript
28
+
29
+ ```tsx
30
+ import { MoiPayWay } from '@moipayway/sdk';
31
+
32
+ const mpw = new MoiPayWay({
33
+ apiKey: 'your_api_key',
34
+ environment: 'test', // 'test' or 'live'
35
+ onSuccess: (data) => console.log('Payment successful', data),
36
+ onError: (error) => console.error('Payment failed', error),
37
+ onClose: () => console.log('Checkout closed'),
38
+ });
39
+
40
+ // Initiate a payment
41
+ const response = await mpw.initiate({
42
+ amount: '5000',
43
+ narration: 'Order #1234',
44
+ wallet_id: 'your_wallet_id',
45
+ user_id: 'customer@email.com',
46
+ allow_payment_method: ['card', 'dynamic_virtual_account', 'ussd'],
47
+ });
48
+
49
+ console.log('Order ref:', response.data.order_reference_code);
50
+ ```
51
+
52
+ ### React Component Example
53
+
54
+ ```tsx
55
+ import { useState } from 'react';
56
+ import { MoiPayWay } from '@moipayway/sdk';
57
+
58
+ function PayButton() {
59
+ const [loading, setLoading] = useState(false);
60
+
61
+ const handlePay = async () => {
62
+ setLoading(true);
63
+
64
+ const mpw = new MoiPayWay({
65
+ apiKey: 'your_api_key',
66
+ environment: 'test',
67
+ onSuccess: (data) => {
68
+ alert('Payment successful!');
69
+ setLoading(false);
70
+ },
71
+ onError: (err) => {
72
+ alert('Payment failed: ' + err.message);
73
+ setLoading(false);
74
+ },
75
+ });
76
+
77
+ try {
78
+ const result = await mpw.initiate({
79
+ amount: '10000',
80
+ narration: 'Premium Plan',
81
+ wallet_id: 'your_wallet_id',
82
+ user_id: 'user@example.com',
83
+ allow_payment_method: ['card', 'ussd', 'dynamic_virtual_account'],
84
+ });
85
+
86
+ // Use result.data.order_reference_code for further steps
87
+ // e.g., mpw.payWithCard(orderRef, cardDetails)
88
+ } catch (error) {
89
+ console.error(error);
90
+ setLoading(false);
91
+ }
92
+ };
93
+
94
+ return (
95
+ <button onClick={handlePay} disabled={loading}>
96
+ {loading ? 'Processing...' : 'Pay ₦10,000'}
97
+ </button>
98
+ );
99
+ }
100
+ ```
101
+
102
+ ### Vanilla JavaScript
103
+
104
+ ```html
105
+ <!DOCTYPE html>
106
+ <html>
107
+ <head>
108
+ <title>MoiPayWay Checkout</title>
109
+ </head>
110
+ <body>
111
+ <button id="pay-btn">Pay ₦5,000</button>
112
+
113
+ <script src="https://checkout.moipayway.com/sdk/v1/checkout.js"></script>
114
+ <script>
115
+ const mpw = new MoiPayWay({
116
+ apiKey: 'your_api_key',
117
+ environment: 'test',
118
+ onSuccess: function (data) {
119
+ alert('Payment successful!');
120
+ console.log(data);
121
+ },
122
+ onError: function (error) {
123
+ alert('Payment failed: ' + error.message);
124
+ },
125
+ onClose: function () {
126
+ console.log('Checkout closed');
127
+ },
128
+ });
129
+
130
+ document.getElementById('pay-btn').addEventListener('click', async function () {
131
+ try {
132
+ const result = await mpw.initiate({
133
+ amount: '5000',
134
+ narration: 'Order #1234',
135
+ wallet_id: 'your_wallet_id',
136
+ user_id: 'customer@email.com',
137
+ allow_payment_method: ['card', 'dynamic_virtual_account', 'ussd'],
138
+ });
139
+
140
+ console.log('Order ref:', result.data.order_reference_code);
141
+ // Continue with payment method selection...
142
+ } catch (err) {
143
+ console.error('Initiation failed:', err);
144
+ }
145
+ });
146
+ </script>
147
+ </body>
148
+ </html>
149
+ ```
150
+
151
+ ### Node.js (Server-side)
152
+
153
+ ```js
154
+ const { MoiPayWay } = require('@moipayway/sdk');
155
+
156
+ const mpw = new MoiPayWay({
157
+ apiKey: 'your_api_key',
158
+ environment: 'live',
159
+ });
160
+
161
+ async function createPayment() {
162
+ const result = await mpw.initiate({
163
+ amount: '25000',
164
+ narration: 'Invoice #5678',
165
+ wallet_id: 'your_wallet_id',
166
+ user_id: 'client@company.com',
167
+ allow_payment_method: ['card', 'dynamic_virtual_account'],
168
+ });
169
+
170
+ return result.data.order_reference_code;
171
+ }
172
+ ```
173
+
174
+ ---
175
+
176
+ ## API Reference
177
+
178
+ ### `new MoiPayWay(config)`
179
+
180
+ | Parameter | Type | Required | Description |
181
+ |-----------|------|----------|-------------|
182
+ | `apiKey` | `string` | ✅ | Your MoiPayWay API key |
183
+ | `environment` | `'test' \| 'live'` | ✅ | API environment |
184
+ | `displayMode` | `'popup' \| 'page' \| 'iframe'` | ❌ | Checkout display mode (default: `'popup'`) |
185
+ | `onSuccess` | `(data) => void` | ❌ | Success callback |
186
+ | `onError` | `(error) => void` | ❌ | Error callback |
187
+ | `onClose` | `() => void` | ❌ | Close/cancel callback |
188
+ | `closeRedirectUrl` | `string` | ❌ | URL to redirect on close |
189
+ | `theme` | `WhiteLabelTheme` | ❌ | Custom theme colors |
190
+ | `content` | `WhiteLabelContent` | ❌ | Custom labels/text |
191
+
192
+ ### Payment Methods
193
+
194
+ | Method | Description |
195
+ |--------|-------------|
196
+ | `card` | Debit/credit card (Visa, Mastercard, Verve, Afrigo) |
197
+ | `dynamic_virtual_account` | One-time bank transfer |
198
+ | `static_virtual_account` | Persistent virtual account |
199
+ | `ussd` | USSD banking |
200
+ | `pay_by_bank` | Direct bank redirect |
201
+ | `mobile_money` | Mobile money (MTN, Airtel, etc.) |
202
+ | `pay_with_crypto` | Cryptocurrency payment |
203
+
204
+ ### Key Methods
205
+
206
+ ```ts
207
+ // Initiate payment
208
+ mpw.initiate(meta: PaymentMeta, orderRef?: string): Promise<ApiResponse>
209
+
210
+ // Pay with card
211
+ mpw.payWithCard(orderRef: string, cardDetails: CardDetails): Promise<ApiResponse<CardResponse>>
212
+
213
+ // Authorize OTP
214
+ mpw.authorizeOTP(orderRef: string, otp: string, paymentId: string, encryptedCard: string): Promise<ApiResponse>
215
+
216
+ // Get payment info
217
+ mpw.getPaymentInfo(orderRef: string): Promise<ApiResponse<PaymentInfoResponse>>
218
+
219
+ // Get supported institutions (for USSD/bank)
220
+ mpw.getSupportedInstitutions(orderRef: string, type: string): Promise<ApiResponse>
221
+
222
+ // Simulate payment (test environment only)
223
+ mpw.simulatePayment(orderRef: string, status: string): Promise<ApiResponse>
224
+ ```
225
+
226
+ ---
227
+
228
+ ## White-Label Theming
229
+
230
+ ```ts
231
+ const mpw = new MoiPayWay({
232
+ apiKey: 'your_key',
233
+ environment: 'live',
234
+ theme: {
235
+ primaryColor: '222 60% 18%',
236
+ accentColor: '160 84% 39%',
237
+ borderRadius: '0.75rem',
238
+ fontFamily: 'Inter, sans-serif',
239
+ },
240
+ content: {
241
+ businessName: 'Your Brand',
242
+ logo: 'https://yourbrand.com/logo.png',
243
+ payButtonText: 'Complete Payment',
244
+ hideBranding: true,
245
+ },
246
+ });
247
+ ```
248
+
249
+ ---
250
+
251
+ ## License
252
+
253
+ MIT
@@ -0,0 +1,234 @@
1
+ type MoiPayWayEnvironment = 'live' | 'test';
2
+ type PaymentMethod = 'ussd' | 'dynamic_virtual_account' | 'static_virtual_account' | 'card' | 'pay_with_crypto' | 'pay_by_bank' | 'mobile_money';
3
+ type DisplayMode = 'popup' | 'page' | 'iframe';
4
+ interface SplitWallet {
5
+ id: string;
6
+ share: string;
7
+ }
8
+ interface SplitConfig {
9
+ type: string;
10
+ wallet: SplitWallet[];
11
+ }
12
+ interface PaymentMeta {
13
+ amount: string;
14
+ narration: string;
15
+ wallet_id: string;
16
+ redirect_url?: string;
17
+ bearer?: string;
18
+ user_id: string;
19
+ recurring_payment?: string;
20
+ channel_id?: string;
21
+ split?: SplitConfig;
22
+ allow_payment_method: PaymentMethod[];
23
+ }
24
+ interface CardDetails {
25
+ phone_number?: string;
26
+ holder_name?: string;
27
+ pan: string;
28
+ expire_month: string;
29
+ expire_year: string;
30
+ cvv: string;
31
+ pin: string;
32
+ street?: string;
33
+ country_code?: string;
34
+ state?: string;
35
+ city?: string;
36
+ postal_code?: string;
37
+ }
38
+ type AuthorizationType = 'OTP' | '3DS' | 'NONE';
39
+ interface ApiResponse<T = any> {
40
+ status: string;
41
+ response_code: number;
42
+ message: string;
43
+ data: T;
44
+ }
45
+ interface CardResponse {
46
+ code?: string;
47
+ order_reference_code: string;
48
+ authorization?: AuthorizationType;
49
+ paymentId?: string;
50
+ transactionRef?: string;
51
+ transactionId?: number;
52
+ ACSUrl?: string;
53
+ TermUrl?: string;
54
+ JWT?: string;
55
+ MD?: number;
56
+ eciFlag?: number;
57
+ meta?: {
58
+ embed_url?: string;
59
+ amount?: number;
60
+ currency?: string;
61
+ ussd?: string;
62
+ bank_name?: string;
63
+ duration?: string;
64
+ duration_unit?: string;
65
+ narration?: string;
66
+ account_name?: string;
67
+ account_no?: string;
68
+ institution?: string;
69
+ name?: string;
70
+ phone_number?: string;
71
+ reference_number?: string;
72
+ };
73
+ }
74
+ interface InstitutionItem {
75
+ institution: string;
76
+ }
77
+ interface PaymentInfoResponse {
78
+ order_reference_code: string;
79
+ amount: string;
80
+ narration: string;
81
+ status: string;
82
+ currency?: string;
83
+ [key: string]: any;
84
+ }
85
+ interface WhiteLabelTheme {
86
+ /** Primary brand color (HSL string e.g. "222 60% 18%") */
87
+ primaryColor?: string;
88
+ /** Accent/CTA color (HSL string e.g. "160 84% 39%") */
89
+ accentColor?: string;
90
+ /** Header gradient start color (HSL) */
91
+ gradientFrom?: string;
92
+ /** Header gradient end color (HSL) */
93
+ gradientTo?: string;
94
+ /** Background color (HSL) */
95
+ backgroundColor?: string;
96
+ /** Card background color (HSL) */
97
+ cardColor?: string;
98
+ /** Text/foreground color (HSL) */
99
+ foregroundColor?: string;
100
+ /** Border color (HSL) */
101
+ borderColor?: string;
102
+ /** Muted text color (HSL) */
103
+ mutedColor?: string;
104
+ /** Border radius for inputs/buttons (e.g. "0.5rem", "9999px") */
105
+ borderRadius?: string;
106
+ /** Font family */
107
+ fontFamily?: string;
108
+ }
109
+ interface WhiteLabelContent {
110
+ /** Business/brand name shown in header */
111
+ businessName?: string;
112
+ /** Logo URL */
113
+ logo?: string;
114
+ /** Tagline under business name */
115
+ tagline?: string;
116
+ /** Pay button text (default: "Pay Now") */
117
+ payButtonText?: string;
118
+ /** Footer secured-by text (default: "Secured by MoiPayWay") */
119
+ footerText?: string;
120
+ /** Footer cancel text (default: "Cancel") */
121
+ cancelText?: string;
122
+ /** Success title (default: "Payment Successful!") */
123
+ successTitle?: string;
124
+ /** Success button text (default: "Done") */
125
+ successButtonText?: string;
126
+ /** Methods screen title */
127
+ methodsTitle?: string;
128
+ /** Methods screen subtitle */
129
+ methodsSubtitle?: string;
130
+ /** Hide the footer entirely */
131
+ hideFooter?: boolean;
132
+ /** Hide the powered-by branding */
133
+ hideBranding?: boolean;
134
+ }
135
+ interface MoiPayWayConfig {
136
+ apiKey: string;
137
+ environment: MoiPayWayEnvironment;
138
+ displayMode?: DisplayMode;
139
+ onSuccess?: (data: any) => void;
140
+ onError?: (error: any) => void;
141
+ onClose?: () => void;
142
+ /** URL to redirect to when checkout is closed/cancelled. If not set, onClose callback is used instead. */
143
+ closeRedirectUrl?: string;
144
+ /** White-label theme customization */
145
+ theme?: WhiteLabelTheme;
146
+ /** White-label content/copy customization */
147
+ content?: WhiteLabelContent;
148
+ /** @deprecated Use theme and content instead */
149
+ customStyles?: {
150
+ primaryColor?: string;
151
+ accentColor?: string;
152
+ logo?: string;
153
+ businessName?: string;
154
+ };
155
+ }
156
+ type CheckoutStep = 'validating' | 'loading' | 'info' | 'methods' | 'card' | 'otp' | '3ds' | 'embed' | 'ussd' | 'ussd_code' | 'transfer' | 'transfer_details' | 'pay_by_bank' | 'pay_by_bank_redirect' | 'mobile_money' | 'mobile_money_pending' | 'static_account' | 'static_sender_form' | 'static_account_details' | 'crypto' | 'crypto_form' | 'crypto_details' | 'crypto_confirm' | 'success' | 'failed' | 'error';
157
+
158
+ declare class MoiPayWay {
159
+ private config;
160
+ private api;
161
+ constructor(config: MoiPayWayConfig);
162
+ initiate(meta: PaymentMeta, orderReferenceCode?: string): Promise<ApiResponse>;
163
+ getPaymentInfo(orderReferenceCode: string): Promise<ApiResponse<PaymentInfoResponse>>;
164
+ payWithCard(orderReferenceCode: string, cardDetails: CardDetails): Promise<ApiResponse<CardResponse>>;
165
+ getSupportedInstitutions(type: string, currencyCode: string): Promise<ApiResponse<InstitutionItem[]>>;
166
+ getSupportedCurrencies(type: string): Promise<ApiResponse<{
167
+ currency: string;
168
+ }[]>>;
169
+ getSupportedCountries(type: string, currency: string): Promise<ApiResponse<{
170
+ country: string;
171
+ currency: string;
172
+ }[]>>;
173
+ getSupportedNetworks(type: string, currency: string, country: string): Promise<ApiResponse<{
174
+ network: string;
175
+ country: string;
176
+ currency: string;
177
+ }[]>>;
178
+ payWithUSSD(orderReferenceCode: string, institution: string): Promise<ApiResponse<CardResponse>>;
179
+ payWithTransfer(orderReferenceCode: string, prefix: string, firstname: string, lastname: string): Promise<ApiResponse<CardResponse>>;
180
+ payByBank(orderReferenceCode: string, phoneNumber: string, name: string): Promise<ApiResponse<CardResponse>>;
181
+ payWithMobileMoney(orderReferenceCode: string, network: string, phoneNumber: string, accountName: string): Promise<ApiResponse<CardResponse>>;
182
+ payWithStaticAccount(orderReferenceCode: string, meta?: Record<string, string>): Promise<ApiResponse<CardResponse>>;
183
+ payWithCrypto(orderReferenceCode: string, fromAddress?: string): Promise<ApiResponse<CardResponse>>;
184
+ confirmCryptoPayment(orderReferenceCode: string, txHash: string): Promise<ApiResponse>;
185
+ resendOTP(orderReferenceCode: string, cardDetails: CardDetails): Promise<ApiResponse>;
186
+ authorizeOTP(orderReferenceCode: string, cardDetails: CardDetails, otp: string, paymentId: string): Promise<ApiResponse<CardResponse>>;
187
+ authorize3DS(orderReferenceCode: string): Promise<ApiResponse<CardResponse>>;
188
+ simulatePayment(orderReferenceCode: string, paymentStatus: 'Successful' | 'Failed'): Promise<ApiResponse>;
189
+ getConfig(): MoiPayWayConfig;
190
+ getEnvironment(): MoiPayWayEnvironment;
191
+ getBaseUrl(): "https://api.moipayway.co" | "https://dev.moipayway.co";
192
+ }
193
+
194
+ declare class ApiClient {
195
+ private baseUrl;
196
+ private apiKey;
197
+ constructor(environment: MoiPayWayEnvironment, apiKey: string);
198
+ private request;
199
+ initiatePayment(payload: any): Promise<unknown>;
200
+ getPaymentInfo(orderReferenceCode: string): Promise<unknown>;
201
+ createPaymentMethod(payload: any): Promise<unknown>;
202
+ getSupportedInstitutions(payload: any): Promise<unknown>;
203
+ getSupportedCurrencies(payload: any): Promise<unknown>;
204
+ getSupportedCountries(payload: any): Promise<unknown>;
205
+ getSupportedNetworks(payload: any): Promise<unknown>;
206
+ resendOTP(payload: any): Promise<unknown>;
207
+ authorizeOTP(payload: any): Promise<unknown>;
208
+ authorize3DS(payload: any): Promise<unknown>;
209
+ confirmPaymentMethod(payload: any): Promise<unknown>;
210
+ simulatePayment(payload: any): Promise<unknown>;
211
+ }
212
+
213
+ /**
214
+ * Matches PHP: encryptUsingMPW()
215
+ * RSA-OAEP(SHA-1) + AES-256-GCM(tag16) + AAD=salt
216
+ */
217
+ declare function encryptCardDetails(cardDetails: {
218
+ pan: string;
219
+ expire_month: string;
220
+ expire_year: string;
221
+ cvv: string;
222
+ pin: string;
223
+ phone_number?: string;
224
+ holder_name?: string;
225
+ street?: string;
226
+ country_code?: string;
227
+ state?: string;
228
+ city?: string;
229
+ postal_code?: string;
230
+ }, salt?: string, ttlSeconds?: number): Promise<string>;
231
+
232
+ declare function generateOrderReference(length?: number): string;
233
+
234
+ export { ApiClient, type ApiResponse, type CardDetails, type CardResponse, type CheckoutStep, type DisplayMode, type InstitutionItem, MoiPayWay, type MoiPayWayConfig, type MoiPayWayEnvironment, type PaymentInfoResponse, type PaymentMeta, type PaymentMethod, type SplitConfig, type SplitWallet, type WhiteLabelContent, type WhiteLabelTheme, encryptCardDetails, generateOrderReference };
@@ -0,0 +1,15 @@
1
+ var w={live:"https://api.moipayway.co",test:"https://dev.moipayway.co"},i=class{constructor(e,t){this.baseUrl=w[e],this.apiKey=t}async request(e,t){let r=`${this.baseUrl}/${e}`,o=await(await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify(t)})).json();if(o.status==="error"||o.status==="failed")throw new Error(o.message||"Request failed");return o}async initiatePayment(e){return this.request("wallet/collection/initiate",e)}async getPaymentInfo(e){return this.request("wallet/collection/info",{order_reference_code:e})}async createPaymentMethod(e){return this.request("wallet/collection/method/create",e)}async getSupportedInstitutions(e){return this.request("wallet/collection/method/supported-institutions",e)}async getSupportedCurrencies(e){return this.request("wallet/collection/method/supported-currencies",e)}async getSupportedCountries(e){return this.request("wallet/collection/method/supported-countries",e)}async getSupportedNetworks(e){return this.request("wallet/collection/method/supported-networks",e)}async resendOTP(e){return this.request("wallet/collection/method/resend-otp",e)}async authorizeOTP(e){return this.request("wallet/collection/method/authorize-otp",e)}async authorize3DS(e){return this.request("wallet/collection/method/authorize-3ds",e)}async confirmPaymentMethod(e){return this.request("wallet/collection/method/confirmation",e)}async simulatePayment(e){return this.request("simulation/collection-order",e)}};function y(n=10){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",t="";for(let r=0;r<n;r++)t+=e.charAt(Math.floor(Math.random()*e.length));return t}var b=`-----BEGIN PUBLIC KEY-----
2
+ MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwl+N8sgsM2DPFLvBRwyx
3
+ 55yNdSzZYucBzTwrRhE7qpc9i69hDhKAGukXvqm2R/HGHjKRPCojTDgEpZEPqE0d
4
+ d7oD2gq9pLKk5XmOGNSCIyL3HsHNhLKSSonrTeDkBfrVp0DJ/pw1pLQRz6bbWIYL
5
+ ILLaBJ35B5wlcwzlQz+m3INH/RkfTSsji/aToITdwmLeREJ3/c+eBxWkU5nTXLub
6
+ iUyoN47FMimXzfIUgIxAtrlOuilKY37Ft6T4JJvDcNU1EVdiv/YX7OMUFbwxeTOn
7
+ RhkhNKWwsDUc1JHp/AuW5P6tGMA0XxDXIFGrkcBGIrgOgyvbydcOQTcLBCgB3+qt
8
+ 18R/Yup0LR7ut/rF98EOfu3JiKiBfCh2o89dmmaeHdgIi7CyepU31e0JQCCAKG2l
9
+ RTvqdMZkWfLH1EK7G+HgKdF08Dbuy+bguV/gRF09Hp16vEl2bKZL1Pk5mJc0JBM2
10
+ 7eDqXorXmym6v9h6ugu4Anc85u6fORN3WabRcLMLbRBfr1j/B9cETlGNNQ8zlBmJ
11
+ Qya765pNonNXC5AMJqgDm9uk9fmGBwc68UPALx8+PO4/GyHkM4u0ITtnvvNtdK5d
12
+ G62wC4dQhOCfr/eJoiplefGGuir3MMCqyOi+zWe+HlKQpVcpS285Y5aPE3WmDl09
13
+ 9qYq6sb+UBuCIzag7FECy8MCAwEAAQ==
14
+ -----END PUBLIC KEY-----`;function M(n){let e=n.replace(/-----BEGIN PUBLIC KEY-----/,"").replace(/-----END PUBLIC KEY-----/,"").replace(/[\s\n\r]/g,""),t=atob(e),r=new Uint8Array(t.length);for(let s=0;s<t.length;s++)r[s]=t.charCodeAt(s);return r.buffer}function c(n){let e=new Uint8Array(n),t="";for(let r=0;r<e.length;r++)t+=String.fromCharCode(e[r]);return btoa(t)}function S(n){let e=crypto.getRandomValues(new Uint8Array(n));return Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("")}async function a(n,e="",t=300){try{let r=new TextEncoder,o={data:JSON.stringify({phone_number:n.phone_number||"",holder_name:n.holder_name||"",pan:n.pan,expire_month:n.expire_month,expire_year:n.expire_year,cvv:n.cvv,pin:n.pin,street:n.street||"",country_code:n.country_code||"",state:n.state||"",city:n.city||"",postal_code:n.postal_code||""}),ts:Math.floor(Date.now()/1e3),ttl:t<0?300:t,nonce:S(16)},l=JSON.stringify(o),u=crypto.getRandomValues(new Uint8Array(32)),d=crypto.getRandomValues(new Uint8Array(12)),h=await crypto.subtle.importKey("raw",u,{name:"AES-GCM"},!1,["encrypt"]),g={name:"AES-GCM",iv:d,tagLength:128};e&&(g.additionalData=r.encode(e));let f=await crypto.subtle.encrypt(g,h,r.encode(l)),p=new Uint8Array(f),P=p.slice(0,p.length-16),A=p.slice(p.length-16),R=await crypto.subtle.importKey("spki",M(b),{name:"RSA-OAEP",hash:"SHA-1"},!1,["encrypt"]),C=await crypto.subtle.encrypt({name:"RSA-OAEP"},R,u),_=JSON.stringify({alg:"RSA-OAEP(SHA1)+AES-256-GCM(tag16)+AAD=salt",ek:c(C),iv:c(d.buffer),ct:c(P.buffer),tag:c(A.buffer)});return btoa(_)}catch(r){throw console.error("Encryption error:",r),new Error("Card encryption failed. Please try again.")}}var m=class{constructor(e){this.config={displayMode:"popup",...e},this.api=new i(e.environment,e.apiKey)}async initiate(e,t){let r={order_reference_code:t||y(),meta:e};return this.api.initiatePayment(r)}async getPaymentInfo(e){return this.api.getPaymentInfo(e)}async payWithCard(e,t){let r=await a(t);return this.api.createPaymentMethod({type:"card",order_reference_code:e,meta:{card_details:r}})}async getSupportedInstitutions(e,t){return this.api.getSupportedInstitutions({type:e,meta:{currency_code:t}})}async getSupportedCurrencies(e){return this.api.getSupportedCurrencies({type:e,meta:{currency:""}})}async getSupportedCountries(e,t){return this.api.getSupportedCountries({type:e,meta:{currency:t,country:""}})}async getSupportedNetworks(e,t,r){return this.api.getSupportedNetworks({type:e,meta:{currency:t,country:r,network:""}})}async payWithUSSD(e,t){return this.api.createPaymentMethod({type:"ussd",order_reference_code:e,meta:{institution:t}})}async payWithTransfer(e,t,r,s){return this.api.createPaymentMethod({type:"dynamic_virtual_account",order_reference_code:e,meta:{prefix:t,firstname:r,lastname:s}})}async payByBank(e,t,r){return this.api.createPaymentMethod({type:"pay_by_bank",order_reference_code:e,meta:{phone_number:t,name:r}})}async payWithMobileMoney(e,t,r,s){return this.api.createPaymentMethod({type:"mobile_money",order_reference_code:e,meta:{network:t,phone_number:r,account_name:s}})}async payWithStaticAccount(e,t={}){return this.api.createPaymentMethod({type:"static_virtual_account",order_reference_code:e,meta:t})}async payWithCrypto(e,t){return this.api.createPaymentMethod({type:"pay_with_crypto",order_reference_code:e,meta:{from_address:t||""}})}async confirmCryptoPayment(e,t){return this.api.confirmPaymentMethod({type:"pay_with_crypto",order_reference_code:e,meta:{tx_hash:t}})}async resendOTP(e,t){let r=await a(t);return this.api.resendOTP({type:"card",order_reference_code:e,meta:{card_details:r}})}async authorizeOTP(e,t,r,s){let o=await a(t);return this.api.authorizeOTP({type:"card",order_reference_code:e,meta:{card_details:o,otp:r,paymentId:s}})}async authorize3DS(e){return this.api.authorize3DS({type:"card",order_reference_code:e})}async simulatePayment(e,t){return this.api.simulatePayment({order_reference_code:e,payment_status:t,order_status:t})}getConfig(){return this.config}getEnvironment(){return this.config.environment}getBaseUrl(){return this.config.environment==="live"?"https://api.moipayway.co":"https://dev.moipayway.co"}};export{i as ApiClient,m as MoiPayWay,a as encryptCardDetails,y as generateOrderReference};
15
+ //# sourceMappingURL=checkout.esm.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api.ts","../src/utils.ts","../src/encryption.ts","../src/MoiPayWay.ts"],"sourcesContent":["import type { MoiPayWayEnvironment } from './types';\n\nconst BASE_URLS: Record<MoiPayWayEnvironment, string> = {\n live: 'https://api.moipayway.co',\n test: 'https://dev.moipayway.co',\n};\n\nexport class ApiClient {\n private baseUrl: string;\n private apiKey: string;\n\n constructor(environment: MoiPayWayEnvironment, apiKey: string) {\n this.baseUrl = BASE_URLS[environment];\n this.apiKey = apiKey;\n }\n\n private async request<T>(endpoint: string, body: any): Promise<T> {\n const url = `${this.baseUrl}/${endpoint}`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n const data = await response.json();\n if (data.status === 'error' || data.status === 'failed') {\n throw new Error(data.message || 'Request failed');\n }\n return data;\n }\n\n async initiatePayment(payload: any) {\n return this.request('wallet/collection/initiate', payload);\n }\n\n async getPaymentInfo(orderReferenceCode: string) {\n return this.request('wallet/collection/info', {\n order_reference_code: orderReferenceCode,\n });\n }\n\n async createPaymentMethod(payload: any) {\n return this.request('wallet/collection/method/create', payload);\n }\n\n async getSupportedInstitutions(payload: any) {\n return this.request('wallet/collection/method/supported-institutions', payload);\n }\n\n async getSupportedCurrencies(payload: any) {\n return this.request('wallet/collection/method/supported-currencies', payload);\n }\n\n async getSupportedCountries(payload: any) {\n return this.request('wallet/collection/method/supported-countries', payload);\n }\n\n async getSupportedNetworks(payload: any) {\n return this.request('wallet/collection/method/supported-networks', payload);\n }\n\n async resendOTP(payload: any) {\n return this.request('wallet/collection/method/resend-otp', payload);\n }\n\n async authorizeOTP(payload: any) {\n return this.request('wallet/collection/method/authorize-otp', payload);\n }\n\n async authorize3DS(payload: any) {\n return this.request('wallet/collection/method/authorize-3ds', payload);\n }\n\n async confirmPaymentMethod(payload: any) {\n return this.request('wallet/collection/method/confirmation', payload);\n }\n\n async simulatePayment(payload: any) {\n return this.request('simulation/collection-order', payload);\n }\n}\n","export function generateOrderReference(length = 10): string {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n\nexport function formatAmount(amount: string | number, currency = 'NGN'): string {\n const num = typeof amount === 'string' ? parseFloat(amount) : amount;\n const code = currency.toUpperCase();\n const formatted = num.toLocaleString('en', { minimumFractionDigits: 2, maximumFractionDigits: 2 });\n return `${code} ${formatted}`;\n}\n\nexport const PAYMENT_METHOD_LABELS: Record<string, { label: string; icon: string }> = {\n card: { label: 'Card Payment', icon: '💳' },\n ussd: { label: 'USSD', icon: '📱' },\n dynamic_virtual_account: { label: 'Pay with Transfer (One time)', icon: '🏦' },\n static_virtual_account: { label: 'Static Account', icon: '🏛️' },\n pay_with_crypto: { label: 'Pay with Crypto', icon: '🪙' },\n pay_by_bank: { label: 'Pay by Bank', icon: '🔗' },\n mobile_money: { label: 'Mobile Money', icon: '📲' },\n};\n","const PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwl+N8sgsM2DPFLvBRwyx\n55yNdSzZYucBzTwrRhE7qpc9i69hDhKAGukXvqm2R/HGHjKRPCojTDgEpZEPqE0d\nd7oD2gq9pLKk5XmOGNSCIyL3HsHNhLKSSonrTeDkBfrVp0DJ/pw1pLQRz6bbWIYL\nILLaBJ35B5wlcwzlQz+m3INH/RkfTSsji/aToITdwmLeREJ3/c+eBxWkU5nTXLub\niUyoN47FMimXzfIUgIxAtrlOuilKY37Ft6T4JJvDcNU1EVdiv/YX7OMUFbwxeTOn\nRhkhNKWwsDUc1JHp/AuW5P6tGMA0XxDXIFGrkcBGIrgOgyvbydcOQTcLBCgB3+qt\n18R/Yup0LR7ut/rF98EOfu3JiKiBfCh2o89dmmaeHdgIi7CyepU31e0JQCCAKG2l\nRTvqdMZkWfLH1EK7G+HgKdF08Dbuy+bguV/gRF09Hp16vEl2bKZL1Pk5mJc0JBM2\n7eDqXorXmym6v9h6ugu4Anc85u6fORN3WabRcLMLbRBfr1j/B9cETlGNNQ8zlBmJ\nQya765pNonNXC5AMJqgDm9uk9fmGBwc68UPALx8+PO4/GyHkM4u0ITtnvvNtdK5d\nG62wC4dQhOCfr/eJoiplefGGuir3MMCqyOi+zWe+HlKQpVcpS285Y5aPE3WmDl09\n9qYq6sb+UBuCIzag7FECy8MCAwEAAQ==\n-----END PUBLIC KEY-----`;\n\nfunction pemToArrayBuffer(pem: string): ArrayBuffer {\n const b64 = pem\n .replace(/-----BEGIN PUBLIC KEY-----/, '')\n .replace(/-----END PUBLIC KEY-----/, '')\n .replace(/[\\s\\n\\r]/g, '');\n const bin = atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return bytes.buffer;\n}\n\nfunction arrayBufferToBase64(buf: ArrayBuffer): string {\n const bytes = new Uint8Array(buf);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);\n return btoa(binary);\n}\n\nfunction randomHex(byteCount: number): string {\n const bytes = crypto.getRandomValues(new Uint8Array(byteCount));\n return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * Matches PHP: encryptUsingMPW()\n * RSA-OAEP(SHA-1) + AES-256-GCM(tag16) + AAD=salt\n */\nexport async function encryptCardDetails(\n cardDetails: { pan: string; expire_month: string; expire_year: string; cvv: string; pin: string; phone_number?: string; holder_name?: string; street?: string; country_code?: string; state?: string; city?: string; postal_code?: string },\n salt: string = '',\n ttlSeconds: number = 300\n): Promise<string> {\n try {\n const encoder = new TextEncoder();\n\n // 1. Build payload (matches PHP structure — data is a STRING, not object)\n const cardString = JSON.stringify({\n phone_number: cardDetails.phone_number || '',\n holder_name: cardDetails.holder_name || '',\n pan: cardDetails.pan,\n expire_month: cardDetails.expire_month,\n expire_year: cardDetails.expire_year,\n cvv: cardDetails.cvv,\n pin: cardDetails.pin,\n street: cardDetails.street || '',\n country_code: cardDetails.country_code || '',\n state: cardDetails.state || '',\n city: cardDetails.city || '',\n postal_code: cardDetails.postal_code || '',\n });\n const payload = {\n data: cardString,\n ts: Math.floor(Date.now() / 1000),\n ttl: ttlSeconds < 0 ? 300 : ttlSeconds,\n nonce: randomHex(16),\n };\n const plain = JSON.stringify(payload);\n\n // 2. Generate AES-256 key (32 bytes) + GCM IV (12 bytes)\n const aesKeyRaw = crypto.getRandomValues(new Uint8Array(32));\n const iv = crypto.getRandomValues(new Uint8Array(12));\n\n // 3. Import AES key\n const aesKey = await crypto.subtle.importKey(\n 'raw', aesKeyRaw, { name: 'AES-GCM' }, false, ['encrypt']\n );\n\n // 4. AES-256-GCM encrypt with salt as AAD, 128-bit tag\n const aesParams: AesGcmParams = {\n name: 'AES-GCM',\n iv,\n tagLength: 128,\n };\n if (salt) {\n aesParams.additionalData = encoder.encode(salt);\n }\n\n const cipherAndTag = await crypto.subtle.encrypt(aesParams, aesKey, encoder.encode(plain));\n\n // Web Crypto appends tag to ciphertext; split them\n const cipherAndTagBytes = new Uint8Array(cipherAndTag);\n const ct = cipherAndTagBytes.slice(0, cipherAndTagBytes.length - 16);\n const tag = cipherAndTagBytes.slice(cipherAndTagBytes.length - 16);\n\n // 5. RSA-OAEP (SHA-1) wrap the AES key\n const rsaKey = await crypto.subtle.importKey(\n 'spki',\n pemToArrayBuffer(PUBLIC_KEY),\n { name: 'RSA-OAEP', hash: 'SHA-1' },\n false,\n ['encrypt']\n );\n const ek = await crypto.subtle.encrypt({ name: 'RSA-OAEP' }, rsaKey, aesKeyRaw);\n\n // 6. Build package (matches PHP output)\n const pkg = JSON.stringify({\n alg: 'RSA-OAEP(SHA1)+AES-256-GCM(tag16)+AAD=salt',\n ek: arrayBufferToBase64(ek),\n iv: arrayBufferToBase64(iv.buffer),\n ct: arrayBufferToBase64(ct.buffer),\n tag: arrayBufferToBase64(tag.buffer),\n });\n\n // 7. Base64 encode the entire package\n return btoa(pkg);\n } catch (err) {\n console.error('Encryption error:', err);\n throw new Error('Card encryption failed. Please try again.');\n }\n}\n","import { ApiClient } from './api';\nimport { generateOrderReference } from './utils';\nimport { encryptCardDetails } from './encryption';\nimport type {\n MoiPayWayConfig,\n InitiatePayload,\n PaymentMeta,\n CardDetails,\n ApiResponse,\n CardResponse,\n PaymentInfoResponse,\n InstitutionItem,\n} from './types';\n\nexport class MoiPayWay {\n private config: MoiPayWayConfig;\n private api: ApiClient;\n\n constructor(config: MoiPayWayConfig) {\n this.config = {\n displayMode: 'popup',\n ...config,\n };\n this.api = new ApiClient(config.environment, config.apiKey);\n }\n\n async initiate(meta: PaymentMeta, orderReferenceCode?: string): Promise<ApiResponse> {\n const payload: InitiatePayload = {\n order_reference_code: orderReferenceCode || generateOrderReference(),\n meta,\n };\n return this.api.initiatePayment(payload) as Promise<ApiResponse>;\n }\n\n async getPaymentInfo(orderReferenceCode: string): Promise<ApiResponse<PaymentInfoResponse>> {\n return this.api.getPaymentInfo(orderReferenceCode) as Promise<ApiResponse<PaymentInfoResponse>>;\n }\n\n async payWithCard(\n orderReferenceCode: string,\n cardDetails: CardDetails\n ): Promise<ApiResponse<CardResponse>> {\n const encrypted = await encryptCardDetails(cardDetails);\n return this.api.createPaymentMethod({\n type: 'card',\n order_reference_code: orderReferenceCode,\n meta: { card_details: encrypted },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async getSupportedInstitutions(type: string, currencyCode: string): Promise<ApiResponse<InstitutionItem[]>> {\n return this.api.getSupportedInstitutions({\n type,\n meta: { currency_code: currencyCode },\n }) as Promise<ApiResponse<InstitutionItem[]>>;\n }\n\n async getSupportedCurrencies(type: string): Promise<ApiResponse<{ currency: string }[]>> {\n return this.api.getSupportedCurrencies({\n type,\n meta: { currency: '' },\n }) as Promise<ApiResponse<{ currency: string }[]>>;\n }\n\n async getSupportedCountries(type: string, currency: string): Promise<ApiResponse<{ country: string; currency: string }[]>> {\n return this.api.getSupportedCountries({\n type,\n meta: { currency, country: '' },\n }) as Promise<ApiResponse<{ country: string; currency: string }[]>>;\n }\n\n async getSupportedNetworks(type: string, currency: string, country: string): Promise<ApiResponse<{ network: string; country: string; currency: string }[]>> {\n return this.api.getSupportedNetworks({\n type,\n meta: { currency, country, network: '' },\n }) as Promise<ApiResponse<{ network: string; country: string; currency: string }[]>>;\n }\n\n async payWithUSSD(\n orderReferenceCode: string,\n institution: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'ussd',\n order_reference_code: orderReferenceCode,\n meta: { institution },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payWithTransfer(\n orderReferenceCode: string,\n prefix: string,\n firstname: string,\n lastname: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'dynamic_virtual_account',\n order_reference_code: orderReferenceCode,\n meta: { prefix, firstname, lastname },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payByBank(\n orderReferenceCode: string,\n phoneNumber: string,\n name: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'pay_by_bank',\n order_reference_code: orderReferenceCode,\n meta: { phone_number: phoneNumber, name },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payWithMobileMoney(\n orderReferenceCode: string,\n network: string,\n phoneNumber: string,\n accountName: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'mobile_money',\n order_reference_code: orderReferenceCode,\n meta: { network, phone_number: phoneNumber, account_name: accountName },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payWithStaticAccount(\n orderReferenceCode: string,\n meta: Record<string, string> = {}\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'static_virtual_account',\n order_reference_code: orderReferenceCode,\n meta,\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payWithCrypto(\n orderReferenceCode: string,\n fromAddress?: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'pay_with_crypto',\n order_reference_code: orderReferenceCode,\n meta: { from_address: fromAddress || '' },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async confirmCryptoPayment(\n orderReferenceCode: string,\n txHash: string\n ): Promise<ApiResponse> {\n return this.api.confirmPaymentMethod({\n type: 'pay_with_crypto',\n order_reference_code: orderReferenceCode,\n meta: { tx_hash: txHash },\n }) as Promise<ApiResponse>;\n }\n\n async resendOTP(\n orderReferenceCode: string,\n cardDetails: CardDetails\n ): Promise<ApiResponse> {\n const encrypted = await encryptCardDetails(cardDetails);\n return this.api.resendOTP({\n type: 'card',\n order_reference_code: orderReferenceCode,\n meta: { card_details: encrypted },\n }) as Promise<ApiResponse>;\n }\n\n async authorizeOTP(\n orderReferenceCode: string,\n cardDetails: CardDetails,\n otp: string,\n paymentId: string\n ): Promise<ApiResponse<CardResponse>> {\n const encrypted = await encryptCardDetails(cardDetails);\n return this.api.authorizeOTP({\n type: 'card',\n order_reference_code: orderReferenceCode,\n meta: { card_details: encrypted, otp, paymentId },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async authorize3DS(orderReferenceCode: string): Promise<ApiResponse<CardResponse>> {\n return this.api.authorize3DS({\n type: 'card',\n order_reference_code: orderReferenceCode,\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async simulatePayment(\n orderReferenceCode: string,\n paymentStatus: 'Successful' | 'Failed'\n ): Promise<ApiResponse> {\n return this.api.simulatePayment({\n order_reference_code: orderReferenceCode,\n payment_status: paymentStatus,\n order_status: paymentStatus,\n }) as Promise<ApiResponse>;\n }\n\n getConfig() {\n return this.config;\n }\n\n getEnvironment() {\n return this.config.environment;\n }\n\n getBaseUrl() {\n return this.config.environment === 'live'\n ? 'https://api.moipayway.co'\n : 'https://dev.moipayway.co';\n }\n}\n\nexport type { MoiPayWayConfig, PaymentMeta, CardDetails, PaymentMethod, DisplayMode } from './types';\n"],"mappings":"AAEA,IAAMA,EAAkD,CACtD,KAAM,2BACN,KAAM,0BACR,EAEaC,EAAN,KAAgB,CAIrB,YAAYC,EAAmCC,EAAgB,CAC7D,KAAK,QAAUH,EAAUE,CAAW,EACpC,KAAK,OAASC,CAChB,CAEA,MAAc,QAAWC,EAAkBC,EAAuB,CAChE,IAAMC,EAAM,GAAG,KAAK,OAAO,IAAIF,CAAQ,GAUjCG,EAAO,MATI,MAAM,MAAMD,EAAK,CAChC,OAAQ,OACR,QAAS,CACP,eAAgB,mBAChB,cAAiB,UAAU,KAAK,MAAM,EACxC,EACA,KAAM,KAAK,UAAUD,CAAI,CAC3B,CAAC,GAE2B,KAAK,EACjC,GAAIE,EAAK,SAAW,SAAWA,EAAK,SAAW,SAC7C,MAAM,IAAI,MAAMA,EAAK,SAAW,gBAAgB,EAElD,OAAOA,CACT,CAEA,MAAM,gBAAgBC,EAAc,CAClC,OAAO,KAAK,QAAQ,6BAA8BA,CAAO,CAC3D,CAEA,MAAM,eAAeC,EAA4B,CAC/C,OAAO,KAAK,QAAQ,yBAA0B,CAC5C,qBAAsBA,CACxB,CAAC,CACH,CAEA,MAAM,oBAAoBD,EAAc,CACtC,OAAO,KAAK,QAAQ,kCAAmCA,CAAO,CAChE,CAEA,MAAM,yBAAyBA,EAAc,CAC3C,OAAO,KAAK,QAAQ,kDAAmDA,CAAO,CAChF,CAEA,MAAM,uBAAuBA,EAAc,CACzC,OAAO,KAAK,QAAQ,gDAAiDA,CAAO,CAC9E,CAEA,MAAM,sBAAsBA,EAAc,CACxC,OAAO,KAAK,QAAQ,+CAAgDA,CAAO,CAC7E,CAEA,MAAM,qBAAqBA,EAAc,CACvC,OAAO,KAAK,QAAQ,8CAA+CA,CAAO,CAC5E,CAEA,MAAM,UAAUA,EAAc,CAC5B,OAAO,KAAK,QAAQ,sCAAuCA,CAAO,CACpE,CAEA,MAAM,aAAaA,EAAc,CAC/B,OAAO,KAAK,QAAQ,yCAA0CA,CAAO,CACvE,CAEA,MAAM,aAAaA,EAAc,CAC/B,OAAO,KAAK,QAAQ,yCAA0CA,CAAO,CACvE,CAEA,MAAM,qBAAqBA,EAAc,CACvC,OAAO,KAAK,QAAQ,wCAAyCA,CAAO,CACtE,CAEA,MAAM,gBAAgBA,EAAc,CAClC,OAAO,KAAK,QAAQ,8BAA+BA,CAAO,CAC5D,CACF,ECnFO,SAASE,EAAuBC,EAAS,GAAY,CAC1D,IAAMC,EAAQ,iEACVC,EAAS,GACb,QAASC,EAAI,EAAGA,EAAIH,EAAQG,IAC1BD,GAAUD,EAAM,OAAO,KAAK,MAAM,KAAK,OAAO,EAAIA,EAAM,MAAM,CAAC,EAEjE,OAAOC,CACT,CCPA,IAAME,EAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAenB,SAASC,EAAiBC,EAA0B,CAClD,IAAMC,EAAMD,EACT,QAAQ,6BAA8B,EAAE,EACxC,QAAQ,2BAA4B,EAAE,EACtC,QAAQ,YAAa,EAAE,EACpBE,EAAM,KAAKD,CAAG,EACdE,EAAQ,IAAI,WAAWD,EAAI,MAAM,EACvC,QAASE,EAAI,EAAGA,EAAIF,EAAI,OAAQE,IAAKD,EAAMC,CAAC,EAAIF,EAAI,WAAWE,CAAC,EAChE,OAAOD,EAAM,MACf,CAEA,SAASE,EAAoBC,EAA0B,CACrD,IAAMH,EAAQ,IAAI,WAAWG,CAAG,EAC5BC,EAAS,GACb,QAASH,EAAI,EAAGA,EAAID,EAAM,OAAQC,IAAKG,GAAU,OAAO,aAAaJ,EAAMC,CAAC,CAAC,EAC7E,OAAO,KAAKG,CAAM,CACpB,CAEA,SAASC,EAAUC,EAA2B,CAC5C,IAAMN,EAAQ,OAAO,gBAAgB,IAAI,WAAWM,CAAS,CAAC,EAC9D,OAAO,MAAM,KAAKN,CAAK,EAAE,IAAIO,GAAKA,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,EAAE,KAAK,EAAE,CAC5E,CAMA,eAAsBC,EACpBC,EACAC,EAAe,GACfC,EAAqB,IACJ,CACjB,GAAI,CACF,IAAMC,EAAU,IAAI,YAiBdC,EAAU,CACd,KAfiB,KAAK,UAAU,CAChC,aAAcJ,EAAY,cAAgB,GAC1C,YAAaA,EAAY,aAAe,GACxC,IAAKA,EAAY,IACjB,aAAcA,EAAY,aAC1B,YAAaA,EAAY,YACzB,IAAKA,EAAY,IACjB,IAAKA,EAAY,IACjB,OAAQA,EAAY,QAAU,GAC9B,aAAcA,EAAY,cAAgB,GAC1C,MAAOA,EAAY,OAAS,GAC5B,KAAMA,EAAY,MAAQ,GAC1B,YAAaA,EAAY,aAAe,EAC1C,CAAC,EAGC,GAAI,KAAK,MAAM,KAAK,IAAI,EAAI,GAAI,EAChC,IAAKE,EAAa,EAAI,IAAMA,EAC5B,MAAON,EAAU,EAAE,CACrB,EACMS,EAAQ,KAAK,UAAUD,CAAO,EAG9BE,EAAY,OAAO,gBAAgB,IAAI,WAAW,EAAE,CAAC,EACrDC,EAAK,OAAO,gBAAgB,IAAI,WAAW,EAAE,CAAC,EAG9CC,EAAS,MAAM,OAAO,OAAO,UACjC,MAAOF,EAAW,CAAE,KAAM,SAAU,EAAG,GAAO,CAAC,SAAS,CAC1D,EAGMG,EAA0B,CAC9B,KAAM,UACN,GAAAF,EACA,UAAW,GACb,EACIN,IACFQ,EAAU,eAAiBN,EAAQ,OAAOF,CAAI,GAGhD,IAAMS,EAAe,MAAM,OAAO,OAAO,QAAQD,EAAWD,EAAQL,EAAQ,OAAOE,CAAK,CAAC,EAGnFM,EAAoB,IAAI,WAAWD,CAAY,EAC/CE,EAAKD,EAAkB,MAAM,EAAGA,EAAkB,OAAS,EAAE,EAC7DE,EAAMF,EAAkB,MAAMA,EAAkB,OAAS,EAAE,EAG3DG,EAAS,MAAM,OAAO,OAAO,UACjC,OACA3B,EAAiBD,CAAU,EAC3B,CAAE,KAAM,WAAY,KAAM,OAAQ,EAClC,GACA,CAAC,SAAS,CACZ,EACM6B,EAAK,MAAM,OAAO,OAAO,QAAQ,CAAE,KAAM,UAAW,EAAGD,EAAQR,CAAS,EAGxEU,EAAM,KAAK,UAAU,CACzB,IAAK,6CACL,GAAIvB,EAAoBsB,CAAE,EAC1B,GAAItB,EAAoBc,EAAG,MAAM,EACjC,GAAId,EAAoBmB,EAAG,MAAM,EACjC,IAAKnB,EAAoBoB,EAAI,MAAM,CACrC,CAAC,EAGD,OAAO,KAAKG,CAAG,CACjB,OAASC,EAAK,CACZ,cAAQ,MAAM,oBAAqBA,CAAG,EAChC,IAAI,MAAM,2CAA2C,CAC7D,CACF,CC9GO,IAAMC,EAAN,KAAgB,CAIrB,YAAYC,EAAyB,CACnC,KAAK,OAAS,CACZ,YAAa,QACb,GAAGA,CACL,EACA,KAAK,IAAM,IAAIC,EAAUD,EAAO,YAAaA,EAAO,MAAM,CAC5D,CAEA,MAAM,SAASE,EAAmBC,EAAmD,CACnF,IAAMC,EAA2B,CAC/B,qBAAsBD,GAAsBE,EAAuB,EACnE,KAAAH,CACF,EACA,OAAO,KAAK,IAAI,gBAAgBE,CAAO,CACzC,CAEA,MAAM,eAAeD,EAAuE,CAC1F,OAAO,KAAK,IAAI,eAAeA,CAAkB,CACnD,CAEA,MAAM,YACJA,EACAG,EACoC,CACpC,IAAMC,EAAY,MAAMC,EAAmBF,CAAW,EACtD,OAAO,KAAK,IAAI,oBAAoB,CAClC,KAAM,OACN,qBAAsBH,EACtB,KAAM,CAAE,aAAcI,CAAU,CAClC,CAAC,CACH,CAEA,MAAM,yBAAyBE,EAAcC,EAA+D,CAC1G,OAAO,KAAK,IAAI,yBAAyB,CACvC,KAAAD,EACA,KAAM,CAAE,cAAeC,CAAa,CACtC,CAAC,CACH,CAEA,MAAM,uBAAuBD,EAA4D,CACvF,OAAO,KAAK,IAAI,uBAAuB,CACrC,KAAAA,EACA,KAAM,CAAE,SAAU,EAAG,CACvB,CAAC,CACH,CAEA,MAAM,sBAAsBA,EAAcE,EAAiF,CACzH,OAAO,KAAK,IAAI,sBAAsB,CACpC,KAAAF,EACA,KAAM,CAAE,SAAAE,EAAU,QAAS,EAAG,CAChC,CAAC,CACH,CAEA,MAAM,qBAAqBF,EAAcE,EAAkBC,EAAiG,CAC1J,OAAO,KAAK,IAAI,qBAAqB,CACnC,KAAAH,EACA,KAAM,CAAE,SAAAE,EAAU,QAAAC,EAAS,QAAS,EAAG,CACzC,CAAC,CACH,CAEA,MAAM,YACJT,EACAU,EACoC,CACpC,OAAO,KAAK,IAAI,oBAAoB,CAClC,KAAM,OACN,qBAAsBV,EACtB,KAAM,CAAE,YAAAU,CAAY,CACtB,CAAC,CACH,CAEA,MAAM,gBACJV,EACAW,EACAC,EACAC,EACoC,CACpC,OAAO,KAAK,IAAI,oBAAoB,CAClC,KAAM,0BACN,qBAAsBb,EACtB,KAAM,CAAE,OAAAW,EAAQ,UAAAC,EAAW,SAAAC,CAAS,CACtC,CAAC,CACH,CAEA,MAAM,UACJb,EACAc,EACAC,EACoC,CACpC,OAAO,KAAK,IAAI,oBAAoB,CAClC,KAAM,cACN,qBAAsBf,EACtB,KAAM,CAAE,aAAcc,EAAa,KAAAC,CAAK,CAC1C,CAAC,CACH,CAEA,MAAM,mBACJf,EACAgB,EACAF,EACAG,EACoC,CACpC,OAAO,KAAK,IAAI,oBAAoB,CAClC,KAAM,eACN,qBAAsBjB,EACtB,KAAM,CAAE,QAAAgB,EAAS,aAAcF,EAAa,aAAcG,CAAY,CACxE,CAAC,CACH,CAEA,MAAM,qBACJjB,EACAD,EAA+B,CAAC,EACI,CACpC,OAAO,KAAK,IAAI,oBAAoB,CAClC,KAAM,yBACN,qBAAsBC,EACtB,KAAAD,CACF,CAAC,CACH,CAEA,MAAM,cACJC,EACAkB,EACoC,CACpC,OAAO,KAAK,IAAI,oBAAoB,CAClC,KAAM,kBACN,qBAAsBlB,EACtB,KAAM,CAAE,aAAckB,GAAe,EAAG,CAC1C,CAAC,CACH,CAEA,MAAM,qBACJlB,EACAmB,EACsB,CACtB,OAAO,KAAK,IAAI,qBAAqB,CACnC,KAAM,kBACN,qBAAsBnB,EACtB,KAAM,CAAE,QAASmB,CAAO,CAC1B,CAAC,CACH,CAEA,MAAM,UACJnB,EACAG,EACsB,CACtB,IAAMC,EAAY,MAAMC,EAAmBF,CAAW,EACtD,OAAO,KAAK,IAAI,UAAU,CACxB,KAAM,OACN,qBAAsBH,EACtB,KAAM,CAAE,aAAcI,CAAU,CAClC,CAAC,CACH,CAEA,MAAM,aACJJ,EACAG,EACAiB,EACAC,EACoC,CACpC,IAAMjB,EAAY,MAAMC,EAAmBF,CAAW,EACtD,OAAO,KAAK,IAAI,aAAa,CAC3B,KAAM,OACN,qBAAsBH,EACtB,KAAM,CAAE,aAAcI,EAAW,IAAAgB,EAAK,UAAAC,CAAU,CAClD,CAAC,CACH,CAEA,MAAM,aAAarB,EAAgE,CACjF,OAAO,KAAK,IAAI,aAAa,CAC3B,KAAM,OACN,qBAAsBA,CACxB,CAAC,CACH,CAEA,MAAM,gBACJA,EACAsB,EACsB,CACtB,OAAO,KAAK,IAAI,gBAAgB,CAC9B,qBAAsBtB,EACtB,eAAgBsB,EAChB,aAAcA,CAChB,CAAC,CACH,CAEA,WAAY,CACV,OAAO,KAAK,MACd,CAEA,gBAAiB,CACf,OAAO,KAAK,OAAO,WACrB,CAEA,YAAa,CACX,OAAO,KAAK,OAAO,cAAgB,OAC/B,2BACA,0BACN,CACF","names":["BASE_URLS","ApiClient","environment","apiKey","endpoint","body","url","data","payload","orderReferenceCode","generateOrderReference","length","chars","result","i","PUBLIC_KEY","pemToArrayBuffer","pem","b64","bin","bytes","i","arrayBufferToBase64","buf","binary","randomHex","byteCount","b","encryptCardDetails","cardDetails","salt","ttlSeconds","encoder","payload","plain","aesKeyRaw","iv","aesKey","aesParams","cipherAndTag","cipherAndTagBytes","ct","tag","rsaKey","ek","pkg","err","MoiPayWay","config","ApiClient","meta","orderReferenceCode","payload","generateOrderReference","cardDetails","encrypted","encryptCardDetails","type","currencyCode","currency","country","institution","prefix","firstname","lastname","phoneNumber","name","network","accountName","fromAddress","txHash","otp","paymentId","paymentStatus"]}
@@ -0,0 +1,15 @@
1
+ "use strict";var MoiPayWaySDK=(()=>{var u=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var I=(n,e)=>{for(var t in e)u(n,t,{get:e[t],enumerable:!0})},E=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of M(e))!S.call(n,s)&&s!==t&&u(n,s,{get:()=>e[s],enumerable:!(r=b(e,s))||r.enumerable});return n};var v=n=>E(u({},"__esModule",{value:!0}),n);var L={};I(L,{ApiClient:()=>i,MoiPayWay:()=>m,encryptCardDetails:()=>a,generateOrderReference:()=>c});var B={live:"https://api.moipayway.co",test:"https://dev.moipayway.co"},i=class{constructor(e,t){this.baseUrl=B[e],this.apiKey=t}async request(e,t){let r=`${this.baseUrl}/${e}`,o=await(await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify(t)})).json();if(o.status==="error"||o.status==="failed")throw new Error(o.message||"Request failed");return o}async initiatePayment(e){return this.request("wallet/collection/initiate",e)}async getPaymentInfo(e){return this.request("wallet/collection/info",{order_reference_code:e})}async createPaymentMethod(e){return this.request("wallet/collection/method/create",e)}async getSupportedInstitutions(e){return this.request("wallet/collection/method/supported-institutions",e)}async getSupportedCurrencies(e){return this.request("wallet/collection/method/supported-currencies",e)}async getSupportedCountries(e){return this.request("wallet/collection/method/supported-countries",e)}async getSupportedNetworks(e){return this.request("wallet/collection/method/supported-networks",e)}async resendOTP(e){return this.request("wallet/collection/method/resend-otp",e)}async authorizeOTP(e){return this.request("wallet/collection/method/authorize-otp",e)}async authorize3DS(e){return this.request("wallet/collection/method/authorize-3ds",e)}async confirmPaymentMethod(e){return this.request("wallet/collection/method/confirmation",e)}async simulatePayment(e){return this.request("simulation/collection-order",e)}};function c(n=10){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",t="";for(let r=0;r<n;r++)t+=e.charAt(Math.floor(Math.random()*e.length));return t}var T=`-----BEGIN PUBLIC KEY-----
2
+ MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwl+N8sgsM2DPFLvBRwyx
3
+ 55yNdSzZYucBzTwrRhE7qpc9i69hDhKAGukXvqm2R/HGHjKRPCojTDgEpZEPqE0d
4
+ d7oD2gq9pLKk5XmOGNSCIyL3HsHNhLKSSonrTeDkBfrVp0DJ/pw1pLQRz6bbWIYL
5
+ ILLaBJ35B5wlcwzlQz+m3INH/RkfTSsji/aToITdwmLeREJ3/c+eBxWkU5nTXLub
6
+ iUyoN47FMimXzfIUgIxAtrlOuilKY37Ft6T4JJvDcNU1EVdiv/YX7OMUFbwxeTOn
7
+ RhkhNKWwsDUc1JHp/AuW5P6tGMA0XxDXIFGrkcBGIrgOgyvbydcOQTcLBCgB3+qt
8
+ 18R/Yup0LR7ut/rF98EOfu3JiKiBfCh2o89dmmaeHdgIi7CyepU31e0JQCCAKG2l
9
+ RTvqdMZkWfLH1EK7G+HgKdF08Dbuy+bguV/gRF09Hp16vEl2bKZL1Pk5mJc0JBM2
10
+ 7eDqXorXmym6v9h6ugu4Anc85u6fORN3WabRcLMLbRBfr1j/B9cETlGNNQ8zlBmJ
11
+ Qya765pNonNXC5AMJqgDm9uk9fmGBwc68UPALx8+PO4/GyHkM4u0ITtnvvNtdK5d
12
+ G62wC4dQhOCfr/eJoiplefGGuir3MMCqyOi+zWe+HlKQpVcpS285Y5aPE3WmDl09
13
+ 9qYq6sb+UBuCIzag7FECy8MCAwEAAQ==
14
+ -----END PUBLIC KEY-----`;function O(n){let e=n.replace(/-----BEGIN PUBLIC KEY-----/,"").replace(/-----END PUBLIC KEY-----/,"").replace(/[\s\n\r]/g,""),t=atob(e),r=new Uint8Array(t.length);for(let s=0;s<t.length;s++)r[s]=t.charCodeAt(s);return r.buffer}function y(n){let e=new Uint8Array(n),t="";for(let r=0;r<e.length;r++)t+=String.fromCharCode(e[r]);return btoa(t)}function k(n){let e=crypto.getRandomValues(new Uint8Array(n));return Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("")}async function a(n,e="",t=300){try{let r=new TextEncoder,o={data:JSON.stringify({phone_number:n.phone_number||"",holder_name:n.holder_name||"",pan:n.pan,expire_month:n.expire_month,expire_year:n.expire_year,cvv:n.cvv,pin:n.pin,street:n.street||"",country_code:n.country_code||"",state:n.state||"",city:n.city||"",postal_code:n.postal_code||""}),ts:Math.floor(Date.now()/1e3),ttl:t<0?300:t,nonce:k(16)},h=JSON.stringify(o),d=crypto.getRandomValues(new Uint8Array(32)),g=crypto.getRandomValues(new Uint8Array(12)),f=await crypto.subtle.importKey("raw",d,{name:"AES-GCM"},!1,["encrypt"]),l={name:"AES-GCM",iv:g,tagLength:128};e&&(l.additionalData=r.encode(e));let P=await crypto.subtle.encrypt(l,f,r.encode(h)),p=new Uint8Array(P),A=p.slice(0,p.length-16),R=p.slice(p.length-16),C=await crypto.subtle.importKey("spki",O(T),{name:"RSA-OAEP",hash:"SHA-1"},!1,["encrypt"]),_=await crypto.subtle.encrypt({name:"RSA-OAEP"},C,d),w=JSON.stringify({alg:"RSA-OAEP(SHA1)+AES-256-GCM(tag16)+AAD=salt",ek:y(_),iv:y(g.buffer),ct:y(A.buffer),tag:y(R.buffer)});return btoa(w)}catch(r){throw console.error("Encryption error:",r),new Error("Card encryption failed. Please try again.")}}var m=class{constructor(e){this.config={displayMode:"popup",...e},this.api=new i(e.environment,e.apiKey)}async initiate(e,t){let r={order_reference_code:t||c(),meta:e};return this.api.initiatePayment(r)}async getPaymentInfo(e){return this.api.getPaymentInfo(e)}async payWithCard(e,t){let r=await a(t);return this.api.createPaymentMethod({type:"card",order_reference_code:e,meta:{card_details:r}})}async getSupportedInstitutions(e,t){return this.api.getSupportedInstitutions({type:e,meta:{currency_code:t}})}async getSupportedCurrencies(e){return this.api.getSupportedCurrencies({type:e,meta:{currency:""}})}async getSupportedCountries(e,t){return this.api.getSupportedCountries({type:e,meta:{currency:t,country:""}})}async getSupportedNetworks(e,t,r){return this.api.getSupportedNetworks({type:e,meta:{currency:t,country:r,network:""}})}async payWithUSSD(e,t){return this.api.createPaymentMethod({type:"ussd",order_reference_code:e,meta:{institution:t}})}async payWithTransfer(e,t,r,s){return this.api.createPaymentMethod({type:"dynamic_virtual_account",order_reference_code:e,meta:{prefix:t,firstname:r,lastname:s}})}async payByBank(e,t,r){return this.api.createPaymentMethod({type:"pay_by_bank",order_reference_code:e,meta:{phone_number:t,name:r}})}async payWithMobileMoney(e,t,r,s){return this.api.createPaymentMethod({type:"mobile_money",order_reference_code:e,meta:{network:t,phone_number:r,account_name:s}})}async payWithStaticAccount(e,t={}){return this.api.createPaymentMethod({type:"static_virtual_account",order_reference_code:e,meta:t})}async payWithCrypto(e,t){return this.api.createPaymentMethod({type:"pay_with_crypto",order_reference_code:e,meta:{from_address:t||""}})}async confirmCryptoPayment(e,t){return this.api.confirmPaymentMethod({type:"pay_with_crypto",order_reference_code:e,meta:{tx_hash:t}})}async resendOTP(e,t){let r=await a(t);return this.api.resendOTP({type:"card",order_reference_code:e,meta:{card_details:r}})}async authorizeOTP(e,t,r,s){let o=await a(t);return this.api.authorizeOTP({type:"card",order_reference_code:e,meta:{card_details:o,otp:r,paymentId:s}})}async authorize3DS(e){return this.api.authorize3DS({type:"card",order_reference_code:e})}async simulatePayment(e,t){return this.api.simulatePayment({order_reference_code:e,payment_status:t,order_status:t})}getConfig(){return this.config}getEnvironment(){return this.config.environment}getBaseUrl(){return this.config.environment==="live"?"https://api.moipayway.co":"https://dev.moipayway.co"}};return v(L);})();
15
+ //# sourceMappingURL=checkout.global.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/api.ts","../src/utils.ts","../src/encryption.ts","../src/MoiPayWay.ts"],"sourcesContent":["export { MoiPayWay } from './MoiPayWay';\nexport { ApiClient } from './api';\nexport { encryptCardDetails } from './encryption';\nexport { generateOrderReference } from './utils';\n\nexport type {\n MoiPayWayConfig,\n MoiPayWayEnvironment,\n PaymentMeta,\n PaymentMethod,\n DisplayMode,\n CardDetails,\n ApiResponse,\n CardResponse,\n PaymentInfoResponse,\n InstitutionItem,\n WhiteLabelTheme,\n WhiteLabelContent,\n SplitConfig,\n SplitWallet,\n CheckoutStep,\n} from './types';\n","import type { MoiPayWayEnvironment } from './types';\n\nconst BASE_URLS: Record<MoiPayWayEnvironment, string> = {\n live: 'https://api.moipayway.co',\n test: 'https://dev.moipayway.co',\n};\n\nexport class ApiClient {\n private baseUrl: string;\n private apiKey: string;\n\n constructor(environment: MoiPayWayEnvironment, apiKey: string) {\n this.baseUrl = BASE_URLS[environment];\n this.apiKey = apiKey;\n }\n\n private async request<T>(endpoint: string, body: any): Promise<T> {\n const url = `${this.baseUrl}/${endpoint}`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n const data = await response.json();\n if (data.status === 'error' || data.status === 'failed') {\n throw new Error(data.message || 'Request failed');\n }\n return data;\n }\n\n async initiatePayment(payload: any) {\n return this.request('wallet/collection/initiate', payload);\n }\n\n async getPaymentInfo(orderReferenceCode: string) {\n return this.request('wallet/collection/info', {\n order_reference_code: orderReferenceCode,\n });\n }\n\n async createPaymentMethod(payload: any) {\n return this.request('wallet/collection/method/create', payload);\n }\n\n async getSupportedInstitutions(payload: any) {\n return this.request('wallet/collection/method/supported-institutions', payload);\n }\n\n async getSupportedCurrencies(payload: any) {\n return this.request('wallet/collection/method/supported-currencies', payload);\n }\n\n async getSupportedCountries(payload: any) {\n return this.request('wallet/collection/method/supported-countries', payload);\n }\n\n async getSupportedNetworks(payload: any) {\n return this.request('wallet/collection/method/supported-networks', payload);\n }\n\n async resendOTP(payload: any) {\n return this.request('wallet/collection/method/resend-otp', payload);\n }\n\n async authorizeOTP(payload: any) {\n return this.request('wallet/collection/method/authorize-otp', payload);\n }\n\n async authorize3DS(payload: any) {\n return this.request('wallet/collection/method/authorize-3ds', payload);\n }\n\n async confirmPaymentMethod(payload: any) {\n return this.request('wallet/collection/method/confirmation', payload);\n }\n\n async simulatePayment(payload: any) {\n return this.request('simulation/collection-order', payload);\n }\n}\n","export function generateOrderReference(length = 10): string {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n\nexport function formatAmount(amount: string | number, currency = 'NGN'): string {\n const num = typeof amount === 'string' ? parseFloat(amount) : amount;\n const code = currency.toUpperCase();\n const formatted = num.toLocaleString('en', { minimumFractionDigits: 2, maximumFractionDigits: 2 });\n return `${code} ${formatted}`;\n}\n\nexport const PAYMENT_METHOD_LABELS: Record<string, { label: string; icon: string }> = {\n card: { label: 'Card Payment', icon: '💳' },\n ussd: { label: 'USSD', icon: '📱' },\n dynamic_virtual_account: { label: 'Pay with Transfer (One time)', icon: '🏦' },\n static_virtual_account: { label: 'Static Account', icon: '🏛️' },\n pay_with_crypto: { label: 'Pay with Crypto', icon: '🪙' },\n pay_by_bank: { label: 'Pay by Bank', icon: '🔗' },\n mobile_money: { label: 'Mobile Money', icon: '📲' },\n};\n","const PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwl+N8sgsM2DPFLvBRwyx\n55yNdSzZYucBzTwrRhE7qpc9i69hDhKAGukXvqm2R/HGHjKRPCojTDgEpZEPqE0d\nd7oD2gq9pLKk5XmOGNSCIyL3HsHNhLKSSonrTeDkBfrVp0DJ/pw1pLQRz6bbWIYL\nILLaBJ35B5wlcwzlQz+m3INH/RkfTSsji/aToITdwmLeREJ3/c+eBxWkU5nTXLub\niUyoN47FMimXzfIUgIxAtrlOuilKY37Ft6T4JJvDcNU1EVdiv/YX7OMUFbwxeTOn\nRhkhNKWwsDUc1JHp/AuW5P6tGMA0XxDXIFGrkcBGIrgOgyvbydcOQTcLBCgB3+qt\n18R/Yup0LR7ut/rF98EOfu3JiKiBfCh2o89dmmaeHdgIi7CyepU31e0JQCCAKG2l\nRTvqdMZkWfLH1EK7G+HgKdF08Dbuy+bguV/gRF09Hp16vEl2bKZL1Pk5mJc0JBM2\n7eDqXorXmym6v9h6ugu4Anc85u6fORN3WabRcLMLbRBfr1j/B9cETlGNNQ8zlBmJ\nQya765pNonNXC5AMJqgDm9uk9fmGBwc68UPALx8+PO4/GyHkM4u0ITtnvvNtdK5d\nG62wC4dQhOCfr/eJoiplefGGuir3MMCqyOi+zWe+HlKQpVcpS285Y5aPE3WmDl09\n9qYq6sb+UBuCIzag7FECy8MCAwEAAQ==\n-----END PUBLIC KEY-----`;\n\nfunction pemToArrayBuffer(pem: string): ArrayBuffer {\n const b64 = pem\n .replace(/-----BEGIN PUBLIC KEY-----/, '')\n .replace(/-----END PUBLIC KEY-----/, '')\n .replace(/[\\s\\n\\r]/g, '');\n const bin = atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return bytes.buffer;\n}\n\nfunction arrayBufferToBase64(buf: ArrayBuffer): string {\n const bytes = new Uint8Array(buf);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);\n return btoa(binary);\n}\n\nfunction randomHex(byteCount: number): string {\n const bytes = crypto.getRandomValues(new Uint8Array(byteCount));\n return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * Matches PHP: encryptUsingMPW()\n * RSA-OAEP(SHA-1) + AES-256-GCM(tag16) + AAD=salt\n */\nexport async function encryptCardDetails(\n cardDetails: { pan: string; expire_month: string; expire_year: string; cvv: string; pin: string; phone_number?: string; holder_name?: string; street?: string; country_code?: string; state?: string; city?: string; postal_code?: string },\n salt: string = '',\n ttlSeconds: number = 300\n): Promise<string> {\n try {\n const encoder = new TextEncoder();\n\n // 1. Build payload (matches PHP structure — data is a STRING, not object)\n const cardString = JSON.stringify({\n phone_number: cardDetails.phone_number || '',\n holder_name: cardDetails.holder_name || '',\n pan: cardDetails.pan,\n expire_month: cardDetails.expire_month,\n expire_year: cardDetails.expire_year,\n cvv: cardDetails.cvv,\n pin: cardDetails.pin,\n street: cardDetails.street || '',\n country_code: cardDetails.country_code || '',\n state: cardDetails.state || '',\n city: cardDetails.city || '',\n postal_code: cardDetails.postal_code || '',\n });\n const payload = {\n data: cardString,\n ts: Math.floor(Date.now() / 1000),\n ttl: ttlSeconds < 0 ? 300 : ttlSeconds,\n nonce: randomHex(16),\n };\n const plain = JSON.stringify(payload);\n\n // 2. Generate AES-256 key (32 bytes) + GCM IV (12 bytes)\n const aesKeyRaw = crypto.getRandomValues(new Uint8Array(32));\n const iv = crypto.getRandomValues(new Uint8Array(12));\n\n // 3. Import AES key\n const aesKey = await crypto.subtle.importKey(\n 'raw', aesKeyRaw, { name: 'AES-GCM' }, false, ['encrypt']\n );\n\n // 4. AES-256-GCM encrypt with salt as AAD, 128-bit tag\n const aesParams: AesGcmParams = {\n name: 'AES-GCM',\n iv,\n tagLength: 128,\n };\n if (salt) {\n aesParams.additionalData = encoder.encode(salt);\n }\n\n const cipherAndTag = await crypto.subtle.encrypt(aesParams, aesKey, encoder.encode(plain));\n\n // Web Crypto appends tag to ciphertext; split them\n const cipherAndTagBytes = new Uint8Array(cipherAndTag);\n const ct = cipherAndTagBytes.slice(0, cipherAndTagBytes.length - 16);\n const tag = cipherAndTagBytes.slice(cipherAndTagBytes.length - 16);\n\n // 5. RSA-OAEP (SHA-1) wrap the AES key\n const rsaKey = await crypto.subtle.importKey(\n 'spki',\n pemToArrayBuffer(PUBLIC_KEY),\n { name: 'RSA-OAEP', hash: 'SHA-1' },\n false,\n ['encrypt']\n );\n const ek = await crypto.subtle.encrypt({ name: 'RSA-OAEP' }, rsaKey, aesKeyRaw);\n\n // 6. Build package (matches PHP output)\n const pkg = JSON.stringify({\n alg: 'RSA-OAEP(SHA1)+AES-256-GCM(tag16)+AAD=salt',\n ek: arrayBufferToBase64(ek),\n iv: arrayBufferToBase64(iv.buffer),\n ct: arrayBufferToBase64(ct.buffer),\n tag: arrayBufferToBase64(tag.buffer),\n });\n\n // 7. Base64 encode the entire package\n return btoa(pkg);\n } catch (err) {\n console.error('Encryption error:', err);\n throw new Error('Card encryption failed. Please try again.');\n }\n}\n","import { ApiClient } from './api';\nimport { generateOrderReference } from './utils';\nimport { encryptCardDetails } from './encryption';\nimport type {\n MoiPayWayConfig,\n InitiatePayload,\n PaymentMeta,\n CardDetails,\n ApiResponse,\n CardResponse,\n PaymentInfoResponse,\n InstitutionItem,\n} from './types';\n\nexport class MoiPayWay {\n private config: MoiPayWayConfig;\n private api: ApiClient;\n\n constructor(config: MoiPayWayConfig) {\n this.config = {\n displayMode: 'popup',\n ...config,\n };\n this.api = new ApiClient(config.environment, config.apiKey);\n }\n\n async initiate(meta: PaymentMeta, orderReferenceCode?: string): Promise<ApiResponse> {\n const payload: InitiatePayload = {\n order_reference_code: orderReferenceCode || generateOrderReference(),\n meta,\n };\n return this.api.initiatePayment(payload) as Promise<ApiResponse>;\n }\n\n async getPaymentInfo(orderReferenceCode: string): Promise<ApiResponse<PaymentInfoResponse>> {\n return this.api.getPaymentInfo(orderReferenceCode) as Promise<ApiResponse<PaymentInfoResponse>>;\n }\n\n async payWithCard(\n orderReferenceCode: string,\n cardDetails: CardDetails\n ): Promise<ApiResponse<CardResponse>> {\n const encrypted = await encryptCardDetails(cardDetails);\n return this.api.createPaymentMethod({\n type: 'card',\n order_reference_code: orderReferenceCode,\n meta: { card_details: encrypted },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async getSupportedInstitutions(type: string, currencyCode: string): Promise<ApiResponse<InstitutionItem[]>> {\n return this.api.getSupportedInstitutions({\n type,\n meta: { currency_code: currencyCode },\n }) as Promise<ApiResponse<InstitutionItem[]>>;\n }\n\n async getSupportedCurrencies(type: string): Promise<ApiResponse<{ currency: string }[]>> {\n return this.api.getSupportedCurrencies({\n type,\n meta: { currency: '' },\n }) as Promise<ApiResponse<{ currency: string }[]>>;\n }\n\n async getSupportedCountries(type: string, currency: string): Promise<ApiResponse<{ country: string; currency: string }[]>> {\n return this.api.getSupportedCountries({\n type,\n meta: { currency, country: '' },\n }) as Promise<ApiResponse<{ country: string; currency: string }[]>>;\n }\n\n async getSupportedNetworks(type: string, currency: string, country: string): Promise<ApiResponse<{ network: string; country: string; currency: string }[]>> {\n return this.api.getSupportedNetworks({\n type,\n meta: { currency, country, network: '' },\n }) as Promise<ApiResponse<{ network: string; country: string; currency: string }[]>>;\n }\n\n async payWithUSSD(\n orderReferenceCode: string,\n institution: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'ussd',\n order_reference_code: orderReferenceCode,\n meta: { institution },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payWithTransfer(\n orderReferenceCode: string,\n prefix: string,\n firstname: string,\n lastname: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'dynamic_virtual_account',\n order_reference_code: orderReferenceCode,\n meta: { prefix, firstname, lastname },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payByBank(\n orderReferenceCode: string,\n phoneNumber: string,\n name: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'pay_by_bank',\n order_reference_code: orderReferenceCode,\n meta: { phone_number: phoneNumber, name },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payWithMobileMoney(\n orderReferenceCode: string,\n network: string,\n phoneNumber: string,\n accountName: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'mobile_money',\n order_reference_code: orderReferenceCode,\n meta: { network, phone_number: phoneNumber, account_name: accountName },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payWithStaticAccount(\n orderReferenceCode: string,\n meta: Record<string, string> = {}\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'static_virtual_account',\n order_reference_code: orderReferenceCode,\n meta,\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payWithCrypto(\n orderReferenceCode: string,\n fromAddress?: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'pay_with_crypto',\n order_reference_code: orderReferenceCode,\n meta: { from_address: fromAddress || '' },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async confirmCryptoPayment(\n orderReferenceCode: string,\n txHash: string\n ): Promise<ApiResponse> {\n return this.api.confirmPaymentMethod({\n type: 'pay_with_crypto',\n order_reference_code: orderReferenceCode,\n meta: { tx_hash: txHash },\n }) as Promise<ApiResponse>;\n }\n\n async resendOTP(\n orderReferenceCode: string,\n cardDetails: CardDetails\n ): Promise<ApiResponse> {\n const encrypted = await encryptCardDetails(cardDetails);\n return this.api.resendOTP({\n type: 'card',\n order_reference_code: orderReferenceCode,\n meta: { card_details: encrypted },\n }) as Promise<ApiResponse>;\n }\n\n async authorizeOTP(\n orderReferenceCode: string,\n cardDetails: CardDetails,\n otp: string,\n paymentId: string\n ): Promise<ApiResponse<CardResponse>> {\n const encrypted = await encryptCardDetails(cardDetails);\n return this.api.authorizeOTP({\n type: 'card',\n order_reference_code: orderReferenceCode,\n meta: { card_details: encrypted, otp, paymentId },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async authorize3DS(orderReferenceCode: string): Promise<ApiResponse<CardResponse>> {\n return this.api.authorize3DS({\n type: 'card',\n order_reference_code: orderReferenceCode,\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async simulatePayment(\n orderReferenceCode: string,\n paymentStatus: 'Successful' | 'Failed'\n ): Promise<ApiResponse> {\n return this.api.simulatePayment({\n order_reference_code: orderReferenceCode,\n payment_status: paymentStatus,\n order_status: paymentStatus,\n }) as Promise<ApiResponse>;\n }\n\n getConfig() {\n return this.config;\n }\n\n getEnvironment() {\n return this.config.environment;\n }\n\n getBaseUrl() {\n return this.config.environment === 'live'\n ? 'https://api.moipayway.co'\n : 'https://dev.moipayway.co';\n }\n}\n\nexport type { MoiPayWayConfig, PaymentMeta, CardDetails, PaymentMethod, DisplayMode } from './types';\n"],"mappings":"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","names":["src_exports","__export","ApiClient","MoiPayWay","encryptCardDetails","generateOrderReference","BASE_URLS","ApiClient","environment","apiKey","endpoint","body","url","data","payload","orderReferenceCode","generateOrderReference","length","chars","result","i","PUBLIC_KEY","pemToArrayBuffer","pem","b64","bin","bytes","i","arrayBufferToBase64","buf","binary","randomHex","byteCount","b","encryptCardDetails","cardDetails","salt","ttlSeconds","encoder","payload","plain","aesKeyRaw","iv","aesKey","aesParams","cipherAndTag","cipherAndTagBytes","ct","tag","rsaKey","ek","pkg","err","MoiPayWay","config","ApiClient","meta","orderReferenceCode","payload","generateOrderReference","cardDetails","encrypted","encryptCardDetails","type","currencyCode","currency","country","institution","prefix","firstname","lastname","phoneNumber","name","network","accountName","fromAddress","txHash","otp","paymentId","paymentStatus"]}
@@ -0,0 +1,15 @@
1
+ "use strict";var u=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var I=(n,e)=>{for(var t in e)u(n,t,{get:e[t],enumerable:!0})},E=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of M(e))!S.call(n,s)&&s!==t&&u(n,s,{get:()=>e[s],enumerable:!(r=b(e,s))||r.enumerable});return n};var v=n=>E(u({},"__esModule",{value:!0}),n);var L={};I(L,{ApiClient:()=>i,MoiPayWay:()=>m,encryptCardDetails:()=>a,generateOrderReference:()=>c});module.exports=v(L);var B={live:"https://api.moipayway.co",test:"https://dev.moipayway.co"},i=class{constructor(e,t){this.baseUrl=B[e],this.apiKey=t}async request(e,t){let r=`${this.baseUrl}/${e}`,o=await(await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify(t)})).json();if(o.status==="error"||o.status==="failed")throw new Error(o.message||"Request failed");return o}async initiatePayment(e){return this.request("wallet/collection/initiate",e)}async getPaymentInfo(e){return this.request("wallet/collection/info",{order_reference_code:e})}async createPaymentMethod(e){return this.request("wallet/collection/method/create",e)}async getSupportedInstitutions(e){return this.request("wallet/collection/method/supported-institutions",e)}async getSupportedCurrencies(e){return this.request("wallet/collection/method/supported-currencies",e)}async getSupportedCountries(e){return this.request("wallet/collection/method/supported-countries",e)}async getSupportedNetworks(e){return this.request("wallet/collection/method/supported-networks",e)}async resendOTP(e){return this.request("wallet/collection/method/resend-otp",e)}async authorizeOTP(e){return this.request("wallet/collection/method/authorize-otp",e)}async authorize3DS(e){return this.request("wallet/collection/method/authorize-3ds",e)}async confirmPaymentMethod(e){return this.request("wallet/collection/method/confirmation",e)}async simulatePayment(e){return this.request("simulation/collection-order",e)}};function c(n=10){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",t="";for(let r=0;r<n;r++)t+=e.charAt(Math.floor(Math.random()*e.length));return t}var T=`-----BEGIN PUBLIC KEY-----
2
+ MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwl+N8sgsM2DPFLvBRwyx
3
+ 55yNdSzZYucBzTwrRhE7qpc9i69hDhKAGukXvqm2R/HGHjKRPCojTDgEpZEPqE0d
4
+ d7oD2gq9pLKk5XmOGNSCIyL3HsHNhLKSSonrTeDkBfrVp0DJ/pw1pLQRz6bbWIYL
5
+ ILLaBJ35B5wlcwzlQz+m3INH/RkfTSsji/aToITdwmLeREJ3/c+eBxWkU5nTXLub
6
+ iUyoN47FMimXzfIUgIxAtrlOuilKY37Ft6T4JJvDcNU1EVdiv/YX7OMUFbwxeTOn
7
+ RhkhNKWwsDUc1JHp/AuW5P6tGMA0XxDXIFGrkcBGIrgOgyvbydcOQTcLBCgB3+qt
8
+ 18R/Yup0LR7ut/rF98EOfu3JiKiBfCh2o89dmmaeHdgIi7CyepU31e0JQCCAKG2l
9
+ RTvqdMZkWfLH1EK7G+HgKdF08Dbuy+bguV/gRF09Hp16vEl2bKZL1Pk5mJc0JBM2
10
+ 7eDqXorXmym6v9h6ugu4Anc85u6fORN3WabRcLMLbRBfr1j/B9cETlGNNQ8zlBmJ
11
+ Qya765pNonNXC5AMJqgDm9uk9fmGBwc68UPALx8+PO4/GyHkM4u0ITtnvvNtdK5d
12
+ G62wC4dQhOCfr/eJoiplefGGuir3MMCqyOi+zWe+HlKQpVcpS285Y5aPE3WmDl09
13
+ 9qYq6sb+UBuCIzag7FECy8MCAwEAAQ==
14
+ -----END PUBLIC KEY-----`;function O(n){let e=n.replace(/-----BEGIN PUBLIC KEY-----/,"").replace(/-----END PUBLIC KEY-----/,"").replace(/[\s\n\r]/g,""),t=atob(e),r=new Uint8Array(t.length);for(let s=0;s<t.length;s++)r[s]=t.charCodeAt(s);return r.buffer}function y(n){let e=new Uint8Array(n),t="";for(let r=0;r<e.length;r++)t+=String.fromCharCode(e[r]);return btoa(t)}function k(n){let e=crypto.getRandomValues(new Uint8Array(n));return Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("")}async function a(n,e="",t=300){try{let r=new TextEncoder,o={data:JSON.stringify({phone_number:n.phone_number||"",holder_name:n.holder_name||"",pan:n.pan,expire_month:n.expire_month,expire_year:n.expire_year,cvv:n.cvv,pin:n.pin,street:n.street||"",country_code:n.country_code||"",state:n.state||"",city:n.city||"",postal_code:n.postal_code||""}),ts:Math.floor(Date.now()/1e3),ttl:t<0?300:t,nonce:k(16)},h=JSON.stringify(o),d=crypto.getRandomValues(new Uint8Array(32)),g=crypto.getRandomValues(new Uint8Array(12)),f=await crypto.subtle.importKey("raw",d,{name:"AES-GCM"},!1,["encrypt"]),l={name:"AES-GCM",iv:g,tagLength:128};e&&(l.additionalData=r.encode(e));let P=await crypto.subtle.encrypt(l,f,r.encode(h)),p=new Uint8Array(P),A=p.slice(0,p.length-16),R=p.slice(p.length-16),C=await crypto.subtle.importKey("spki",O(T),{name:"RSA-OAEP",hash:"SHA-1"},!1,["encrypt"]),_=await crypto.subtle.encrypt({name:"RSA-OAEP"},C,d),w=JSON.stringify({alg:"RSA-OAEP(SHA1)+AES-256-GCM(tag16)+AAD=salt",ek:y(_),iv:y(g.buffer),ct:y(A.buffer),tag:y(R.buffer)});return btoa(w)}catch(r){throw console.error("Encryption error:",r),new Error("Card encryption failed. Please try again.")}}var m=class{constructor(e){this.config={displayMode:"popup",...e},this.api=new i(e.environment,e.apiKey)}async initiate(e,t){let r={order_reference_code:t||c(),meta:e};return this.api.initiatePayment(r)}async getPaymentInfo(e){return this.api.getPaymentInfo(e)}async payWithCard(e,t){let r=await a(t);return this.api.createPaymentMethod({type:"card",order_reference_code:e,meta:{card_details:r}})}async getSupportedInstitutions(e,t){return this.api.getSupportedInstitutions({type:e,meta:{currency_code:t}})}async getSupportedCurrencies(e){return this.api.getSupportedCurrencies({type:e,meta:{currency:""}})}async getSupportedCountries(e,t){return this.api.getSupportedCountries({type:e,meta:{currency:t,country:""}})}async getSupportedNetworks(e,t,r){return this.api.getSupportedNetworks({type:e,meta:{currency:t,country:r,network:""}})}async payWithUSSD(e,t){return this.api.createPaymentMethod({type:"ussd",order_reference_code:e,meta:{institution:t}})}async payWithTransfer(e,t,r,s){return this.api.createPaymentMethod({type:"dynamic_virtual_account",order_reference_code:e,meta:{prefix:t,firstname:r,lastname:s}})}async payByBank(e,t,r){return this.api.createPaymentMethod({type:"pay_by_bank",order_reference_code:e,meta:{phone_number:t,name:r}})}async payWithMobileMoney(e,t,r,s){return this.api.createPaymentMethod({type:"mobile_money",order_reference_code:e,meta:{network:t,phone_number:r,account_name:s}})}async payWithStaticAccount(e,t={}){return this.api.createPaymentMethod({type:"static_virtual_account",order_reference_code:e,meta:t})}async payWithCrypto(e,t){return this.api.createPaymentMethod({type:"pay_with_crypto",order_reference_code:e,meta:{from_address:t||""}})}async confirmCryptoPayment(e,t){return this.api.confirmPaymentMethod({type:"pay_with_crypto",order_reference_code:e,meta:{tx_hash:t}})}async resendOTP(e,t){let r=await a(t);return this.api.resendOTP({type:"card",order_reference_code:e,meta:{card_details:r}})}async authorizeOTP(e,t,r,s){let o=await a(t);return this.api.authorizeOTP({type:"card",order_reference_code:e,meta:{card_details:o,otp:r,paymentId:s}})}async authorize3DS(e){return this.api.authorize3DS({type:"card",order_reference_code:e})}async simulatePayment(e,t){return this.api.simulatePayment({order_reference_code:e,payment_status:t,order_status:t})}getConfig(){return this.config}getEnvironment(){return this.config.environment}getBaseUrl(){return this.config.environment==="live"?"https://api.moipayway.co":"https://dev.moipayway.co"}};0&&(module.exports={ApiClient,MoiPayWay,encryptCardDetails,generateOrderReference});
15
+ //# sourceMappingURL=checkout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/api.ts","../src/utils.ts","../src/encryption.ts","../src/MoiPayWay.ts"],"sourcesContent":["export { MoiPayWay } from './MoiPayWay';\nexport { ApiClient } from './api';\nexport { encryptCardDetails } from './encryption';\nexport { generateOrderReference } from './utils';\n\nexport type {\n MoiPayWayConfig,\n MoiPayWayEnvironment,\n PaymentMeta,\n PaymentMethod,\n DisplayMode,\n CardDetails,\n ApiResponse,\n CardResponse,\n PaymentInfoResponse,\n InstitutionItem,\n WhiteLabelTheme,\n WhiteLabelContent,\n SplitConfig,\n SplitWallet,\n CheckoutStep,\n} from './types';\n","import type { MoiPayWayEnvironment } from './types';\n\nconst BASE_URLS: Record<MoiPayWayEnvironment, string> = {\n live: 'https://api.moipayway.co',\n test: 'https://dev.moipayway.co',\n};\n\nexport class ApiClient {\n private baseUrl: string;\n private apiKey: string;\n\n constructor(environment: MoiPayWayEnvironment, apiKey: string) {\n this.baseUrl = BASE_URLS[environment];\n this.apiKey = apiKey;\n }\n\n private async request<T>(endpoint: string, body: any): Promise<T> {\n const url = `${this.baseUrl}/${endpoint}`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n const data = await response.json();\n if (data.status === 'error' || data.status === 'failed') {\n throw new Error(data.message || 'Request failed');\n }\n return data;\n }\n\n async initiatePayment(payload: any) {\n return this.request('wallet/collection/initiate', payload);\n }\n\n async getPaymentInfo(orderReferenceCode: string) {\n return this.request('wallet/collection/info', {\n order_reference_code: orderReferenceCode,\n });\n }\n\n async createPaymentMethod(payload: any) {\n return this.request('wallet/collection/method/create', payload);\n }\n\n async getSupportedInstitutions(payload: any) {\n return this.request('wallet/collection/method/supported-institutions', payload);\n }\n\n async getSupportedCurrencies(payload: any) {\n return this.request('wallet/collection/method/supported-currencies', payload);\n }\n\n async getSupportedCountries(payload: any) {\n return this.request('wallet/collection/method/supported-countries', payload);\n }\n\n async getSupportedNetworks(payload: any) {\n return this.request('wallet/collection/method/supported-networks', payload);\n }\n\n async resendOTP(payload: any) {\n return this.request('wallet/collection/method/resend-otp', payload);\n }\n\n async authorizeOTP(payload: any) {\n return this.request('wallet/collection/method/authorize-otp', payload);\n }\n\n async authorize3DS(payload: any) {\n return this.request('wallet/collection/method/authorize-3ds', payload);\n }\n\n async confirmPaymentMethod(payload: any) {\n return this.request('wallet/collection/method/confirmation', payload);\n }\n\n async simulatePayment(payload: any) {\n return this.request('simulation/collection-order', payload);\n }\n}\n","export function generateOrderReference(length = 10): string {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n\nexport function formatAmount(amount: string | number, currency = 'NGN'): string {\n const num = typeof amount === 'string' ? parseFloat(amount) : amount;\n const code = currency.toUpperCase();\n const formatted = num.toLocaleString('en', { minimumFractionDigits: 2, maximumFractionDigits: 2 });\n return `${code} ${formatted}`;\n}\n\nexport const PAYMENT_METHOD_LABELS: Record<string, { label: string; icon: string }> = {\n card: { label: 'Card Payment', icon: '💳' },\n ussd: { label: 'USSD', icon: '📱' },\n dynamic_virtual_account: { label: 'Pay with Transfer (One time)', icon: '🏦' },\n static_virtual_account: { label: 'Static Account', icon: '🏛️' },\n pay_with_crypto: { label: 'Pay with Crypto', icon: '🪙' },\n pay_by_bank: { label: 'Pay by Bank', icon: '🔗' },\n mobile_money: { label: 'Mobile Money', icon: '📲' },\n};\n","const PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwl+N8sgsM2DPFLvBRwyx\n55yNdSzZYucBzTwrRhE7qpc9i69hDhKAGukXvqm2R/HGHjKRPCojTDgEpZEPqE0d\nd7oD2gq9pLKk5XmOGNSCIyL3HsHNhLKSSonrTeDkBfrVp0DJ/pw1pLQRz6bbWIYL\nILLaBJ35B5wlcwzlQz+m3INH/RkfTSsji/aToITdwmLeREJ3/c+eBxWkU5nTXLub\niUyoN47FMimXzfIUgIxAtrlOuilKY37Ft6T4JJvDcNU1EVdiv/YX7OMUFbwxeTOn\nRhkhNKWwsDUc1JHp/AuW5P6tGMA0XxDXIFGrkcBGIrgOgyvbydcOQTcLBCgB3+qt\n18R/Yup0LR7ut/rF98EOfu3JiKiBfCh2o89dmmaeHdgIi7CyepU31e0JQCCAKG2l\nRTvqdMZkWfLH1EK7G+HgKdF08Dbuy+bguV/gRF09Hp16vEl2bKZL1Pk5mJc0JBM2\n7eDqXorXmym6v9h6ugu4Anc85u6fORN3WabRcLMLbRBfr1j/B9cETlGNNQ8zlBmJ\nQya765pNonNXC5AMJqgDm9uk9fmGBwc68UPALx8+PO4/GyHkM4u0ITtnvvNtdK5d\nG62wC4dQhOCfr/eJoiplefGGuir3MMCqyOi+zWe+HlKQpVcpS285Y5aPE3WmDl09\n9qYq6sb+UBuCIzag7FECy8MCAwEAAQ==\n-----END PUBLIC KEY-----`;\n\nfunction pemToArrayBuffer(pem: string): ArrayBuffer {\n const b64 = pem\n .replace(/-----BEGIN PUBLIC KEY-----/, '')\n .replace(/-----END PUBLIC KEY-----/, '')\n .replace(/[\\s\\n\\r]/g, '');\n const bin = atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return bytes.buffer;\n}\n\nfunction arrayBufferToBase64(buf: ArrayBuffer): string {\n const bytes = new Uint8Array(buf);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);\n return btoa(binary);\n}\n\nfunction randomHex(byteCount: number): string {\n const bytes = crypto.getRandomValues(new Uint8Array(byteCount));\n return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * Matches PHP: encryptUsingMPW()\n * RSA-OAEP(SHA-1) + AES-256-GCM(tag16) + AAD=salt\n */\nexport async function encryptCardDetails(\n cardDetails: { pan: string; expire_month: string; expire_year: string; cvv: string; pin: string; phone_number?: string; holder_name?: string; street?: string; country_code?: string; state?: string; city?: string; postal_code?: string },\n salt: string = '',\n ttlSeconds: number = 300\n): Promise<string> {\n try {\n const encoder = new TextEncoder();\n\n // 1. Build payload (matches PHP structure — data is a STRING, not object)\n const cardString = JSON.stringify({\n phone_number: cardDetails.phone_number || '',\n holder_name: cardDetails.holder_name || '',\n pan: cardDetails.pan,\n expire_month: cardDetails.expire_month,\n expire_year: cardDetails.expire_year,\n cvv: cardDetails.cvv,\n pin: cardDetails.pin,\n street: cardDetails.street || '',\n country_code: cardDetails.country_code || '',\n state: cardDetails.state || '',\n city: cardDetails.city || '',\n postal_code: cardDetails.postal_code || '',\n });\n const payload = {\n data: cardString,\n ts: Math.floor(Date.now() / 1000),\n ttl: ttlSeconds < 0 ? 300 : ttlSeconds,\n nonce: randomHex(16),\n };\n const plain = JSON.stringify(payload);\n\n // 2. Generate AES-256 key (32 bytes) + GCM IV (12 bytes)\n const aesKeyRaw = crypto.getRandomValues(new Uint8Array(32));\n const iv = crypto.getRandomValues(new Uint8Array(12));\n\n // 3. Import AES key\n const aesKey = await crypto.subtle.importKey(\n 'raw', aesKeyRaw, { name: 'AES-GCM' }, false, ['encrypt']\n );\n\n // 4. AES-256-GCM encrypt with salt as AAD, 128-bit tag\n const aesParams: AesGcmParams = {\n name: 'AES-GCM',\n iv,\n tagLength: 128,\n };\n if (salt) {\n aesParams.additionalData = encoder.encode(salt);\n }\n\n const cipherAndTag = await crypto.subtle.encrypt(aesParams, aesKey, encoder.encode(plain));\n\n // Web Crypto appends tag to ciphertext; split them\n const cipherAndTagBytes = new Uint8Array(cipherAndTag);\n const ct = cipherAndTagBytes.slice(0, cipherAndTagBytes.length - 16);\n const tag = cipherAndTagBytes.slice(cipherAndTagBytes.length - 16);\n\n // 5. RSA-OAEP (SHA-1) wrap the AES key\n const rsaKey = await crypto.subtle.importKey(\n 'spki',\n pemToArrayBuffer(PUBLIC_KEY),\n { name: 'RSA-OAEP', hash: 'SHA-1' },\n false,\n ['encrypt']\n );\n const ek = await crypto.subtle.encrypt({ name: 'RSA-OAEP' }, rsaKey, aesKeyRaw);\n\n // 6. Build package (matches PHP output)\n const pkg = JSON.stringify({\n alg: 'RSA-OAEP(SHA1)+AES-256-GCM(tag16)+AAD=salt',\n ek: arrayBufferToBase64(ek),\n iv: arrayBufferToBase64(iv.buffer),\n ct: arrayBufferToBase64(ct.buffer),\n tag: arrayBufferToBase64(tag.buffer),\n });\n\n // 7. Base64 encode the entire package\n return btoa(pkg);\n } catch (err) {\n console.error('Encryption error:', err);\n throw new Error('Card encryption failed. Please try again.');\n }\n}\n","import { ApiClient } from './api';\nimport { generateOrderReference } from './utils';\nimport { encryptCardDetails } from './encryption';\nimport type {\n MoiPayWayConfig,\n InitiatePayload,\n PaymentMeta,\n CardDetails,\n ApiResponse,\n CardResponse,\n PaymentInfoResponse,\n InstitutionItem,\n} from './types';\n\nexport class MoiPayWay {\n private config: MoiPayWayConfig;\n private api: ApiClient;\n\n constructor(config: MoiPayWayConfig) {\n this.config = {\n displayMode: 'popup',\n ...config,\n };\n this.api = new ApiClient(config.environment, config.apiKey);\n }\n\n async initiate(meta: PaymentMeta, orderReferenceCode?: string): Promise<ApiResponse> {\n const payload: InitiatePayload = {\n order_reference_code: orderReferenceCode || generateOrderReference(),\n meta,\n };\n return this.api.initiatePayment(payload) as Promise<ApiResponse>;\n }\n\n async getPaymentInfo(orderReferenceCode: string): Promise<ApiResponse<PaymentInfoResponse>> {\n return this.api.getPaymentInfo(orderReferenceCode) as Promise<ApiResponse<PaymentInfoResponse>>;\n }\n\n async payWithCard(\n orderReferenceCode: string,\n cardDetails: CardDetails\n ): Promise<ApiResponse<CardResponse>> {\n const encrypted = await encryptCardDetails(cardDetails);\n return this.api.createPaymentMethod({\n type: 'card',\n order_reference_code: orderReferenceCode,\n meta: { card_details: encrypted },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async getSupportedInstitutions(type: string, currencyCode: string): Promise<ApiResponse<InstitutionItem[]>> {\n return this.api.getSupportedInstitutions({\n type,\n meta: { currency_code: currencyCode },\n }) as Promise<ApiResponse<InstitutionItem[]>>;\n }\n\n async getSupportedCurrencies(type: string): Promise<ApiResponse<{ currency: string }[]>> {\n return this.api.getSupportedCurrencies({\n type,\n meta: { currency: '' },\n }) as Promise<ApiResponse<{ currency: string }[]>>;\n }\n\n async getSupportedCountries(type: string, currency: string): Promise<ApiResponse<{ country: string; currency: string }[]>> {\n return this.api.getSupportedCountries({\n type,\n meta: { currency, country: '' },\n }) as Promise<ApiResponse<{ country: string; currency: string }[]>>;\n }\n\n async getSupportedNetworks(type: string, currency: string, country: string): Promise<ApiResponse<{ network: string; country: string; currency: string }[]>> {\n return this.api.getSupportedNetworks({\n type,\n meta: { currency, country, network: '' },\n }) as Promise<ApiResponse<{ network: string; country: string; currency: string }[]>>;\n }\n\n async payWithUSSD(\n orderReferenceCode: string,\n institution: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'ussd',\n order_reference_code: orderReferenceCode,\n meta: { institution },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payWithTransfer(\n orderReferenceCode: string,\n prefix: string,\n firstname: string,\n lastname: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'dynamic_virtual_account',\n order_reference_code: orderReferenceCode,\n meta: { prefix, firstname, lastname },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payByBank(\n orderReferenceCode: string,\n phoneNumber: string,\n name: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'pay_by_bank',\n order_reference_code: orderReferenceCode,\n meta: { phone_number: phoneNumber, name },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payWithMobileMoney(\n orderReferenceCode: string,\n network: string,\n phoneNumber: string,\n accountName: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'mobile_money',\n order_reference_code: orderReferenceCode,\n meta: { network, phone_number: phoneNumber, account_name: accountName },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payWithStaticAccount(\n orderReferenceCode: string,\n meta: Record<string, string> = {}\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'static_virtual_account',\n order_reference_code: orderReferenceCode,\n meta,\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async payWithCrypto(\n orderReferenceCode: string,\n fromAddress?: string\n ): Promise<ApiResponse<CardResponse>> {\n return this.api.createPaymentMethod({\n type: 'pay_with_crypto',\n order_reference_code: orderReferenceCode,\n meta: { from_address: fromAddress || '' },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async confirmCryptoPayment(\n orderReferenceCode: string,\n txHash: string\n ): Promise<ApiResponse> {\n return this.api.confirmPaymentMethod({\n type: 'pay_with_crypto',\n order_reference_code: orderReferenceCode,\n meta: { tx_hash: txHash },\n }) as Promise<ApiResponse>;\n }\n\n async resendOTP(\n orderReferenceCode: string,\n cardDetails: CardDetails\n ): Promise<ApiResponse> {\n const encrypted = await encryptCardDetails(cardDetails);\n return this.api.resendOTP({\n type: 'card',\n order_reference_code: orderReferenceCode,\n meta: { card_details: encrypted },\n }) as Promise<ApiResponse>;\n }\n\n async authorizeOTP(\n orderReferenceCode: string,\n cardDetails: CardDetails,\n otp: string,\n paymentId: string\n ): Promise<ApiResponse<CardResponse>> {\n const encrypted = await encryptCardDetails(cardDetails);\n return this.api.authorizeOTP({\n type: 'card',\n order_reference_code: orderReferenceCode,\n meta: { card_details: encrypted, otp, paymentId },\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async authorize3DS(orderReferenceCode: string): Promise<ApiResponse<CardResponse>> {\n return this.api.authorize3DS({\n type: 'card',\n order_reference_code: orderReferenceCode,\n }) as Promise<ApiResponse<CardResponse>>;\n }\n\n async simulatePayment(\n orderReferenceCode: string,\n paymentStatus: 'Successful' | 'Failed'\n ): Promise<ApiResponse> {\n return this.api.simulatePayment({\n order_reference_code: orderReferenceCode,\n payment_status: paymentStatus,\n order_status: paymentStatus,\n }) as Promise<ApiResponse>;\n }\n\n getConfig() {\n return this.config;\n }\n\n getEnvironment() {\n return this.config.environment;\n }\n\n getBaseUrl() {\n return this.config.environment === 'live'\n ? 'https://api.moipayway.co'\n : 'https://dev.moipayway.co';\n }\n}\n\nexport type { MoiPayWayConfig, PaymentMeta, CardDetails, PaymentMethod, DisplayMode } from './types';\n"],"mappings":"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","names":["src_exports","__export","ApiClient","MoiPayWay","encryptCardDetails","generateOrderReference","__toCommonJS","BASE_URLS","ApiClient","environment","apiKey","endpoint","body","url","data","payload","orderReferenceCode","generateOrderReference","length","chars","result","i","PUBLIC_KEY","pemToArrayBuffer","pem","b64","bin","bytes","i","arrayBufferToBase64","buf","binary","randomHex","byteCount","b","encryptCardDetails","cardDetails","salt","ttlSeconds","encoder","payload","plain","aesKeyRaw","iv","aesKey","aesParams","cipherAndTag","cipherAndTagBytes","ct","tag","rsaKey","ek","pkg","err","MoiPayWay","config","ApiClient","meta","orderReferenceCode","payload","generateOrderReference","cardDetails","encrypted","encryptCardDetails","type","currencyCode","currency","country","institution","prefix","firstname","lastname","phoneNumber","name","network","accountName","fromAddress","txHash","otp","paymentId","paymentStatus"]}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@moipayway/sdk",
3
+ "version": "1.0.0",
4
+ "description": "MoiPayWay Payment SDK - Accept payments via card, bank transfer, USSD, mobile money, crypto and more",
5
+ "main": "dist/checkout.js",
6
+ "module": "dist/checkout.esm.js",
7
+ "browser": "dist/checkout.esm.js",
8
+ "types": "dist/checkout.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/checkout.d.ts",
12
+ "import": "./dist/checkout.esm.js",
13
+ "require": "./dist/checkout.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsup",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "keywords": [
25
+ "payment",
26
+ "moipayway",
27
+ "checkout",
28
+ "card",
29
+ "ussd",
30
+ "bank-transfer",
31
+ "mobile-money",
32
+ "crypto",
33
+ "nigeria",
34
+ "africa"
35
+ ],
36
+ "author": "MoiPayWay",
37
+ "license": "MIT",
38
+ "devDependencies": {
39
+ "tsup": "^8.0.0",
40
+ "typescript": "^5.8.0"
41
+ }
42
+ }