From 11ec136a113dffd1b9b7508ea558b9128e092321 Mon Sep 17 00:00:00 2001 From: "e.kireev" Date: Mon, 26 Feb 2024 08:29:27 +0300 Subject: [PATCH] feat(PAYMENTS-18083): Google pay component --- examples/google-pay/index.html | 162 ++++++++++++++++++ examples/google-pay/style.css | 107 ++++++++++++ src/core/actions/check-status.action.type.ts | 15 +- src/core/actions/next-action.interface.ts | 4 +- .../actions/special-button.action.type.ts | 16 ++ .../web-component-tag-name.enum.ts | 1 + src/core/web-components/web-components.map.ts | 2 + .../google-pay-button.component.spec.ts | 34 ++++ .../google-pay/google-pay-button.component.ts | 14 ++ .../submit-button/submit-button.component.ts | 1 + src/web-components.ts | 2 + 11 files changed, 343 insertions(+), 15 deletions(-) create mode 100644 examples/google-pay/index.html create mode 100644 examples/google-pay/style.css create mode 100644 src/core/actions/special-button.action.type.ts create mode 100644 src/features/headless-checkout/web-components/pages/google-pay/google-pay-button.component.spec.ts create mode 100644 src/features/headless-checkout/web-components/pages/google-pay/google-pay-button.component.ts diff --git a/examples/google-pay/index.html b/examples/google-pay/index.html new file mode 100644 index 0000000..d3540df --- /dev/null +++ b/examples/google-pay/index.html @@ -0,0 +1,162 @@ + + + + + + + Document + + + + + + +

Pay Station SDK

+ +

GooglePay payment integration (only https)

+ +
+
+ + + + + + + + + + diff --git a/examples/google-pay/style.css b/examples/google-pay/style.css new file mode 100644 index 0000000..364aee2 --- /dev/null +++ b/examples/google-pay/style.css @@ -0,0 +1,107 @@ +/* *** *** COMMON: START *** *** */ + +.application { + margin: 0 auto; + width: 100%; + max-width: 700px; +} + +.columns-wrapper { + display: flex; + padding-bottom: 20px; +} + +.left-col, +.right-col { + width: 50%; +} + +/* *** *** COMMON: END *** *** */ + +/* *** *** CONTROLS: START *** *** */ +psdk-google-pay-button iframe { + border: none; + width: inherit; + height: 40px; +} + +psdk-text { + display: flex; + flex-direction: column; + align-items: flex-start; + width: 400px; + height: 60px; + margin-bottom: 30px; +} + +psdk-text iframe { + border: none; + width: inherit; + height: 30px; +} + +.field-error { + color: #f30; +} + +psdk-submit-button { + width: 100%; + max-width: 300px; + padding: 3px 6px; +} + +/* *** *** CONTROLS: END *** *** */ + +/* *** *** FINANCE DETAILS: START *** *** */ + +psdk-finance-details { + display: block; + background: #f5f5f5; + margin-right: 10px; + padding: 10px; +} + +.subtotal-row, +.total-row { + display: flex; + width: 100%; + justify-content: space-between; + margin: 10px 0; +} + +/* *** *** FINANCE DETAILS: END *** *** */ + +/* *** *** STATUS: START *** *** */ +psdk-status { + display: flex; +} + +psdk-status .image { + display: block; + width: 100%; + height: auto; +} + +psdk-status .title-text { + text-align: center; +} + +/* *** *** STATUS: END *** *** */ + +/* *** *** FOOTER LINKS: START *** *** */ +.company { + padding-top: 5px; + display: flex; +} + +.company .logo { + margin-right: 3px; +} + +.legal-links { + padding-top: 5px; + display: flex; + justify-content: space-between; +} + +/* *** *** FOOTER LINKS: END *** *** */ diff --git a/src/core/actions/check-status.action.type.ts b/src/core/actions/check-status.action.type.ts index f9b791f..c557477 100644 --- a/src/core/actions/check-status.action.type.ts +++ b/src/core/actions/check-status.action.type.ts @@ -2,17 +2,4 @@ import { Action } from './action.interface'; export type CheckStatusActionType = 'check_status'; -export interface CheckStatusActionData { - invoice: number; - signature: string; - locale: string; - testProject?: string; - testPs?: string; - testXsolla?: string; - userReturnStatus?: string; -} - -export type CheckStatusAction = Action< - CheckStatusActionType, - CheckStatusActionData ->; +export type CheckStatusAction = Action; diff --git a/src/core/actions/next-action.interface.ts b/src/core/actions/next-action.interface.ts index 3c95779..f3f10b5 100644 --- a/src/core/actions/next-action.interface.ts +++ b/src/core/actions/next-action.interface.ts @@ -4,6 +4,7 @@ import { ShowErrorsAction } from './show-errors.action.type'; import { ShowFieldsAction } from './show-fields.action.type'; import { StatusUpdatedAction } from './status-updated.action.type'; import { ThreeDsAction } from './three-ds/three-ds.action.type'; +import { SpecialButtonAction } from './special-button.action.type'; export type NextAction = | CheckStatusAction @@ -11,4 +12,5 @@ export type NextAction = | StatusUpdatedAction | ShowErrorsAction | RedirectAction - | ThreeDsAction; + | ThreeDsAction + | SpecialButtonAction; diff --git a/src/core/actions/special-button.action.type.ts b/src/core/actions/special-button.action.type.ts new file mode 100644 index 0000000..116f851 --- /dev/null +++ b/src/core/actions/special-button.action.type.ts @@ -0,0 +1,16 @@ +import { Action } from './action.interface'; + +export type SpecialButtonActionType = 'special_button'; + +export enum SpecialButtonName { + googlePay = 'google-pay', +} + +export interface SpecialButtonActionData { + buttonName: SpecialButtonName; +} + +export type SpecialButtonAction = Action< + SpecialButtonActionType, + SpecialButtonActionData +>; diff --git a/src/core/web-components/web-component-tag-name.enum.ts b/src/core/web-components/web-component-tag-name.enum.ts index 10b31e3..8b802bb 100644 --- a/src/core/web-components/web-component-tag-name.enum.ts +++ b/src/core/web-components/web-component-tag-name.enum.ts @@ -15,4 +15,5 @@ export enum WebComponentTagName { CheckboxComponent = 'psdk-checkbox', UserBalanceComponent = 'psdk-user-balance', PaymentFormMessages = 'psdk-payment-form-messages', + GooglePayButtonComponent = 'psdk-google-pay-button', } diff --git a/src/core/web-components/web-components.map.ts b/src/core/web-components/web-components.map.ts index 8a72f8e..f62e8e1 100644 --- a/src/core/web-components/web-components.map.ts +++ b/src/core/web-components/web-components.map.ts @@ -15,6 +15,7 @@ import { CheckboxComponent } from '../../features/headless-checkout/web-componen import { SavedMethodsComponent } from '../../features/headless-checkout/web-components/saved-methods/saved-methods.component'; import { UserBalanceComponent } from '../../features/headless-checkout/web-components/user-balance-component/user-balance-component'; import { PaymentFormMessagesComponent } from '../../features/headless-checkout/web-components/payment-form-messages/payment-form-messages.component'; +import { GooglePayButtonComponent } from '../../features/headless-checkout/web-components/pages/google-pay/google-pay-button.component'; export const webComponents: { [key in WebComponentTagName]: CustomElementConstructor; @@ -35,4 +36,5 @@ export const webComponents: { [WebComponentTagName.CheckboxComponent]: CheckboxComponent, [WebComponentTagName.UserBalanceComponent]: UserBalanceComponent, [WebComponentTagName.PaymentFormMessages]: PaymentFormMessagesComponent, + [WebComponentTagName.GooglePayButtonComponent]: GooglePayButtonComponent, }; diff --git a/src/features/headless-checkout/web-components/pages/google-pay/google-pay-button.component.spec.ts b/src/features/headless-checkout/web-components/pages/google-pay/google-pay-button.component.spec.ts new file mode 100644 index 0000000..40d2c59 --- /dev/null +++ b/src/features/headless-checkout/web-components/pages/google-pay/google-pay-button.component.spec.ts @@ -0,0 +1,34 @@ +import { WebComponentTagName } from '../../../../../core/web-components/web-component-tag-name.enum'; +import { GooglePayButtonComponent } from '../../../../../web-components'; + +function createComponent(): void { + const element = document.createElement( + WebComponentTagName.GooglePayButtonComponent, + ); + (document.getElementById('container')! as HTMLElement).appendChild(element); +} + +describe('GooglePayButtonComponent', () => { + window.customElements.define( + WebComponentTagName.GooglePayButtonComponent, + GooglePayButtonComponent, + ); + + beforeEach(() => { + document.body.innerHTML = '
'; + }); + + afterEach(() => { + document.body.innerHTML = ''; + }); + + it('Should create iframe', () => { + createComponent(); + + const iframe = document.querySelector('iframe'); + + expect((iframe as HTMLElement).getAttribute('src')).toContain( + 'google-pay-button', + ); + }); +}); diff --git a/src/features/headless-checkout/web-components/pages/google-pay/google-pay-button.component.ts b/src/features/headless-checkout/web-components/pages/google-pay/google-pay-button.component.ts new file mode 100644 index 0000000..138987a --- /dev/null +++ b/src/features/headless-checkout/web-components/pages/google-pay/google-pay-button.component.ts @@ -0,0 +1,14 @@ +import { SecureComponentAbstract } from '../../../../../core/web-components/secure-component/secure-component.abstract'; +import { headlessCheckoutAppUrl } from '../../../environment'; + +export class GooglePayButtonComponent extends SecureComponentAbstract { + protected componentName = 'pages/google-pay-button'; + + protected getHtml(): string { + return this.getSecureHtml(); + } + + protected getSecureHtml(): string { + return ``; + } +} diff --git a/src/features/headless-checkout/web-components/submit-button/submit-button.component.ts b/src/features/headless-checkout/web-components/submit-button/submit-button.component.ts index 20f33ba..cfb1d54 100644 --- a/src/features/headless-checkout/web-components/submit-button/submit-button.component.ts +++ b/src/features/headless-checkout/web-components/submit-button/submit-button.component.ts @@ -63,6 +63,7 @@ export class SubmitButtonComponent extends WebComponentAbstract { this.render(); } }); + void this.postMessagesClient.send( { name: EventName.submitForm }, submitButtonHandler, diff --git a/src/web-components.ts b/src/web-components.ts index 53bb0d7..677e99a 100644 --- a/src/web-components.ts +++ b/src/web-components.ts @@ -12,6 +12,7 @@ import { SelectComponent } from './features/headless-checkout/web-components/sel import { CheckboxComponent } from './features/headless-checkout/web-components/checkbox/checkbox.component'; import { UserBalanceComponent } from './features/headless-checkout/web-components/user-balance-component/user-balance-component'; import { PaymentFormMessagesComponent } from './features/headless-checkout/web-components/payment-form-messages/payment-form-messages.component'; +import { GooglePayButtonComponent } from './features/headless-checkout/web-components/pages/google-pay/google-pay-button.component'; export { SubmitButtonComponent, @@ -28,4 +29,5 @@ export { CheckboxComponent, UserBalanceComponent, PaymentFormMessagesComponent, + GooglePayButtonComponent, };