Reputation: 3589
How can I ensure the security of my payment system via PayPal?
I use the vue-paypal-check create the frontend PayPal button for the payment.
the code is bellow:
<Pay-Pal
v-if="paypal_live_id && paypal_sandbox_id"
:amount="amount"
currency="USD"
:client="credentials"
:env="paypal_env"
@payment-authorized="payment_authorized_cb"
@payment-completed="payment_completed_cb"
@payment-cancelled="payment_cancelled_cb"
:items="pay_items"
>
</Pay-Pal>
some dota is bellow:
data(){
return {
paypal_env: this.$GLOBAL_CONST.PAYMENT.PAYPAL_ENV,
paypal_sandbox_id: undefined,
paypal_live_id: undefined,
}
},
computed: {
credentials() {
return {
sandbox: this.paypal_sandbox_id,
production: this.paypal_live_id,
}
},
},
the callback method of pay success:
payment_completed_cb(res){
some method to access API for payment success // there will request the API for change the order status or reduce the balance.
},
but I have a question, if someone of customer is evil with technology, he call the payment_completed_cb
directly, not pass the paypal payment.
How can I prevent this?
Upvotes: 5
Views: 598
Reputation: 69681
There needs to be a server-to-server communication outside of your front-end checkout flow between Paypal's server and yours.
You can use Instant Payment Notification (IPN) for this.
vue-paypal-check shows you can put an IPN url in (with notify-url
)
<PayPal
amount="10.00"
currency="USD"
:client="credentials"
notify-url="<your-ipn-url>">
</PayPal>
Per Paypal, you shouldn't wait for the IPN notification to complete the checkout flow, but you also shouldn't fulfill the order until you receive it.
The worst someone could do by calling payment_complete_cb
directly is get to some meaningless checkout complete page. They would not be able to get goods from you without payment though.
Upvotes: 2
Reputation: 5014
This can't be safely handled in the frontend. As you've pointed out someone could manually invoke that payment_completed_cb
function.
The code you have is purely for User Experience. Someone clicks buy, they go to paypal, purchase, get redirected back and your website says "thanks". Which is all that function should do, handle the display of some thank you prompt.
A payment may appear to go through but can take time to resolve. So paypal will respond with a "looks good" message and redirect a customer back to your site. And later truly complete the tranfser. One example maybe if while processing the transaction Paypal decides it looks fraudulent they can cancel the payment.
To get around all of this the actual handling of the payment confirmation will happen on a server. You can configure Paypal to ping a server of your choosing when a payment is actually confirmed (it'll also be hidden from a customer). This is called Instant Payment Notification (IPN)
Picture from this ipn introductory post
You can do this with NodeJS and deploy as a Serverless function to AWS (first million requests free). Or deploy to a free Heroku instance. These are both cheap options but have small start up times if the server has been idle. In my experience its only been 200-300ms just a fraction of a second to start. Which is too long to respond to an HTML request but perfect for a handling an eventual ping from some background API.
Example Node implementation from paypal ipn
var ipn = require('paypal-ipn');
ipn.verify(params, function callback(err, msg) {
if (err) {
console.error(err);
} else {
// Do stuff with original params here
if (params.payment_status == 'Completed') {
// Payment has been confirmed as completed
}
}
});
//You can also pass a settings object to the verify function:
ipn.verify(params, {'allow_sandbox': true}, function callback(err, mes) {
//The library will attempt to verify test payments instead of blocking them
});
For an in-depth guide with intgration steps Paypal has the documentation Paypal IPN
Upvotes: 1