@voxepay/checkout 0.5.3 → 0.5.5

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/src/api/client.ts CHANGED
@@ -11,6 +11,7 @@ export interface InitiatePaymentRequest {
11
11
  customerId?: string;
12
12
  customerEmail?: string;
13
13
  customerPhone?: string;
14
+ customerName?: string;
14
15
  amount: number;
15
16
  currency: string;
16
17
  paymentMethod: 'CARD' | 'BANK_TRANSFER';
@@ -102,11 +103,11 @@ export interface ResendOTPRequest {
102
103
  }
103
104
 
104
105
  export class VoxePayApiClient {
105
- private apiKey: string;
106
+ private apiKey?: string;
106
107
  private bearerToken?: string;
107
108
  private baseUrl: string;
108
109
 
109
- constructor(apiKey: string, baseUrl?: string, bearerToken?: string) {
110
+ constructor(apiKey?: string, baseUrl?: string, bearerToken?: string) {
110
111
  this.apiKey = apiKey;
111
112
  this.bearerToken = bearerToken;
112
113
  this.baseUrl = baseUrl || DEFAULT_BASE_URL;
@@ -127,7 +128,7 @@ export class VoxePayApiClient {
127
128
  'Accept': 'application/json',
128
129
  };
129
130
 
130
- if (includeApiKey) {
131
+ if (includeApiKey && this.apiKey) {
131
132
  headers['X-API-Key'] = this.apiKey;
132
133
  }
133
134
 
@@ -160,7 +161,7 @@ export class VoxePayApiClient {
160
161
 
161
162
  if (authType === 'bearer' && this.bearerToken) {
162
163
  headers['Authorization'] = `Bearer ${this.bearerToken}`;
163
- } else if (authType === 'api-key') {
164
+ } else if (authType === 'api-key' && this.apiKey) {
164
165
  headers['X-API-Key'] = this.apiKey;
165
166
  }
166
167
  // authType === 'none' → no auth header added
@@ -186,16 +187,31 @@ export class VoxePayApiClient {
186
187
  }
187
188
 
188
189
  /**
189
- * Initiate a payment (card or bank transfer)
190
- * BANK_TRANSFER uses the public endpoint — no X-API-Key required
191
- * CARD uses X-API-Key authentication
190
+ * Initiate card payment via standard payments endpoint.
192
191
  */
193
192
  async initiatePayment(data: InitiatePaymentRequest): Promise<InitiatePaymentResponse> {
194
- const includeApiKey = data.paymentMethod !== 'BANK_TRANSFER';
195
193
  const response = await this.request<{ success?: boolean; data?: InitiatePaymentResponse } & InitiatePaymentResponse>(
196
194
  '/api/v1/payments/initiate',
197
195
  data,
198
- includeApiKey
196
+ true
197
+ );
198
+ if (response.data && typeof response.data === 'object' && 'transactionRef' in response.data) {
199
+ return response.data;
200
+ }
201
+ return response;
202
+ }
203
+
204
+ /**
205
+ * Initiate bank transfer via public payment-link endpoint.
206
+ */
207
+ async initiateTransferPayment(
208
+ paymentLinkSlug: string,
209
+ data: InitiatePaymentRequest
210
+ ): Promise<InitiatePaymentResponse> {
211
+ const response = await this.request<{ success?: boolean; data?: InitiatePaymentResponse } & InitiatePaymentResponse>(
212
+ `/api/v1/payment-links/public/${encodeURIComponent(paymentLinkSlug)}/pay`,
213
+ data,
214
+ false
199
215
  );
200
216
  // Handle both wrapped { success, data: {...} } and flat response formats
201
217
  if (response.data && typeof response.data === 'object' && 'transactionRef' in response.data) {
@@ -773,22 +773,33 @@ export class VoxePayModal {
773
773
  // Use merchant-provided callback
774
774
  details = await this.options.onBankTransferRequested();
775
775
  } else if (this.apiClient && this.options._sdkConfig) {
776
+ if (!this.options._sdkConfig.paymentLinkSlug) {
777
+ throw {
778
+ code: 'MISSING_PAYMENT_LINK_SLUG',
779
+ message: 'paymentLinkSlug is required in VoxePay.init() for bank transfer.',
780
+ };
781
+ }
782
+
776
783
  // Call real DVA API
777
784
  const transactionRef = `VP-${Date.now().toString(36).toUpperCase()}-${Math.random().toString(36).substring(2, 8).toUpperCase()}`;
778
785
 
779
- const response = await this.apiClient.initiatePayment({
780
- organizationId: this.options._sdkConfig.organizationId,
781
- transactionRef,
782
- customerId: this.options.customerEmail || '',
783
- customerEmail: this.options.customerEmail,
784
- customerPhone: this.options.customerPhone,
785
- amount: this.options.amount / 100, // Convert from kobo/cents to main unit
786
- currency: this.options.currency,
787
- paymentMethod: 'BANK_TRANSFER',
788
- authData: btoa(JSON.stringify({ source: 'web', method: 'bank_transfer' })),
789
- narration: this.options.description,
790
- durationMinutes: 30,
791
- });
786
+ const response = await this.apiClient.initiateTransferPayment(
787
+ this.options._sdkConfig.paymentLinkSlug,
788
+ {
789
+ organizationId: this.options._sdkConfig.organizationId,
790
+ transactionRef,
791
+ customerId: this.options.customerEmail || '',
792
+ customerEmail: this.options.customerEmail,
793
+ customerPhone: this.options.customerPhone,
794
+ customerName: this.options.customerName,
795
+ amount: this.options.amount / 100,
796
+ currency: this.options.currency,
797
+ paymentMethod: 'BANK_TRANSFER',
798
+ authData: btoa(JSON.stringify({ source: 'web', method: 'bank_transfer' })),
799
+ narration: this.options.description,
800
+ durationMinutes: 30,
801
+ }
802
+ );
792
803
 
793
804
  // Store transaction ref for status polling
794
805
  // API may return 'id' (DVA) or 'paymentId' (card) depending on payment method
@@ -814,7 +825,7 @@ export class VoxePayModal {
814
825
  expiresAt: va.expires_at,
815
826
  };
816
827
  } else {
817
- throw { code: 'SDK_ERROR', message: 'SDK not properly initialized. Missing API key or organization ID.' };
828
+ throw { code: 'SDK_ERROR', message: 'SDK not properly initialized. Missing required organizationId.' };
818
829
  }
819
830
 
820
831
  this.state.bankTransferDetails = details;
package/src/types.ts CHANGED
@@ -6,12 +6,14 @@
6
6
  * Configuration for initializing VoxePay
7
7
  */
8
8
  export interface VoxePayConfig {
9
- /** Your VoxePay API key (e.g., vxp_live_xxxxx) */
10
- apiKey: string;
9
+ /** Optional API key (not required for public transfer/status flow) */
10
+ apiKey?: string;
11
11
  /** Your VoxePay organization ID */
12
12
  organizationId: string;
13
13
  /** API base URL (defaults to https://devpay.voxepay.app) */
14
14
  baseUrl?: string;
15
+ /** Public payment link slug used for bank transfer initiation endpoint */
16
+ paymentLinkSlug?: string;
15
17
  /** Theme mode: 'dark' (default), 'light', or 'auto' (follows system) */
16
18
  theme?: 'dark' | 'light' | 'auto';
17
19
  /** Locale for formatting (e.g., 'en-US', 'en-NG') */
@@ -80,6 +82,8 @@ export interface CheckoutOptions {
80
82
  customerEmail?: string;
81
83
  /** Customer's phone number */
82
84
  customerPhone?: string;
85
+ /** Customer's full name */
86
+ customerName?: string;
83
87
  /** Additional metadata to attach to the payment */
84
88
  metadata?: Record<string, unknown>;
85
89
  /** Payment methods to show. Defaults to ['card', 'bank_transfer'] */
@@ -90,9 +94,10 @@ export interface CheckoutOptions {
90
94
  onBankTransferRequested?: () => Promise<BankTransferDetails>;
91
95
  /** @internal SDK config passed from VoxePaySDK to modal */
92
96
  _sdkConfig?: {
93
- apiKey: string;
97
+ apiKey?: string;
94
98
  organizationId: string;
95
99
  baseUrl?: string;
100
+ paymentLinkSlug?: string;
96
101
  simulateWebhook?: boolean;
97
102
  bypassKey?: string;
98
103
  };
package/src/voxepay.ts CHANGED
@@ -29,14 +29,9 @@ class VoxePaySDK {
29
29
 
30
30
  /**
31
31
  * Initialize VoxePay with your configuration
32
- * @param config - Configuration object with API key and optional settings
32
+ * @param config - Configuration object with required organizationId and optional settings
33
33
  */
34
34
  init(config: VoxePayConfig): void {
35
- if (!config.apiKey) {
36
- console.error('[VoxePay] API key is required. Get your API key from the VoxePay dashboard: Settings > API Keys');
37
- return;
38
- }
39
-
40
35
  if (!config.organizationId) {
41
36
  console.error('[VoxePay] Organization ID is required. Find it in your VoxePay dashboard.');
42
37
  return;
@@ -109,6 +104,7 @@ class VoxePaySDK {
109
104
  apiKey: this.config!.apiKey,
110
105
  organizationId: this.config!.organizationId,
111
106
  baseUrl: this.config!.baseUrl,
107
+ paymentLinkSlug: this.config!.paymentLinkSlug,
112
108
  simulateWebhook: this.config!.simulateWebhook,
113
109
  bypassKey: this.config!.bypassKey,
114
110
  },
@@ -181,7 +177,7 @@ class VoxePaySDK {
181
177
  * Get the SDK version
182
178
  */
183
179
  get version(): string {
184
- return '0.3.0';
180
+ return '0.5.4';
185
181
  }
186
182
 
187
183
  /**