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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # straumur-web-component
2
2
 
3
- An embeddable, PCI-friendly checkout component for accepting card, Google Pay, and Apple 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
- "en-US": {
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 | Type | Required | Description |
81
- | -------------------- | -------------------------------- | :------: | ------------------------------------------------------------------------------- |
82
- | `sessionId` | `string` | ✅ | The session id from your `/embeddedcheckout/session` response. |
83
- | `environment` | `"test" \| "live"` | ✅ | Selects the Straumur staging or production backend. |
84
- | `locale` | `"is" \| "en"` | | UI language. Defaults to Icelandic (`is`). |
85
- | `theme` | `"light" \| "dark" \| "system"` | | Color theme. `"system"` follows `prefers-color-scheme` live. Default `"light"`. |
86
- | `onPaymentCompleted` | `(data: { resultCode }) => void` | | Called when the payment flow completes (see result codes below). |
87
- | `onPaymentFailed` | `(data: { resultCode }) => void` | | Called when the payment flow fails (see result codes below). |
88
- | `instantPayments` | `("googlepay" \| "applepay")[]` | | Renders the listed wallets as express buttons above the standard methods. |
89
- | `placeholders` | `object` | | Input placeholders — see below. |
90
- | `localizations` | `object` | | Override built-in copy per language and key. |
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 locale (`"is-IS"` / `"en-US"`). Provided strings take precedence
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
- "en-US": { "cards.title": "Card Information" },
105
- "is-IS": { "cards.title": "Kortaupplýsingar" },
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 | Description |
155
- | ----------------------- | -------------------------------------------------------------------------------------------------- |
156
- | `mount(selector)` | Fetches the payment methods and renders the component into a CSS selector or `HTMLElement`. Async. |
157
- | `setLanguage(locale)` | Switches the UI language at runtime (`"en"` or `"is"`, same codes as the `locale` option). |
158
- | `updateConfig(partial)` | Merges new configuration and re-renders. |
159
- | `submitDetails(result)` | Completes a redirect-based (e.g. 3‑D Secure) flow using the `redirectResult` from the return URL. |
160
- | `destroy()` | Unmounts the component and cleans up. |
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 fields.
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`.