@sikka/hawa 0.0.1 → 0.0.4

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.
Files changed (169) hide show
  1. package/.github/workflows/hawa-publish-push.yml +45 -0
  2. package/.github/workflows/hawa-publish.yml +45 -0
  3. package/.prettierrc +28 -28
  4. package/README.md +149 -119
  5. package/es/index.es.js +1 -0
  6. package/lib/index.js +1 -0
  7. package/package.json +59 -47
  8. package/rollup.config.js +30 -40
  9. package/src/Assets/images/card-background/1.jpeg +0 -0
  10. package/src/Assets/images/card-background/10.jpeg +0 -0
  11. package/src/Assets/images/card-background/11.jpeg +0 -0
  12. package/src/Assets/images/card-background/12.jpeg +0 -0
  13. package/src/Assets/images/card-background/13.jpeg +0 -0
  14. package/src/Assets/images/card-background/14.jpeg +0 -0
  15. package/src/Assets/images/card-background/15.jpeg +0 -0
  16. package/src/Assets/images/card-background/16.jpeg +0 -0
  17. package/src/Assets/images/card-background/17.jpeg +0 -0
  18. package/src/Assets/images/card-background/18.jpeg +0 -0
  19. package/src/Assets/images/card-background/19.jpeg +0 -0
  20. package/src/Assets/images/card-background/2.jpeg +0 -0
  21. package/src/Assets/images/card-background/20.jpeg +0 -0
  22. package/src/Assets/images/card-background/21.jpeg +0 -0
  23. package/src/Assets/images/card-background/22.jpeg +0 -0
  24. package/src/Assets/images/card-background/23.jpeg +0 -0
  25. package/src/Assets/images/card-background/24.jpeg +0 -0
  26. package/src/Assets/images/card-background/25.jpeg +0 -0
  27. package/src/Assets/images/card-background/3.jpeg +0 -0
  28. package/src/Assets/images/card-background/4.jpeg +0 -0
  29. package/src/Assets/images/card-background/5.jpeg +0 -0
  30. package/src/Assets/images/card-background/6.jpeg +0 -0
  31. package/src/Assets/images/card-background/7.jpeg +0 -0
  32. package/src/Assets/images/card-background/8.jpeg +0 -0
  33. package/src/Assets/images/card-background/9.jpeg +0 -0
  34. package/src/Assets/images/card-type/amex.png +0 -0
  35. package/src/Assets/images/card-type/diners.png +0 -0
  36. package/src/Assets/images/card-type/discover.png +0 -0
  37. package/src/Assets/images/card-type/mastercard.png +0 -0
  38. package/src/Assets/images/card-type/troy.png +0 -0
  39. package/src/Assets/images/card-type/unionpay.png +0 -0
  40. package/src/Assets/images/card-type/visa.png +0 -0
  41. package/src/blocks/Account/UserProfile.js +15 -0
  42. package/src/blocks/Account/UserSettings.js +15 -0
  43. package/src/blocks/Account/index.js +2 -0
  44. package/src/blocks/AuthForms/NewPasswordForm.js +17 -0
  45. package/src/blocks/AuthForms/ResetPasswordForm.js +14 -0
  46. package/src/blocks/AuthForms/SignInForm.js +19 -0
  47. package/src/blocks/AuthForms/SignUpForm.js +20 -0
  48. package/src/blocks/AuthForms/index.js +4 -0
  49. package/src/blocks/AuthForms/viaFacebook.js +0 -0
  50. package/src/blocks/AuthForms/viaGithub.js +0 -0
  51. package/src/blocks/AuthForms/viaGoogle.js +0 -0
  52. package/src/blocks/AuthForms/viaTwitter.js +0 -0
  53. package/src/blocks/Payment/Form/CForm.js +326 -0
  54. package/src/blocks/Payment/Form/Card.js +242 -0
  55. package/src/blocks/Payment/Gateway/GooglePay.js +251 -0
  56. package/src/blocks/Payment/Gateway/Payfort.js +90 -0
  57. package/src/blocks/Payment/Gateway/Paypal.js +138 -0
  58. package/src/blocks/Payment/Gateway/Wallet.js +149 -0
  59. package/src/blocks/Payment/PaymentMethod.js +132 -0
  60. package/src/blocks/index.js +13 -0
  61. package/src/index.js +2 -1
  62. package/src/layout/Box.js +25 -0
  63. package/src/layout/index.js +1 -0
  64. package/src/stories/ActionButton.stories.js +49 -0
  65. package/src/stories/AdaptiveButton.stories.js +80 -84
  66. package/src/stories/Alert.stories.js +41 -0
  67. package/src/stories/AuthForm.stories.js +79 -0
  68. package/src/stories/Box.stories.js +64 -0
  69. package/src/stories/CheckBox.stories.js +35 -33
  70. package/src/stories/GlobalVariables.stories.js +101 -108
  71. package/src/stories/HawaProvider.stories.js +23 -23
  72. package/src/stories/InputLabel.stories.js +92 -100
  73. package/src/stories/Introduction.stories.js +211 -0
  74. package/src/stories/RadioSelector.stories.js +69 -69
  75. package/src/stories/TextField.stories.js +50 -59
  76. package/src/stories/UserAccount.stories.js +46 -0
  77. package/src/styles.css +400 -403
  78. package/src/styles.scss +679 -0
  79. package/src/themes/HawaProvider.js +45 -0
  80. package/src/ui/ActionButton.js +15 -0
  81. package/src/{components/Hawa/AdaptiveButton/AdaptiveButton.jsx → ui/AdaptiveButton.js} +252 -261
  82. package/src/{components/Hawa/AutoCompleteField/AutoCompleteField.jsx → ui/AutoCompleteField.js} +33 -33
  83. package/src/{components/Hawa/Checkbox/Checkbox.jsx → ui/Checkbox.js} +21 -20
  84. package/src/{components/Hawa/DragDropImages/DragDropImages.jsx → ui/DragDropImages.js} +180 -180
  85. package/src/{components/Hawa/Hawa.jsx → ui/Hawa.js} +3 -3
  86. package/src/{components/Hawa/RadioBox/RadioBox.jsx → ui/RadioBox.js} +29 -29
  87. package/src/{components/Hawa/RadioSelector/RadioSelector.jsx → ui/RadioSelector.js} +51 -51
  88. package/src/ui/Row.js +21 -0
  89. package/src/{components/Hawa/SelectedField/SelectedField.jsx → ui/SelectedField.js} +46 -46
  90. package/src/ui/StyledAlert.js +30 -0
  91. package/src/ui/StyledInputLabel.js +19 -0
  92. package/src/ui/StyledTooltip.js +46 -0
  93. package/src/{components/Hawa/TabPanel/TabPanel.jsx → ui/TabPanel.js} +37 -38
  94. package/src/{components/Hawa/TextArea/TextArea.jsx → ui/TextArea.js} +38 -39
  95. package/src/ui/TextField.js +62 -0
  96. package/src/{components/Hawa → ui}/index.js +13 -11
  97. package/src/util.js +20 -0
  98. package/storybook-static/0.d3bc3395610cf5d3ee94.manager.bundle.js +1 -0
  99. package/storybook-static/0.dd3d47f5.iframe.bundle.js +1 -0
  100. package/storybook-static/1.4e43f671.iframe.bundle.js +3 -0
  101. package/storybook-static/{4.f6eb74f4.iframe.bundle.js.LICENSE.txt → 1.4e43f671.iframe.bundle.js.LICENSE.txt} +8 -8
  102. package/storybook-static/1.4e43f671.iframe.bundle.js.map +1 -0
  103. package/storybook-static/2.9a757207.iframe.bundle.js +1 -0
  104. package/storybook-static/3.c1dc7159.iframe.bundle.js +1 -0
  105. package/storybook-static/4.8c311a6b48cad9f29317.manager.bundle.js +2 -0
  106. package/storybook-static/{5.fa71488e730c5c7f885f.manager.bundle.js.LICENSE.txt → 4.8c311a6b48cad9f29317.manager.bundle.js.LICENSE.txt} +8 -8
  107. package/storybook-static/5.88fe62ee92ff5ca67829.manager.bundle.js +1 -0
  108. package/storybook-static/6.96d184f368dea006cb52.manager.bundle.js +2 -0
  109. package/storybook-static/{11.49c687eaa6261f8b7be2.manager.bundle.js.LICENSE.txt → 6.96d184f368dea006cb52.manager.bundle.js.LICENSE.txt} +12 -12
  110. package/storybook-static/{7.a806a38f.iframe.bundle.js → 7.5ec31f3702b08ab0b71c.manager.bundle.js} +1 -1
  111. package/storybook-static/7.69d2e532.iframe.bundle.js +1 -0
  112. package/storybook-static/8.5ce13be7612bd3a6b864.manager.bundle.js +1 -0
  113. package/storybook-static/8.68cd1217.iframe.bundle.js +3 -0
  114. package/storybook-static/{6.fbc7b90b.iframe.bundle.js.LICENSE.txt → 8.68cd1217.iframe.bundle.js.LICENSE.txt} +12 -12
  115. package/storybook-static/8.68cd1217.iframe.bundle.js.map +1 -0
  116. package/storybook-static/9.488e3969.iframe.bundle.js +1 -0
  117. package/storybook-static/iframe.html +348 -138
  118. package/storybook-static/index.html +59 -47
  119. package/storybook-static/main.65cb2769.iframe.bundle.js +1 -0
  120. package/storybook-static/main.7e391cf7bf72b0d18ea5.manager.bundle.js +1 -0
  121. package/storybook-static/runtime~main.6e2e1544.iframe.bundle.js +1 -0
  122. package/storybook-static/runtime~main.cc29f4c2175f187a3707.manager.bundle.js +1 -0
  123. package/storybook-static/vendors~main.d144d840.iframe.bundle.js +3 -0
  124. package/storybook-static/{vendors~main.73411ca9.iframe.bundle.js.LICENSE.txt → vendors~main.d144d840.iframe.bundle.js.LICENSE.txt} +148 -148
  125. package/storybook-static/vendors~main.d144d840.iframe.bundle.js.map +1 -0
  126. package/storybook-static/vendors~main.f228d62e92b69563cefb.manager.bundle.js +2 -0
  127. package/storybook-static/{vendors~main.d3455eed64b243c89325.manager.bundle.js.LICENSE.txt → vendors~main.f228d62e92b69563cefb.manager.bundle.js.LICENSE.txt} +104 -88
  128. package/tools/build-styles.js +17 -0
  129. package/yarn-error.log +10910 -0
  130. package/src/components/Hawa/AdaptiveButton/index.js +0 -1
  131. package/src/components/Hawa/AutoCompleteField/index.js +0 -1
  132. package/src/components/Hawa/Checkbox/index.js +0 -1
  133. package/src/components/Hawa/DragDropImages/index.js +0 -1
  134. package/src/components/Hawa/HawaProvider/HawaProvider.js +0 -19
  135. package/src/components/Hawa/HawaProvider/index.js +0 -1
  136. package/src/components/Hawa/InputLabel/StyledInputLabel.jsx +0 -36
  137. package/src/components/Hawa/InputLabel/index.js +0 -1
  138. package/src/components/Hawa/RadioBox/index.js +0 -1
  139. package/src/components/Hawa/RadioSelector/index.js +0 -1
  140. package/src/components/Hawa/Row/Row.jsx +0 -23
  141. package/src/components/Hawa/Row/index.js +0 -1
  142. package/src/components/Hawa/SelectedField/index.js +0 -1
  143. package/src/components/Hawa/TabPanel/index.js +0 -1
  144. package/src/components/Hawa/TextArea/index.js +0 -1
  145. package/src/components/Hawa/TextField/TextField.jsx +0 -41
  146. package/src/components/Hawa/TextField/index.js +0 -1
  147. package/storybook-static/0.86a7edfd.iframe.bundle.js +0 -1
  148. package/storybook-static/0.b73eaee9a88f178d62ed.manager.bundle.js +0 -1
  149. package/storybook-static/1.f296d183a17268696d73.manager.bundle.js +0 -1
  150. package/storybook-static/10.9998ba67d65d81d20896.manager.bundle.js +0 -1
  151. package/storybook-static/11.49c687eaa6261f8b7be2.manager.bundle.js +0 -2
  152. package/storybook-static/12.c9538ed3766c96f289e7.manager.bundle.js +0 -1
  153. package/storybook-static/4.f6eb74f4.iframe.bundle.js +0 -3
  154. package/storybook-static/4.f6eb74f4.iframe.bundle.js.map +0 -1
  155. package/storybook-static/5.ec6f37af.iframe.bundle.js +0 -1
  156. package/storybook-static/5.fa71488e730c5c7f885f.manager.bundle.js +0 -2
  157. package/storybook-static/6.8096ae4aadde0743697b.manager.bundle.js +0 -1
  158. package/storybook-static/6.fbc7b90b.iframe.bundle.js +0 -3
  159. package/storybook-static/6.fbc7b90b.iframe.bundle.js.map +0 -1
  160. package/storybook-static/7.b34baecbd082bc7b188d.manager.bundle.js +0 -1
  161. package/storybook-static/8.15577edffecf900a8de2.manager.bundle.js +0 -1
  162. package/storybook-static/9.d7d85aa0a49a98f17218.manager.bundle.js +0 -1
  163. package/storybook-static/main.355ffc59.iframe.bundle.js +0 -1
  164. package/storybook-static/main.ce406c7e93b98325390e.manager.bundle.js +0 -1
  165. package/storybook-static/runtime~main.3d81579b.iframe.bundle.js +0 -1
  166. package/storybook-static/runtime~main.909d038f912f063e8837.manager.bundle.js +0 -1
  167. package/storybook-static/vendors~main.73411ca9.iframe.bundle.js +0 -3
  168. package/storybook-static/vendors~main.73411ca9.iframe.bundle.js.map +0 -1
  169. package/storybook-static/vendors~main.d3455eed64b243c89325.manager.bundle.js +0 -2
@@ -0,0 +1,242 @@
1
+ import React, { useState, useEffect, useCallback, useMemo } from "react";
2
+ import {
3
+ CSSTransition,
4
+ TransitionGroup,
5
+ SwitchTransition
6
+ } from "react-transition-group";
7
+
8
+ const CARDS = {
9
+ visa: "^4",
10
+ amex: "^(34|37)",
11
+ mastercard: "^5[1-5]",
12
+ discover: "^6011",
13
+ unionpay: "^62",
14
+ troy: "^9792",
15
+ diners: "^(30[0-5]|36)"
16
+ };
17
+
18
+ const cardBackgroundName = () => {
19
+ let random = Math.floor(Math.random() * 25 + 1);
20
+ return `${random}.jpeg`;
21
+ };
22
+
23
+ const BACKGROUND_IMG = cardBackgroundName();
24
+
25
+ const Card = ({
26
+ cardHolder,
27
+ cardNumber,
28
+ cardMonth,
29
+ cardYear,
30
+ cardCvv,
31
+ isCardFlipped,
32
+ currentFocusedElm,
33
+ onCardElementClick,
34
+ cardNumberRef,
35
+ cardHolderRef,
36
+ cardDateRef
37
+ }) => {
38
+ const [style, setStyle] = useState(null);
39
+
40
+ const cardType = (cardNumber) => {
41
+ const number = cardNumber;
42
+ let re;
43
+ for (const [card, pattern] of Object.entries(CARDS)) {
44
+ re = new RegExp(pattern);
45
+ if (number.match(re) != null) {
46
+ return card;
47
+ }
48
+ }
49
+
50
+ return "visa"; // default type
51
+ };
52
+
53
+ const useCardType = useMemo(() => {
54
+ return cardType(cardNumber);
55
+ }, [cardNumber]);
56
+
57
+ const outlineElementStyle = (element) => {
58
+ return element
59
+ ? {
60
+ width: `${element.offsetWidth}px`,
61
+ height: `${element.offsetHeight}px`,
62
+ transform: `translateX(${element.offsetLeft}px) translateY(${element.offsetTop}px)`
63
+ }
64
+ : null;
65
+ };
66
+
67
+ useEffect(() => {
68
+ if (currentFocusedElm) {
69
+ const style = outlineElementStyle(currentFocusedElm.current);
70
+ setStyle(style);
71
+ }
72
+ }, [currentFocusedElm]);
73
+
74
+ const maskCardNumber = (cardNumber) => {
75
+ let cardNumberArr = cardNumber.split("");
76
+ cardNumberArr.forEach((val, index) => {
77
+ if (index > 4 && index < 14) {
78
+ if (cardNumberArr[index] !== " ") {
79
+ cardNumberArr[index] = "*";
80
+ }
81
+ }
82
+ });
83
+
84
+ return cardNumberArr;
85
+ };
86
+
87
+ return (
88
+ <div className={"card-item " + (isCardFlipped ? "-active" : "")}>
89
+ <div className="card-item__side -front">
90
+ <div
91
+ className={`card-item__focus ${currentFocusedElm ? `-active` : ``}`}
92
+ style={style}
93
+ />
94
+ <div className="card-item__cover">
95
+ <img
96
+ alt=""
97
+ src={`/card-background/${BACKGROUND_IMG}`}
98
+ className="card-item__bg"
99
+ />
100
+ </div>
101
+
102
+ <div className="card-item__wrapper">
103
+ <div className="card-item__top">
104
+ <img src={"/chip.png"} alt="" className="card-item__chip" />
105
+ <div className="card-item__type">
106
+ <img
107
+ alt={useCardType}
108
+ src={`/card-type/${useCardType}.png`}
109
+ className="card-item__typeImg"
110
+ />
111
+ </div>
112
+ </div>
113
+
114
+ <label
115
+ className="card-item__number"
116
+ ref={cardNumberRef}
117
+ onClick={() => onCardElementClick("cardNumber")}
118
+ >
119
+ <TransitionGroup className="slide-fade-up" component="div">
120
+ {cardNumber ? (
121
+ maskCardNumber(cardNumber).map((val, index) => (
122
+ <CSSTransition
123
+ classNames="slide-fade-up"
124
+ timeout={250}
125
+ key={index}
126
+ >
127
+ <div className="card-item__numberItem">{val}</div>
128
+ </CSSTransition>
129
+ ))
130
+ ) : (
131
+ <CSSTransition classNames="slide-fade-up" timeout={250}>
132
+ <div className="card-item__numberItem">#</div>
133
+ </CSSTransition>
134
+ )}
135
+ </TransitionGroup>
136
+ </label>
137
+ <div className="card-item__content">
138
+ <label
139
+ className="card-item__info"
140
+ onClick={() => onCardElementClick("cardHolder")}
141
+ ref={cardHolderRef}
142
+ >
143
+ <div className="card-item__holder">Card Holder</div>
144
+ <div className="card-item__name">
145
+ <TransitionGroup component="div" className="slide-fade-up">
146
+ {cardHolder === "FULL NAME" ? (
147
+ <CSSTransition classNames="slide-fade-up" timeout={250}>
148
+ <div>FULL NAME</div>
149
+ </CSSTransition>
150
+ ) : (
151
+ cardHolder.split("").map((val, index) => (
152
+ <CSSTransition
153
+ timeout={250}
154
+ classNames="slide-fade-right"
155
+ key={index}
156
+ >
157
+ <span className="card-item__nameItem">{val}</span>
158
+ </CSSTransition>
159
+ ))
160
+ )}
161
+ </TransitionGroup>
162
+ </div>
163
+ </label>
164
+ <div
165
+ className="card-item__date"
166
+ onClick={() => onCardElementClick("cardDate")}
167
+ ref={cardDateRef}
168
+ >
169
+ <label className="card-item__dateTitle">Expires</label>
170
+ <label className="card-item__dateItem">
171
+ <SwitchTransition in-out>
172
+ <CSSTransition
173
+ classNames="slide-fade-up"
174
+ timeout={200}
175
+ key={cardMonth}
176
+ >
177
+ <span>{!cardMonth ? "MM" : cardMonth} </span>
178
+ </CSSTransition>
179
+ </SwitchTransition>
180
+ </label>
181
+ /
182
+ <label htmlFor="cardYear" className="card-item__dateItem">
183
+ <SwitchTransition out-in>
184
+ <CSSTransition
185
+ classNames="slide-fade-up"
186
+ timeout={250}
187
+ key={cardYear}
188
+ >
189
+ <span>
190
+ {!cardYear ? "YY" : cardYear.toString().substr(-2)}
191
+ </span>
192
+ </CSSTransition>
193
+ </SwitchTransition>
194
+ </label>
195
+ </div>
196
+ <div
197
+ className="card-item__date"
198
+ onClick={() => onCardElementClick("cardDate")}
199
+ ref={cardDateRef}
200
+ ></div>
201
+ </div>
202
+ </div>
203
+ </div>
204
+
205
+ <div className="card-item__side -back">
206
+ <div className="card-item__cover">
207
+ <img
208
+ alt=""
209
+ src={`/card-background/${BACKGROUND_IMG}`}
210
+ className="card-item__bg"
211
+ />
212
+ </div>
213
+ <div className="card-item__band" />
214
+ <div className="card-item__cvv">
215
+ <div className="card-item__cvvTitle">CVV</div>
216
+ <div className="card-item__cvvBand">
217
+ <TransitionGroup>
218
+ {cardCvv.split("").map((val, index) => (
219
+ <CSSTransition
220
+ classNames="zoom-in-out"
221
+ key={index}
222
+ timeout={250}
223
+ >
224
+ <span>*</span>
225
+ </CSSTransition>
226
+ ))}
227
+ </TransitionGroup>
228
+ </div>
229
+ <div className="card-item__type">
230
+ <img
231
+ alt="card-type"
232
+ src={"/card-type/visa.png"}
233
+ className="card-item__typeImg"
234
+ />
235
+ </div>
236
+ </div>
237
+ </div>
238
+ </div>
239
+ );
240
+ };
241
+
242
+ export default Card;
@@ -0,0 +1,251 @@
1
+ import axios from "axios";
2
+ import qs from "qs";
3
+ import { useRouter } from "next/router";
4
+ import { useState, useEffect } from "react";
5
+ import useTranslation from "next-translate/useTranslation";
6
+ import Script from "next/script";
7
+
8
+ const GooglePay = (props) => {
9
+ const transaction = props.currenttransactiongpay;
10
+ const router = useRouter();
11
+ console.log("transaction=", transaction);
12
+ const { t, lang } = useTranslation("common");
13
+ const [googlepayloaded, setGooglePayLoaded] = useState(false);
14
+ const [googlepay, setGooglePay] = useState(false);
15
+ const [braintreegatewayclient, setBraintreeGatewayClient] = useState(false);
16
+ const [braintreegatewaygooglepayment, setBraintreeGatewayGooglePayment] =
17
+ useState(false);
18
+ const [braintreegatewaydatacollector, setBraintreeGatewayDataCollector] =
19
+ useState(false);
20
+
21
+ let paymentsClient;
22
+
23
+ useEffect(() => {
24
+ if (
25
+ !googlepayloaded &&
26
+ googlepay &&
27
+ braintreegatewaydatacollector &&
28
+ braintreegatewayclient &&
29
+ braintreegatewaygooglepayment
30
+ ) {
31
+ console.log("okkkk");
32
+ onGooglePayLoaded();
33
+ }
34
+ }, [
35
+ googlepay,
36
+ braintreegatewayclient,
37
+ braintreegatewaygooglepayment,
38
+ braintreegatewaydatacollector,
39
+ googlepayloaded
40
+ ]);
41
+
42
+ /**
43
+ * Add a Google Pay purchase button alongside an existing checkout button
44
+ *
45
+ * @see {@link https://developers.google.com/pay/api/web/reference/request-objects#ButtonOptions|Button options}
46
+ * @see {@link https://developers.google.com/pay/api/web/guides/brand-guidelines|Google Pay brand guidelines}
47
+ */
48
+ const addGooglePayButton = (googlePaymentInstance, clientInstance) => {
49
+ //ok
50
+ const button = paymentsClient.createButton({
51
+ onClick: (event) =>
52
+ onGooglePaymentButtonClicked(
53
+ event,
54
+ googlePaymentInstance,
55
+ clientInstance
56
+ ),
57
+ buttonLocale: lang
58
+ });
59
+ document.getElementById("qawaim-googlepay").appendChild(button);
60
+ };
61
+
62
+ /**
63
+ * Show Google Pay payment sheet when Google Pay payment button is clicked
64
+ */
65
+ const onGooglePaymentButtonClicked = (
66
+ event,
67
+ googlePaymentInstance,
68
+ clientInstance
69
+ ) => {
70
+ let paymentDataRequest = googlePaymentInstance.createPaymentDataRequest({
71
+ merchantInfo: {
72
+ // @todo a merchant ID is available for a production environment after approval by Google
73
+ // See {@link https://developers.google.com/pay/api/web/guides/test-and-deploy/integration-checklist|Integration checklist}
74
+ merchantId: `${process.env.NEXT_PUBLIC_QAWAIM_GOOGLE_MERCHANT_ID}`,
75
+ merchantName: `${process.env.NEXT_PUBLIC_QAWAIM_GOOGLEPAY_MERCHANT_NAME}`
76
+ },
77
+ transactionInfo: {
78
+ displayItems: [
79
+ {
80
+ label: "Subtotal",
81
+ type: "SUBTOTAL",
82
+ price: `${transaction.amount}`
83
+ }
84
+ ],
85
+ currencyCode: `${transaction.currency}`,
86
+ totalPriceStatus: "FINAL",
87
+ totalPrice: `${transaction.amount}`,
88
+ totalPriceLabel: "Total"
89
+ }
90
+ });
91
+
92
+ // We recommend collecting billing address information, at minimum
93
+ // billing postal code, and passing that billing postal code with all
94
+ // Google Pay card transactions as a best practice.
95
+ // See all available options at https://developers.google.com/pay/api/web/reference/object
96
+ let cardPaymentMethod = paymentDataRequest.allowedPaymentMethods[0];
97
+ cardPaymentMethod.parameters.billingAddressRequired = true;
98
+ cardPaymentMethod.parameters.billingAddressParameters = {
99
+ format: "FULL",
100
+ phoneNumberRequired: true
101
+ };
102
+
103
+ paymentsClient
104
+ .loadPaymentData(paymentDataRequest)
105
+ .then(function (paymentData) {
106
+ googlePaymentInstance.parseResponse(
107
+ paymentData,
108
+ function (err, result) {
109
+ if (err) {
110
+ console.log(err);
111
+ // Handle parsing error
112
+ router.push("/payment/error");
113
+ }
114
+
115
+ // Send result.nonce to your server
116
+ // result.type may be either "AndroidPayCard" or "PayPalAccount", and
117
+ // paymentData will contain the billingAddress for card payments
118
+ braintree.dataCollector.create(
119
+ {
120
+ client: clientInstance
121
+ },
122
+ async function (err, dataCollectorInstance) {
123
+ if (err) {
124
+ // Handle error in creation of data collector
125
+ return;
126
+ }
127
+ // At this point, you should access the dataCollectorInstance.deviceData value and provide it
128
+ // to your server, e.g. by injecting it into your form as a hidden input.
129
+ let deviceData = dataCollectorInstance.deviceData;
130
+ const data = {
131
+ deviceDataClient: deviceData,
132
+ nonce: result.nonce,
133
+ billing_address: transaction.billing_address,
134
+ amount: `${transaction.amount}`,
135
+ currency: token.SelectedCurrency?.toUpperCase(),
136
+ transaction_id: `${transaction._id}`
137
+ };
138
+ let checkoutgpay = await axios.post(
139
+ `${process.env.NEXT_PUBLIC_QAWAIM_API_URL}/braintreegateway/googlepay`,
140
+ qs.stringify(data)
141
+ );
142
+ if (checkoutgpay.data.ok === true) {
143
+ router.push(`/confirmation/${transaction._id}`);
144
+ //setCurrentTransaction(checkoutInfo.data.data.transaction);
145
+ router.push(
146
+ `/confirmation/${checkoutgpay.data.data.transaction._id}`
147
+ );
148
+ } else {
149
+ router.push("/payment/error");
150
+ }
151
+ }
152
+ );
153
+ }
154
+ );
155
+ })
156
+ .catch(function (err) {
157
+ console.log(err);
158
+ router.push("/payment/error");
159
+ // Handle errors
160
+ });
161
+ };
162
+
163
+ const onGooglePayLoaded = () => {
164
+ // Make sure to have https://pay.google.com/gp/p/js/pay.js loaded on your page
165
+ // You will need a button element on your page styled according to Google's brand guidelines
166
+ // https://developers.google.com/pay/api/web/guides/brand-guidelines
167
+ paymentsClient = new google.payments.api.PaymentsClient({
168
+ environment: process.env.NEXT_PUBLIC_QAWAIM_GOOGLEPAY_ENVIRONMENT // 'TEST' Or 'PRODUCTION'
169
+ });
170
+
171
+ setGooglePayLoaded(true);
172
+
173
+ braintree.client.create(
174
+ {
175
+ authorization: `${process.env.NEXT_PUBLIC_QAWAIM_BRAINTREE_TOKENIZATION_KEY}`
176
+ },
177
+ function (clientErr, clientInstance) {
178
+ console.log("clientErr=", clientErr);
179
+ console.log("clientInstance=", clientInstance);
180
+ braintree.googlePayment.create(
181
+ {
182
+ client: clientInstance,
183
+ googlePayVersion: 2,
184
+ googleMerchantId: `${process.env.NEXT_PUBLIC_QAWAIM_GOOGLE_MERCHANT_ID}` // Optional in sandbox; if set in sandbox, this value must be a valid production Google Merchant ID
185
+ },
186
+ function (googlePaymentErr, googlePaymentInstance) {
187
+ console.log("googlePaymentErr=", googlePaymentErr);
188
+ console.log("googlePaymentInstance=", googlePaymentInstance);
189
+ paymentsClient
190
+ .isReadyToPay({
191
+ // see https://developers.google.com/pay/api/web/reference/object#IsReadyToPayRequest
192
+ apiVersion: 2,
193
+ apiVersionMinor: 0,
194
+ allowedPaymentMethods:
195
+ googlePaymentInstance.createPaymentDataRequest()
196
+ .allowedPaymentMethods,
197
+ existingPaymentMethodRequired: true // Optional
198
+ })
199
+ .then(function (response) {
200
+ if (response.result) {
201
+ addGooglePayButton(googlePaymentInstance, clientInstance);
202
+ }
203
+ })
204
+ .catch(function (err) {
205
+ console.log(err);
206
+ router.push("/payment/error");
207
+ // Handle errors
208
+ });
209
+ }
210
+ );
211
+
212
+ // Set up other Braintree components
213
+ }
214
+ );
215
+ };
216
+ return (
217
+ <>
218
+ <Script
219
+ id="googlepay"
220
+ src="https://pay.google.com/gp/p/js/pay.js"
221
+ onLoad={() => {
222
+ setGooglePay(true);
223
+ }}
224
+ />
225
+ <Script
226
+ id="braintreegateway-client"
227
+ src="https://js.braintreegateway.com/web/3.82.0/js/client.min.js"
228
+ onLoad={() => {
229
+ setBraintreeGatewayClient(true);
230
+ }}
231
+ />
232
+ <Script
233
+ id="braintreegateway-data-collector"
234
+ src="https://js.braintreegateway.com/web/3.82.0/js/data-collector.min.js"
235
+ onLoad={() => {
236
+ setBraintreeGatewayDataCollector(true);
237
+ }}
238
+ />
239
+ <Script
240
+ id="braintreegateway-google-payment"
241
+ src="https://js.braintreegateway.com/web/3.82.0/js/google-payment.min.js"
242
+ onLoad={() => {
243
+ setBraintreeGatewayGooglePayment(true);
244
+ }}
245
+ />
246
+ <div id="qawaim-googlepay"></div>
247
+ </>
248
+ );
249
+ };
250
+
251
+ export default GooglePay;
@@ -0,0 +1,90 @@
1
+ import { useState, useEffect, memo, useCallback, useRef } from "react";
2
+ import CForm from "../Form/CForm";
3
+ import Card from "../Form/Card";
4
+
5
+ const initialState = {
6
+ cardNumber: "#### #### #### ####",
7
+ cardHolder: "FULL NAME",
8
+ cardMonth: "",
9
+ cardYear: "",
10
+ cardCvv: "",
11
+ isCardFlipped: false
12
+ };
13
+
14
+ const Payfort = (props) => {
15
+ const [state, setState] = useState(initialState);
16
+ const [currentFocusedElm, setCurrentFocusedElm] = useState(null);
17
+
18
+ const updateStateValues = useCallback(
19
+ (keyName, value) => {
20
+ setState({
21
+ ...state,
22
+ [keyName]: value || initialState[keyName]
23
+ });
24
+ },
25
+ [state]
26
+ );
27
+ // References for the Form Inputs used to focus corresponding inputs.
28
+ let formFieldsRefObj = {
29
+ cardNumber: useRef(),
30
+ cardHolder: useRef(),
31
+ cardDate: useRef(),
32
+ cardCvv: useRef()
33
+ };
34
+
35
+ let focusFormFieldByKey = useCallback((key) => {
36
+ formFieldsRefObj[key].current.focus();
37
+ });
38
+
39
+ // This are the references for the Card DIV elements.
40
+ let cardElementsRef = {
41
+ cardNumber: useRef(),
42
+ cardHolder: useRef(),
43
+ cardDate: useRef()
44
+ };
45
+
46
+ let onCardFormInputFocus = (_event, inputName) => {
47
+ const refByName = cardElementsRef[inputName];
48
+ setCurrentFocusedElm(refByName);
49
+ };
50
+
51
+ let onCardInputBlur = useCallback(() => {
52
+ setCurrentFocusedElm(null);
53
+ }, []);
54
+
55
+ return (
56
+ <CForm
57
+ cardNumber={state.cardNumber}
58
+ cardHolder={state.cardHolder}
59
+ cardMonth={state.cardMonth}
60
+ cardYear={state.cardYear}
61
+ cardCvv={state.cardCvv}
62
+ onUpdateState={updateStateValues}
63
+ cardNumberRef={formFieldsRefObj.cardNumber}
64
+ cardHolderRef={formFieldsRefObj.cardHolder}
65
+ cardDateRef={formFieldsRefObj.cardDate}
66
+ cardCvvRef={formFieldsRefObj.cardCvv}
67
+ onCardInputFocus={onCardFormInputFocus}
68
+ onCardInputBlur={onCardInputBlur}
69
+ handlePaymentPayfort={props.handlePaymentPayfort}
70
+ paymentMethod={props.paymentMethod}
71
+ register={props.register}
72
+ >
73
+ <Card
74
+ cardNumber={state.cardNumber}
75
+ cardHolder={state.cardHolder}
76
+ cardMonth={state.cardMonth}
77
+ cardYear={state.cardYear}
78
+ cardCvv={state.cardCvv}
79
+ isCardFlipped={state.isCardFlipped}
80
+ currentFocusedElm={currentFocusedElm}
81
+ onCardElementClick={focusFormFieldByKey}
82
+ cardNumberRef={cardElementsRef.cardNumber}
83
+ cardHolderRef={cardElementsRef.cardHolder}
84
+ cardDateRef={cardElementsRef.cardDate}
85
+ ></Card>
86
+ </CForm>
87
+ );
88
+ };
89
+
90
+ export default Payfort;