straumur-web-component 2.0.0-alpha.7 → 2.0.0-beta.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.
- package/README.md +115 -28
- package/dist/index.cjs +17 -12
- package/dist/index.d.cts +72 -102
- package/dist/index.d.ts +72 -102
- package/dist/index.js +20 -15
- package/dist/index.mjs +17 -12
- package/package.json +12 -7
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# straumur-web-component
|
|
2
2
|
|
|
3
|
-
An embeddable, PCI-friendly checkout component for accepting card, Google Pay,
|
|
4
|
-
payments through [Straumur](https://straumur.is). It renders a complete payment UI into an element
|
|
3
|
+
An embeddable, PCI-friendly checkout component for accepting card, saved-card, Google Pay, Apple Pay
|
|
4
|
+
and Kortalán payments through [Straumur](https://straumur.is). It renders a complete payment UI into an element
|
|
5
5
|
on your page and handles the payment flow (including 3‑D Secure) for you.
|
|
6
6
|
|
|
7
7
|
📚 **Full documentation:** <https://docs.straumur.is> — see
|
|
@@ -47,7 +47,7 @@ const paymentConfiguration = {
|
|
|
47
47
|
cardNumber: "1234 5678 9012 3456",
|
|
48
48
|
},
|
|
49
49
|
localizations: {
|
|
50
|
-
|
|
50
|
+
en: {
|
|
51
51
|
"cards.title": "Card Information",
|
|
52
52
|
},
|
|
53
53
|
},
|
|
@@ -59,11 +59,13 @@ checkout.mount("#component-container");
|
|
|
59
59
|
|
|
60
60
|
### Using the CDN / script tag (no bundler)
|
|
61
61
|
|
|
62
|
-
The package also ships an IIFE build that exposes a global `StraumurWeb
|
|
62
|
+
The package also ships an IIFE build that exposes a global `StraumurWeb`. Pin the exact version in
|
|
63
|
+
production — 2.x pre-releases are published under the `next` tag, so an unversioned URL still
|
|
64
|
+
resolves to 1.x:
|
|
63
65
|
|
|
64
66
|
```html
|
|
65
67
|
<div id="component-container"></div>
|
|
66
|
-
<script src="https://unpkg.com/straumur-web-component"></script>
|
|
68
|
+
<script src="https://unpkg.com/straumur-web-component@2.0.0-beta.1"></script>
|
|
67
69
|
<script>
|
|
68
70
|
const checkout = new StraumurWeb.StraumurCheckout({
|
|
69
71
|
environment: "test",
|
|
@@ -77,17 +79,38 @@ The package also ships an IIFE build that exposes a global `StraumurWeb`:
|
|
|
77
79
|
|
|
78
80
|
Passed to the `StraumurCheckout` constructor:
|
|
79
81
|
|
|
80
|
-
| Option
|
|
81
|
-
|
|
|
82
|
-
| `sessionId`
|
|
83
|
-
| `environment`
|
|
84
|
-
| `locale`
|
|
85
|
-
| `theme`
|
|
86
|
-
| `onPaymentCompleted`
|
|
87
|
-
| `onPaymentFailed`
|
|
88
|
-
| `instantPayments`
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
82
|
+
| Option | Type | Required | Description |
|
|
83
|
+
| -------------------------- | ---------------------------------------------------------- | :------: | ----------------------------------------------------------------------------------------------------- |
|
|
84
|
+
| `sessionId` | `string` | ✅ | The session id from your `/embeddedcheckout/session` response. |
|
|
85
|
+
| `environment` | `"test" \| "live"` | ✅ | Selects the Straumur staging or production backend. |
|
|
86
|
+
| `locale` | `"is" \| "en"` | | UI language. Defaults to Icelandic (`is`). |
|
|
87
|
+
| `theme` | `"light" \| "dark" \| "system" \| ThemeConfiguration` | | Color theme, optionally with wallet button styles — see [Theming](#theming). |
|
|
88
|
+
| `onPaymentCompleted` | `(data: { resultCode }) => void` | | Called when the payment flow completes (see result codes below). |
|
|
89
|
+
| `onPaymentFailed` | `(data: { resultCode }) => void` | | Called when the payment flow fails (see result codes below). |
|
|
90
|
+
| `instantPayments` | `("googlepay" \| "applepay")[]` | | Renders the listed wallets as express buttons above the standard methods. |
|
|
91
|
+
| `allowedPaymentMethods` | `PaymentMethod[]` | | Only show these of the session's methods. Omit to show all. |
|
|
92
|
+
| `orderPaymentMethods` | `PaymentMethodOrder[]` | | Top-to-bottom order of the methods — see [Choosing methods](#choosing-methods). |
|
|
93
|
+
| `openDefaultPaymentMethod` | `"card" \| "firstStoredCard" \| "googlepay" \| "applepay"` | | Method to expand on load. Ignored if unavailable. Default: none expanded. |
|
|
94
|
+
| `hideSubmitButton` | `boolean` | | Hide the built-in card pay button and use your own — see [Your own pay button](#your-own-pay-button). |
|
|
95
|
+
| `onCardValidityChanged` | `(isValid: boolean, isActive: boolean) => void` | | Card form state for your own pay button. |
|
|
96
|
+
| `placeholders` | `object` | | Input placeholders — see below. |
|
|
97
|
+
| `localizations` | `object` | | Override built-in copy per language and key. |
|
|
98
|
+
|
|
99
|
+
### Choosing methods
|
|
100
|
+
|
|
101
|
+
`PaymentMethod` is one of `"card"`, `"storedcard"`, `"googlepay"`, `"applepay"` and `"kortalan"`.
|
|
102
|
+
Which ones appear is decided by the session (and the shopper's device, for the wallets);
|
|
103
|
+
`allowedPaymentMethods` can only narrow that list.
|
|
104
|
+
|
|
105
|
+
`orderPaymentMethods` takes the same tokens plus `"instantpayments"` (the express wallet row). The
|
|
106
|
+
default order is `["instantpayments", "kortalan", "storedcard", "card", "googlepay", "applepay"]`;
|
|
107
|
+
any available method you leave out is appended in that order, so nothing is hidden just by being
|
|
108
|
+
omitted. A wallet listed in `instantPayments` only ever renders in the express row.
|
|
109
|
+
|
|
110
|
+
**Kortalán** is listed by the backend only when the store has it enabled **and** Kortalán accepts
|
|
111
|
+
the basket's amount, so it can come and go between sessions. Paying with it redirects the shopper
|
|
112
|
+
to Kortalán; handle the return with [`submitDetails`](#returning-from-a-redirect), exactly like a
|
|
113
|
+
redirect-based 3-D Secure flow.
|
|
91
114
|
|
|
92
115
|
### `placeholders`
|
|
93
116
|
|
|
@@ -96,13 +119,14 @@ Any subset of: `cardNumber`, `expiryDate`, `expiryMonth`, `expiryYear`, `securit
|
|
|
96
119
|
|
|
97
120
|
### `localizations`
|
|
98
121
|
|
|
99
|
-
Override any translation key per
|
|
100
|
-
over the built-in translations; missing keys fall back to the defaults.
|
|
122
|
+
Override any translation key per language (`"is"` / `"en"`). Provided strings take precedence
|
|
123
|
+
over the built-in translations; missing keys fall back to the defaults. The 1.x full tags
|
|
124
|
+
(`"is-IS"` / `"en-US"`) are still accepted as keys.
|
|
101
125
|
|
|
102
126
|
```javascript
|
|
103
127
|
localizations: {
|
|
104
|
-
|
|
105
|
-
|
|
128
|
+
en: { "cards.title": "Card Information" },
|
|
129
|
+
is: { "cards.title": "Kortaupplýsingar" },
|
|
106
130
|
}
|
|
107
131
|
```
|
|
108
132
|
|
|
@@ -114,6 +138,17 @@ Set `theme` to `"light"` (default), `"dark"`, or `"system"`:
|
|
|
114
138
|
const checkout = new StraumurCheckout({ sessionId, environment: "test", theme: "system" });
|
|
115
139
|
```
|
|
116
140
|
|
|
141
|
+
To also choose the Google Pay / Apple Pay button styles, pass a `ThemeConfiguration` object. A
|
|
142
|
+
button style you omit follows the widget mode (light widget → light button, dark → black):
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
theme: {
|
|
146
|
+
mode: "dark", // "light" | "dark" | "system"
|
|
147
|
+
googlePayButtonTheme: "white", // "dark" | "white"
|
|
148
|
+
applePayButtonTheme: "light", // "dark" | "light"
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
117
152
|
`"system"` follows the shopper's OS/browser `prefers-color-scheme` and switches live if they
|
|
118
153
|
change it. The theme is scoped to the widget and never affects the surrounding page. Change it at
|
|
119
154
|
runtime with `updateConfig({ theme: "dark" })`.
|
|
@@ -139,6 +174,49 @@ The full set of tokens is defined in `src/styles/main.css`. Note: the card numbe
|
|
|
139
174
|
inputs are rendered inside Adyen's secure iframes, which CSS custom properties cannot reach — their
|
|
140
175
|
text colors are set internally and won't follow a heavily customized palette.
|
|
141
176
|
|
|
177
|
+
## Your own pay button
|
|
178
|
+
|
|
179
|
+
Set `hideSubmitButton: true` to drop the built-in card pay button, render your own, and drive it
|
|
180
|
+
with `onCardValidityChanged` and `submitCard()`:
|
|
181
|
+
|
|
182
|
+
```javascript
|
|
183
|
+
const payButton = document.querySelector("#my-pay-button");
|
|
184
|
+
|
|
185
|
+
const checkout = new StraumurCheckout({
|
|
186
|
+
sessionId,
|
|
187
|
+
environment: "test",
|
|
188
|
+
hideSubmitButton: true,
|
|
189
|
+
// isActive: a card-type method (new or saved card) is selected and ready; hide your button otherwise.
|
|
190
|
+
// isValid: its fields are complete; disable your button until then.
|
|
191
|
+
onCardValidityChanged: (isValid, isActive) => {
|
|
192
|
+
payButton.hidden = !isActive;
|
|
193
|
+
payButton.disabled = !isValid;
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
payButton.addEventListener("click", () => checkout.submitCard());
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
`submitCard()` returns `true` if a card-type method was active and submission started (the outcome
|
|
201
|
+
arrives through `onPaymentCompleted` / `onPaymentFailed`), `false` otherwise. Repeated clicks while
|
|
202
|
+
a payment is in flight are ignored. The wallets and Kortalán keep their own buttons.
|
|
203
|
+
|
|
204
|
+
## Returning from a redirect
|
|
205
|
+
|
|
206
|
+
Some flows leave your page — a redirect-based 3-D Secure challenge, or Kortalán — and come back to
|
|
207
|
+
your return URL with `redirectResult` and `paymentCheckoutReference` in the query string. Complete the
|
|
208
|
+
payment on that page with `submitDetails`:
|
|
209
|
+
|
|
210
|
+
```javascript
|
|
211
|
+
const params = new URLSearchParams(window.location.search);
|
|
212
|
+
const checkout = new StraumurCheckout({ sessionId, environment: "test", onPaymentCompleted, onPaymentFailed });
|
|
213
|
+
|
|
214
|
+
// The third argument is where to render the result screen; it's only needed if you don't also mount().
|
|
215
|
+
checkout.submitDetails(params.get("redirectResult"), params.get("paymentCheckoutReference"), "#component-container");
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
It shows a loader while the result is fetched, then the result screen, and calls your callbacks.
|
|
219
|
+
|
|
142
220
|
## Accessibility
|
|
143
221
|
|
|
144
222
|
Payment results are announced to assistive tech (`role="alert"` for failures, `role="status"` for
|
|
@@ -151,13 +229,14 @@ into a 3-D Secure challenge when it takes over the widget.
|
|
|
151
229
|
const checkout = new StraumurCheckout(config);
|
|
152
230
|
```
|
|
153
231
|
|
|
154
|
-
| Method
|
|
155
|
-
|
|
|
156
|
-
| `mount(selector)`
|
|
157
|
-
| `setLanguage(locale)`
|
|
158
|
-
| `updateConfig(partial)`
|
|
159
|
-
| `submitDetails(
|
|
160
|
-
| `
|
|
232
|
+
| Method | Description |
|
|
233
|
+
| --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
234
|
+
| `mount(selector)` | Fetches the payment methods and renders the component into a CSS selector or `HTMLElement`. Async. |
|
|
235
|
+
| `setLanguage(locale)` | Switches the UI language at runtime (`"en"` or `"is"`, same codes as the `locale` option). |
|
|
236
|
+
| `updateConfig(partial)` | Merges new options (`locale`, `localizations`, `theme`, callbacks, …) and re-renders. |
|
|
237
|
+
| `submitDetails(redirectResult, paymentCheckoutReference?, selector?)` | Completes a redirect-based flow (3‑D Secure, Kortalán) — see [Returning from a redirect](#returning-from-a-redirect). |
|
|
238
|
+
| `submitCard()` | Submits the active card form from your own button; returns whether it started — see [Your own pay button](#your-own-pay-button). |
|
|
239
|
+
| `destroy()` | Unmounts the component and cleans up. |
|
|
161
240
|
|
|
162
241
|
## Payment result codes
|
|
163
242
|
|
|
@@ -166,10 +245,18 @@ and `Error` invoke `onPaymentFailed`; every other outcome (`Authorised`, `Receiv
|
|
|
166
245
|
invokes `onPaymentCompleted`. `onPaymentFailed` always receives a `resultCode` — if the underlying
|
|
167
246
|
provider reports a failure without one, it is delivered as `Error`.
|
|
168
247
|
|
|
248
|
+
The shopper sees a success screen for `Authorised`, a "being processed" screen for `Pending` /
|
|
249
|
+
`Received`, and a failure screen otherwise.
|
|
250
|
+
|
|
251
|
+
If the Straumur API doesn't answer a payment request within 90 seconds, the shopper is told the
|
|
252
|
+
payment couldn't be confirmed and `onPaymentFailed` receives `Error` — but the payment may still have
|
|
253
|
+
gone through. Treat the server-side result (your webhook / payment status) as the source of truth
|
|
254
|
+
before fulfilling or cancelling an order.
|
|
255
|
+
|
|
169
256
|
## Breaking changes in v2.0.0
|
|
170
257
|
|
|
171
258
|
- Removed the config field `submitDetails?: (details: any) => void` (it was never invoked). Use the `submitDetails(redirectResult)` method on the class instead.
|
|
172
|
-
- `updateConfig()` accepts only the documented configuration
|
|
259
|
+
- `updateConfig()` accepts only the documented configuration options (typed as `StraumurCheckoutUpdateOptions`). `sessionId` and `environment` are fixed for an instance's lifetime — they are ignored with a console warning; create a new `StraumurCheckout` instead. Use `localizations` (as in the constructor); `customLocalizations` still works but is deprecated.
|
|
173
260
|
- `submitDetails(redirectResult)` now invokes `onPaymentCompleted` / `onPaymentFailed`.
|
|
174
261
|
- Result routing now follows Adyen Web 6: a `Refused`, `Cancelled`, or `Error` outcome invokes `onPaymentFailed` (in 1.x every gateway response, including refusals, invoked `onPaymentCompleted`). If your integration branched on `resultCode` inside `onPaymentCompleted`, move the failure branches to `onPaymentFailed`.
|
|
175
262
|
- `onPaymentFailed`'s argument is no longer optional — it always carries a `resultCode`.
|