@zippypay/checkout 1.0.0 → 1.1.10

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 CHANGED
@@ -1,5 +1,8 @@
1
1
  # @zippypay/checkout
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@zippypay/checkout.svg)](https://www.npmjs.com/package/@zippypay/checkout)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
+
3
6
  Browser checkout SDK for **Zippy Pay** merchants. Embed payment UI inline on a checkout page or open it in a modal. Works with vanilla JavaScript, React, Vue, Angular, and any stack that runs modern JavaScript.
4
7
 
5
8
  Styles are scoped inside Shadow DOM — no extra CSS import is required.
@@ -16,6 +19,10 @@ npm install @zippypay/checkout
16
19
  yarn add @zippypay/checkout
17
20
  ```
18
21
 
22
+ ```bash
23
+ pnpm add @zippypay/checkout
24
+ ```
25
+
19
26
  ---
20
27
 
21
28
  ## Before the SDK runs
@@ -24,10 +31,10 @@ Your **server** creates a payment session and passes credentials to the checkout
24
31
 
25
32
  | Field | Description |
26
33
  |---|---|
27
- | `sessionId` | UUID v4 from `POST /payment-sessions` — safe in URLs |
28
- | `clientToken` | `zps_…` from the create-session response — **server → browser only** |
34
+ | `sessionId` | Payment session identifier — safe in URLs |
35
+ | `clientToken` | Short-lived token from your server — **browser only, never public** |
29
36
 
30
- Never expose `X-Api-Key` or Clerk JWT from browser code. Never put `clientToken` in QR codes, query strings, logs, or analytics.
37
+ Never expose merchant API credentials in browser code. Never put `clientToken` in QR codes, query strings, logs, or analytics.
31
38
 
32
39
  ---
33
40
 
@@ -86,7 +93,7 @@ ZippyPay.create({
86
93
 
87
94
  ### Script tag (UMD)
88
95
 
89
- Serve or bundle is not required — load from a public npm CDN:
96
+ Load from a public npm CDN:
90
97
 
91
98
  ```html
92
99
  <script src="https://unpkg.com/@zippypay/checkout@1/dist/index.min.js"></script>
@@ -101,23 +108,19 @@ Serve or bundle is not required — load from a public npm CDN:
101
108
  </script>
102
109
  ```
103
110
 
104
- Pin the version in production (`@1.0.0` instead of `@1`).
111
+ Pin the version in production (e.g. `@1.1.0` instead of `@1`).
105
112
 
106
113
  ---
107
114
 
108
115
  ## Environments
109
116
 
110
- Pass `environment` — the SDK resolves the API base URL:
111
-
112
- | Environment | API origin |
117
+ | Environment | Use when |
113
118
  |---|---|
114
- | `production` | `https://api.zippypay.io` |
115
- | `staging` | `https://staging.api.zippypay.io` |
116
- | `development` | Same-origin (empty base — for local proxies) |
119
+ | `production` | Live merchant checkout |
120
+ | `staging` | Pre-production testing |
121
+ | `development` | Local development with a proxy |
117
122
 
118
- All requests use the prefix `/api/v1` (e.g. `GET https://api.zippypay.io/api/v1/payment-sessions/:id`).
119
-
120
- Use the environment where your merchant backend created the session.
123
+ Use the same environment where your server created the payment session.
121
124
 
122
125
  ---
123
126
 
@@ -131,6 +134,10 @@ type ZippyPayConfig = {
131
134
  mode?: 'inline' | 'modal';
132
135
  container?: HTMLElement | string; // required for inline
133
136
  theme?: ZippyTheme;
137
+ /** Restrict checkout methods. Omit for full chooser (QR + manual). */
138
+ checkoutPolicy?: 'QR' | 'MANUAL';
139
+ /** Phone-only app handoff. Ignored on desktop. */
140
+ mobileApp?: { policy?: 'off' | 'option' | 'enforce' };
134
141
  redirectOnComplete?: boolean;
135
142
  redirectOnFailure?: boolean;
136
143
  closeOnBackdropClick?: boolean;
@@ -146,6 +153,30 @@ type ZippyPayConfig = {
146
153
 
147
154
  **Instance methods:** `open()`, `close()` (modal), `destroy()`
148
155
 
156
+ ### Checkout policy
157
+
158
+ Control which payment methods customers can use:
159
+
160
+ | Config | Customer sees |
161
+ |---|---|
162
+ | *(omit `checkoutPolicy`)* | Full chooser — QR + manual |
163
+ | `checkoutPolicy: 'QR'` | QR only |
164
+ | `checkoutPolicy: 'MANUAL'` | Manual Zippy ID only |
165
+
166
+ ### Mobile app (phone)
167
+
168
+ | `mobileApp.policy` | Phone behavior |
169
+ |---|---|
170
+ | `off` *(default)* | Web checkout only (QR / manual per policy) |
171
+ | `option` | “Pay with Zippy” on the chooser; opens the app on tap |
172
+ | `enforce` | Auto-starts app handoff; QR/manual hidden unless handoff fails |
173
+
174
+ On **Pay with Zippy** (iPhone and Android), checkout shows “Opening Zippy…”, tries the app in a hidden iframe so the browser stays on checkout, and waits 5 seconds. If Safari, Chrome, or any other browser is still in front, it opens the App Store (`itms-apps://`) or the Play Store listing (`https://play.google.com/store/apps/details?id=com.zippy.pay`).
175
+
176
+ On **desktop**, the app option is never shown — customers use QR or manual as allowed by `checkoutPolicy`.
177
+
178
+ Web component attributes: `checkout-policy="QR"`, `mobile-app-policy="enforce"`.
179
+
149
180
  ### Theming
150
181
 
151
182
  | Token | CSS variable | Default |
@@ -165,27 +196,52 @@ Web component: use `theme-primary`, `theme-mode`, etc.
165
196
 
166
197
  ---
167
198
 
168
- ## Checkout flow
199
+ ## Checkout experience
169
200
 
170
- 1. **Choose method** — QR scan or manual Zippy ID (one-way; cannot switch)
171
- 2. **QR** — `POST …/checkout/start { method: "QR" }` → show QR + pay timer → poll until paid
172
- 3. **Manual** — verify ID → attach payer → pay timer → poll until paid
201
+ The SDK guides customers through payment and keeps your page updated until the session reaches a final state.
173
202
 
174
- Display the **amount from the GET session response**, not from your page props.
203
+ ### Payment methods
175
204
 
176
- Three time boundaries: `expiresAt` (idle), `paymentExpiryAt` (pay window), `absoluteExpiresAt` (hard max).
205
+ | Method | Customer experience |
206
+ |---|---|
207
+ | **QR** | Scan a QR code in the Zippy app, then confirm payment in the app |
208
+ | **Manual** | Enter a Zippy ID, verify identity, then confirm payment in the app |
209
+ | **Mobile app** | Open the Zippy app on this phone; fallback to QR/manual if the app cannot open |
210
+
211
+ After a method is chosen, the customer generally cannot switch to another method.
212
+
213
+ ### Timers and amount
214
+
215
+ - A **pay timer** appears once checkout is in progress.
216
+ - Display the **amount from the session** passed to your callbacks (`onReady`, `onSessionUpdate`, `onComplete`) — do not rely on amount props from your own page markup alone.
217
+ - Sessions also have idle and absolute expiry boundaries handled by the SDK UI.
177
218
 
178
219
  ---
179
220
 
180
- ## Web component events
221
+ ## Web component
222
+
223
+ ### Attributes
224
+
225
+ | Attribute | Values |
226
+ |---|---|
227
+ | `environment` | `production`, `staging`, `development` |
228
+ | `session-id` | Session UUID |
229
+ | `mode` | `inline`, `modal` |
230
+ | `checkout-policy` | `QR`, `MANUAL` |
231
+ | `mobile-app-policy` | `option`, `enforce` |
232
+ | `theme-*` | See theming table above |
233
+
234
+ Set `clientToken` via the **property** (not an HTML attribute).
235
+
236
+ ### Events
181
237
 
182
238
  | Event | When |
183
239
  |---|---|
184
- | `zippy-ready` | Session loaded |
185
- | `zippy-session-update` | Poll update |
240
+ | `zippy-ready` | Checkout loaded and ready |
241
+ | `zippy-session-update` | Session status updated |
186
242
  | `zippy-complete` | Payment succeeded |
187
243
  | `zippy-expired` | Session expired |
188
- | `zippy-error` | Terminal / API error |
244
+ | `zippy-error` | Checkout error |
189
245
  | `zippy-close` | Modal closed |
190
246
 
191
247
  ---
@@ -235,26 +291,18 @@ Import the package, use `CUSTOM_ELEMENTS_SCHEMA`, set `nativeElement.clientToken
235
291
 
236
292
  ---
237
293
 
238
- ## API authentication (SDK)
294
+ ## Error handling
239
295
 
240
- | Header | Value |
241
- |---|---|
242
- | `X-Payment-Session-Token` | `zps_…` (preferred) |
243
- | `Authorization` | `Bearer zps_…` (fallback) |
244
-
245
- Errors are RFC 7807 `application/problem+json`, surfaced as `ZippyPayError` with `code`, `status`, and `detail`.
246
-
247
- On **401**: treat the token as invalid; create a new session — do not retry blindly.
296
+ Use `onError` to receive a `ZippyPayError` with `code`, `status`, and `detail`. If checkout cannot continue (for example, an invalid or expired token), show your own recovery flow — typically creating a new session on your server and re-initializing the SDK.
248
297
 
249
298
  ---
250
299
 
251
300
  ## Security checklist
252
301
 
253
- 1. Never bundle `X-Api-Key` in browser code.
302
+ 1. Never bundle merchant API credentials in browser code.
254
303
  2. Keep `clientToken` in memory only.
255
- 3. Encode only `sessionId` in QR / deep links — never the client token.
256
- 4. Display amount from GET session, not merchant page props.
257
- 5. Ensure your Zippy API environment allows your site origin in CORS for browser calls.
304
+ 3. Put only `sessionId` in QR codes and app deep links — never the client token.
305
+ 4. Use the session amount from SDK callbacks, not from unchecked page props.
258
306
 
259
307
  ---
260
308
 
@@ -265,6 +313,14 @@ On **401**: treat the token as invalid; create a new session — do not retry bl
265
313
 
266
314
  ---
267
315
 
316
+ ## More documentation
317
+
318
+ Full integration guide and framework examples:
319
+
320
+ **[github.com/IMAGINE-INNOVATION-LIMITED/zippy-pay-web-sdk](https://github.com/IMAGINE-INNOVATION-LIMITED/zippy-pay-web-sdk)**
321
+
322
+ ---
323
+
268
324
  ## License
269
325
 
270
326
  MIT © Imagine Innovation Limited