Javascript database trouble - javascript

So I have successfully implemented paypal to my page but I need to know how to check if the payment was approved (which I have) and then changed their payed status in my database.
payed = 0 : user has not bought service
payed = 1 : user has bought service
<div id="smart-button-container">
<div style="text-align: center;">
<div id="paypal-button-container"></div>
</div>
</div>
<script src="https://www.paypal.com/sdk/js?client-id=myid&currency=EUR" data-sdk-integration-source="button-factory"></script>
<script>
var payment_valid;
function initPayPalButton() {
paypal.Buttons({
style: {
shape: 'rect',
color: 'black',
layout: 'vertical',
label: 'paypal',
},
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{"description":"Premium","amount":{"currency_code":"EUR","value":0.1}}]
});
},
//Need to insert something here into my database
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
alert('Transaction completed by ' + details.payer.name.given_name + '!' + ' data:' + data);
});
},
onError: function(err) {
console.log(err);
}
}).render('#paypal-button-container');
}
initPayPalButton();
</script>

To record payment status in your database, capture from your server via an API to get the success status. Do not use actions.order.capture() on the client side, since there is no guarantee of being able to record a successful capture on your server if you do that.
So, for a proper server integration, create two routes -- one for 'Create Order' and one for 'Capture Order', as documented here. Your routes should return/output JSON (and only JSON). The capture route should check for success after calling PayPal and do any database writing before returning JSON to the client.
Pair your two routes with the following approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server

Related

PayPal JavaScript SDK button opens about:blank#blocked window in Django template but not in local HTML file

I've been trying to integrate PayPal buttons on my Django website, but I keep having this problem where the PayPal popup window appears as about:blank#blocked. I can see this error in console:
popup_open_error_iframe_fallback
{err: 'n: Can not open popup window - blocked\n at Ie (…owser=false&allowBillingPayments=true:1342:297830', timestamp: '1644780862712', referer: 'www.sandbox.paypal.com', sdkCorrelationID: 'f12370135a997', sessionID: 'uid_d36969c1b2_mtk6mja6mzy', …}
What I don't understand is that the problem isn't there if I just open the HTML file itself in a browser... The script looks like this:
<!-- Set up a container element for the button -->
<div id="paypal-button-container" class='text-center mt-2'></div>
<!-- Include the PayPal JavaScript SDK -->
<script src="https://www.paypal.com/sdk/js?client-id=blahblahmyid&currency=EUR"></script>
<script>
// Render the PayPal button into #paypal-button-container
paypal.Buttons({
locale: 'it_IT',
style: {
color: 'gold',
shape: 'rect',
layout: 'vertical',
label: 'pay'
},
// Set up the transaction
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: '88.44'
}
}]
});
},
// Finalize the transaction
onApprove: function(data, actions) {
return actions.order.capture().then(function(orderData) {
// Successful capture! For demo purposes:
console.log('Capture result', orderData, JSON.stringify(orderData, null, 2));
var transaction = orderData.purchase_units[0].payments.captures[0];
alert('Transaction '+ transaction.status + ': ' + transaction.id + '\n\nSee console for all available details');
// Replace the above to show a success message within this page, e.g.
// const element = document.getElementById('paypal-button-container');
// element.innerHTML = '';
// element.innerHTML = '<h3>Thank you for your payment!</h3>';
// Or go to another URL: actions.redirect('thank_you.html');
});
}
}).render('#paypal-button-container');
</script>
What's the problem ? I don't understand.
There's a new feature in django 4.0 that follows the addition of the COOP header in newer browsers which, as I understand it, stops remote sites from opening a window in the same browsing context.
The default setting of SECURE_CROSS_ORIGIN_OPENER_POLICY in django isolates the browsing context to just the current document origin. Setting it to same-origin-allow-popups allows the paypal popup to open in the current context.
See https://docs.djangoproject.com/en/4.0/ref/middleware/#cross-origin-opener-policy
TLDR; set SECURE_CROSS_ORIGIN_OPENER_POLICY='same-origin-allow-popups'
For django 4.0 settings.py add
SECURE_CROSS_ORIGIN_OPENER_POLICY='same-origin-allow-popups'

Paypal button event onshippingChange is not working at all can somebody tell me why?

Can somebody tell me why? This is a simple integration of paypal sdk for javascript. And It is working fine except that the event bellow onShippingChange is never fired. I've searching this for 2 days now. I need to update my price according to the user address.
src="https://www.paypal.com/sdk/js?client-id=XXXXXXXXX"> // Required. Replace SB_CLIENT_ID with your sandbox client ID.
</script>
<div id="paypal-button-container"></div>
<script>
paypal.Buttons({
createOrder: function(data, actions) {
// This function sets up the details of the transaction, including the amount and line item details.
console.log('createOrder ' + data);
return actions.order.create({
application_context : {
shipping_preference: 'SET_PROVIDED_ADDRESS'
},purchase_units: [{
shipping: {
address: {
address_line_1: '555 example bs',
admin_area_2: 'San bastard',
admin_area_1: 'CA',
postal_code: '95111',
country_code: 'CA'
}
},
amount: {
value: '0.01'
}
}]
});
},
onApprove: function(data, actions) {
console.log('onApprove ' + data);
// 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 completed by ' + details.payer.name.given_name);
});
},
onClientAuthorization: (data) => {
console.log('onClientAuthorization - you should probably inform your server about completed transaction at this point', data);
this.showSuccess = true;
},
onShippingChange: (data, actions) => {
// this event is never fired no matter what I do
console.log('onShippingChange - Shipping information have changed', data, actions);
},
onCancel: (data, actions) => {
console.log('OnCancel', data, actions);
},
onError: err => {
console.log('OnError', err);
},
onClick: (data, actions) => {
console.log('onClick', data, actions);
}
}).render('#paypal-button-container');
//This function displays Smart Payment Buttons on your web page.
</script>
here is the solution of this question first of the shippings fees can only be managed after you enable it on your account (Login to PayPal >> Hover over to the profile name >> Account Settings >> Shipping >> Here you can create shipping profiles as per your requirements.) it will be available only for customer who pay from a paypal account. For any other payment you won't be able to manage it.
Regards

PayPal integration 400 Bad Request / Order could not be captured

I'm trying to integrate PayPal and I get the error below
You can test the code here with any PayPal sandbox buyer account:
Codepen
Here is the code I'm using
paypal.Buttons({
createOrder: function (data, actions) {
// This function sets up the details of the transaction, including the amount and line item details.
return actions.order.create({
purchase_units: [{
amount: {
value: '5.00'
}
}]
});
},
onApprove: function (data, actions) {
// This function captures the funds from the transaction.
return actions.order.capture().then(details => {
// This function shows a transaction success message to your buyer.
alert('Transaction completed by ' + details.payer.name.given_name);
});
}
}).render('#paypal-button-container');
more about the error
Testing your Codepen from the Network tab, you are getting a COMPLIANCE_VIOLATION -- probably due to the country of the account you are testing with not being properly set up in sandbox.
Try simply using a different country for your testing within sandbox. Create a new business account at https://www.paypal.com/signin?intent=developer&returnUri=https%3A%2F%2Fdeveloper.paypal.com%2Fdeveloper%2Faccounts%2F , and then create a new REST app with a new ClientID/Secret for it.

PayPal Smart Button updated via Ajax

I have a shopping cart which is updated via Ajax (quantity, removing of products). How do I update the value in the Smart Button iframe? It obviously works when I refresh the page, but how to do it in the background with Ajax? I have tried reloading the PayPal iframe using a hack which bypasses the same origin policy but it didn't work, the Smart Button disappeared.
This is the hack I'm talking about:
const iframe = document.querySelector("iframe");
iframe.src = iframe.src
This is my Smart Button code:
<script>
paypal.Buttons({
style: {
shape: "rect",
color: "gold",
layout: "horizontal",
label: "checkout",
size: "responsive",
tagline: "false"
},
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
currency_code: "GBP",
value: <?php echo number_format($total, 2); ?>
},
}]
});
},
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
alert("Dear " + details.payer.name.given_name + ", Thank you for your payment!");
});
},
onShippingChange: function(data, actions) {
if (data.shipping_address.country_code !== "GB") {
return actions.reject();
}
return actions.resolve();
}
}).render("#paypal-button-container");
}
</script>
Change this line:
value: <?php echo number_format($total, 2); ?>
To call a JavaScript function, which you will need to write and serve as part of the page
value: getCartTotal()
Somewhere, perhaps at the top of the <script>, you will have something like:
window.myCartTotal = '<?php echo number_format($total, 2); ?>';
function getCartTotal() {
return window.myCartTotal;
}
Then have your AJAX also update window.myCartTotal
There are many more elegant ways to code this, but that should get you going.
The proper server-side solution
For best results you shouldn't be setting the amount on the client side's createOrder, and perhaps even more importantly not capturing on the client side. Doing these things on the client side opens you to a whole series of issues and problems. Instead, have the client side call two routes on your server, one for 'Create Transaction' and another for 'Set Up Transaction', documented here: https://developer.paypal.com/docs/checkout/reference/server-integration/
Then, use those two new routes following button approval code's ajax/fetch calls: https://developer.paypal.com/demo/checkout/#/pattern/server

PayPal Smart Buttons (Subscription) using paypal.FUNDING.CARD button update_client_config_error

I'm implementing the Paypal Smart buttons to my website for subscription, with the following code:
paypal.Buttons({
commit: false,
createSubscription: function(data, actions) {
return actions.subscription.create({
plan_id: 'P-4688500211745173CL4LO52Y'
});
},
onCancel: function (data) {
},
onApprove: function(data, actions) {
}
}).render('#paypal-button-container');
I subscribed via Debit Or Credit Card (paypal.FUNDING.CARD button). It returns the JSON data for subscription:
{
billingToken: "BA-28952229JX1690450"
facilitatorAccessToken: "A21AAF2g9HmhCrpdlvKv82KzTOL7s-
h7udVM63Jx6PoEQJvhRHUKZXuxdEewBWbAlh7Tta44GREGBKPqydgSaWBdTZBInLTMA"
orderID: "91D07990YA8971453"
subscriptionID: "I-EN0D6RAEFN8R"
}
But when I need to downgrade or upgrade the current subscription using https://api.sandbox.paypal.com/v1/billing/subscriptions/I-EN0D6RAEFN8R/revise API endpoint base on the PayPal docs. https://developer.paypal.com/docs/business/subscriptions/add-capabilities/revise-subscriptions/
The PayPal window automatically close and I get the error: "Uncaught Error: Api: /smart/api/billagmt/subscriptions/I-EN0D6RAEFN8R/cartid returned status code: 500 (Corr ID: e0a949aefc835)"
This is my code to revise subscription:
paypal.Buttons({
commit: false,
createSubscription: function(data, actions) {
return actions.subscription.revise('I-EN0D6RAEFN8R', {
plan_id: 'P-0P5665289K689682KL4MD5PQ'
});
},
onCancel: function (data) {
},
onApprove: function(data, actions) {
}
}).render('#paypal-button-container');
Note: Subscribing via PayPal Account (paypal.FUNDING.PAYPAL button) doesn't have the error that I'm encountering when I subscribe via PayPal Credit Or Debit Card. I can also upgrade or downgrade the subscription plan using the revise code above.
Anybody experienced the same issue?
The behavior makes sense, you need to log into a PayPal account to approve revising a subscription.
When there is nothing to log into, there is no way to approve a revision on the client side. Your own authorized server-side API call is necessary to modify/cancel it. You can have the user sign up again (new profile) and cancel the original one.

Categories