@paypal/checkout-components 5.0.297 → 5.0.299-alpha.0
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 +4 -0
- package/dist/button.js +1 -1
- package/dist/test/button.js +1 -1
- package/package.json +4 -3
- package/src/api/shopper-insights/validation.js +8 -7
- package/src/api/shopper-insights/validation.test.js +3 -1
- package/src/connect/component.jsx +25 -30
- package/src/connect/component.test.js +2 -11
- package/src/constants/api.js +1 -2
- package/src/hosted-buttons/index.js +28 -26
- package/src/hosted-buttons/index.test.js +7 -4
- package/src/hosted-buttons/types.js +29 -7
- package/src/hosted-buttons/utils.js +93 -36
- package/src/hosted-buttons/utils.test.js +58 -6
- package/src/connect/sendCountMetric.js +0 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paypal/checkout-components",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.299-alpha.0",
|
|
4
4
|
"description": "PayPal Checkout components, for integrating checkout products.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"vitest": "^0.25.3"
|
|
103
103
|
},
|
|
104
104
|
"dependencies": {
|
|
105
|
+
"@krakenjs/beaver-logger": "^5.7.0",
|
|
105
106
|
"@krakenjs/belter": "^2.0.0",
|
|
106
107
|
"@krakenjs/cross-domain-utils": "^3.0.0",
|
|
107
108
|
"@krakenjs/jsx-pragmatic": "^3",
|
|
@@ -111,8 +112,8 @@
|
|
|
111
112
|
"@paypal/common-components": "^1.0.35",
|
|
112
113
|
"@paypal/connect-loader-component": "1.1.1",
|
|
113
114
|
"@paypal/funding-components": "^1.0.31",
|
|
114
|
-
"@paypal/sdk-client": "^4.0.
|
|
115
|
-
"@paypal/sdk-constants": "^1.0.
|
|
115
|
+
"@paypal/sdk-client": "^4.0.181",
|
|
116
|
+
"@paypal/sdk-constants": "^1.0.141",
|
|
116
117
|
"@paypal/sdk-logos": "^2.2.6"
|
|
117
118
|
},
|
|
118
119
|
"lint-staged": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* @flow */
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { getLogger } from "@paypal/sdk-client/src";
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
SHOPPER_INSIGHTS_METRIC_NAME,
|
|
@@ -21,9 +21,10 @@ export function validateMerchantConfig({
|
|
|
21
21
|
userIDToken,
|
|
22
22
|
clientToken,
|
|
23
23
|
}: MerchantConfigParams) {
|
|
24
|
+
const logger = getLogger();
|
|
24
25
|
if (!sdkToken) {
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
logger.metricCounter({
|
|
27
|
+
namespace: SHOPPER_INSIGHTS_METRIC_NAME,
|
|
27
28
|
event: "error",
|
|
28
29
|
dimensions: {
|
|
29
30
|
errorType: "merchant_configuration_validation_error",
|
|
@@ -37,8 +38,8 @@ export function validateMerchantConfig({
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
if (!pageType) {
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
logger.metricCounter({
|
|
42
|
+
namespace: SHOPPER_INSIGHTS_METRIC_NAME,
|
|
42
43
|
event: "error",
|
|
43
44
|
dimensions: {
|
|
44
45
|
errorType: "merchant_configuration_validation_error",
|
|
@@ -52,8 +53,8 @@ export function validateMerchantConfig({
|
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
if (userIDToken) {
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
logger.metricCounter({
|
|
57
|
+
namespace: SHOPPER_INSIGHTS_METRIC_NAME,
|
|
57
58
|
event: "error",
|
|
58
59
|
dimensions: {
|
|
59
60
|
errorType: "merchant_configuration_validation_error",
|
|
@@ -15,8 +15,6 @@ import {
|
|
|
15
15
|
} from "@paypal/sdk-client/src";
|
|
16
16
|
import { FPTI_KEY } from "@paypal/sdk-constants";
|
|
17
17
|
|
|
18
|
-
import { sendCountMetric } from "./sendCountMetric";
|
|
19
|
-
|
|
20
18
|
const MIN_MAJOR_VERSION = 3;
|
|
21
19
|
const MIN_MINOR_VERSION = 97;
|
|
22
20
|
export const MIN_BT_VERSION = `${MIN_MAJOR_VERSION}.${MIN_MINOR_VERSION}.3-connect-alpha.6.1`; // Minimum for supporting AXO
|
|
@@ -33,8 +31,8 @@ export function getSdkVersion(version: string | null): string {
|
|
|
33
31
|
majorVersion < MIN_MAJOR_VERSION ||
|
|
34
32
|
(majorVersion === MIN_MAJOR_VERSION && minorVersion < MIN_MINOR_VERSION)
|
|
35
33
|
) {
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
getLogger().metricCounter({
|
|
35
|
+
namespace: "connect.init.count",
|
|
38
36
|
event: "error",
|
|
39
37
|
dimensions: {
|
|
40
38
|
errorName: "braintree_version_not_supported_error",
|
|
@@ -42,7 +40,7 @@ export function getSdkVersion(version: string | null): string {
|
|
|
42
40
|
});
|
|
43
41
|
|
|
44
42
|
throw new Error(
|
|
45
|
-
`The braintree version
|
|
43
|
+
`The braintree version: ${version} does not support Connect. Please use version ${MIN_BT_VERSION} or above`
|
|
46
44
|
);
|
|
47
45
|
}
|
|
48
46
|
|
|
@@ -65,9 +63,9 @@ export const getConnectComponent = async (merchantProps = {}) => {
|
|
|
65
63
|
// queryStringParams = {}, // TODO: what do we need here in this case?
|
|
66
64
|
});
|
|
67
65
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
getLogger().metricCounter({
|
|
67
|
+
namespace: "connect.init.count",
|
|
68
|
+
event: "init",
|
|
71
69
|
});
|
|
72
70
|
|
|
73
71
|
const debugEnabled = getDebug() || false;
|
|
@@ -82,21 +80,20 @@ export const getConnectComponent = async (merchantProps = {}) => {
|
|
|
82
80
|
metadata,
|
|
83
81
|
});
|
|
84
82
|
} catch (error) {
|
|
85
|
-
sendCountMetric({
|
|
86
|
-
name: "pp.app.paypal_sdk.connect.init.error.count",
|
|
87
|
-
event: "error",
|
|
88
|
-
dimensions: {
|
|
89
|
-
errorName: "connect_load_error",
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
|
|
93
83
|
getLogger()
|
|
84
|
+
.error("load_connect_error", { err: stringifyError(error) })
|
|
94
85
|
.track({
|
|
95
86
|
[FPTI_KEY.CONTEXT_TYPE]: "CMID",
|
|
96
87
|
[FPTI_KEY.CONTEXT_ID]: cmid,
|
|
97
88
|
[FPTI_KEY.EVENT_NAME]: `ppcp_axo_failure`,
|
|
98
89
|
})
|
|
99
|
-
.
|
|
90
|
+
.metricCounter({
|
|
91
|
+
namespace: "connect.init.count",
|
|
92
|
+
event: "error",
|
|
93
|
+
dimensions: {
|
|
94
|
+
errorName: "connect_load_error",
|
|
95
|
+
},
|
|
96
|
+
})
|
|
100
97
|
.flush();
|
|
101
98
|
|
|
102
99
|
throw new Error(error);
|
|
@@ -121,23 +118,14 @@ export const getConnectComponent = async (merchantProps = {}) => {
|
|
|
121
118
|
[FPTI_KEY.CONTEXT_ID]: cmid,
|
|
122
119
|
[FPTI_KEY.EVENT_NAME]: `ppcp_connect_success`,
|
|
123
120
|
})
|
|
121
|
+
.metricCounter({
|
|
122
|
+
namespace: "connect.init.count",
|
|
123
|
+
event: "success",
|
|
124
|
+
})
|
|
124
125
|
.flush();
|
|
125
|
-
sendCountMetric({
|
|
126
|
-
name: "pp.app.paypal_sdk.connect.init.success.count",
|
|
127
|
-
event: "success",
|
|
128
|
-
dimensions: {},
|
|
129
|
-
});
|
|
130
126
|
|
|
131
127
|
return connect;
|
|
132
128
|
} catch (error) {
|
|
133
|
-
sendCountMetric({
|
|
134
|
-
name: "pp.app.paypal_sdk.connect.init.error.count",
|
|
135
|
-
event: "error",
|
|
136
|
-
dimensions: {
|
|
137
|
-
errorName: "connect_init_error",
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
|
|
141
129
|
getLogger()
|
|
142
130
|
.track({
|
|
143
131
|
[FPTI_KEY.CONTEXT_TYPE]: "CMID",
|
|
@@ -145,6 +133,13 @@ export const getConnectComponent = async (merchantProps = {}) => {
|
|
|
145
133
|
[FPTI_KEY.EVENT_NAME]: `ppcp_connect_failure`,
|
|
146
134
|
})
|
|
147
135
|
.error("init_connect_error", { err: stringifyError(error) })
|
|
136
|
+
.metricCounter({
|
|
137
|
+
namespace: "connect.init.count",
|
|
138
|
+
event: "error",
|
|
139
|
+
dimensions: {
|
|
140
|
+
errorName: "connect_init_error",
|
|
141
|
+
},
|
|
142
|
+
})
|
|
148
143
|
.flush();
|
|
149
144
|
|
|
150
145
|
throw new Error(error);
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
getSdkVersion,
|
|
10
10
|
MIN_BT_VERSION,
|
|
11
11
|
} from "./component";
|
|
12
|
-
import { sendCountMetric } from "./sendCountMetric";
|
|
13
12
|
|
|
14
13
|
vi.mock("@paypal/sdk-client/src", () => {
|
|
15
14
|
return {
|
|
@@ -23,6 +22,7 @@ vi.mock("@paypal/sdk-client/src", () => {
|
|
|
23
22
|
error: vi.fn().mockReturnThis(),
|
|
24
23
|
track: vi.fn().mockReturnThis(),
|
|
25
24
|
flush: vi.fn().mockReturnThis(),
|
|
25
|
+
metricCounter: vi.fn().mockReturnThis(),
|
|
26
26
|
})),
|
|
27
27
|
getEnv: vi.fn().mockReturnValue("mock-env"),
|
|
28
28
|
getCSPNonce: vi.fn(),
|
|
@@ -36,15 +36,10 @@ vi.mock("@paypal/connect-loader-component", () => {
|
|
|
36
36
|
};
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
-
vi.mock("./sendCountMetric", () => {
|
|
40
|
-
return {
|
|
41
|
-
sendCountMetric: vi.fn(),
|
|
42
|
-
};
|
|
43
|
-
});
|
|
44
|
-
|
|
45
39
|
describe("getConnectComponent: returns ConnectComponent", () => {
|
|
46
40
|
const mockAxoMetadata = { someData: "data" };
|
|
47
41
|
const mockProps = { someProp: "value" };
|
|
42
|
+
|
|
48
43
|
beforeEach(() => {
|
|
49
44
|
vi.clearAllMocks();
|
|
50
45
|
window.braintree = {
|
|
@@ -76,7 +71,6 @@ describe("getConnectComponent: returns ConnectComponent", () => {
|
|
|
76
71
|
env: "mock-env",
|
|
77
72
|
},
|
|
78
73
|
});
|
|
79
|
-
expect(sendCountMetric).toBeCalledTimes(2);
|
|
80
74
|
});
|
|
81
75
|
|
|
82
76
|
test("uses sdk token if present", async () => {
|
|
@@ -99,7 +93,6 @@ describe("getConnectComponent: returns ConnectComponent", () => {
|
|
|
99
93
|
env: "mock-env",
|
|
100
94
|
},
|
|
101
95
|
});
|
|
102
|
-
expect(sendCountMetric).toBeCalledTimes(2);
|
|
103
96
|
});
|
|
104
97
|
|
|
105
98
|
test("loadAxo failure is handled", async () => {
|
|
@@ -109,7 +102,6 @@ describe("getConnectComponent: returns ConnectComponent", () => {
|
|
|
109
102
|
await expect(() => getConnectComponent(mockProps)).rejects.toThrow(
|
|
110
103
|
errorMessage
|
|
111
104
|
);
|
|
112
|
-
expect(sendCountMetric).toHaveBeenCalledTimes(2);
|
|
113
105
|
});
|
|
114
106
|
|
|
115
107
|
test("connect create failure is handled", async () => {
|
|
@@ -119,7 +111,6 @@ describe("getConnectComponent: returns ConnectComponent", () => {
|
|
|
119
111
|
await expect(() => getConnectComponent(mockProps)).rejects.toThrow(
|
|
120
112
|
expectedError
|
|
121
113
|
);
|
|
122
|
-
expect(sendCountMetric).toBeCalledTimes(2);
|
|
123
114
|
});
|
|
124
115
|
|
|
125
116
|
test("minified is set according to debug value", async () => {
|
package/src/constants/api.js
CHANGED
|
@@ -15,8 +15,7 @@ export const FPTI_TRANSITION = {
|
|
|
15
15
|
SHOPPER_INSIGHTS_API_ERROR: "sdk_shopper_insights_recommended_error",
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
export const SHOPPER_INSIGHTS_METRIC_NAME =
|
|
19
|
-
"pp.app.paypal_sdk.api.shopper_insights.count";
|
|
18
|
+
export const SHOPPER_INSIGHTS_METRIC_NAME = "shopper_insights.count";
|
|
20
19
|
|
|
21
20
|
export type MerchantPayloadData = {|
|
|
22
21
|
email?: string,
|
|
@@ -17,38 +17,40 @@ import type {
|
|
|
17
17
|
|
|
18
18
|
export const getHostedButtonsComponent = (): HostedButtonsComponent => {
|
|
19
19
|
function HostedButtons({
|
|
20
|
+
enableDPoP = false,
|
|
20
21
|
hostedButtonId,
|
|
21
22
|
}: HostedButtonsComponentProps): HostedButtonsInstance {
|
|
22
23
|
const Buttons = getButtonsComponent();
|
|
23
|
-
const render = (selector) => {
|
|
24
|
+
const render = async (selector) => {
|
|
24
25
|
const merchantId = getMerchantID();
|
|
26
|
+
const { html, htmlScript, style } = await getHostedButtonDetails({
|
|
27
|
+
hostedButtonId,
|
|
28
|
+
});
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
selector,
|
|
33
|
-
});
|
|
30
|
+
const { onInit, onClick } = renderForm({
|
|
31
|
+
hostedButtonId,
|
|
32
|
+
html,
|
|
33
|
+
htmlScript,
|
|
34
|
+
selector,
|
|
35
|
+
});
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
);
|
|
37
|
+
// $FlowFixMe
|
|
38
|
+
Buttons({
|
|
39
|
+
hostedButtonId,
|
|
40
|
+
style,
|
|
41
|
+
onInit,
|
|
42
|
+
onClick,
|
|
43
|
+
createOrder: buildHostedButtonCreateOrder({
|
|
44
|
+
enableDPoP,
|
|
45
|
+
hostedButtonId,
|
|
46
|
+
merchantId,
|
|
47
|
+
}),
|
|
48
|
+
onApprove: buildHostedButtonOnApprove({
|
|
49
|
+
enableDPoP,
|
|
50
|
+
hostedButtonId,
|
|
51
|
+
merchantId,
|
|
52
|
+
}),
|
|
53
|
+
}).render(selector);
|
|
52
54
|
};
|
|
53
55
|
return {
|
|
54
56
|
render,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* @flow */
|
|
2
|
+
/* eslint-disable no-restricted-globals, promise/no-native */
|
|
2
3
|
|
|
3
4
|
import { describe, test, expect, vi } from "vitest";
|
|
4
5
|
import { request } from "@krakenjs/belter/src";
|
|
5
|
-
import { ZalgoPromise } from "@krakenjs/zalgo-promise";
|
|
6
6
|
|
|
7
7
|
import { getButtonsComponent } from "../zoid/buttons";
|
|
8
8
|
|
|
@@ -61,16 +61,17 @@ const getHostedButtonDetailsResponse = {
|
|
|
61
61
|
};
|
|
62
62
|
|
|
63
63
|
describe("HostedButtons", () => {
|
|
64
|
-
test("paypal.Buttons calls getHostedButtonDetails and invokes v5 of the SDK", () => {
|
|
64
|
+
test("paypal.Buttons calls getHostedButtonDetails and invokes v5 of the SDK", async () => {
|
|
65
65
|
const Buttons = vi.fn(() => ({ render: vi.fn() }));
|
|
66
66
|
// $FlowIssue
|
|
67
67
|
getButtonsComponent.mockImplementationOnce(() => Buttons);
|
|
68
68
|
const HostedButtons = getHostedButtonsComponent();
|
|
69
69
|
// $FlowIssue
|
|
70
70
|
request.mockImplementationOnce(() =>
|
|
71
|
-
|
|
71
|
+
// eslint-disable-next-line compat/compat
|
|
72
|
+
Promise.resolve(getHostedButtonDetailsResponse)
|
|
72
73
|
);
|
|
73
|
-
HostedButtons({
|
|
74
|
+
await HostedButtons({
|
|
74
75
|
hostedButtonId: "B1234567890",
|
|
75
76
|
}).render("#example");
|
|
76
77
|
expect(Buttons).toHaveBeenCalledWith(
|
|
@@ -81,3 +82,5 @@ describe("HostedButtons", () => {
|
|
|
81
82
|
expect.assertions(1);
|
|
82
83
|
});
|
|
83
84
|
});
|
|
85
|
+
|
|
86
|
+
/* eslint-enable no-restricted-globals, promise/no-native */
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/* @flow */
|
|
2
|
-
|
|
3
|
-
import { ZalgoPromise } from "@krakenjs/zalgo-promise/src";
|
|
2
|
+
/* eslint-disable no-restricted-globals, promise/no-native */
|
|
4
3
|
|
|
5
4
|
export type HostedButtonsComponentProps = {|
|
|
6
5
|
hostedButtonId: string,
|
|
7
6
|
|};
|
|
8
7
|
|
|
9
8
|
export type GetCallbackProps = {|
|
|
9
|
+
enableDPoP?: boolean,
|
|
10
10
|
hostedButtonId: string,
|
|
11
11
|
merchantId?: string,
|
|
12
12
|
|};
|
|
13
13
|
|
|
14
14
|
export type HostedButtonsInstance = {|
|
|
15
|
-
render: (string | HTMLElement) => void
|
|
15
|
+
render: (string | HTMLElement) => Promise<void>,
|
|
16
16
|
|};
|
|
17
17
|
|
|
18
18
|
export type HostedButtonDetailsParams =
|
|
19
|
-
(HostedButtonsComponentProps) =>
|
|
19
|
+
(HostedButtonsComponentProps) => Promise<{|
|
|
20
20
|
html: string,
|
|
21
21
|
htmlScript: string,
|
|
22
22
|
style: {|
|
|
@@ -34,14 +34,17 @@ export type ButtonVariables = $ReadOnlyArray<{|
|
|
|
34
34
|
|
|
35
35
|
export type CreateOrder = (data: {|
|
|
36
36
|
paymentSource: string,
|
|
37
|
-
|}) =>
|
|
37
|
+
|}) => Promise<string | void>;
|
|
38
38
|
|
|
39
39
|
export type OnApprove = (data: {|
|
|
40
40
|
orderID: string,
|
|
41
41
|
paymentSource: string,
|
|
42
|
-
|}) =>
|
|
42
|
+
|}) => Promise<mixed>;
|
|
43
43
|
|
|
44
|
-
export type CreateAccessToken = (
|
|
44
|
+
export type CreateAccessToken = ({|
|
|
45
|
+
clientId: string,
|
|
46
|
+
enableDPoP?: boolean,
|
|
47
|
+
|}) => Promise<{| accessToken: string, nonce: string |}>;
|
|
45
48
|
|
|
46
49
|
export type HostedButtonsComponent =
|
|
47
50
|
(HostedButtonsComponentProps) => HostedButtonsInstance;
|
|
@@ -55,3 +58,22 @@ export type RenderForm = ({|
|
|
|
55
58
|
onInit: (data: mixed, actions: mixed) => void,
|
|
56
59
|
onClick: (data: mixed, actions: mixed) => void,
|
|
57
60
|
|};
|
|
61
|
+
|
|
62
|
+
type Request = {|
|
|
63
|
+
url: string,
|
|
64
|
+
headers: {|
|
|
65
|
+
[key: string]: string,
|
|
66
|
+
Authorization?: string,
|
|
67
|
+
|},
|
|
68
|
+
method: string,
|
|
69
|
+
body: string,
|
|
70
|
+
|};
|
|
71
|
+
|
|
72
|
+
type Response = {|
|
|
73
|
+
status: number,
|
|
74
|
+
headers: { [string]: string },
|
|
75
|
+
body: Object,
|
|
76
|
+
|};
|
|
77
|
+
|
|
78
|
+
export type RequestWithDPoP = (Request) => Response;
|
|
79
|
+
/* eslint-enable no-restricted-globals, promise/no-native */
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { request, memoize } from "@krakenjs/belter/src";
|
|
4
4
|
import {
|
|
5
|
+
buildDPoPHeaders,
|
|
5
6
|
getSDKHost,
|
|
6
7
|
getClientID,
|
|
7
8
|
getMerchantID as getSDKMerchantID,
|
|
@@ -15,6 +16,7 @@ import type {
|
|
|
15
16
|
HostedButtonDetailsParams,
|
|
16
17
|
OnApprove,
|
|
17
18
|
RenderForm,
|
|
19
|
+
RequestWithDPoP,
|
|
18
20
|
} from "./types";
|
|
19
21
|
|
|
20
22
|
const entryPoint = "SDK";
|
|
@@ -38,9 +40,43 @@ export const getMerchantID = (): string | void => {
|
|
|
38
40
|
return merchantIds[0];
|
|
39
41
|
};
|
|
40
42
|
|
|
43
|
+
export const requestWithDPoP: RequestWithDPoP = async ({
|
|
44
|
+
url,
|
|
45
|
+
headers,
|
|
46
|
+
method,
|
|
47
|
+
body,
|
|
48
|
+
}) => {
|
|
49
|
+
let accessToken, nonce;
|
|
50
|
+
if (!headers.Authorization?.match(/Basic/)) {
|
|
51
|
+
// eslint-disable-next-line no-use-before-define
|
|
52
|
+
const response = await createAccessToken({
|
|
53
|
+
clientId: getClientID(),
|
|
54
|
+
});
|
|
55
|
+
accessToken = response.accessToken;
|
|
56
|
+
nonce = response.nonce;
|
|
57
|
+
}
|
|
58
|
+
const DPoPHeaders = await buildDPoPHeaders({
|
|
59
|
+
method,
|
|
60
|
+
uri: url,
|
|
61
|
+
accessToken,
|
|
62
|
+
nonce,
|
|
63
|
+
});
|
|
64
|
+
// $FlowIssue request() returns ZalgoPromise
|
|
65
|
+
return request({
|
|
66
|
+
url,
|
|
67
|
+
method,
|
|
68
|
+
body,
|
|
69
|
+
headers: {
|
|
70
|
+
...headers,
|
|
71
|
+
...DPoPHeaders,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
|
|
41
76
|
export const createAccessToken: CreateAccessToken = memoize<CreateAccessToken>(
|
|
42
|
-
(clientId) => {
|
|
43
|
-
|
|
77
|
+
async ({ clientId, enableDPoP }) => {
|
|
78
|
+
const requestFn = enableDPoP ? requestWithDPoP : request;
|
|
79
|
+
const response = await requestFn({
|
|
44
80
|
url: `${apiUrl}/v1/oauth2/token`,
|
|
45
81
|
method: "POST",
|
|
46
82
|
body: "grant_type=client_credentials",
|
|
@@ -48,32 +84,40 @@ export const createAccessToken: CreateAccessToken = memoize<CreateAccessToken>(
|
|
|
48
84
|
Authorization: `Basic ${btoa(clientId)}`,
|
|
49
85
|
"Content-Type": "application/json",
|
|
50
86
|
},
|
|
51
|
-
})
|
|
87
|
+
});
|
|
88
|
+
// $FlowIssue request returns ZalgoPromise
|
|
89
|
+
const { access_token: accessToken, nonce } = response.body;
|
|
90
|
+
return {
|
|
91
|
+
accessToken,
|
|
92
|
+
nonce,
|
|
93
|
+
};
|
|
52
94
|
}
|
|
53
95
|
);
|
|
54
96
|
|
|
55
97
|
const getButtonVariable = (variables: ButtonVariables, key: string): string =>
|
|
56
98
|
variables?.find((variable) => variable.name === key)?.value ?? "";
|
|
57
99
|
|
|
58
|
-
export const getHostedButtonDetails: HostedButtonDetailsParams = ({
|
|
100
|
+
export const getHostedButtonDetails: HostedButtonDetailsParams = async ({
|
|
59
101
|
hostedButtonId,
|
|
60
102
|
}) => {
|
|
61
|
-
|
|
103
|
+
const response = await request({
|
|
62
104
|
url: `${baseUrl}/ncp/api/form-fields/${hostedButtonId}`,
|
|
63
105
|
headers: getHeaders(),
|
|
64
|
-
}).then(({ body }) => {
|
|
65
|
-
const variables = body.button_details.link_variables;
|
|
66
|
-
return {
|
|
67
|
-
style: {
|
|
68
|
-
layout: getButtonVariable(variables, "layout"),
|
|
69
|
-
shape: getButtonVariable(variables, "shape"),
|
|
70
|
-
color: getButtonVariable(variables, "color"),
|
|
71
|
-
label: getButtonVariable(variables, "button_text"),
|
|
72
|
-
},
|
|
73
|
-
html: body.html,
|
|
74
|
-
htmlScript: body.html_script,
|
|
75
|
-
};
|
|
76
106
|
});
|
|
107
|
+
|
|
108
|
+
// $FlowIssue request returns ZalgoPromise
|
|
109
|
+
const { body } = response;
|
|
110
|
+
const variables = body.button_details.link_variables;
|
|
111
|
+
return {
|
|
112
|
+
style: {
|
|
113
|
+
layout: getButtonVariable(variables, "layout"),
|
|
114
|
+
shape: getButtonVariable(variables, "shape"),
|
|
115
|
+
color: getButtonVariable(variables, "color"),
|
|
116
|
+
label: getButtonVariable(variables, "button_text"),
|
|
117
|
+
},
|
|
118
|
+
html: body.html,
|
|
119
|
+
htmlScript: body.html_script,
|
|
120
|
+
};
|
|
77
121
|
};
|
|
78
122
|
|
|
79
123
|
/**
|
|
@@ -106,15 +150,21 @@ export const renderForm: RenderForm = ({
|
|
|
106
150
|
};
|
|
107
151
|
|
|
108
152
|
export const buildHostedButtonCreateOrder = ({
|
|
153
|
+
enableDPoP,
|
|
109
154
|
hostedButtonId,
|
|
110
155
|
merchantId,
|
|
111
156
|
}: GetCallbackProps): CreateOrder => {
|
|
112
|
-
return (data) => {
|
|
157
|
+
return async (data) => {
|
|
113
158
|
const userInputs =
|
|
114
159
|
window[`__pp_form_fields_${hostedButtonId}`]?.getUserInputs?.() || {};
|
|
115
160
|
const onError = window[`__pp_form_fields_${hostedButtonId}`]?.onError;
|
|
116
|
-
|
|
117
|
-
|
|
161
|
+
const { accessToken } = await createAccessToken({
|
|
162
|
+
clientId: getClientID(),
|
|
163
|
+
enableDPoP,
|
|
164
|
+
});
|
|
165
|
+
try {
|
|
166
|
+
const requestFn = enableDPoP ? requestWithDPoP : request;
|
|
167
|
+
const response = await requestFn({
|
|
118
168
|
url: `${apiUrl}/v1/checkout/links/${hostedButtonId}/create-context`,
|
|
119
169
|
headers: getHeaders(accessToken),
|
|
120
170
|
method: "POST",
|
|
@@ -124,29 +174,36 @@ export const buildHostedButtonCreateOrder = ({
|
|
|
124
174
|
merchant_id: merchantId,
|
|
125
175
|
...userInputs,
|
|
126
176
|
}),
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
177
|
+
});
|
|
178
|
+
// $FlowIssue request returns ZalgoPromise
|
|
179
|
+
const { body } = response;
|
|
180
|
+
return body.context_id || onError(body.name);
|
|
181
|
+
} catch (e) {
|
|
182
|
+
return onError("REQUEST_FAILED");
|
|
183
|
+
}
|
|
131
184
|
};
|
|
132
185
|
};
|
|
133
186
|
|
|
134
187
|
export const buildHostedButtonOnApprove = ({
|
|
188
|
+
enableDPoP,
|
|
135
189
|
hostedButtonId,
|
|
136
190
|
merchantId,
|
|
137
191
|
}: GetCallbackProps): OnApprove => {
|
|
138
|
-
return (data) => {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
192
|
+
return async (data) => {
|
|
193
|
+
const { accessToken } = await createAccessToken({
|
|
194
|
+
clientId: getClientID(),
|
|
195
|
+
enableDPoP,
|
|
196
|
+
});
|
|
197
|
+
const requestFn = enableDPoP ? requestWithDPoP : request;
|
|
198
|
+
return requestFn({
|
|
199
|
+
url: `${apiUrl}/v1/checkout/links/${hostedButtonId}/pay`,
|
|
200
|
+
headers: getHeaders(accessToken),
|
|
201
|
+
method: "POST",
|
|
202
|
+
body: JSON.stringify({
|
|
203
|
+
entry_point: entryPoint,
|
|
204
|
+
merchant_id: merchantId,
|
|
205
|
+
context_id: data.orderID,
|
|
206
|
+
}),
|
|
150
207
|
});
|
|
151
208
|
};
|
|
152
209
|
};
|