diff --git a/packages/klarna-checkout-types/CHANGELOG.md b/packages/klarna-checkout-types/CHANGELOG.md new file mode 100644 index 00000000..e4d87c4d --- /dev/null +++ b/packages/klarna-checkout-types/CHANGELOG.md @@ -0,0 +1,4 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. diff --git a/packages/klarna-checkout-types/README.md b/packages/klarna-checkout-types/README.md new file mode 100644 index 00000000..45faaaba --- /dev/null +++ b/packages/klarna-checkout-types/README.md @@ -0,0 +1,28 @@ +# @noaignite/centra-types + +This package contains Typescript definitions, intepreted from the Klarna Checkout clientside events. + +## Installation + +klarna-checkout-types is available as an [npm package](https://www.npmjs.com/package/@noaignite/klarna-checkout-types). + +```sh +// with npm +npm install @noaignite/klarna-checkout-types + +// with yarn +yarn add @noaignite/klarna-checkout-types +``` + +## Usage + +```typescript +import type { Klarna } from '@noaignite/klarna-checkout-types' + +declare global { + interface Window { + _klarnaCheckout?: (callback: Klarna.CheckoutCallback) => void + } +} +``` + diff --git a/packages/klarna-checkout-types/api/index.d.ts b/packages/klarna-checkout-types/api/index.d.ts new file mode 100644 index 00000000..dadd69c4 --- /dev/null +++ b/packages/klarna-checkout-types/api/index.d.ts @@ -0,0 +1,275 @@ +import type { Alpha3Code as ImportedAlpha3Code } from 'iso-3166-1-ts' + +export namespace Klarna { + /** + * @desc ISO 3166-1 Alpha 3 code in lowercase + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/ + */ + type Alpha3Code = Lowercase + + /** + * @desc Either string `"person"` or `"organization"` + * + */ + type CustomerType = 'person' | 'organization' + + /** + * @desc The `load` event is triggered whenever Klarna Checkout has rendered for a customer within its iFrame. + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-load-event + */ + export type LoadEvent = { + customer: { + /** + * @desc Either string `"person"` or `"organization"` + * + */ + type: CustomerType + } + shipping_address: { + /** + * @desc ISO 3166-1 Alpha 3 code in lowercase + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/ + */ + country: Alpha3Code + /** + * @desc Postal code without whitespaces + * + */ + postal_code: string + } + } + + /** + * @desc The `user_interacted` event is triggered whenever the user interacts with the KCO iframe either by clicking or typing. This event will only be triggered for the first interaction. + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-user_interacted-event + */ + export type UserInteractedEvent = { + /** + * @desc `"mousedown"` or `"keydown"` depending on the user interaction + * + */ + type: 'mousedown' | 'keydown' + } + + /** + * @desc The `customer` event is triggered whenever Klarna Checkout has detected the customer type or a customer type change. Currently `"organization"` and `"person"` are the two supported types. + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-customer-event + */ + export type CustomerEvent = { + /** + * @desc Either string `"person"` or `"organization"` + * + */ + type: CustomerType + } + + /** + * @desc The `change` event is triggered when the user changes postal code, country or email in their billing address. It is also triggered for given/family name except in the AT & DE markets. + * @note The data returned is not guaranteed to be in the data object. As an example, customer gets prefilled by Klarna and some data gets obfuscated. Obfuscated data is not sent through the API. + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-change-event + */ + export type ChangeEvent = ChangeEventATDE | ChangeEventOther + + type ChangeEventATDE = { + email?: string + /** + * @desc Postal code without whitespaces + */ + postal_code?: string + /** + * @desc ISO 3166-1 Alpha 3 code in lowercase + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/ + */ + country?: Extract + } + + type ChangeEventOther = Omit & { + country?: Exclude + given_name?: string + family_name?: string + } + + /** + * @desc The `billing_address_change` event is triggered when Checkout has detected a complete and valid billing address for the customer. + * @note The data returned is not guaranteed to be in the data object. As an example, customer gets prefilled by Klarna and some data gets obfuscated. Obfuscated data is not sent through the API. + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-billing_address_change-event + */ + export type BillingAddressChangeEvent = + | BillingAddressChangeEventATDE + | BillingAddressChangeEventOther + + type BillingAddressChangeEventATDE = { + /** + * @desc Postal code without whitespaces + */ + postal_code?: string + /** + * @desc ISO 3166-1 Alpha 3 code in lowercase + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/ + */ + country?: Extract + } + + type BillingAddressChangeEventOther = Omit & { + country?: Exclude + given_name?: string + family_name?: string + email?: string + } + + /** + * @desc The `shipping_address_change` event is triggered when Checkout has detected a complete and valid shipping address for the customer. The shipping address will always be the same as billing address, unless a separate shipping address has been provided by the customer. + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-shipping_address_change-event + */ + export type ShippingAddressChangeEvent = + | ShippingAddressChangeEventATDE + | ShippingAddressChangeEventOther + + type ShippingAddressChangeEventATDE = { + /** + * @desc Postal code without whitespaces + */ + postal_code?: string + /** + * @desc ISO 3166-1 Alpha 3 code in lowercase + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/ + */ + country?: Extract + } + + export type ShippingAddressChangeEventOther = Omit & { + given_name?: string + family_name?: string + email?: string + country?: Exclude + } + + /** + * @desc The `shipping_option_change` event is triggered when the customer has selected a new shipping option. + * The event data contains a shipping options object with `price`, `tax_amount`, and `tax_rate` is expressed in [minor units](https://docs.klarna.com/klarna-checkout/api/#tag/Data-Types) (e.g. cents). + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-shipping_option_change-event + */ + export type ShippingOptionChangeEvent = { + description: string + id: string + name: string + price: number + promo: string + tax_amount: number + tax_rate: number + } + + /** + * @desc The `shipping_address_update_error` is a generic error that is triggered whenever something goes wrong when updating shipping methods/options. The event data is an empty object. + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-shipping_address_update_error-event + */ + export type ShippingAddressUpdateError = object + + /** + * @desc The `order_total_change` event is triggered when the order total has changed. + * The event data contains an object with the order total, expressed in [minor units](https://docs.klarna.com/klarna-checkout/api/#tag/Data-Types) (e.g. cents). + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-order_total_change-event + */ + export type OrderTotalChangeEvent = { + order_total: number + } + + /** + * @desc The `checkbox_change` event is triggered everytime a checkbox is checked/unchecked. + * The event data contains an object with the checkbox key and if the checkbox was checked or unchecked. + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-checkbox_change-event + */ + export type CheckboxChangeEvent = { + /** + * the same the merchant sends to KCO on the `id` property for the [additional checkboxes](https://developers.klarna.com/api/#checkout-api__create-a-new-orderoptions__additional_checkbox) + */ + key: string + checked: boolean + } + + /** + * @desc The `can_not_complete_order` event is triggered when the merchant has to provide other means of paying. A normal case when this happens is when only Credit payment options are available but the customer was refused credit. + * The event data is an empty object. + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-can_not_complete_order-event + */ + export type CanNotCompleteOrderEvent = object + + /** + * @desc The `network_error` event is triggered when a network issue has been detected, which could basically mean that the customer has lost internet connection. + * The event data is an empty object. + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-network_error-event + */ + export type NetworkErrorEvent = object + + /** + * @desc The `redirect_initiated` event is triggered after the user has completed all the required steps to complete the purchase and is about to get redirected to the confirmation page. + * The event data is always `true`. + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-redirect_initiated-event + */ + export type RedirectInitiatedEvent = true + + /** + * @desc The `load_confirmation` event is triggered whenever Klarna confirmation page has rendered for a customer within its iFrame. + * The event data is an empty object. + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-load_confirmation-event + */ + export type LoadConfirmationEvent = object + + /** + * + * + * @desc If you send this property `options.require_client_validation` as `true` while creating the order, the client will give you the chance to do some client validations after the `validation_callback` event is triggered. + * + * The `validation_callback` event is triggered when the user clicks the buy button and before the client requests the server to process the purchase. + * The event data is an empty object. + * + * @see https://docs.klarna.com/klarna-checkout/in-depth-knowledge/client-side-events/#checkout-events-the-validation_callback-event + */ + export type ValidationCallbackEvent = object + + export type EventListeners = Partial<{ + load: (data: LoadEvent) => void + user_interacted: (data: UserInteractedEvent) => void + customer: (data: CustomerEvent) => void + change: (data: ChangeEvent) => void + shipping_address_change: (data: ShippingAddressChangeEvent) => void + shipping_option_change: (data: ShippingOptionChangeEvent) => void + order_total_change: (data: OrderTotalChangeEvent) => void + checkbox_change: (data: CheckboxChangeEvent) => void + can_not_complete_order: (data: CanNotCompleteOrderEvent) => void + network_error: (data: NetworkErrorEvent) => void + redirect_initiated: (data: RedirectInitiatedEvent) => void + load_confirmation: (data: LoadConfirmationEvent) => void + validation_callback: ( + data: ValidationCallbackEvent, + callback: (param: { should_proceed: boolean; message?: string }) => void, + ) => void + }> + + export type Api = { + suspend: (event: unknown) => Api + resume: () => Api + on: (eventListeners: EventListeners) => Api + } + + export type CheckoutCallback = (api: Api) => void +} diff --git a/packages/klarna-checkout-types/index.d.ts b/packages/klarna-checkout-types/index.d.ts new file mode 100644 index 00000000..3318fdbc --- /dev/null +++ b/packages/klarna-checkout-types/index.d.ts @@ -0,0 +1 @@ +export * from './api' diff --git a/packages/klarna-checkout-types/package.json b/packages/klarna-checkout-types/package.json new file mode 100644 index 00000000..17f60c7d --- /dev/null +++ b/packages/klarna-checkout-types/package.json @@ -0,0 +1,40 @@ +{ + "name": "@noaignite/klarna-checkout-types", + "version": "1.0.0-alpha.1", + "private": false, + "author": "NoA Ignite", + "description": "Typescript definitions for the Klarna Checkout API", + "keywords": [ + "typescript", + "types", + "klarna" + ], + "license": "MIT", + "types": "./index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/noaignite/accelerator.git", + "directory": "packages/klarna-checkout-types" + }, + "bugs": { + "url": "https://github.com/noaignite/accelerator/issues" + }, + "scripts": { + "build": "mkdir build && cp index.d.ts build/ && cp -a api/ build/api/ && yarn build:copy-files", + "build:copy-files": "node ../../scripts/copy-files.mjs", + "build:docs": "typedoc", + "prebuild": "yarn typecheck && rimraf build", + "release:yalc": "yarn build && yalc publish ./build", + "typecheck": "tsc -p tsconfig.json" + }, + "devDependencies": { + "iso-3166-1-ts": "^0.2.2" + }, + "sideEffects": false, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=14.0.0" + } +} diff --git a/packages/klarna-checkout-types/tsconfig.json b/packages/klarna-checkout-types/tsconfig.json new file mode 100644 index 00000000..4082f16a --- /dev/null +++ b/packages/klarna-checkout-types/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tsconfig.json" +} diff --git a/packages/klarna-checkout-types/typedoc.json b/packages/klarna-checkout-types/typedoc.json new file mode 100644 index 00000000..9184643a --- /dev/null +++ b/packages/klarna-checkout-types/typedoc.json @@ -0,0 +1,5 @@ +{ + "entryPoints": ["index.d.ts"], + "out": "docs", + "gitRevision": "main" +} diff --git a/yarn.lock b/yarn.lock index 21fb68d0..bd7fffda 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8736,6 +8736,11 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +iso-3166-1-ts@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/iso-3166-1-ts/-/iso-3166-1-ts-0.2.2.tgz#9c9b2f082024c36f523759bed201ed459b46dfea" + integrity sha512-5KJp6m2Y2tW8bekRpy0Vckob8VqsQTTy2BQQ1o2opXsr30t1MD8M/OvOZzIRBR3DcELCnkpnIXoQbM+Hp5U26A== + isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"