paypal / paypal-js Goto Github PK
View Code? Open in Web Editor NEWLoading wrapper and TypeScript types for the PayPal JS SDK
License: Apache License 2.0
Loading wrapper and TypeScript types for the PayPal JS SDK
License: Apache License 2.0
I do not think this is a bug of this specific library but for the script:
https://www.paypal.com/sdk/js
however I did not find any place to submit this bug.
The normal behavior for the smart buttons is :
none of them forces of the users to create an account
"Debit or Credit Card" button opens the form in the same page
however when you specify a locale outside of US for example es_MX
all of the buttons will open a modal and will force the user to create an account
go to:
https://developer.paypal.com/demo/checkout/#/pattern/server
test the behavior without changing anything.
notice that buttons won't force you to create an account and
"Debit or Credit Card" button opens the form in the same page
now change the script src to
<script src="https://www.paypal.com/sdk/js?client-id=sb¤cy=USD&locale=es_MX"></script>
all buttons force the user to create an account
"Debit or Credit Card" opens in a modal.
Using different locales shouldn't force the user to create a Paypal account (this is the most important one)
Debit or credit card button should open within the page (like when no locale is specified or a US locale)
Add any other context about the problem here.
Short Question: How to add headers to show all the buttons and what headers to add?
There is a link to paypal that shows what to do: link.
It says to add data-csp-nonce="xyz-123"
on the script.
How could this be accomplished here?
Could you provide documentation for this on the readme?
Note: I tried addding data-csp-nonce="xyz-123"
to the header and loadscript from your package but no result.
Order capture also contains phone number.
The form requires the submission of a phone number, amongst other fields of personal information. It would require another form to get phone number, which is bad for UX.
onApprove: async function(data, actions) {
const orderInfo = await actions.order.capture()
//orderInfo.payer.phone_number or orderInfo.purchase_units[0].shipping.phone_number
}
According to https://developer.paypal.com/docs/api/orders/v2/#orders_authorize the authorization id can be found in the returned data but the PurchaseUnit
type is missing the payments object.
typescript reports an error when trying to access payments:
error TS2339: Property 'payments' does not exist on type 'PurchaseUnit'.
40 details.purchase_units[0].payments.authorizations[0].id,
~~~~~~~~
compilation works
As per this article the onShippingChange() method should take in two parameters (data and actions) and return actions. In this library, however, it takes in no parameters and returns void (source);
This is a very minor issue and I have managed to get around it with a ts-ignore, but I figured I would let you guys know about it. I can submit a pull request to modify buttons.d.ts but I want to make sure this is the only file that requires changes.
I have two paypal accounts. One appears to be working fine while the other just loads indefinitely.
If I look at the paypal API logs, I see there is a 403 at the timestamp I was trying to load the app.
5.0.332
The code for both apps are the same, only the clientId differs.
import React, { useState, useEffect } from 'react'
import { loadScript } from "@paypal/paypal-js"
const PayPal = () => {
const { getRequest } = useQuery()
useEffect(() => {
loadScript({ "client-id": clientId, vault: true, intent: 'subscription' }).then((paypal) => {
console.log(paypal)
paypal.Buttons({
style: { layout: 'horizontal' },
createSubscription: createPayPalSubscription,
onApprove: payPalSubscriptionApproved
}).render("#paypal-button-container").catch((error) => {
console.error("failed to render the PayPal Buttons", error);
})
}).catch((error) => {
console.error("failed to load the PayPal JS SDK script", error);
})
}, [])
const createPayPalSubscription = (data, actions) => {
// this plan ID is from paypal subscriptions.
return actions.subscription.create({
'plan_id': planId
})
}
const payPalSubscriptionApproved = (data, actions) => { /* do stuff */ }
return <>pp dirct <div id="paypal-button-container" /></>
}
export default PayPal
Could you add data-merchant-id
support?
Without this script option support, we couldn't utilize to create multi seller order.
Direct js inclusion looks like this
<script src="https://www.paypal.com/sdk/js?client-id=Client-ID&merchant-id=*" data-merchant-id="MERCHANT_ID_1,MERCHANT_ID_2"></script>
loadScript({ 'client-id': 'YOUR_CLIENT_ID', 'merchant-id': '*', 'data-merchant-id': 'MERCHANT_ID_1,MERCHANT_ID_2' });
Query: loadScript({ 'client-id': 'sb' });
Attribute: loadScript({ 'client-id': 'sb', 'data-csp-nonce': 'asdf' });
Options: loadScript({ 'client-id': 'sb', 'data-csp-nonce': 'asdf', defer: true });
Link to available query params (https://developer.paypal.com/docs/checkout/reference/customize-sdk/#query-parameters) and attributes (https://developer.paypal.com/docs/checkout/reference/customize-sdk/#script-parameters).
Hi team, we are wrapping up v1 of paypal-js and our goal is to figure out the best dynamic script loading technique to use. This issue has been created to get feedback and come to a group decision on which approach to use.
Here is a link to the specific code in paypal-js that dynamically inserts the JS SDK into the page: https://github.com/paypal/paypal-js/blob/main/src/utils.js#L21.
Note that defer
and async
behave differently when using them on a script tag (<script src="foo" async>
) directly vs using them when dynamically inserting a script (const newScript = document.createElement('script'); newScript.defer = true;
). Our use case is focused on dynamic script insertion.
Here's a list of options to choose from:
defer
or async
when dynamically loading the script. Let the browser do it's default behavior when dynamically loading a script. Note that this is the approach stripe-js takes.defer
to true and async
to false when dynamically loading the script.defer
to false and async
to true when dynamically loading the script.async
and defer
to true when dynamically loading the script.We have this demo for showcasing these different use cases: https://github.com/gregjopa/dynamic-script-loading-demo. Please comment and let us know your thoughts. Also, please share any demos you create to test this out.
A clear and concise description of what the feature is.
Please outline the motivation for the proposal.
Please provide an example for how this feature would be used.
Hi There. I'm trying to integrate PayPal smart button into my service on the angular framework.
I've got 403 permission denied issues moving from sandbox to a live environment.
(Same code works well in sandbox mode.)
To do that I just
here are my code
loadScript({
intent: 'capture',
'client-id': environment.paypalConfig.clientId,
currency: this.app.getCurrencyISOCodeStr(),
debug: true
}).then((paypal) => {
this.isLoading = false;
const order = {
purchase_units: [
{
amount: {
currency_code: this.app.getCurrencyISOCodeStr(),
value: this.amount.toFixed(2)
}
}
]
};
paypal
.Buttons({
fundingSource: 'paypal',
createOrder(data, actions) {
return actions.order.create(order);
},
and the error is below.
{"name":"NOT_AUTHORIZED","details":[{"issue":"PERMISSION_DENIED","description":"You do not have permission to access or perform operations on this resource."}],"message":"Authorization failed due to insufficient permissions.","debug_id":"f24387243d3d6","links":[{"href":"https://developer.paypal.com/docs/api/orders/v2/#error-PERMISSION_DENIED","rel":"information_link"}]}
Am I miss something?
This project isn't written in TypeScript, but many TypeScript users would like to use published typings. For this issue, create TypeScript typings that cover the exported functions, and contribute it back to DefinitelyTyped!
This issue is great for someone who wants to learn more about TypeScript!
When the paypay button has been rendered into the document, a quick click cannot arouse the pop-up window, and the button is in the focused state (as shown in the figure below). When the button is clicked for the second time, the state is successfully aroused
Nothing
Nothing
Nothing
I am trying to add the Venmo button by setting 'enable-funding': 'venmo' but the Venmo button does not appear. I can get others like eps and ideal but venmo does not. I am using USD for currency. Is there something else I am missing to allow the venmo button?
As a side note, right now I only need the Venmo button but if I wanted to have both Venmo and Ideal is there a way I could do that with this package?
Here is the loadScript I am trying to use:
loadScript({
'client-id': paypalClientId,
'disable-funding': 'credit',
'enable-funding': 'venmo',
'vault': false,
'merchant-id': this.clientInfo.paypal_email,
'currency': this.invoice.currSymbol,
})
and the currSymbol is USD in this case.
From today, the Paypal JS script has stopped to work, the call fails with this error: net::ERR_ABORTED 400
This is the request URL that my site made: https://www.paypal.com/sdk/js?client-id=MY_CLIENT_ID&vault=true&intent=subscription
The script stopped working today, until yesterday it worked.
I have tryed to cancel cookie and cache but the problem is not solved.
Add a new public function called appendScript(options)
that would be used for reloading the JS SDK script. This new option would use the previous script options and would only override the new ones passed in.
Currently loadScript(options)
can be used to:
The problem with this approach is loadScript(options)
will always replace all the options previously used.
There are "website builder" use cases where they might not know all the previous options used to load the JS SDK script. They would prefer to append to the existing options rather than replace them.
loadScript({
'client-id': 'sb',
'components': 'buttons',
'disable-funding': 'card',
'merchant-id': '12345',
'data-partner-attribution-id': '678910',
})
.then(() => {
renderButtons();
});
// assume this `appendScript()` function is called later on in the code base to load the messages component
// it doesn't know about params like "merchant-id" or "data-partner-attribution-id" but still wants to use them when reloading the script
appendScript({ components: 'buttons,messages' })
then(() => {
renderMessages();
// we still need to render buttons again since reloading the JS SDK will destroy all components on the page
renderButtons();
});
It would be great to use GitHub Actions for CI instead of travis. To resolve this issue, complete the following:
There are several missing / incorrect types in Typescript definitions
OnApproveActions
is missing get
and patch
functions - needed to retrieve order data without capturing / authorizingPayer
has an incorrect type for phone
- the return value has a phone_type
and national_number
as a sub-property of phone_number
object, but this library just has phone_number
as a string: https://developer.paypal.com/docs/api/orders/v2/#definition-payerShippingInfo
does not include options
, to pass shipping rates: https://developer.paypal.com/docs/checkout/standard/customize/shipping-options/Typescript throws warnings that types are incorrect, but the defined types leads to errors in the browser and missing functionality
Types should match the interfaces outlined in documentation
Export a lower level function for loading any js script. This can be used to provide an easy way to load the partner.js script used for onboarding sellers. https://developer.paypal.com/docs/platforms/seller-onboarding/before-payment/#3-add-sign-up-link-to-your-site
It would be nice if this paypal-js
library could be their single solution to script loading.
import { loadScript, loadCustomScript } from "@paypal/paypal-js";
// new loadCustomScript function for loading any url
loadCustomScript({
url: "https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js",
attributes: {
id: "paypal-partner-js"
}
})
.then(() => {
console.log('partner script successfully loaded');
})
.catch(err => {
console.log('failed to load partner script', err);
});
/*
<!-- the following html is still required for this partner integration -->
<a data-paypal-button="true" href="<Action-URL>&displayMode=minibrowser" target="PPFrame">Sign up for PayPal</a>
*/
The JS SDK script and the partners.js script can load independently. If the developer does want to wait for both to finish before something, then Promise.all
could be used to know when both are complete.
Inline CC validation fails silently.
onError
is not called when inline credit card form validation fails. The console has an error message, but it's not communicated, leaving our clients clueless about
https://paypal-staging.invoicesimple.com/checkout/BwUXs9i6dU
Use the following CC details:
4242...
405 Lexington Ave, New York, NY United States
ZIP code: 101174 << Enter this invalid ZIP code
Nothing's happening. There's a console error from some paypal internal library:
ppxo_inline_guest_unhandled_error
{
"handledErrors": [
{
"billingAddress": {
"contentKey": "fieldErrors.postalCodeInvalid",
"field": "postalCode"
}
}
],
"unhandledErrors": [],
"inline_guest_version": "2.12.8",
"timestamp": 1626133611140,
"windowID": "d4ef436b46",
"pageID": "19427c4852",
"referer": "www.sandbox.paypal.com",
"host": "www.sandbox.paypal.com",
"path": "/smart/card-fields",
"env": "sandbox",
"country": "CA",
"lang": "en",
"uid": "uid_e90d1db9c5_mjm6mjg6ndc",
"ver": "2.12.8"
}
There should be an informative error message displayed and onError
should be called
Might be related https://github.com/paypal/paypal-checkout-components/issues/1550
We have been partnering via PayPal Commerce Platform for high-volume invoice payments processing, and this one causes a real issue for real customers in production systems.
It's kind of crazy that the issue is taking so long to resolve, considering the impact.
java.net.sockettimeoutexception:www.google.org
The return type from HostedFields.render() does not include the on() function to access field event subscription. It must by type-casted as "any" to avoid typescript errors.
In the .then callback from a HostedFields.render() function, try to access the .on() function:
loadScript({
...
}).then(
(paypal) => {
paypal.HostedFields.render({
...
}).then(
(cardFields) => {
cardFields.on('validityChange', (event) => { ... });
}
)
}
)
throws an "method on() does not exist on type HostedFieldsHandler" error
...
.then(
(cardFields) => {
(cardFields as any).on('validityChange', (event) => { ... });
}
)
subscribes to the event just fine.
The interface is missing declarations for the .on() subscription method.
The interface includes all method calls available through the Paypal API
While not a critical breaking issues, as it's easily worked around, it was definitely a source of confusion.
It would be convenient to have the functionality to set amount for Donation button via Donation SDK. Now configuration of amount available only from portal.
In some system user has already predefined amount for donate and he should set amount the second time inside the PayPal Popup
When I use vue, the example is
paypal.Buttons.driver("vue", Vue)
At this time, I cannot use style to set its style.
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
@vitest/coverage-v8
, vitest
).github/workflows/playwright.yml
styfle/cancel-workflow-action 0.11.0
actions/checkout v3
actions/setup-node v3
bahmutov/npm-install v1
actions/upload-artifact v3
.github/workflows/publish.yml
actions/checkout v3
actions/setup-node v3
bahmutov/npm-install v1
.github/workflows/validate.yml
styfle/cancel-workflow-action 0.11.0
actions/checkout v3
actions/setup-node v3
bahmutov/npm-install v1
wagoid/commitlint-github-action v5
codecov/codecov-action v3
package.json
promise-polyfill ^8.3.0
@commitlint/cli 17.7.1
@commitlint/config-conventional 17.7.0
@playwright/test ^1.37.0
@rollup/plugin-commonjs 25.0.4
@rollup/plugin-node-resolve 15.1.0
@rollup/plugin-replace 5.0.2
@rollup/plugin-terser ^0.4.3
@rollup/plugin-typescript 11.1.2
@types/node ^20.5.0
@types/promise-polyfill 6.0.4
@typescript-eslint/eslint-plugin 6.4.0
@typescript-eslint/parser 6.4.0
@vitest/coverage-v8 ^0.34.1
eslint 8.47.0
filesize 10.0.12
husky 8.0.3
jsdom ^22.1.0
lint-staged 14.0.0
prettier 3.0.2
rollup 3.28.0
semver 7.5.4
standard-version 9.5.0
tslib 2.6.1
typescript 5.1.6
vitest ^0.34.1
.nvmrc
node 18
Hi, I just got a Notification, that I should review the PR on the DefinitelyTyped repo and it removes the @paypal/paypal-js typings.
I just wanted to make sure, that it's correct^^ As far as I understand, paypal-js now bundles it's own typings, right?
For reference: DefinitelyTyped/DefinitelyTyped#53216
Must be a recent SDK update that broke the existing PayPal Message component. It's looking for an 'account' property that doesn't exist for existing implementation.
TypeError: String.prototype.startsWith called on null or undefined
at startsWith (<anonymous>)
at Object.decorate (VM175 js:1)
at VM175 js:1
at Vr (VM175 js:1)
at VM175 js:1
at Object.Je [as setProps] (VM175 js:1)
at Object.e [as init] (VM175 js:1)
at t (VM175 js:1)
at Na (VM175 js:1)
at ka (VM175 js:1)
You can view the error on this react component example
https://paypal.github.io/react-paypal-js/?path=/docs/example-paypalmessages--default
Paypal messages does not work
PayPal messages should work
Add any other context about the problem here.
Hi,
I just started using this package and looking at the documentation I cannot find anything about passing a hosted_button_id which is required when implementing a Donate button from PayPal.
I would appreciate it if anyone could help me with any idea/link about this.
Basically the answer to this question: https://stackoverflow.com/questions/73150831/how-to-test-failed-transactions-with-the-paypal-js-sdk
Testing failed payment paths is crucial to any integration. It is not understandable, that there appears to be no easy way to do it with paypal.
It should be something very straight foreward:
Spam
OnApproveOrderActions.order only have the capture function
but is missing the get function
line:
https://github.com/paypal/paypal-js/blob/main/types/components/buttons.d.ts#L32
Add any other context about the problem here.
If this is already possibe with a few minor tweaks, I do apologise.
Reload script on paypal button click so that a new currency can be passed correctly to the sdk
It is very awkward to have more than one paypal button on a page which goes to a checkout for different currencies.
This error is a cummon occurance without tedious workarounds:
Expected currency from order api call to be GBP, got AUD. Please ensure you are passing currency=AUD to the sdk url
This thread highlights the issue:
https://github.com/paypal/paypal-checkout-components/issues/1180
Because components
are an important query param and needed in a lot of scenarios (see: https://developer.paypal.com/sdk/js/reference/) we should include an example
It will make it easier to use in practical examples
Let's include components: "buttons, hosted-fields"
Cannot read properties of undefined (reading 'render') in React js
Here is the code sandbox : https://codesandbox.io/s/react-paypal-with-paypal-paypal-js-package-z2xlnr?file=/src/App.js
When I place clientId to get paypal up and running, I got an error message on console
It should be able to recognise render and behave as expected
I've got the same issue with @paypal/react-paypal-js npm package where React skipped hostedFields for card fields
here is screenshot of the error:
i'm getting errors with message: TOKEN_FAILURE when trying create order with subscription.
Previously everything works well.
I've also tried to create subscription from postman api and visit APPROVE link but got error message on sandbox.paypal.com
'Things don't appear to be working at the moment. Please try again later.'
I've also created a subscription button in paypal editor and tried put piece of code to codepen and got same error(TOKEN_FAILURE)
create account in sandbox, create product, create plan with this product, copy code and paste in codepen
https://codepen.io/Artem122/pen/vYrOeqZ
A clear and concise description of what the feature is.
Please outline the motivation for the proposal.
Please provide an example for how this feature would be used.
A clear and concise description of what the feature is.
Please outline the motivation for the proposal.
Please provide an example for how this feature would be used.
Support multiple shipping options as described here: https://developer.paypal.com/docs/business/checkout/configure-payments/shipping-options/
Allowing the user to choose between multiple shipping options improve the ux for express checkout.
Extra note: I could not find how this is done in the Order API documentation here: https://developer.paypal.com/docs/api/orders/v2/
The current PayPalMessagesComponentOptions does not match the documentation found in the sdk docs.
Compare current type to the docs.
Current type is missing options mentioned in the docs.
To be able to reference options present in the docs.
N/A
When using Types PayPalNamespace paypal.Buttons onApprove Callbacks Parameter actions is of Type OnApproveActions. I should be able to call actions.restart() but OnApproveActions type is defined to use actions.order.restart() which leads to Error "actions.order.restart is not a function".
export type OnApproveActions = {
order: {
capture: () => Promise<OrderResponseBody>;
authorize: () => Promise<OrderResponseBody>;
redirect: (redirectURL: string) => void;
restart: () => void;
};
};
Should at least be
export type OnApproveActions = {
order: {
capture: () => Promise<OrderResponseBody>;
authorize: () => Promise<OrderResponseBody>;
redirect: (redirectURL: string) => void;
};
restart: () => void;
};
Perhaps all methods should not be listed under order, I did not check this yet.
The onCLick is not Working Before the createOrder on Android and iOS Devices (before the "createOrder" method).
Works Fine in Desktop.
1.- Make a Button with onClick method
2.- In desktop works fine (before the "createOrder" method)
3.- In mobile devices the function execute after the createOrder method.
This behavior is reproducible with the Developer tools in Chrome on Desktop (simulate the mobile devices)
I am using return_url
to bring user to a new page after order is completed.
It is simply not working
paypal.Buttons({
style: {
"layout": "horizontal",
"shape" : "rect",
"tagline": "false",
"label" : "checkout",
} ,
createOrder: function (data, actions) {
// Set up the transaction
return actions.order.create({
application_context: {
brand_name: "Demo Shop",
shipping_preference: "NO_SHIPPING",
return_url: '<?= (isset($_SERVER['HTTPS']) ? "https://" : "http://"). $_SERVER['HTTP_HOST'] . "/order-ok.php" ?>',
user_action: "PAY_NOW",
},
purchase_units: [{
referenmce_id: "mirkos_<?=time()?>",
description: "Ordine #bla bla 12",
soft_descriptor: "Soft_#<?=time()?>",
amount: {
value: '0.04'
}
}]
});
},
})
.render('#paypal-button-container');
User can pay, but simply the popup disappear
After paying, I expected popup will close and the browser redirected user to a new page
Nothing to add for me, now
The props of style in interface PayPalMessagesComponentOptions
is missing.
Running the following code:
try {
paypal = await loadScript({
'client-id': 'YOUR_CLIENT_ID',
'"data-client-token': 'YOUR_CLIENT_TOKEN',
});
} catch (error) {
console.error('failed to load the PayPal JS SDK script', error);
}
if (paypal) {
const options = {
logo: {
type: 'primary',
position: 'left',
},
text: {
color: 'black',
align: 'left',
size: 12
},
};
try {
await paypal.Messages(options).render('YOUR_MESSAGE_CONTAINER_ID');
} catch (error) {
console.error('failed to render the PayPal Buttons', error);
}
}
By following the instruction from Customize Pay Later messages
I tried typing the code above, but Typescript says:
messages.d.ts(4, 5): The expected type comes from property 'style' which is declared here on type 'PayPalMessagesComponentOptions'
Error TS2332(typing error) shouldn't happen.
A clear and concise description of what the bug is.
Describe steps to reproduce. If possible, please, share a link with a minimal reproduction.
A clear and concise description of what is happening. Please include console logs during the time of the issue, especially error messages.
A clear and concise description of what you expected to happen.
Add any other context about the problem here.
Babel/Rollup is not transpiling startsWith()
which breaks in older browsers (es.string.starts-with { "chrome":"49", "edge":"18", "ie":"11" }
)
Possible solutions:
startsWith()
key.startsWith('data-')
and instead use key.substring(0, 5) === 'data-'
One thing to keep in mind with options 1 and 2 is we want to keep the overall bundle size small. Including too many polyfills will bloat this micro-module. I also tested this out in browserstack in IE11. It techincally works if we provide a promise polyfill and don't use startsWith()
.
Thoughts on this?
A clear and concise description of what the bug is.
Describe steps to reproduce. If possible, please, share a link with a minimal reproduction.
A clear and concise description of what is happening. Please include console logs during the time of the issue, especially error messages.
A clear and concise description of what you expected to happen.
Add any other context about the problem here.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.