Skip to content

Commit f594d7e

Browse files
feat: add typescript types for the v6 sdk (#659)
1 parent a2e716e commit f594d7e

File tree

11 files changed

+473
-7
lines changed

11 files changed

+473
-7
lines changed

.changeset/shiny-guests-wink.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@paypal/paypal-js": minor
3+
---
4+
5+
Update rollup config and add V6 types

packages/paypal-js/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,45 @@ loadCustomScript({
293293

294294
This package includes TypeScript type definitions for the PayPal JS SDK. This includes types for the `window.paypal` namespace. We support projects using TypeScript versions >= 3.8.
295295

296+
### V6 TypeScript Types
297+
298+
In addition to the type definitions above, this package also includes Typescript type definitions for the PayPal JS SDK V6.
299+
300+
#### Importing and Using V6 Types
301+
302+
A basic example showing data-typing for PayPal One Time Payment.
303+
304+
```js
305+
import type {
306+
PayPalV6Namespace,
307+
CreateInstanceOptions,
308+
OnApproveDataOneTimePayments,
309+
OnShippingAddressChangeData,
310+
SdkInstance
311+
} from "@paypal/paypal-js/types/sdk-v6";
312+
313+
declare global {
314+
interface Window {
315+
paypal?: PayPalV6Namespace | null;
316+
}
317+
}
318+
319+
const createInstanceOptions: CreateInstanceOptions = {
320+
clientToken,
321+
components: ["paypal-payments", "venmo-payments"]
322+
}
323+
324+
const sdkInstance = await window.paypal.createInstance(createInstanceInputs);
325+
326+
function onApproveCallback(data: OnApproveDataOneTimePayments) {}
327+
function onShippingAddressChangeCallback(data: OnShippingAddressChangeData) {}
328+
329+
const paypalCheckout = sdkInstance.createPayPalOneTimePaymentSession({
330+
onApprove: onApproveCallback,
331+
onShippingAddressChange: onShippingAddressChangeCallback,
332+
});
333+
```
334+
296335
## Releasing
297336

298337
Run `npm run release` to publish a new release. The version number is determined by the git commits which follow [conventional commits spec](https://www.conventionalcommits.org).

packages/paypal-js/e2e-tests/reload-script.test.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ test("Reload script", async ({ page }) => {
1414

1515
await expect(page).toHaveTitle("Reload Script Demo | PayPal JS");
1616

17-
let sdkRequest;
18-
await page.on("request", (request) => {
19-
if (request.url().startsWith("https://www.paypal.com/sdk/js")) {
20-
sdkRequest = request.url();
21-
}
22-
});
17+
// Wait for the request when currency is changed to EUR
18+
const requestPromise = page.waitForRequest(
19+
(request) =>
20+
request.url().startsWith("https://www.paypal.com/sdk/js") &&
21+
request.url().includes("currency=EUR"),
22+
);
2323

2424
await page.locator("select#currency").selectOption("EUR");
25-
expect(sdkRequest.includes("currency=EUR")).toBe(true);
25+
26+
const sdkRequest = await requestPromise;
27+
expect(sdkRequest.url().includes("currency=EUR")).toBe(true);
2628
});

packages/paypal-js/package.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@
88
"publishConfig": {
99
"access": "public"
1010
},
11+
"exports": {
12+
".": {
13+
"types": "./types/index.d.ts",
14+
"import": "./dist/esm/paypal-js.js",
15+
"require": "./dist/cjs/paypal-js.js"
16+
},
17+
"./sdk-v6": {
18+
"types": "./types/v6/index.d.ts",
19+
"import": "./dist/v6/esm/paypal-js.js"
20+
}
21+
},
1122
"scripts": {
1223
"build": "rm -rf dist && rollup --config --bundleConfigAsCjs",
1324
"lint": "eslint .",

packages/paypal-js/rollup.config.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,31 @@ export default [
8989
},
9090
],
9191
},
92+
{
93+
input: "src/v6/index.ts",
94+
plugins: [
95+
typescript({
96+
...tsconfigOverride,
97+
}),
98+
replace({
99+
__VERSION__: pkg.version,
100+
preventAssignment: true,
101+
}),
102+
],
103+
output: [
104+
{
105+
file: `dist/v6/esm/${pkgName}.js`,
106+
format: "esm",
107+
banner,
108+
},
109+
{
110+
file: `dist/v6/esm/${pkgName}.min.js`,
111+
format: "esm",
112+
banner,
113+
plugins: [terser()],
114+
},
115+
],
116+
},
92117
];
93118

94119
function getBannerText() {

packages/paypal-js/src/v6/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { loadCustomScript as originalLoadCustomScript } from "../load-script";
2+
3+
const version = "__VERSION__";
4+
5+
// V6-specific loadCustomScript without PromisePonyfill
6+
function loadCustomScript(options: {
7+
url: string;
8+
attributes?: Record<string, string>;
9+
}): Promise<void> {
10+
return originalLoadCustomScript(options); // Uses default Promise
11+
}
12+
13+
export { loadCustomScript, version };
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import {
2+
PayLaterCountryCodes,
3+
PayLaterProductCodes,
4+
PayPalCreditCountryCodes,
5+
} from "./paypal-payments";
6+
7+
export type EligiblePaymentMethods =
8+
| "paypal_pay_later"
9+
| "paypal_credit"
10+
| "paypal"
11+
| "venmo";
12+
13+
export type FindEligibleMethodsOptions = {
14+
currencyCode?: string;
15+
};
16+
17+
export type FundingSource = "credit" | "paylater" | "paypal" | "venmo";
18+
19+
type BaseEligiblePaymentMethodDetails = {
20+
canBeVaulted: boolean;
21+
};
22+
23+
type CreditEligiblePaymentMethodDetails = BaseEligiblePaymentMethodDetails & {
24+
countryCode: PayPalCreditCountryCodes;
25+
};
26+
27+
type PayLaterEligiblePaymentMethodDetails = BaseEligiblePaymentMethodDetails & {
28+
countryCode: PayLaterCountryCodes;
29+
productCode: PayLaterProductCodes;
30+
};
31+
32+
export type FindEligibleMethodsGetDetails<T extends FundingSource> =
33+
T extends "credit"
34+
? CreditEligiblePaymentMethodDetails
35+
: T extends "paylater"
36+
? PayLaterEligiblePaymentMethodDetails
37+
: BaseEligiblePaymentMethodDetails;
38+
39+
export interface EligiblePaymentMethodsOutput {
40+
isEligible: (paymentMethod: FundingSource) => boolean;
41+
getDetails: <T extends FundingSource>(
42+
fundingSource: T,
43+
) => FindEligibleMethodsGetDetails<T>;
44+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import {
2+
OnCompleteData,
3+
OnCancelData,
4+
OnErrorData,
5+
OnApproveDataOneTimePayments,
6+
} from "./paypal-payments";
7+
8+
export type BillingOnApproveData = OnApproveDataOneTimePayments;
9+
10+
export type BillingSessionOptions = {
11+
onApprove?: (data: BillingOnApproveData) => Promise<void>;
12+
onCancel?: (data?: OnCancelData) => void;
13+
onComplete?: (data?: OnCompleteData) => void;
14+
onError?: (data: OnErrorData) => void;
15+
billingToken?: string;
16+
};
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
export type PayLaterCountryCodes =
2+
| "AU"
3+
| "DE"
4+
| "ES"
5+
| "FR"
6+
| "GB"
7+
| "IT"
8+
| "US";
9+
10+
export type PayLaterProductCodes = "PAYLATER" | "PAY_LATER_SHORT_TERM";
11+
12+
export type PayPalCreditCountryCodes = "US" | "GB";
13+
14+
export type ShippingAddressErrorType =
15+
| "ADDRESS_ERROR"
16+
| "COUNTRY_ERROR"
17+
| "STATE_ERROR"
18+
| "ZIP_ERROR";
19+
20+
export type ShippingAddressErrorMessages = Record<
21+
ShippingAddressErrorType,
22+
string
23+
>;
24+
25+
export type ShippingOptionsErrorType =
26+
| "METHOD_UNAVAILABLE"
27+
| "STORE_UNAVAILABLE";
28+
29+
export type ShippingOptionsErrorMessages = Record<
30+
ShippingOptionsErrorType,
31+
string
32+
>;
33+
34+
export type OnShippingAddressChangeData = {
35+
errors: ShippingAddressErrorMessages;
36+
orderId: string;
37+
shippingAddress: {
38+
city?: string;
39+
countryCode: string;
40+
postalCode?: string;
41+
state?: string;
42+
};
43+
};
44+
45+
export type OnShippingOptionsChangeData = {
46+
errors: ShippingOptionsErrorMessages;
47+
orderId: string;
48+
selectedShippingOption: {
49+
amount: {
50+
currencyCode: string;
51+
value: string;
52+
};
53+
id: string;
54+
label: string;
55+
selected: boolean;
56+
type: string;
57+
};
58+
};
59+
60+
export type OnApproveDataOneTimePayments = {
61+
orderId: string;
62+
payerId?: string;
63+
billingToken?: string;
64+
};
65+
66+
export type OnApproveDataSavePayments = {
67+
vaultSetupToken: string;
68+
payerId?: string;
69+
};
70+
71+
export type OnCompleteData = {
72+
paymentSessionState?: string;
73+
};
74+
75+
export type OnCancelData = {
76+
orderId: string;
77+
};
78+
79+
export type OnErrorData = Error;
80+
81+
export type BaseSessionOptions = {
82+
onCancel?: (data?: OnCancelData) => void;
83+
onComplete?: (data?: OnCompleteData) => void;
84+
onError?: (data: OnErrorData) => void;
85+
testBuyerCountry?: string;
86+
};
87+
88+
export type PayPalOneTimePaymentSessionOptions = BaseSessionOptions & {
89+
onApprove?: (data: OnApproveDataOneTimePayments) => Promise<void>;
90+
onShippingAddressChange?: (
91+
data: OnShippingAddressChangeData,
92+
) => Promise<void>;
93+
onShippingOptionsChange?: (
94+
data: OnShippingOptionsChangeData,
95+
) => Promise<void>;
96+
savePayment?: boolean;
97+
};
98+
99+
export type SavePaymentSessionOptions = BaseSessionOptions & {
100+
clientMetadataId?: string;
101+
orderId?: never;
102+
vaultSetupToken?: string;
103+
onApprove?: (data?: OnApproveDataSavePayments) => void;
104+
};
105+
106+
export type PayLaterOneTimePaymentSessionOptions =
107+
PayPalOneTimePaymentSessionOptions;
108+
109+
export type PayPalCreditOneTimePaymentSessionOptions =
110+
PayPalOneTimePaymentSessionOptions;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { PayPalOneTimePaymentSessionOptions } from "./paypal-payments";
2+
3+
export type VenmoPaymentSessionOptions = Omit<
4+
PayPalOneTimePaymentSessionOptions,
5+
"onShippingAddressChange" | "onShippingOptionsChange"
6+
>;

0 commit comments

Comments
 (0)