@paypal/checkout-components 5.0.294-alpha.0 → 5.0.294
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/__sdk__.js +0 -4
- package/package.json +1 -1
- package/src/api/shopper-insights/component.js +1 -2
- package/src/api/shopper-insights/component.test.js +26 -1
- package/src/connect/component.jsx +2 -2
- package/src/ui/buttons/props.js +0 -1
- package/src/zoid/buttons/component.jsx +2 -12
- package/src/zoid/buttons/prerender.jsx +1 -7
- package/src/zoid/checkout/component.jsx +0 -5
- package/src/hosted-buttons/index.js +0 -62
- package/src/hosted-buttons/index.test.js +0 -84
- package/src/hosted-buttons/types.js +0 -57
- package/src/hosted-buttons/utils.js +0 -157
- package/src/hosted-buttons/utils.test.js +0 -121
- package/src/interface/hosted-buttons.js +0 -29
package/__sdk__.js
CHANGED
package/package.json
CHANGED
|
@@ -125,10 +125,9 @@ export function getShopperInsightsComponent(): ShopperInsightsComponent {
|
|
|
125
125
|
[FPTI_KEY.EVENT_NAME]: FPTI_TRANSITION.SHOPPER_INSIGHTS_API_INIT,
|
|
126
126
|
});
|
|
127
127
|
|
|
128
|
-
validateMerchantConfig({ sdkToken, pageType, userIDToken, clientToken });
|
|
129
|
-
|
|
130
128
|
const shopperInsights = {
|
|
131
129
|
getRecommendedPaymentMethods: (merchantPayload) => {
|
|
130
|
+
validateMerchantConfig({ sdkToken, pageType, userIDToken, clientToken });
|
|
132
131
|
validateMerchantPayload(merchantPayload);
|
|
133
132
|
|
|
134
133
|
const requestPayload =
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/* @flow */
|
|
2
2
|
import { ZalgoPromise } from "@krakenjs/zalgo-promise/src";
|
|
3
|
-
import { getEnv, getBuyerCountry } from "@paypal/sdk-client/src";
|
|
3
|
+
import { getEnv, getBuyerCountry, getSDKToken } from "@paypal/sdk-client/src";
|
|
4
4
|
import { vi, describe, expect } from "vitest";
|
|
5
5
|
import { request } from "@krakenjs/belter/src";
|
|
6
6
|
|
|
7
|
+
import { ValidationError } from "../../lib";
|
|
8
|
+
|
|
7
9
|
import { getShopperInsightsComponent } from "./component";
|
|
8
10
|
|
|
9
11
|
vi.mock("@paypal/sdk-client/src", () => {
|
|
@@ -348,4 +350,27 @@ describe("shopper insights component - getRecommendedPaymentMethods()", () => {
|
|
|
348
350
|
})
|
|
349
351
|
);
|
|
350
352
|
});
|
|
353
|
+
|
|
354
|
+
test("ensure sdk-token is passed when using the getRecommendedPaymentMethods", async () => {
|
|
355
|
+
// $FlowFixMe
|
|
356
|
+
getSDKToken.mockImplementationOnce(() => undefined);
|
|
357
|
+
// $FlowFixMe
|
|
358
|
+
const shopperInsightsComponent = getShopperInsightsComponent();
|
|
359
|
+
const error = new ValidationError(
|
|
360
|
+
`script data attribute sdk-client-token is required but was not passed`
|
|
361
|
+
);
|
|
362
|
+
await expect(
|
|
363
|
+
async () =>
|
|
364
|
+
await shopperInsightsComponent.getRecommendedPaymentMethods({
|
|
365
|
+
customer: {
|
|
366
|
+
email: "email@test.com",
|
|
367
|
+
phone: {
|
|
368
|
+
countryCode: "1",
|
|
369
|
+
nationalNumber: "2345678905",
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
})
|
|
373
|
+
).rejects.toThrowError(error);
|
|
374
|
+
expect.assertions(1);
|
|
375
|
+
});
|
|
351
376
|
});
|
|
@@ -51,7 +51,7 @@ export function getSdkVersion(version: string | null): string {
|
|
|
51
51
|
// $FlowFixMe
|
|
52
52
|
export const getConnectComponent = async (merchantProps = {}) => {
|
|
53
53
|
const cmid = getClientMetadataID() || getSessionID();
|
|
54
|
-
const
|
|
54
|
+
const clientId = getClientID();
|
|
55
55
|
const userIdToken = getUserIDToken();
|
|
56
56
|
const env = getEnv();
|
|
57
57
|
const cspNonce = getCSPNonce();
|
|
@@ -108,7 +108,7 @@ export const getConnectComponent = async (merchantProps = {}) => {
|
|
|
108
108
|
platformOptions: {
|
|
109
109
|
platform: "PPCP",
|
|
110
110
|
userIdToken,
|
|
111
|
-
|
|
111
|
+
clientId,
|
|
112
112
|
fraudnet: collect,
|
|
113
113
|
clientMetadataId: cmid,
|
|
114
114
|
env,
|
package/src/ui/buttons/props.js
CHANGED
|
@@ -521,7 +521,6 @@ export type ButtonProps = {|
|
|
|
521
521
|
renderedButtons: $ReadOnlyArray<$Values<typeof FUNDING>>,
|
|
522
522
|
createVaultSetupToken: CreateVaultSetupToken,
|
|
523
523
|
displayOnly?: $ReadOnlyArray<$Values<typeof DISPLAY_ONLY_VALUES>>,
|
|
524
|
-
hostedButtonId?: string,
|
|
525
524
|
|};
|
|
526
525
|
|
|
527
526
|
// eslint-disable-next-line flowtype/require-exact-type
|
|
@@ -158,13 +158,8 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
|
|
|
158
158
|
<PrerenderedButtons
|
|
159
159
|
nonce={props.nonce}
|
|
160
160
|
props={props}
|
|
161
|
-
onRenderCheckout={({ win, fundingSource, card
|
|
162
|
-
state.prerenderDetails = {
|
|
163
|
-
win,
|
|
164
|
-
fundingSource,
|
|
165
|
-
card,
|
|
166
|
-
hostedButtonId,
|
|
167
|
-
};
|
|
161
|
+
onRenderCheckout={({ win, fundingSource, card }) => {
|
|
162
|
+
state.prerenderDetails = { win, fundingSource, card };
|
|
168
163
|
}}
|
|
169
164
|
/>
|
|
170
165
|
).render(dom({ doc }));
|
|
@@ -854,11 +849,6 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
|
|
|
854
849
|
value: getExperimentation,
|
|
855
850
|
},
|
|
856
851
|
|
|
857
|
-
hostedButtonId: {
|
|
858
|
-
type: "string",
|
|
859
|
-
required: false,
|
|
860
|
-
},
|
|
861
|
-
|
|
862
852
|
displayOnly: {
|
|
863
853
|
type: "array",
|
|
864
854
|
queryParam: true,
|
|
@@ -27,7 +27,6 @@ type PrerenderedButtonsProps = {|
|
|
|
27
27
|
win?: CrossDomainWindowType,
|
|
28
28
|
fundingSource: $Values<typeof FUNDING>,
|
|
29
29
|
card: ?$Values<typeof CARD>,
|
|
30
|
-
hostedButtonId?: string,
|
|
31
30
|
|}) => void,
|
|
32
31
|
|};
|
|
33
32
|
|
|
@@ -78,12 +77,7 @@ export function PrerenderedButtons({
|
|
|
78
77
|
|
|
79
78
|
writeElementToWindow(win, spinner);
|
|
80
79
|
|
|
81
|
-
onRenderCheckout({
|
|
82
|
-
win,
|
|
83
|
-
fundingSource,
|
|
84
|
-
card,
|
|
85
|
-
hostedButtonId: props.hostedButtonId,
|
|
86
|
-
});
|
|
80
|
+
onRenderCheckout({ win, fundingSource, card });
|
|
87
81
|
} else {
|
|
88
82
|
onRenderCheckout({ fundingSource, card });
|
|
89
83
|
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
|
|
3
|
-
import { getMerchantID } from "@paypal/sdk-client/src";
|
|
4
|
-
|
|
5
|
-
import { getButtonsComponent } from "../zoid/buttons";
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
buildHostedButtonCreateOrder,
|
|
9
|
-
buildHostedButtonOnApprove,
|
|
10
|
-
getHostedButtonDetails,
|
|
11
|
-
renderForm,
|
|
12
|
-
} from "./utils";
|
|
13
|
-
import type {
|
|
14
|
-
HostedButtonsComponent,
|
|
15
|
-
HostedButtonsComponentProps,
|
|
16
|
-
HostedButtonsInstance,
|
|
17
|
-
} from "./types";
|
|
18
|
-
|
|
19
|
-
export const getHostedButtonsComponent = (): HostedButtonsComponent => {
|
|
20
|
-
function HostedButtons({
|
|
21
|
-
hostedButtonId,
|
|
22
|
-
}: HostedButtonsComponentProps): HostedButtonsInstance {
|
|
23
|
-
const Buttons = getButtonsComponent();
|
|
24
|
-
const render = (selector) => {
|
|
25
|
-
// The SDK supports mutiple merchant IDs, but hosted buttons only
|
|
26
|
-
// have one merchant id as a query parameter to the SDK script.
|
|
27
|
-
// https://github.com/paypal/paypal-sdk-client/blob/c58e35f8f7adbab76523eb25b9c10543449d2d29/src/script.js#L144
|
|
28
|
-
const merchantId = getMerchantID()[0];
|
|
29
|
-
|
|
30
|
-
getHostedButtonDetails({ hostedButtonId }).then(
|
|
31
|
-
({ html, htmlScript, style }) => {
|
|
32
|
-
const { onInit, onClick } = renderForm({
|
|
33
|
-
hostedButtonId,
|
|
34
|
-
html,
|
|
35
|
-
htmlScript,
|
|
36
|
-
selector,
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
// $FlowFixMe
|
|
40
|
-
Buttons({
|
|
41
|
-
hostedButtonId,
|
|
42
|
-
style,
|
|
43
|
-
onInit,
|
|
44
|
-
onClick,
|
|
45
|
-
createOrder: buildHostedButtonCreateOrder({
|
|
46
|
-
hostedButtonId,
|
|
47
|
-
merchantId,
|
|
48
|
-
}),
|
|
49
|
-
onApprove: buildHostedButtonOnApprove({
|
|
50
|
-
hostedButtonId,
|
|
51
|
-
merchantId,
|
|
52
|
-
}),
|
|
53
|
-
}).render(selector);
|
|
54
|
-
}
|
|
55
|
-
);
|
|
56
|
-
};
|
|
57
|
-
return {
|
|
58
|
-
render,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
return HostedButtons;
|
|
62
|
-
};
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
|
|
3
|
-
import { describe, test, expect, vi } from "vitest";
|
|
4
|
-
import { request } from "@krakenjs/belter/src";
|
|
5
|
-
import { ZalgoPromise } from "@krakenjs/zalgo-promise";
|
|
6
|
-
|
|
7
|
-
import { getButtonsComponent } from "../zoid/buttons";
|
|
8
|
-
|
|
9
|
-
import { getHostedButtonsComponent } from ".";
|
|
10
|
-
|
|
11
|
-
vi.mock("@krakenjs/belter/src", async () => {
|
|
12
|
-
return {
|
|
13
|
-
...(await vi.importActual("@krakenjs/belter/src")),
|
|
14
|
-
request: vi.fn(),
|
|
15
|
-
};
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
vi.mock("@paypal/sdk-client/src", async () => {
|
|
19
|
-
return {
|
|
20
|
-
...(await vi.importActual("@paypal/sdk-client/src")),
|
|
21
|
-
getSDKHost: () => "example.com",
|
|
22
|
-
getClientID: () => "client_id_123",
|
|
23
|
-
getMerchantID: () => ["merchant_id_123"],
|
|
24
|
-
};
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
vi.mock("../zoid/buttons", async () => {
|
|
28
|
-
return {
|
|
29
|
-
...(await vi.importActual("../zoid/buttons")),
|
|
30
|
-
getButtonsComponent: vi.fn(),
|
|
31
|
-
};
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const getHostedButtonDetailsResponse = {
|
|
35
|
-
body: {
|
|
36
|
-
button_details: {
|
|
37
|
-
link_variables: [
|
|
38
|
-
{
|
|
39
|
-
name: "shape",
|
|
40
|
-
value: "rect",
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
name: "layout",
|
|
44
|
-
value: "vertical",
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
name: "color",
|
|
48
|
-
value: "gold",
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
name: "button_text",
|
|
52
|
-
value: "paypal",
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: "button_type",
|
|
56
|
-
value: "FIXED_PRICE",
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
describe("HostedButtons", () => {
|
|
64
|
-
test("paypal.Buttons calls getHostedButtonDetails and invokes v5 of the SDK", () => {
|
|
65
|
-
const Buttons = vi.fn(() => ({ render: vi.fn() }));
|
|
66
|
-
// $FlowIssue
|
|
67
|
-
getButtonsComponent.mockImplementationOnce(() => Buttons);
|
|
68
|
-
const HostedButtons = getHostedButtonsComponent();
|
|
69
|
-
// $FlowIssue
|
|
70
|
-
request.mockImplementationOnce(() =>
|
|
71
|
-
ZalgoPromise.resolve(getHostedButtonDetailsResponse)
|
|
72
|
-
);
|
|
73
|
-
HostedButtons({
|
|
74
|
-
hostedButtonId: "B1234567890",
|
|
75
|
-
}).render("#example");
|
|
76
|
-
expect(Buttons).toHaveBeenCalledWith(
|
|
77
|
-
expect.objectContaining({
|
|
78
|
-
hostedButtonId: "B1234567890",
|
|
79
|
-
hostedButtonType: "NO_CODE_FIXED_PRICE",
|
|
80
|
-
})
|
|
81
|
-
);
|
|
82
|
-
expect.assertions(1);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
|
|
3
|
-
import { ZalgoPromise } from "@krakenjs/zalgo-promise/src";
|
|
4
|
-
|
|
5
|
-
export type HostedButtonsComponentProps = {|
|
|
6
|
-
hostedButtonId: string,
|
|
7
|
-
|};
|
|
8
|
-
|
|
9
|
-
export type GetCallbackProps = {|
|
|
10
|
-
hostedButtonId: string,
|
|
11
|
-
merchantId: string,
|
|
12
|
-
|};
|
|
13
|
-
|
|
14
|
-
export type HostedButtonsInstance = {|
|
|
15
|
-
render: (string | HTMLElement) => void,
|
|
16
|
-
|};
|
|
17
|
-
|
|
18
|
-
export type HostedButtonDetailsParams =
|
|
19
|
-
(HostedButtonsComponentProps) => ZalgoPromise<{|
|
|
20
|
-
html: string,
|
|
21
|
-
htmlScript: string,
|
|
22
|
-
style: {|
|
|
23
|
-
layout: string,
|
|
24
|
-
shape: string,
|
|
25
|
-
color: string,
|
|
26
|
-
label: string,
|
|
27
|
-
|},
|
|
28
|
-
|}>;
|
|
29
|
-
|
|
30
|
-
export type ButtonVariables = $ReadOnlyArray<{|
|
|
31
|
-
name: string,
|
|
32
|
-
value: string,
|
|
33
|
-
|}>;
|
|
34
|
-
|
|
35
|
-
export type CreateOrder = (data: {|
|
|
36
|
-
paymentSource: string,
|
|
37
|
-
|}) => ZalgoPromise<string>;
|
|
38
|
-
|
|
39
|
-
export type OnApprove = (data: {|
|
|
40
|
-
orderID: string,
|
|
41
|
-
paymentSource: string,
|
|
42
|
-
|}) => ZalgoPromise<mixed>;
|
|
43
|
-
|
|
44
|
-
export type CreateAccessToken = (clientID: string) => ZalgoPromise<string>;
|
|
45
|
-
|
|
46
|
-
export type HostedButtonsComponent =
|
|
47
|
-
(HostedButtonsComponentProps) => HostedButtonsInstance;
|
|
48
|
-
|
|
49
|
-
export type RenderForm = ({|
|
|
50
|
-
hostedButtonId: string,
|
|
51
|
-
html: string,
|
|
52
|
-
htmlScript: string,
|
|
53
|
-
selector: string | HTMLElement,
|
|
54
|
-
|}) => {|
|
|
55
|
-
onInit: (data: mixed, actions: mixed) => void,
|
|
56
|
-
onClick: (data: mixed, actions: mixed) => void,
|
|
57
|
-
|};
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
|
|
3
|
-
import { request, memoize, popup } from "@krakenjs/belter/src";
|
|
4
|
-
import { getSDKHost, getClientID } from "@paypal/sdk-client/src";
|
|
5
|
-
|
|
6
|
-
import { DEFAULT_POPUP_SIZE } from "../zoid/checkout";
|
|
7
|
-
|
|
8
|
-
import type {
|
|
9
|
-
ButtonVariables,
|
|
10
|
-
CreateAccessToken,
|
|
11
|
-
CreateOrder,
|
|
12
|
-
GetCallbackProps,
|
|
13
|
-
HostedButtonDetailsParams,
|
|
14
|
-
OnApprove,
|
|
15
|
-
RenderForm,
|
|
16
|
-
} from "./types";
|
|
17
|
-
|
|
18
|
-
const entryPoint = "SDK";
|
|
19
|
-
const baseUrl = `https://${getSDKHost()}`;
|
|
20
|
-
const apiUrl = baseUrl.replace("www", "api");
|
|
21
|
-
|
|
22
|
-
const getHeaders = (accessToken?: string) => ({
|
|
23
|
-
...(accessToken && { Authorization: `Bearer ${accessToken}` }),
|
|
24
|
-
"Content-Type": "application/json",
|
|
25
|
-
"PayPal-Entry-Point": entryPoint,
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
export const createAccessToken: CreateAccessToken = memoize<CreateAccessToken>(
|
|
29
|
-
(clientId) => {
|
|
30
|
-
return request({
|
|
31
|
-
url: `${apiUrl}/v1/oauth2/token`,
|
|
32
|
-
method: "POST",
|
|
33
|
-
body: "grant_type=client_credentials",
|
|
34
|
-
headers: {
|
|
35
|
-
Authorization: `Basic ${btoa(clientId)}`,
|
|
36
|
-
"Content-Type": "application/json",
|
|
37
|
-
},
|
|
38
|
-
}).then((response) => response.body.access_token);
|
|
39
|
-
}
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
const getButtonVariable = (variables: ButtonVariables, key: string): string =>
|
|
43
|
-
variables?.find((variable) => variable.name === key)?.value ?? "";
|
|
44
|
-
|
|
45
|
-
const getFundingSource = (paymentSource) => {
|
|
46
|
-
if (paymentSource === "credit") {
|
|
47
|
-
return `CARD`;
|
|
48
|
-
}
|
|
49
|
-
return paymentSource.toUpperCase();
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export const getHostedButtonDetails: HostedButtonDetailsParams = ({
|
|
53
|
-
hostedButtonId,
|
|
54
|
-
}) => {
|
|
55
|
-
return request({
|
|
56
|
-
url: `${baseUrl}/ncp/api/form-fields/${hostedButtonId}`,
|
|
57
|
-
headers: getHeaders(),
|
|
58
|
-
}).then(({ body }) => {
|
|
59
|
-
const variables = body.button_details.link_variables;
|
|
60
|
-
return {
|
|
61
|
-
style: {
|
|
62
|
-
layout: getButtonVariable(variables, "layout"),
|
|
63
|
-
shape: getButtonVariable(variables, "shape"),
|
|
64
|
-
color: getButtonVariable(variables, "color"),
|
|
65
|
-
label: getButtonVariable(variables, "button_text"),
|
|
66
|
-
},
|
|
67
|
-
html: body.html,
|
|
68
|
-
htmlScript: body.html_script,
|
|
69
|
-
};
|
|
70
|
-
});
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Attaches form fields (html) to the given selector, and
|
|
75
|
-
* initializes window.__pp_form_fields (htmlScript).
|
|
76
|
-
*/
|
|
77
|
-
export const renderForm: RenderForm = ({
|
|
78
|
-
hostedButtonId,
|
|
79
|
-
html,
|
|
80
|
-
htmlScript,
|
|
81
|
-
selector,
|
|
82
|
-
}) => {
|
|
83
|
-
const elm =
|
|
84
|
-
typeof selector === "string" ? document.querySelector(selector) : selector;
|
|
85
|
-
if (elm) {
|
|
86
|
-
elm.innerHTML = html + htmlScript;
|
|
87
|
-
const newScriptEl = document.createElement("script");
|
|
88
|
-
const oldScriptEl = elm.querySelector("script");
|
|
89
|
-
newScriptEl.innerHTML = oldScriptEl?.innerHTML ?? "";
|
|
90
|
-
oldScriptEl?.parentNode?.replaceChild(newScriptEl, oldScriptEl);
|
|
91
|
-
}
|
|
92
|
-
return {
|
|
93
|
-
// disable the button, listen for input changes,
|
|
94
|
-
// and enable the button when the form is valid
|
|
95
|
-
// using actions.disable() and actions.enable()
|
|
96
|
-
onInit: window[`__pp_form_fields_${hostedButtonId}`]?.onInit,
|
|
97
|
-
// render form errors, if present
|
|
98
|
-
onClick: window[`__pp_form_fields_${hostedButtonId}`]?.onClick,
|
|
99
|
-
};
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
export const buildHostedButtonCreateOrder = ({
|
|
103
|
-
hostedButtonId,
|
|
104
|
-
merchantId,
|
|
105
|
-
}: GetCallbackProps): CreateOrder => {
|
|
106
|
-
return (data) => {
|
|
107
|
-
const userInputs =
|
|
108
|
-
window[`__pp_form_fields_${hostedButtonId}`]?.getUserInputs?.() || {};
|
|
109
|
-
return createAccessToken(getClientID()).then((accessToken) => {
|
|
110
|
-
return request({
|
|
111
|
-
url: `${apiUrl}/v1/checkout/links/${hostedButtonId}/create-context`,
|
|
112
|
-
headers: getHeaders(accessToken),
|
|
113
|
-
method: "POST",
|
|
114
|
-
body: JSON.stringify({
|
|
115
|
-
entry_point: entryPoint,
|
|
116
|
-
funding_source: getFundingSource(data.paymentSource),
|
|
117
|
-
merchant_id: merchantId,
|
|
118
|
-
...userInputs,
|
|
119
|
-
}),
|
|
120
|
-
}).then(({ body }) => {
|
|
121
|
-
return body.context_id;
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
};
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
export const buildHostedButtonOnApprove = ({
|
|
128
|
-
hostedButtonId,
|
|
129
|
-
merchantId,
|
|
130
|
-
}: GetCallbackProps): OnApprove => {
|
|
131
|
-
return (data) => {
|
|
132
|
-
return createAccessToken(getClientID()).then((accessToken) => {
|
|
133
|
-
return request({
|
|
134
|
-
url: `${apiUrl}/v1/checkout/links/${hostedButtonId}/pay`,
|
|
135
|
-
headers: getHeaders(accessToken),
|
|
136
|
-
method: "POST",
|
|
137
|
-
body: JSON.stringify({
|
|
138
|
-
entry_point: entryPoint,
|
|
139
|
-
merchant_id: merchantId,
|
|
140
|
-
context_id: data.orderID,
|
|
141
|
-
}),
|
|
142
|
-
}).then((response) => {
|
|
143
|
-
// The "Debit or Credit Card" button does not open a popup
|
|
144
|
-
// so we need to open a new popup for buyers who complete
|
|
145
|
-
// a checkout via "Debit or Credit Card".
|
|
146
|
-
if (data.paymentSource === "card") {
|
|
147
|
-
const url = `${baseUrl}/ncp/payment/${hostedButtonId}/${data.orderID}`;
|
|
148
|
-
popup(url, {
|
|
149
|
-
width: DEFAULT_POPUP_SIZE.WIDTH,
|
|
150
|
-
height: DEFAULT_POPUP_SIZE.HEIGHT,
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
return response;
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
};
|
|
157
|
-
};
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
|
|
3
|
-
import { test, expect, vi } from "vitest";
|
|
4
|
-
import { request } from "@krakenjs/belter/src";
|
|
5
|
-
import { ZalgoPromise } from "@krakenjs/zalgo-promise/src";
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
getHostedButtonDetails,
|
|
9
|
-
buildHostedButtonCreateOrder,
|
|
10
|
-
buildHostedButtonOnApprove,
|
|
11
|
-
} from "./utils";
|
|
12
|
-
|
|
13
|
-
vi.mock("@krakenjs/belter/src", async () => {
|
|
14
|
-
return {
|
|
15
|
-
...(await vi.importActual("@krakenjs/belter/src")),
|
|
16
|
-
request: vi.fn(),
|
|
17
|
-
};
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
vi.mock("@paypal/sdk-client/src", async () => {
|
|
21
|
-
return {
|
|
22
|
-
...(await vi.importActual("@paypal/sdk-client/src")),
|
|
23
|
-
getSDKHost: () => "example.com",
|
|
24
|
-
getClientID: () => "client_id_123",
|
|
25
|
-
getMerchantID: () => ["merchant_id_123"],
|
|
26
|
-
};
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
const getHostedButtonDetailsResponse = {
|
|
30
|
-
body: {
|
|
31
|
-
button_details: {
|
|
32
|
-
link_variables: [
|
|
33
|
-
{
|
|
34
|
-
name: "business",
|
|
35
|
-
value: "M1234567890",
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
name: "shape",
|
|
39
|
-
value: "rect",
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
name: "layout",
|
|
43
|
-
value: "vertical",
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
name: "color",
|
|
47
|
-
value: "gold",
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
name: "button_text",
|
|
51
|
-
value: "paypal",
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
test("getHostedButtonDetails", async () => {
|
|
59
|
-
// $FlowIssue
|
|
60
|
-
request.mockImplementationOnce(() =>
|
|
61
|
-
ZalgoPromise.resolve(getHostedButtonDetailsResponse)
|
|
62
|
-
);
|
|
63
|
-
await getHostedButtonDetails({
|
|
64
|
-
hostedButtonId: "B1234567890",
|
|
65
|
-
}).then(({ style }) => {
|
|
66
|
-
expect(style).toEqual({
|
|
67
|
-
layout: "vertical",
|
|
68
|
-
shape: "rect",
|
|
69
|
-
color: "gold",
|
|
70
|
-
label: "paypal",
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
expect.assertions(1);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
test("buildHostedButtonCreateOrder", async () => {
|
|
77
|
-
const createOrder = buildHostedButtonCreateOrder({
|
|
78
|
-
hostedButtonId: "B1234567890",
|
|
79
|
-
merchantId: "M1234567890",
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
// $FlowIssue
|
|
83
|
-
request.mockImplementation(() =>
|
|
84
|
-
ZalgoPromise.resolve({
|
|
85
|
-
body: {
|
|
86
|
-
link_id: "B1234567890",
|
|
87
|
-
merchant_id: "M1234567890",
|
|
88
|
-
context_id: "EC-1234567890",
|
|
89
|
-
status: "CREATED",
|
|
90
|
-
},
|
|
91
|
-
})
|
|
92
|
-
);
|
|
93
|
-
const orderID = await createOrder({ paymentSource: "paypal" });
|
|
94
|
-
expect(orderID).toBe("EC-1234567890");
|
|
95
|
-
expect.assertions(1);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
test("buildHostedButtonOnApprove", async () => {
|
|
99
|
-
const onApprove = buildHostedButtonOnApprove({
|
|
100
|
-
hostedButtonId: "B1234567890",
|
|
101
|
-
merchantId: "M1234567890",
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
// $FlowIssue
|
|
105
|
-
request.mockImplementation(() =>
|
|
106
|
-
ZalgoPromise.resolve({
|
|
107
|
-
body: {},
|
|
108
|
-
})
|
|
109
|
-
);
|
|
110
|
-
await onApprove({ orderID: "EC-1234567890", paymentSource: "paypal" });
|
|
111
|
-
expect(request).toHaveBeenCalledWith(
|
|
112
|
-
expect.objectContaining({
|
|
113
|
-
body: JSON.stringify({
|
|
114
|
-
entry_point: "SDK",
|
|
115
|
-
merchant_id: "M1234567890",
|
|
116
|
-
context_id: "EC-1234567890",
|
|
117
|
-
}),
|
|
118
|
-
})
|
|
119
|
-
);
|
|
120
|
-
expect.assertions(1);
|
|
121
|
-
});
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
|
|
3
|
-
import { getHostedButtonsComponent } from "../hosted-buttons";
|
|
4
|
-
import type { HostedButtonsComponent } from "../hosted-buttons/types";
|
|
5
|
-
import { getButtonsComponent } from "../zoid/buttons";
|
|
6
|
-
import {
|
|
7
|
-
getCardFormComponent,
|
|
8
|
-
type CardFormComponent,
|
|
9
|
-
} from "../zoid/card-form";
|
|
10
|
-
import { getCheckoutComponent, type CheckoutComponent } from "../zoid/checkout";
|
|
11
|
-
import type { LazyExport, LazyProtectedExport } from "../types";
|
|
12
|
-
import { protectedExport } from "../lib";
|
|
13
|
-
|
|
14
|
-
export const HostedButtons: LazyExport<HostedButtonsComponent> = {
|
|
15
|
-
__get__: () => getHostedButtonsComponent(),
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export const Checkout: LazyProtectedExport<CheckoutComponent> = {
|
|
19
|
-
__get__: () => protectedExport(getCheckoutComponent()),
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const CardForm: LazyProtectedExport<CardFormComponent> = {
|
|
23
|
-
__get__: () => protectedExport(getCardFormComponent()),
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export function setup() {
|
|
27
|
-
getButtonsComponent();
|
|
28
|
-
getCheckoutComponent();
|
|
29
|
-
}
|