@doujins/payments-ui 0.0.18 → 0.1.2
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 +140 -0
- package/dist/index.cjs +231 -127
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -10
- package/dist/index.d.ts +8 -10
- package/dist/index.js +230 -126
- package/dist/index.js.map +1 -1
- package/dist/styles.css +2 -1
- package/package.json +6 -3
package/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Payments UI
|
|
2
|
+
|
|
3
|
+
Reusable Solana + card checkout widgets for the Doujins billing stack. The package assumes the host application already handles user authentication and can supply API tokens for the Doujins Billing API (`/v1`).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm install @doujins/payments-ui
|
|
9
|
+
# or
|
|
10
|
+
npm install @doujins/payments-ui
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
All builds ship precompiled JavaScript modules (`dist/index.js`, `dist/index.cjs`, `dist/index.d.ts`) and a single CSS bundle (`dist/styles.css`). Consumers must import both JS and CSS outputs.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import '@doujins/payments-ui/styles.css'
|
|
17
|
+
import { BillingThemeProvider, PaymentExperience } from '@doujins/payments-ui'
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
1. **Create the billing client** – this is the only API layer. Provide your billing + account base URLs plus an auth-token resolver. You can optionally pass a custom `fetch` implementation for SSR or retries.
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { createClient } from '@doujins/payments-ui'
|
|
26
|
+
|
|
27
|
+
const billingClient = createClient({
|
|
28
|
+
billingBaseUrl: 'https://billing.example.com',
|
|
29
|
+
accountBaseUrl: 'https://accounts.example.com',
|
|
30
|
+
getAuthToken: async () => authStore.jwt,
|
|
31
|
+
defaultHeaders: {
|
|
32
|
+
'X-App-Version': appVersion,
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
2. **Provide context + theme scope** – wrap all embedded Payments UI components in `BillingThemeProvider` and the exported `PaymentContext` so CSS variables and React Query state are scoped.
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import {
|
|
41
|
+
BillingThemeProvider,
|
|
42
|
+
PaymentProvider,
|
|
43
|
+
} from '@doujins/payments-ui'
|
|
44
|
+
|
|
45
|
+
const App = () => (
|
|
46
|
+
<BillingThemeProvider>
|
|
47
|
+
<PaymentProvider
|
|
48
|
+
config={{
|
|
49
|
+
endpoints: {
|
|
50
|
+
billingBaseUrl: 'https://billing.example.com',
|
|
51
|
+
accountBaseUrl: 'https://accounts.example.com',
|
|
52
|
+
},
|
|
53
|
+
getAuthToken: () => authStore.jwt,
|
|
54
|
+
}}
|
|
55
|
+
>
|
|
56
|
+
<SubscriptionCheckoutModal priceId="price_123" usdAmount={9.99} />
|
|
57
|
+
</PaymentProvider>
|
|
58
|
+
</BillingThemeProvider>
|
|
59
|
+
)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
3. **Drop in the widgets** – the main surface is `PaymentExperience`, but you can also use individual building blocks (`CardDetailsForm`, `StoredPaymentMethods`, `SolanaPaymentView`, etc.). Every component reads from the `PaymentProvider` context and automatically calls the lean client.
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
<PaymentExperience
|
|
66
|
+
priceId="price_monthly"
|
|
67
|
+
usdAmount={14.99}
|
|
68
|
+
enableSolanaPay
|
|
69
|
+
onNewCardPayment={async ({ token, billing }) => {
|
|
70
|
+
await client.checkout({
|
|
71
|
+
price_id: 'price_monthly',
|
|
72
|
+
processor: 'mobius',
|
|
73
|
+
payment_token: token,
|
|
74
|
+
...billing,
|
|
75
|
+
})
|
|
76
|
+
}}
|
|
77
|
+
onSavedMethodPayment={async ({ paymentMethodId }) => {
|
|
78
|
+
await client.checkout({
|
|
79
|
+
price_id: 'price_monthly',
|
|
80
|
+
processor: 'mobius',
|
|
81
|
+
payment_method_id: paymentMethodId,
|
|
82
|
+
})
|
|
83
|
+
}}
|
|
84
|
+
/>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Architecture
|
|
88
|
+
|
|
89
|
+
- **Lean client only** – `createClient` is the single integration point. It handles auth-token injection, optional account vs billing base URLs, Solana endpoints, and list normalization. There are no “services” or `PaymentApp` instances to maintain.
|
|
90
|
+
- **Scoped CSS theme** – `BillingThemeProvider` adds `payments-ui-root` around our components and defines CSS variables (`--background`, `--primary`, etc.) inside that scope. This prevents the host application's `:root` from being overridden.
|
|
91
|
+
- **React Query + hooks** – Every exported hook (`usePaymentMethods`, `useSubscriptionActions`, `useSupportedTokens`, `useSolanaQrPayment`, etc.) talks directly to the client. There are no legacy contexts or Solana wallet-link flows to wire up.
|
|
92
|
+
- **Solana QR-only** – The backend only exposes `/v1/solana/pay` + `/v1/solana/pay/:reference`, so the UI only renders the QR flow. Wallet-linking, verification, and direct-sign flows were removed to avoid confusing embedding apps.
|
|
93
|
+
|
|
94
|
+
## API surface
|
|
95
|
+
|
|
96
|
+
### `createClient(config)`
|
|
97
|
+
- `billingBaseUrl` (required) – Billing API host (e.g. `https://billing.example.com`).
|
|
98
|
+
- `billingBasePath` – defaults to `/v1`.
|
|
99
|
+
- `accountBaseUrl`, `accountBasePath` – optional override for account endpoints (`/me/payment-methods` etc.).
|
|
100
|
+
- `getAuthToken` – optional sync/async function returning the bearer token.
|
|
101
|
+
- `defaultHeaders` – merged into every request.
|
|
102
|
+
- `fetch` – optional custom fetch implementation.
|
|
103
|
+
|
|
104
|
+
Helpers exposed by the client:
|
|
105
|
+
- `listPaymentMethods`, `createPaymentMethod`, `updatePaymentMethod`, `deletePaymentMethod`, `activatePaymentMethod`
|
|
106
|
+
- `checkout`, `cancelSubscription`
|
|
107
|
+
- `getPaymentHistory`
|
|
108
|
+
- `getSolanaTokens`, `createSolanaPayIntent`, `getSolanaPayStatus`
|
|
109
|
+
- `getPaymentStatus`
|
|
110
|
+
|
|
111
|
+
All helpers return typed promises and throw `ClientApiError` on non-OK responses (exposes `status`, `body`, `request`).
|
|
112
|
+
|
|
113
|
+
### Hooks/components
|
|
114
|
+
- `usePaymentMethods` – wraps React Query around the client and normalizes list responses to the old Stripe-like shape for convenience.
|
|
115
|
+
- `useSubscriptionActions` – helper around `client.checkout` for card vs saved payment flows.
|
|
116
|
+
- `SolanaPaymentView` – shows amount, token selector, and the QR flow. It uses `useSupportedTokens` and `useSolanaQrPayment` internally.
|
|
117
|
+
- `PaymentExperience` – orchestrates card tabs, stored methods, and optionally toggles the Solana flow. It’s built entirely on the hooks listed above.
|
|
118
|
+
|
|
119
|
+
## Styling
|
|
120
|
+
- Import `@doujins/payments-ui/styles.css` once. It only scopes to `.payments-ui-root`, `.payments-ui-portal`, or `[data-payments-ui]` so host CSS remains untouched.
|
|
121
|
+
- Wrap all embedded UI inside `BillingThemeProvider` (or manually add the `payments-ui-root` class/data attribute) so the CSS custom properties take effect.
|
|
122
|
+
- The library uses Tailwind utility classes plus Radix primitives. If the host app already runs Tailwind, there’s no conflict because our CSS is namespaced via the wrapper.
|
|
123
|
+
|
|
124
|
+
## Solana specifics
|
|
125
|
+
- Supported tokens are fetched via `client.getSolanaTokens` (backed by `/v1/solana/tokens`). The UI caches tokens for 5 minutes and sorts them alphabetically.
|
|
126
|
+
- QR intents call `client.createSolanaPayIntent`, which returns the exact payload from `/v1/solana/pay`. The UI handles countdown + polling via `client.getSolanaPayStatus` and stops when the backend reports `confirmed` or the QR expires.
|
|
127
|
+
- `usePaymentStatus` can poll `/payment/status/:id` for extra confirmation if the host wants to display completion states elsewhere.
|
|
128
|
+
|
|
129
|
+
## Removing legacy features
|
|
130
|
+
- Solana wallet linking, direct wallet payments, flexform/CCBill dialogs, and Collect.js verification flows that do not exist on the backend were removed. Only card tokenization via Collect.js (for new cards) and Solana Pay QR remain.
|
|
131
|
+
- There is no barcode/backward compatibility shim. Hosts must adopt `BillingThemeProvider`, `PaymentProvider`, and `createClient` to integrate the new widgets.
|
|
132
|
+
|
|
133
|
+
## Development
|
|
134
|
+
```bash
|
|
135
|
+
pnpm install
|
|
136
|
+
pnpm run typecheck
|
|
137
|
+
pnpm run build
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The build generates `dist/index.*` plus `dist/styles.css`. Consumers should import both the compiled JS and CSS bundle.
|