I'm trying to integrate PayPal Express Checkout using their checkout.js and instructions provided here: /
Whenever I click the 'PayPal' button, I get an error about indexOf of undefined ing from the checkout.js script. I do get the modal popup flash very quickly and then disappear.
TypeError: Cannot read property 'indexOf' of undefined
at Object.onSuccess (.js:11449:30)
at _loop2 (.js:1670:62)
at SyncPromise.dispatch (.js:1700:29)
at SyncPromise.then (.js:1718:18)
at Component.buildUrl (.js:11448:40)
at Object.onSuccess (.js:8770:57)
at _loop2 (.js:1670:62)
at SyncPromise.dispatch (.js:1700:29)
at SyncPromise.then (.js:1718:18)
at Function.syncPromiseTry [as try] (.js:1763:42)"
The line it's referencing is within checkout.js:
return props.payment().then(function(token) {
if (token.indexOf("BA-") === 0) {
The code I'm using is straight from PayPal's documentation:
paypal.Button.render({
env: 'sandbox', // Specify 'sandbox' for the test environment
payment: function() {
var CREATE_PAYMENT_URL = '/api/checkout/create-express-payment';
paypal.request.post(CREATE_PAYMENT_URL)
.then(function(data) {
console.log('Payment ID: ', data.paymentId);
resolve(data.paymentId);
})
.catch(function(err) {
reject(err);
});
},
onAuthorize: function(data, actions) {
// Execute the payment here, when the buyer approves the transaction
}
}, '#paypal-button');
I can confirm data.paymentId is in fact ing back with a proper Payment ID, and I've even tried hard coding it into the resolve
call. This error seems to occur before my internal API even gets called to get the payment ID (and then again after it gets called).
I have been trying to reach PayPal technical support for a week now and have not even received an acknowledgement after many requests. Additionally I can't test the REST APIs on Heroku because their sandbox takes over 30 seconds to respond and Heroku times out. This will be the last time I ever use PayPal on a project... and at this rate looks like I need to change from this project ASAP.
I'm trying to integrate PayPal Express Checkout using their checkout.js and instructions provided here: https://developer.paypal./docs/integration/direct/express-checkout/integration-jsv4/advanced-integration/
Whenever I click the 'PayPal' button, I get an error about indexOf of undefined ing from the checkout.js script. I do get the modal popup flash very quickly and then disappear.
TypeError: Cannot read property 'indexOf' of undefined
at Object.onSuccess (https://www.paypalobjects./api/checkout.js:11449:30)
at _loop2 (https://www.paypalobjects./api/checkout.js:1670:62)
at SyncPromise.dispatch (https://www.paypalobjects./api/checkout.js:1700:29)
at SyncPromise.then (https://www.paypalobjects./api/checkout.js:1718:18)
at Component.buildUrl (https://www.paypalobjects./api/checkout.js:11448:40)
at Object.onSuccess (https://www.paypalobjects./api/checkout.js:8770:57)
at _loop2 (https://www.paypalobjects./api/checkout.js:1670:62)
at SyncPromise.dispatch (https://www.paypalobjects./api/checkout.js:1700:29)
at SyncPromise.then (https://www.paypalobjects./api/checkout.js:1718:18)
at Function.syncPromiseTry [as try] (https://www.paypalobjects./api/checkout.js:1763:42)"
The line it's referencing is within checkout.js:
return props.payment().then(function(token) {
if (token.indexOf("BA-") === 0) {
The code I'm using is straight from PayPal's documentation:
paypal.Button.render({
env: 'sandbox', // Specify 'sandbox' for the test environment
payment: function() {
var CREATE_PAYMENT_URL = '/api/checkout/create-express-payment';
paypal.request.post(CREATE_PAYMENT_URL)
.then(function(data) {
console.log('Payment ID: ', data.paymentId);
resolve(data.paymentId);
})
.catch(function(err) {
reject(err);
});
},
onAuthorize: function(data, actions) {
// Execute the payment here, when the buyer approves the transaction
}
}, '#paypal-button');
I can confirm data.paymentId is in fact ing back with a proper Payment ID, and I've even tried hard coding it into the resolve
call. This error seems to occur before my internal API even gets called to get the payment ID (and then again after it gets called).
I have been trying to reach PayPal technical support for a week now and have not even received an acknowledgement after many requests. Additionally I can't test the REST APIs on Heroku because their sandbox takes over 30 seconds to respond and Heroku times out. This will be the last time I ever use PayPal on a project... and at this rate looks like I need to change from this project ASAP.
Share Improve this question edited Dec 30, 2016 at 7:32 Ryan asked Dec 28, 2016 at 4:06 RyanRyan 18.1k24 gold badges64 silver badges90 bronze badges3 Answers
Reset to default 5I had this issue. My use case is Express Checkout (client) and Paypal SDK (server). Paypal refers to this as Advanced Integration.
I resolved this problem as follows:
I let my Server return a JSON object as response with the single property "paymentID". This is explained in the Advanced Integration page of the Paypal documentation, however its importance is not stated clearly enough.
Look at step 4 of that documentation, which makes clear what you need to return:
Your server sends a response to your client to pass back the payment ID:
{ "paymentID": "PAY-0J356327TH335450NK56Y2PQ" }
The checkout.js processes this return value as the "token" parameter.
Here is the code that works for me:
paypal.Button.render({ env: 'sandbox', payment: function(resolve, reject) { var CREATE_PAYMENT_URL = 'http://localhost/api/payment/create'; paypal.request.post(CREATE_PAYMENT_URL, { // js object used to create payment }).then(function(data) { resolve(data.paymentID); }).catch(function(err) { reject(err); }); }, onAuthorize: function(data) { var EXECUTE_PAYMENT_URL = 'http://localhost/api/payment/execute'; paypal.request.post(EXECUTE_PAYMENT_URL, { // js object used to plete payment // needs to include properties for paymentID and payerID }).then(function(data) { // process results after transaction is pleted }).catch(function(err) {}); }, onCancel: function(data) {} }, '#paypal-button');
Right now you have:
payment: function() {
This needs to be:
payment: function(resolve, reject) {
Otherwise the resolve
and reject
functions aren't going to be available to pass the paymentID back to checkout.js.
This solution was really helpful, but instead of the payid we can pass the token id received from paypal to resolve method, resolve(data.tokenid); and instead of paypal.request.post method we can make a ajax call, the code will be like,
<script src="https://www.paypalobjects./api/checkout.js"></script>
<div id="paypal-buttoncheckout"></div>
paypal.Button.render({
env: "sandbox", // Optional: specify 'sandbox' environment
locale: //your respective locale,
payment: function(resolve, reject) {
var CREATE_PAYMENT_URL = //URL for creating payment
$.ajax({
type:'POST',
dataType : 'html',
contentType: 'application/html',
url : CREATE_PAYMENT_URL,
success : function(data){
resolve(data.tokenid);
},
error : function(response){
}
});
},
onAuthorize: function(data) {
// Note: you can display a confirmation page before executing
var EXECUTE_PAYMENT_URL = //reauthorize URL;
paypal.request.post(EXECUTE_PAYMENT_URL,
{ paymentID: data.paymentID, payerID: data.payerID,token: data.paymentToken })
.then(function(data) { window.location = //SUCCESS PAGE })
.catch(function(err) { window.location = //ERROR PAGE});
},
onCancel: function(data, actions) {
window.location = //ON CANCEL URL
}
}, '#paypal-buttoncheckout');
Thanks, Manoj