@ozura/elements 1.2.4-next.48 → 1.2.4-next.50
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/dist/frame/element-frame.html +1 -1
- package/dist/frame/element-frame.js +47 -3
- package/dist/frame/element-frame.js.map +1 -1
- package/dist/frame/tokenizer-frame.js +55 -8
- package/dist/frame/tokenizer-frame.js.map +1 -1
- package/dist/react/server/index.d.ts +224 -0
- package/dist/server/index.cjs.js +314 -2
- package/dist/server/index.cjs.js.map +1 -1
- package/dist/server/index.esm.js +313 -3
- package/dist/server/index.esm.js.map +1 -1
- package/dist/server/server/index.d.ts +224 -0
- package/dist/types/server/index.d.ts +224 -0
- package/package.json +1 -1
|
@@ -174,6 +174,93 @@ export interface CardSaleInput {
|
|
|
174
174
|
*/
|
|
175
175
|
transactionChannel?: 'cardPresent' | 'ecommerce' | 'moto' | 'recurring';
|
|
176
176
|
}
|
|
177
|
+
/** Billing cadence for a recurring subscription plan. */
|
|
178
|
+
export type RecurringInterval = 'daily' | 'weekly' | 'monthly' | 'yearly';
|
|
179
|
+
export interface CreateRecurringPlanInput {
|
|
180
|
+
/** From TokenResponse.token (frontend SDK). */
|
|
181
|
+
token: string;
|
|
182
|
+
/** From TokenResponse.cvcSession (frontend SDK). */
|
|
183
|
+
cvcSession: string;
|
|
184
|
+
/** Decimal string — the base recurring charge amount, e.g. "19.99". */
|
|
185
|
+
amount: string;
|
|
186
|
+
/** ISO 4217, e.g. "USD". Default: "USD". */
|
|
187
|
+
currency?: string;
|
|
188
|
+
/**
|
|
189
|
+
* Customer billing details. All address fields are required by the Pay API
|
|
190
|
+
* for recurring plans (stricter than one-time card sales).
|
|
191
|
+
*/
|
|
192
|
+
billing: BillingDetails;
|
|
193
|
+
/** Client IP address — always obtain server-side, never from the browser. */
|
|
194
|
+
clientIpAddress: string;
|
|
195
|
+
/** Display name for the subscription plan (shown on statements and receipts). */
|
|
196
|
+
planName: string;
|
|
197
|
+
/** Billing cadence. */
|
|
198
|
+
interval: RecurringInterval;
|
|
199
|
+
/** Optional plan description shown to customers (max 100 chars). */
|
|
200
|
+
planDescription?: string;
|
|
201
|
+
/**
|
|
202
|
+
* Amount for the initial trial period cycles. Requires `initialCycles`.
|
|
203
|
+
* Pass `"0.00"` for a free trial.
|
|
204
|
+
*/
|
|
205
|
+
initialAmount?: string;
|
|
206
|
+
/** Number of cycles to charge `initialAmount` before switching to `amount`. */
|
|
207
|
+
initialCycles?: number;
|
|
208
|
+
/** One-time setup fee charged alongside the first cycle (additive). */
|
|
209
|
+
setupFee?: string;
|
|
210
|
+
/**
|
|
211
|
+
* Multiplier for the interval period. Default: 1.
|
|
212
|
+
* e.g. `interval: "monthly"` + `intervalCount: 3` → billed every 3 months.
|
|
213
|
+
*/
|
|
214
|
+
intervalCount?: number;
|
|
215
|
+
/** ISO 8601 end date. Must be at least one full cycle after the enrollment date. */
|
|
216
|
+
endDate?: string;
|
|
217
|
+
/** Maximum number of billing cycles. Omit for indefinite. */
|
|
218
|
+
maxCycles?: number;
|
|
219
|
+
/** Payment retry attempts on failure. Default: 3. */
|
|
220
|
+
maxAttempts?: number;
|
|
221
|
+
/** Hours between retry attempts. Default: 24. */
|
|
222
|
+
retryIntervalHours?: number;
|
|
223
|
+
/** Your own internal subscription reference ID (max 50 chars). */
|
|
224
|
+
merchantRecurringReference?: string;
|
|
225
|
+
salesTaxExempt?: boolean;
|
|
226
|
+
/** Defaults to "0.00". */
|
|
227
|
+
surchargePercent?: string;
|
|
228
|
+
/** Processor to use. If omitted, the Pay API auto-selects. */
|
|
229
|
+
processor?: 'elavon' | 'nuvei' | 'worldpay';
|
|
230
|
+
/**
|
|
231
|
+
* Transaction channel. Default: `"ecommerce"`.
|
|
232
|
+
* Use `"moto"` for mail/telephone-order enrollment flows.
|
|
233
|
+
*
|
|
234
|
+
* Note: `transactionInitiationType` is always `"cit"` for recurring
|
|
235
|
+
* enrollment and is not configurable — the Pay API enforces this.
|
|
236
|
+
* Subsequent MIT charges are handled by Ozura's recurring queue worker.
|
|
237
|
+
*/
|
|
238
|
+
transactionChannel?: 'ecommerce' | 'moto';
|
|
239
|
+
}
|
|
240
|
+
export interface CreateRecurringPlanResponseData {
|
|
241
|
+
/** Ozura's internal plan identifier. Store this to manage the subscription. */
|
|
242
|
+
planId: string;
|
|
243
|
+
planName: string;
|
|
244
|
+
planDescription?: string;
|
|
245
|
+
merchantRecurringReference?: string;
|
|
246
|
+
/** Base recurring charge amount as a decimal string. */
|
|
247
|
+
amount: string;
|
|
248
|
+
currency: string;
|
|
249
|
+
/** Transaction ID of the initial enrollment charge (Pay API's `citTransactionId`). */
|
|
250
|
+
transactionId: string;
|
|
251
|
+
/** Actual amount charged on enrollment (includes setup fee, initial amount, tax, surcharge). */
|
|
252
|
+
transactionAmount: string;
|
|
253
|
+
transactionSurchargeAmount?: string;
|
|
254
|
+
transactionSalesTaxAmount?: string;
|
|
255
|
+
/** ISO 8601 timestamp of the next scheduled billing cycle. */
|
|
256
|
+
nextCycleAt: string;
|
|
257
|
+
endDate?: string;
|
|
258
|
+
cardLastFour?: string;
|
|
259
|
+
cardBrand?: string;
|
|
260
|
+
cardExpMonth?: string;
|
|
261
|
+
cardExpYear?: string;
|
|
262
|
+
transDate?: string;
|
|
263
|
+
}
|
|
177
264
|
export interface ListTransactionsInput {
|
|
178
265
|
/** Look up a single transaction by ID. When set, dateFrom/dateTo are not required. */
|
|
179
266
|
transactionId?: string;
|
|
@@ -214,6 +301,32 @@ export declare class Ozura {
|
|
|
214
301
|
* Rate limit: 100 requests/minute per merchant.
|
|
215
302
|
*/
|
|
216
303
|
cardSale(input: CardSaleInput): Promise<CardSaleResponseData>;
|
|
304
|
+
/**
|
|
305
|
+
* Create a recurring subscription plan and execute the enrollment charge.
|
|
306
|
+
*
|
|
307
|
+
* The customer's card is charged immediately for the first billing cycle
|
|
308
|
+
* (at `initialAmount` if set, otherwise `amount`) and a subscription record
|
|
309
|
+
* is created in Ozura's billing engine for all future cycles.
|
|
310
|
+
*
|
|
311
|
+
* `transactionInitiationType` is always `"cit"` for enrollment — the Pay API
|
|
312
|
+
* enforces this. Subsequent MIT charges are processed automatically by Ozura's
|
|
313
|
+
* recurring queue worker; merchants do not need to trigger them.
|
|
314
|
+
*
|
|
315
|
+
* Rate limit: 100 requests/minute per merchant.
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* const plan = await ozura.createRecurringPlan({
|
|
319
|
+
* token: tokenResponse.token,
|
|
320
|
+
* cvcSession: tokenResponse.cvcSession,
|
|
321
|
+
* amount: '19.99',
|
|
322
|
+
* billing: tokenResponse.billing,
|
|
323
|
+
* clientIpAddress: req.ip,
|
|
324
|
+
* planName: 'Pro Monthly',
|
|
325
|
+
* interval: 'monthly',
|
|
326
|
+
* });
|
|
327
|
+
* console.log(plan.planId, plan.transactionId);
|
|
328
|
+
*/
|
|
329
|
+
createRecurringPlan(input: CreateRecurringPlanInput): Promise<CreateRecurringPlanResponseData>;
|
|
217
330
|
/**
|
|
218
331
|
* List transactions by date range with pagination.
|
|
219
332
|
*
|
|
@@ -478,5 +591,116 @@ export declare function createCardSaleMiddleware(ozura: Ozura, options: CardSale
|
|
|
478
591
|
body?: unknown;
|
|
479
592
|
headers?: unknown;
|
|
480
593
|
}, res: NodeLikeResponse) => Promise<void>;
|
|
594
|
+
/**
|
|
595
|
+
* Server-side recurring plan configuration resolved per-request.
|
|
596
|
+
* Source all plan details from your own database — never trust client-supplied values.
|
|
597
|
+
*/
|
|
598
|
+
export interface RecurringPlanConfig {
|
|
599
|
+
/** Display name for the subscription. */
|
|
600
|
+
planName: string;
|
|
601
|
+
/** Billing cadence. */
|
|
602
|
+
interval: RecurringInterval;
|
|
603
|
+
planDescription?: string;
|
|
604
|
+
initialAmount?: string;
|
|
605
|
+
initialCycles?: number;
|
|
606
|
+
setupFee?: string;
|
|
607
|
+
intervalCount?: number;
|
|
608
|
+
endDate?: string;
|
|
609
|
+
maxCycles?: number;
|
|
610
|
+
maxAttempts?: number;
|
|
611
|
+
retryIntervalHours?: number;
|
|
612
|
+
merchantRecurringReference?: string;
|
|
613
|
+
salesTaxExempt?: boolean;
|
|
614
|
+
surchargePercent?: string;
|
|
615
|
+
processor?: 'elavon' | 'nuvei' | 'worldpay';
|
|
616
|
+
/**
|
|
617
|
+
* Transaction channel. Default: `"ecommerce"`.
|
|
618
|
+
* Use `"moto"` for mail/telephone-order enrollment flows.
|
|
619
|
+
* Source from your database via `getPlanConfig` — do not read from the request body.
|
|
620
|
+
*/
|
|
621
|
+
transactionChannel?: 'ecommerce' | 'moto';
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Options for {@link createRecurringPlanHandler} and {@link createRecurringPlanMiddleware}.
|
|
625
|
+
*
|
|
626
|
+
* Both `getAmount` and `getPlanConfig` must source their values from your own
|
|
627
|
+
* records — never trust the request body for plan price or configuration.
|
|
628
|
+
*/
|
|
629
|
+
export interface RecurringPlanHandlerOptions {
|
|
630
|
+
/**
|
|
631
|
+
* Return the base recurring charge amount as a decimal string (e.g. `"19.99"`).
|
|
632
|
+
* Source from your database; never trust the value the client sends.
|
|
633
|
+
*/
|
|
634
|
+
getAmount: (body: Record<string, unknown>) => string | Promise<string>;
|
|
635
|
+
/**
|
|
636
|
+
* Return the recurring plan configuration for this subscription.
|
|
637
|
+
* At minimum you must return `planName` and `interval`.
|
|
638
|
+
*
|
|
639
|
+
* @example
|
|
640
|
+
* getPlanConfig: async (body) => {
|
|
641
|
+
* const plan = await db.plans.findById(body.planId as string);
|
|
642
|
+
* return { planName: plan.name, interval: plan.interval };
|
|
643
|
+
* }
|
|
644
|
+
*/
|
|
645
|
+
getPlanConfig: (body: Record<string, unknown>) => RecurringPlanConfig | Promise<RecurringPlanConfig>;
|
|
646
|
+
/** Return the ISO 4217 currency code. Default: `"USD"`. */
|
|
647
|
+
getCurrency?: (body: Record<string, unknown>) => string | Promise<string>;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Creates a ready-to-use Fetch API route handler for recurring subscription enrollment.
|
|
651
|
+
*
|
|
652
|
+
* Drop-in for Next.js App Router, Cloudflare Workers, Vercel Edge, and any runtime
|
|
653
|
+
* built on the standard Web API `Request` / `Response`.
|
|
654
|
+
*
|
|
655
|
+
* The handler reads `{ token, cvcSession, billing }` from the JSON request body,
|
|
656
|
+
* resolves the amount and plan configuration via your `options` callbacks (which
|
|
657
|
+
* must source data from your own database — never from the request body), calls
|
|
658
|
+
* `ozura.createRecurringPlan()`, and returns
|
|
659
|
+
* `{ planId, transactionId, transactionAmount, nextCycleAt }` on success.
|
|
660
|
+
*
|
|
661
|
+
* @example
|
|
662
|
+
* // app/api/subscribe/route.ts (Next.js App Router)
|
|
663
|
+
* import { Ozura, createRecurringPlanHandler } from '@ozura/elements/server';
|
|
664
|
+
*
|
|
665
|
+
* const ozura = new Ozura({ merchantId: '...', apiKey: '...', vaultKey: '...' });
|
|
666
|
+
*
|
|
667
|
+
* export const POST = createRecurringPlanHandler(ozura, {
|
|
668
|
+
* getAmount: async (body) => {
|
|
669
|
+
* const plan = await db.plans.findById(body.planId as string);
|
|
670
|
+
* return plan.price;
|
|
671
|
+
* },
|
|
672
|
+
* getPlanConfig: async (body) => {
|
|
673
|
+
* const plan = await db.plans.findById(body.planId as string);
|
|
674
|
+
* return { planName: plan.name, interval: plan.interval };
|
|
675
|
+
* },
|
|
676
|
+
* });
|
|
677
|
+
*/
|
|
678
|
+
export declare function createRecurringPlanHandler(ozura: Ozura, options: RecurringPlanHandlerOptions): (req: Request) => Promise<Response>;
|
|
679
|
+
/**
|
|
680
|
+
* Creates a ready-to-use Express / Connect middleware for recurring subscription enrollment.
|
|
681
|
+
*
|
|
682
|
+
* Requires `express.json()` (or equivalent body-parser) to be registered before
|
|
683
|
+
* this middleware so `req.body` is available.
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* // Express
|
|
687
|
+
* import express from 'express';
|
|
688
|
+
* import { Ozura, createRecurringPlanMiddleware } from '@ozura/elements/server';
|
|
689
|
+
*
|
|
690
|
+
* const app = express();
|
|
691
|
+
* const ozura = new Ozura({ merchantId: '...', apiKey: '...', vaultKey: '...' });
|
|
692
|
+
*
|
|
693
|
+
* app.use(express.json());
|
|
694
|
+
* app.post('/api/subscribe', createRecurringPlanMiddleware(ozura, {
|
|
695
|
+
* getAmount: async (body) => db.plans.findById(body.planId).then(p => p.price),
|
|
696
|
+
* getPlanConfig: async (body) => db.plans.findById(body.planId).then(p => ({
|
|
697
|
+
* planName: p.name, interval: p.interval,
|
|
698
|
+
* })),
|
|
699
|
+
* }));
|
|
700
|
+
*/
|
|
701
|
+
export declare function createRecurringPlanMiddleware(ozura: Ozura, options: RecurringPlanHandlerOptions): (req: {
|
|
702
|
+
body?: unknown;
|
|
703
|
+
headers?: unknown;
|
|
704
|
+
}, res: NodeLikeResponse) => Promise<void>;
|
|
481
705
|
export type { BillingDetails, CardSaleResponseData, TransactionQueryPagination, TransactionType, TransactionBase, CardTransactionData, AchTransactionData, CryptoTransactionData, TransactionData, } from '../types';
|
|
482
706
|
export { normalizeCardSaleError } from '../sdk/errors';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ozura/elements",
|
|
3
|
-
"version": "1.2.4-next.
|
|
3
|
+
"version": "1.2.4-next.50",
|
|
4
4
|
"description": "PCI-compliant card tokenization SDK for the Ozura Vault — collect card data in iframe-isolated fields and tokenize without PCI scope",
|
|
5
5
|
"main": "dist/oz-elements.umd.js",
|
|
6
6
|
"module": "dist/oz-elements.esm.js",
|