@neocash/bnpl-widget 0.1.1

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.
@@ -0,0 +1,195 @@
1
+ export interface CartItem {
2
+ name: string;
3
+ qty: number;
4
+ /** Unit price in **kobo**. e.g. ₦2,000 → 200000 */
5
+ price: number;
6
+ imageUrl?: string;
7
+ }
8
+ export interface Cart {
9
+ items: CartItem[];
10
+ /** Cart total in **kobo**. e.g. ₦240,000 → 24000000 */
11
+ total: number;
12
+ currency?: string;
13
+ }
14
+ export interface PartnerPrefill {
15
+ firstName?: string;
16
+ lastName?: string;
17
+ phone?: string;
18
+ email?: string;
19
+ bvn?: string;
20
+ employer?: string;
21
+ role?: string;
22
+ /** Monthly salary in **kobo**. e.g. ₦850,000 → 85000000 */
23
+ monthlySalary?: number;
24
+ officeAddress?: string;
25
+ homeAddress?: string;
26
+ }
27
+ export interface InitOptions {
28
+ publicKey: string;
29
+ cart: Cart;
30
+ partnerPrefill?: PartnerPrefill;
31
+ container?: HTMLElement | string;
32
+ onClose?: () => void;
33
+ onApprovalPending?: (applicationId: string) => void;
34
+ onError?: (err: Error) => void;
35
+ /** Internal staging override. Not part of the stable public API. */
36
+ apiBase?: string;
37
+ /**
38
+ * Where the lazy-loaded Amplify Liveness chunk lives. Defaults to the
39
+ * directory of the main script (captured from document.currentScript at
40
+ * load time). Set explicitly when serving the chunk from a different
41
+ * origin or path.
42
+ */
43
+ assetPrefix?: string;
44
+ }
45
+ export interface WidgetHandle {
46
+ close: () => void;
47
+ }
48
+ export type CartMode = 'hold' | 'release';
49
+ export interface MerchantInfo {
50
+ name: string;
51
+ cart_mode: CartMode;
52
+ }
53
+ export type InterestType = 'flat' | 'reducing_balance';
54
+ export interface SessionConfig {
55
+ /** Monthly interest rate on the financed amount, e.g. 0.05 = 5%. */
56
+ monthly_interest_rate: number;
57
+ /** How interest is computed across the tenure. */
58
+ interest_type: InterestType;
59
+ /** Processing fee, as a fraction of the cart total, e.g. 0.015 = 1.5%. */
60
+ processing_fee_rate: number;
61
+ /** Minimum financeable amount in **kobo**. */
62
+ min_amount_kobo: number;
63
+ /** Maximum financeable amount in **kobo**. */
64
+ max_amount_kobo: number;
65
+ /** Repayment-term bounds, in days. */
66
+ min_tenure_days: number;
67
+ max_tenure_days: number;
68
+ /** Minimum fraction of the cart the borrower must pay today, e.g. 0.20. */
69
+ min_pay_now_rate: number;
70
+ /** Discrete term choices for the tenure slider, in days. */
71
+ tenure_day_options: number[];
72
+ }
73
+ export interface Bank {
74
+ code: string;
75
+ name: string;
76
+ }
77
+ export interface CreateSessionRequest {
78
+ public_key: string;
79
+ cart: Cart;
80
+ partner_prefill?: PartnerPrefill;
81
+ }
82
+ export interface CreateSessionResponse {
83
+ session_token: string;
84
+ merchant: MerchantInfo;
85
+ config: SessionConfig;
86
+ banks: Bank[];
87
+ prefill: PartnerPrefill;
88
+ }
89
+ export interface SendOtpResponse {
90
+ resend_after_seconds: number;
91
+ }
92
+ export interface VerifyOtpResponse {
93
+ verified: boolean;
94
+ attempts_left?: number;
95
+ }
96
+ export interface AwsCredentials {
97
+ accessKeyId: string;
98
+ secretAccessKey: string;
99
+ sessionToken: string;
100
+ /** ISO-8601 timestamp at which the credentials expire. */
101
+ expiration: string;
102
+ }
103
+ export interface LivenessStartResponse {
104
+ rekognition_session_id: string;
105
+ region: string;
106
+ /**
107
+ * Present only for live-mode merchants. STS-vended, scoped to
108
+ * `rekognition:StartFaceLivenessSession`, ~15 min TTL. Test-mode merchants
109
+ * (rekognition_session_id starts with "rl-test-") get no credentials and
110
+ * the widget routes to its in-process placeholder.
111
+ */
112
+ credentials?: AwsCredentials;
113
+ }
114
+ export interface LivenessResultRequest {
115
+ rekognition_session_id: string;
116
+ }
117
+ export type CustomerStatus = 'new' | 'returning';
118
+ export interface LivenessResultResponse {
119
+ passed: boolean;
120
+ attempts_left?: number;
121
+ customer_status?: CustomerStatus;
122
+ }
123
+ export interface CustomerProfile {
124
+ first_name: string;
125
+ last_name: string;
126
+ email: string;
127
+ phone: string;
128
+ bvn_masked: string;
129
+ employer: string;
130
+ role: string;
131
+ /** Monthly salary in **kobo** (wire value; divide by 100 before displaying). */
132
+ monthly_salary: number;
133
+ office_address: string;
134
+ home_address: string;
135
+ }
136
+ export interface CreditCheckResponse {
137
+ status: 'approved' | 'declined';
138
+ reason?: string;
139
+ requires?: ('employment_update' | 'bank_statement')[];
140
+ }
141
+ export interface IdentityRequest {
142
+ first_name: string;
143
+ last_name: string;
144
+ email: string;
145
+ bvn: string;
146
+ }
147
+ export interface IdentityResponse {
148
+ status: 'pass' | 'cant_offer' | 'cant_verify';
149
+ reasons?: string[];
150
+ }
151
+ export interface IdentityStatusResponse {
152
+ face_match: 'pending' | 'pass' | 'fail';
153
+ }
154
+ export interface EmploymentRequest {
155
+ employer: string;
156
+ role: string;
157
+ /** Monthly salary in **kobo**. Widget converts from the naira the user typed. */
158
+ monthly_salary: number;
159
+ office_address: string;
160
+ home_address: string;
161
+ location?: {
162
+ lat: number;
163
+ lng: number;
164
+ accuracy?: number;
165
+ };
166
+ }
167
+ export interface MonoLinkTokenResponse {
168
+ public_key: string;
169
+ /** Mono customer id (cus_*). Created server-side via Mono's Create Customer API. */
170
+ customer_ref: string;
171
+ /**
172
+ * Unique reference for this linking attempt. Backend stores
173
+ * `reference → session_id` so it can stitch the Mono webhook
174
+ * back to the BNPL session when the user completes linking.
175
+ */
176
+ reference: string;
177
+ scope: string[];
178
+ }
179
+ export interface FinalizeRequest {
180
+ email: string;
181
+ /** Repayment term the customer picked, in days. */
182
+ tenure_days: number;
183
+ /** Amount the customer chose to finance (cart total − pay-now), in **kobo**. */
184
+ financed_kobo: number;
185
+ }
186
+ export interface FinalizeResponse {
187
+ application_id: string;
188
+ status: 'pending_review';
189
+ est_decision_seconds: number;
190
+ }
191
+ export interface ApiErrorShape {
192
+ code?: string;
193
+ status?: number;
194
+ retryable?: boolean;
195
+ }
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@neocash/bnpl-widget",
3
+ "version": "0.1.1",
4
+ "description": "Embeddable NeoCash BNPL checkout widget",
5
+ "license": "UNLICENSED",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.mjs",
8
+ "types": "dist/index.d.ts",
9
+ "unpkg": "dist/neocash-bnpl.iife.js",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.cjs"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md"
20
+ ],
21
+ "scripts": {
22
+ "build": "node build.mjs",
23
+ "build:all": "npm run build && npm run types",
24
+ "watch": "node build.mjs --watch",
25
+ "types": "tsc",
26
+ "prepack": "npm run build:all",
27
+ "size": "gzip -c dist/neocash-bnpl.iife.js | wc -c"
28
+ },
29
+ "dependencies": {
30
+ "preact": "^10.22.0"
31
+ },
32
+ "devDependencies": {
33
+ "@aws-amplify/ui-react": "^6.5.0",
34
+ "@aws-amplify/ui-react-liveness": "^3.2.0",
35
+ "@types/react": "^18.3.0",
36
+ "@types/react-dom": "^18.3.0",
37
+ "aws-amplify": "^6.6.0",
38
+ "esbuild": "^0.24.0",
39
+ "react": "^18.3.0",
40
+ "react-dom": "^18.3.0",
41
+ "typescript": "^5.6.0"
42
+ }
43
+ }