I want to perform negative testing with a PayPal checkout button
There is one method given in document for REST API. I tried to add header in my paypal render code as per documentation, but doesn't work.
paypal.Button.render({
env: 'sandbox',
client: {
production: 'XXXXX',
sandbox: 'XXXXX'
},
locale: 'en_US',
style: {
size: 'large',
color: 'blue',
shape: 'pill',
tagline: false,
label: 'paypal'
},
headers: {
"PayPal-Mock-Response" : {"mock_application_codes": "INSTRUMENT_DECLINED"}
},
commit: true,
payment: this.paypalPayment,
onAuthorize: this.paypalAuthCallback
}, '#paypal-button');
General REST API negative testing can only be done with a server-side integration, where your server communicates with the PayPal API directly, per https://developer.paypal.com/docs/checkout/reference/server-integration/ , and your front-end UI calls corresponding routes on your server per https://developer.paypal.com/demo/checkout/#/pattern/server
For some generated Card #s (not all Card #s), you can trigger an INSTRUMENT_DECLINED by setting the shipping address to CCREJECT-REFUSED https://developer.paypal.com/docs/archive/express-checkout/ht-ec-fundingfailure10486/#test-your-integration
Whatever you do, update from the old checkout.js (in your code example) to the latest sdk.js ; the client-side demo is here: https://developer.paypal.com/demo/checkout/#/pattern/client
Related
I am making an Ecommerce website which should allow Paypal payments, using Smart Checkout Buttons.
My worry is that everyone can Curl my website, getting the raw HTML+js page and edit the purchase unit values. Once they've done that they could run the webpage, the js code will be executed, the button gets rendered with fake values, and they could fake the payment (with less money).
Is that true? And are there any solutions still using the Smart Button (Without the REST API)?
I cannot create manually the buttons since there will be many articles which are sold by different users.
paypal.Buttons({
// Set up the transaction
createOrder: function(data, actions) {
var o = actions.order.create({
purchase_units: [{
amount: {
value: '30.99' //Can users change this ?
},
payee: {
email_address: 'sb-qloys3515897#business.example.com'//email of the sellers
}
}]
})
return o;
},
// Finalize the transaction
onApprove: function(data, actions) {
console.log(details);
return actions.order.capture().then(function(details) {
// Show a success message to the buyer
//alert('Transaction completed by ' + details.payer.name.given_name + '!');
alert(details);
});
}
}).render('#paypal-button-container');
If you use client-side code only then yes, anyone can edit that client side code right in their browser and pay you any amount they wish, from $0.01 to tens of thousands of dollars.
If this scenario concerns you, then a client-side only integration is obviously too simple for you, and you should instead implement one with your server that does the validation you desire.
Create two routes on your server, one for 'Set Up Transaction' and one for 'Capture Transaction', documented here.
Then have your PayPal button call those two routes; here is the best demo code: https://developer.paypal.com/demo/checkout/#/pattern/server
We are integrating the PayPal client side Checkout Integration for taking payments on our website. This can be found here:
https://developer.paypal.com/docs/checkout/integrate/#6-verify-the-transaction
Once the payment has been made and approved by PayPal, we need to call our server to verify the transaction and store it within our database. This code can be found below, note the part "Call your server to save the transaction".
<script>
paypal.Buttons({
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: '0.01'
}
}]
});
},
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
alert('Transaction completed by ' + details.payer.name.given_name);
// Call your server to save the transaction
return fetch('/paypal-transaction-complete', {
method: 'post',
body: JSON.stringify({
orderID: data.orderID
})
});
});
}
}).render('#paypal-button-container');
</script>
Now, in the above instance, what happens if the call to "/paypal-transaction-complete" fails? session timeout or lost internet connection? For example, in the Stripe integration, the money is "approved" in on the client side and then only confirmed/charged in our API to "/stripe-transaction-complete". If there is an error, we don't actually charge the money.
Within PayPal, the money is charged before the API call, so the is the small possibility we charge the user but they don't receive the paid order in the database. How would we best handle this? one option would be to call the PayPal API and match all the orders with payments and then either auto-refund or auto-complete the order. But I'm not sure if this is recommended.
For both PayPal and similar issues with Stripe Checkout, this can be addressed using WebHooks.
https://developer.paypal.com/docs/integration/direct/webhooks/rest-webhooks/#
I am building a really simple payment form where the user can enter an amount and a thank you message. I have got it successfully working with just the amount but I cannot get add a message field and get it to come through!
Here is just the payment function of my JavaScript:
payment: function(data, actions) {
return actions.payment.create({
payment: {
transactions: [
{
amount: {
total: window.transactionAmount,
currency: 'GBP'
},
note_to_payee: document.getElementById('custom-message').value,
description: 'A gift to Martin.',
custom: 'This is a test custom field',
payee: {
"email": "martin#[hidden].com"
}
}
]
},
experience: {
input_fields: {
no_shipping: 1,
allow_note: true
}
}
});
},
I have tried setting custom and note_to_payee but neither seem to be recorded on either the notification email or the data that is logged in the recipient's account.
I have also tried turning on the ability for the payer to add a note by setting allow_note: true in the experience config but that does nothing!
Please help, just any way of passing through a little message with the payment is all I need.
It took PayPal Support team 4 days to come back with the answer that No, it cannot be done.
Here's their full response:
With regard to your request, I have to inform you that "note to seller" (allow_note:true) field is only available in the older PayPal payment experience, and is not available in the newer payment experience.
Unfortunately, there's nothing the caller can do at this time to force an old or new experience and we recommend to collect this information in your website where possible.
So it looks like they've dropped one of the nicest and most simple features of the PayPal checkout which was the ability to include a friendly little note.
Now, my only option is to build a whole back-end system with API end-points and extend my JavaScript just to record my payer's note. Meanwhile, every email notification I receive will continue to contain that annoying lie: "The buyer hasn't entered any instructions".
PayPal: Please, either implement a feature in your new process or remove/hide the feature! Don't do a half-way job. You take 10% of all my transactions, I expect better.
A workaround for this would be to use an "option variable" to create a textbox in your checkout flow. An example of an option variable would be "os0" and "on0".
Here is an example on our website on how you would implement this: https://www.paypal.com/us/cgi-bin/webscr?cmd=_pdn_xclick_options_help_outside
https://developer.paypal.com/sdk/js/reference/#onapprove
paypal.Buttons({
createOrder: function(data, actions) {
...
},
onApprove: function(data, actions) {
// This function captures the funds from the transaction.
return actions.order.capture().then(function(details) {
// This function shows a transaction success message to your buyer
alert('Transaction ' + transaction.status + transaction.id);
window.location.href = 'https://www.yoursite.com/page.php?trnsid='+ transaction.id;
});
}
}).render('#paypal-button-container');
You can do a redirect onApprove.
If the transaction was completed redirect the user to a page with a FORM THAT GET/capture the transactionID (associate the message with a transaction) and ADD a MESSAGE TEXTAREA so user can send some notes after payment.
I'm currently investigating whether or not it would be possible to use the recent version of Paypal Express Checkout (checkout.js v4) to add it as payment option for a website that has recurring donations.
I'm aware of the old NVP/SOAP version, which is currently flagged as deprecated.
I've checked through the (numerous) documentation pages on the new checkout, starting here and so forth.
I'm also aware of the Billing Plans & Billing Agreement APIs.
I can find plenty of examples using the old NVP but not this combination.
Is it possible to do using these?
Are there any official(ish) examples of this?
You can still use the TOKEN from the NVP api with the javascript integration, by passing it back in the payment() call:
<script src="https://www.paypalobjects.com/api/checkout.js">
</script>
<script>
var CREATE_PAYMENT_URL = 'https://my-store.com/paypal/create-payment';
paypal.Button.render({
env: 'production', // Optional: specify 'sandbox' environment
payment: function() {
return paypal.request.post(CREATE_PAYMENT_URL).then(function(data) {
return data.token;
});
},
onAuthorize: function(data, actions) {
return actions.redirect();
},
onCancel: function(data, actions) {
return actions.redirect();
}
}, '#paymentMethods');
</script>
I'm merchants using it payment api.
I had completed the sandbox sample.
It was confirmed that payment in the sandbox account.
But suddenly it is not working. Program code is not changed.
`"error : This transaction is invalid.
Please return to the recipient's website to complete your transaction using their regular checkout flow."`
A "sandbox" is not working.
But it works if i switch to "live".
I have to test more than 20 days in the same way.
Suddenly, should not I do not know why. :(
See the following (approval_url)
{ id: 'PAY-3YF970037H573622HK7QOABY',
intent: 'sale',
state: 'created',
payer: { payment_method: 'paypal' },
transactions:
[ { amount: [Object],
description: 'This is the payment description.',
custom: '1',
item_list: [Object],
related_resources: [] } ],
create_time: '2016-09-20T07:06:46Z',
links:
[ { href: 'htt ps://api.sandbox.paypal.com/v1/payments/payment/PAY-3YF970037H573622HK7QOABY',
rel: 'self',
method: 'GET' },
{ href: 'htt ps://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-8W611604UP656490X',
rel: 'approval_url',
method: 'REDIRECT' },
{ href: 'htt ps://api.sandbox.paypal.com/v1/payments/payment/PAY-3YF970037H573622HK7QOABY/execute',
rel: 'execute',
method: 'POST' } ],
httpStatusCode: 201 }
"approval_url" is not the sandbox
'execute' and 'self' are the sandbox
It has been changed point
Today error information has changed.
"error : This transaction has expired. Please return to the recipient's website to complete your transaction using their regular checkout flow."
The contents of approval_url is the same.
But it is forced to put a "sandbox" in approval_url.
paypal page(approval_url) is loaded.
This way did not work yesterday.
But it work today.
I sent e-mail to paypal echnical support.
paypal came the answer :
"
Hi
Based from the full logs, it seems that the buyer account that you used for this case is hitting a risk issue in attempting to pay for the payment.
I suggest for you to clear cookies and cache and then retry again using other sandbox account.
Thanks
"
However, it is now working fine.
So the correct answer can not be tested.
I think there is something wrong with "EC", I'm trying to follow de the REST API exmples and I get the same results...
Any one