@fat-zebra/sdk 1.5.0 → 1.5.2

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.
@@ -1 +1,2 @@
1
1
  process.env.API_ENV = 'local'
2
+ process.env.PAYNOW_BASE_URL = 'https://paynow.test'
package/README.dev.md CHANGED
@@ -130,6 +130,39 @@ The deployed SDKs are available from the following URLs.
130
130
  * Sandbox: https://cdn.pmnts-sandbox.io/sdk/v1/fatzebra.js
131
131
  * Production: https://cdn.pmnts.io/sdk/v1/fatzebra.js
132
132
 
133
+ ## Release react npm package
134
+
135
+ Prerequisite: it is essential that you have been added to the https://www.npmjs.com/ group account.
136
+
137
+ To release the react npm package
138
+
139
+ ```
140
+ git checkout master
141
+ git pull
142
+ ```
143
+
144
+ then run
145
+
146
+ ```
147
+ npm run npm:publish
148
+ ```
149
+
150
+ You will be prompted with:
151
+
152
+ ```
153
+ enter (y) for minor release or (n) for patch release
154
+ ```
155
+
156
+ if it is a major release i.e. a breaking change please update the script/consult with management as major release would indicate a breaking change.
157
+
158
+ You will then see the project build and finally be prompted to:
159
+ ```
160
+ Press ENTER to open in the browser...
161
+ ```
162
+
163
+ from here enter your 2FA code and voila! You have published a new version of the SDK. Go tell some merchants.
164
+
165
+
133
166
  ## Release Management
134
167
 
135
168
  The release of the sdk follows a weekly schedule. In the beginning of a new release cycle, do the following
package/README.md CHANGED
@@ -1 +1,4 @@
1
- # Fat Zebra SDK
1
+ # Fat Zebra SDK
2
+
3
+ ## Change log
4
+ Monday 8th - updated the package to consume version from a version.ts file, rather than from package.json.
@@ -1,5 +1,8 @@
1
1
  import { PaymentIntent } from "../shared/types";
2
2
  import { ClickToPayOptions } from "./types";
3
+ export declare const CLICK_TO_PAY_DEFAULT_OPTIONS: {
4
+ [key: string]: boolean | string;
5
+ };
3
6
  interface ClickToPayModuleConfig {
4
7
  paymentIntent: PaymentIntent;
5
8
  username: string;
@@ -20,7 +23,7 @@ declare class ClickToPay {
20
23
  constructor(config: ClickToPayModuleConfig);
21
24
  load(config: ClickToPayLoadParams): void;
22
25
  getPayNowUrl(options?: {
23
- [key: string]: boolean | string;
26
+ [key: string]: any;
24
27
  }): string;
25
28
  setCrossFramesEventListeners(): void;
26
29
  purchase(): void;
@@ -2,7 +2,7 @@ import { PostMessageClient } from "../shared/post-message-client";
2
2
  import { BridgeEvent, PublicEvent } from "../shared/types";
3
3
  import * as util from '../shared/util';
4
4
  import { emit } from "../shared/event-manager";
5
- const CLICK_TO_PAY_DEFAULT_OPTIONS = {
5
+ export const CLICK_TO_PAY_DEFAULT_OPTIONS = {
6
6
  iframe: true,
7
7
  postmessage: true,
8
8
  };
@@ -35,23 +35,24 @@ class ClickToPay {
35
35
  this.username,
36
36
  payment.reference,
37
37
  payment.currency,
38
- payment.amount,
38
+ // If amount is left as 0 (type: Number), it will be filtered out later
39
+ // So we convert to string as "0" will be allowed through the filter
40
+ // Yes, we do want $0 purchases (especially for tokenizeOnly / auth flows)
41
+ payment.amount.toString(),
39
42
  this.paymentIntent.verification
40
43
  ].filter(part => part).join('/');
41
- let queryString;
42
- if (options) {
43
- const _options = Object.assign(Object.assign({}, CLICK_TO_PAY_DEFAULT_OPTIONS), options);
44
- queryString = Object.keys(_options).map(key => {
45
- return util.toSnakeCase(key) + '=' + _options[key];
46
- }).join('&');
47
- }
48
- let searchParams = new URLSearchParams(queryString);
49
- return queryString ? `${base}?${searchParams.toString()}` : `${base}`;
44
+ let searchParams = new URLSearchParams();
45
+ const combinedOptions = Object.assign(Object.assign({}, CLICK_TO_PAY_DEFAULT_OPTIONS), options);
46
+ Object.keys(combinedOptions).map(key => {
47
+ if (combinedOptions[key] !== null && combinedOptions[key] !== undefined) {
48
+ searchParams.append(util.toSnakeCase(key), combinedOptions[key]);
49
+ }
50
+ });
51
+ return searchParams.toString().length > 0 ? `${base}?${searchParams.toString()}` : `${base}`;
50
52
  }
51
53
  setCrossFramesEventListeners() {
52
54
  const handlers = {};
53
55
  handlers[BridgeEvent.TOKENIZE_CARD_RESPONSE] = (data) => {
54
- console.log(data);
55
56
  if (data.errors) {
56
57
  emit(PublicEvent.TOKENIZATION_ERROR, {
57
58
  message: 'Card tokenization failed.',
package/dist/hpp/hpp.js CHANGED
@@ -154,6 +154,8 @@ class Hpp {
154
154
  }
155
155
  setPublicEventListeners() {
156
156
  const handler = (event) => {
157
+ if (this.hppOptions.tokenizeOnly)
158
+ return;
157
159
  const threedsData = event.detail.data;
158
160
  const extra = util.toObjectWithSnakeCaseKeys(threedsData);
159
161
  this.createPurchase(extra);
@@ -0,0 +1,91 @@
1
+ .checkout-button-wrapper {
2
+ display: flex;
3
+ justify-content: center;
4
+ align-items: center;
5
+ height: 200px;
6
+ }
7
+
8
+ .iframe-checkout {
9
+ flex: 1;
10
+ border: none;
11
+ width: 100%;
12
+ height: 100%;
13
+ min-height: 0;
14
+ overflow: auto;
15
+ -webkit-overflow-scrolling: touch;
16
+ }
17
+
18
+ .iframe-foreground,
19
+ .iframe-background {
20
+ top: 0;
21
+ left: 0;
22
+ right: 0;
23
+ bottom: 0;
24
+ flex-direction: column;
25
+ }
26
+
27
+ .iframe-foreground,
28
+ .iframe-background {
29
+ position: fixed;
30
+ }
31
+
32
+ .iframe-foreground {
33
+ z-index: -1;
34
+ }
35
+
36
+ .iframe-background {
37
+ background: rgba(0, 0, 0, 0.5);
38
+ }
39
+
40
+ .iframe-foreground {
41
+ flex-grow: 1;
42
+ top: auto;
43
+ width: 100%;
44
+ max-width: 480px;
45
+ height: 80vh;
46
+ background-color: #ffffff;
47
+ border-radius: 25px 25px 0 0;
48
+ }
49
+
50
+ .slide-in .iframe-foreground {
51
+ transform: translateY(100vh);
52
+ transition: transform 0.4s ease, z-index 0.3s ease 0.4s;
53
+ z-index: -1;
54
+ }
55
+
56
+ .slide-in .iframe-background {
57
+ opacity: 0;
58
+ z-index: -1;
59
+ transition: opacity 0.3s ease, z-index 0.3s ease 0.3s;
60
+ }
61
+
62
+ .slide-in.show .iframe-foreground {
63
+ transform: none;
64
+ transition: transform 0.4s ease;
65
+ z-index: 100;
66
+ }
67
+
68
+ .slide-in.show .iframe-background {
69
+ opacity: 1;
70
+ z-index: 0;
71
+ transition: opacity 0.3s ease;
72
+ }
73
+
74
+ @media only screen and (min-width: 480px) {
75
+ .iframe-foreground {
76
+ margin: 0 auto;
77
+ }
78
+ }
79
+
80
+ @media only screen and (min-width: 768px) {
81
+ .iframe-foreground {
82
+ margin: 0;
83
+ width: 400px;
84
+ height: 100vh;
85
+ left: 0;
86
+ }
87
+
88
+ .slide-in .iframe-foreground {
89
+ transform: translateX(-400px);
90
+ }
91
+ }